Здравствуйте, надеюсь там все в порядке! Сегодня в этой статье у нас есть три разные части. В первой части я хочу поделиться с вами тематической историей, чтобы ввести вас в тему.

Во второй части мы углубимся в процесс. Вы изучите некоторые из методов веб-парсинга. Затем, конечно же, процесс EDA. Когда мы завершим манипулирование данными, мы перейдем к последней части.

В последней части вы познакомитесь с тремя основными шагами.
– Разработка признаков.
– Выбор и развитие модели.
– Прогнозирование с помощью модели. .

Итак, позвольте мне рассказать вам историю Octopus Prime

Давным-давно в антиутопическом мире жил робот по имени Осьминог. Octopus был создан группой фанатичных футбольных специалистов по данным, которые хотели иметь преимущество в прогнозировании результатов матчей. Octopus получал всю статистику, результаты игроков и другие данные о командах и их игроках.

Все начинается с группы увлеченных специалистов по данным.

Они нашли Пола Осьминога симпатичным и решили создать своего Осьминога. Его называли «Осьминог Прайм». Робот умеет предсказывать голы футбольных матчей.

Они начали кормить его всей статистикой. Осьминог начинает зарабатывать деньги. Осьминог учился довольно быстро. Эта модель начала принимать собственные решения. Он хочет купить шикарную машину. Он создал модель для изучения цен на автомобили.

У Осьминога есть деньги, но, в конце концов, он был чужаком в человеческом мире.

Он начал искать все об автомобилях. Ему немного не повезло, потому что он был создан в Турции.

Он решил сосредоточиться на самых продаваемых подержанных автомобилях в 2022 году.

Для создания регрессионной модели сначала он сделал веб-скрейпинг. После того, как он собрал данные, он был готов накормить себя! Он оценивает многие модели. Наконец-то найти лучший!

В те дни Осьминог Прайм был свободен и счастлив, но так продолжалось недолго.

За короткое время правительство взяло его под свой контроль и использовало в своих интересах, что привело к повсеместному недоверию и страху среди населения.

Осьминог, когда-то инструмент для любителей спорта, был испорчен властью, которой он обладал, и начал манипулировать результатами матчей в своих интересах, превратив его в злое существо.

ИСТОЧНИК ДАННЫХ И ИНСТРУМЕНТЫ ДЛЯ ОЧИСТКИ ВЕБ

Для процесса очистки веб-страниц мы будем использовать библиотеки urllib и BeautifulSoup в Python. Нашим источником данных является турецкий веб-сайт подержанных автомобилей «arabam.com».

###Necessary Libraries###
from urllib.request import urlopen
import requests
from bs4 import BeautifulSoup as bts
import pandas as pd 
import re
import numpy as np
import time
### A Function to take links from Website###
def getAndParseURL(url):
    result=requests.get(url,headers={"User-Agent":"Chrome/109.0.5414.120"})
    soup=bts(result.text,"html.parser")
    return soup
### For Collecting All Links in Each Page ###
pages=["https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50"]
for page in range(2,51):
    pages.append("https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=" +str (page))
    
pages
['https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=2',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=3',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=4',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=5',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=6',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=7',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=8',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=9',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=10',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=11',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=12',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=13',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=14',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=15',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=16',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=17',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=18',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=19',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=20',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=21',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=22',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=23',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=24',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=25',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=26',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=27',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=28',
 'https://www.arabam.com/ikinci-el/otomobil/renault-clio?take=50&page=29',
......]

Время собрать все ссылки на автомобили на страницах

Атрибут href указывает URL-адрес страницы, на которую ведет ссылка.

Если атрибут href отсутствует, тег <a> не будет гиперссылкой.

Совет. Вы можете использовать href="#top" или href="#" для ссылки на начало текущей страницы!

Для этого сначала мы должны «Проверить» ссылку и попытаться найти «href».

### Collecting all car links in a list! ###
cars=[]

for page in pages:
    html=getAndParseURL(page)
    for carlink in html.findAll("td",{"class":"listing-modelname pr"}):
        cars.append("https://www.arabam.com/"+carlink.a.get("href"))
        
cars
['https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-touch/kale-otomotiv-den-2018-touch-dizel-otomatik-degisensiz/21907028',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-2-authentique/orjinal-aile-arabasi/21906665',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-0-tce-joy/2022-tam-otomatik-vites-hatasiz-boyasiz-turbo-motor-clio/21905162',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-joy/e-force-guvencesiyle-2016-dusuk-km-temiz-renault-clio-1-5-dci/21898316',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-touch/beyazkent-otomotiv-den-2018-clio-touch/21806590',
 'https://www.arabam.com//ilan/sahibinden-satilik-renault-clio-1-2-turbo-joy/acili-sahibinden-hatasiz-boyasiz-tramersiz-dusuk-km/21877860',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-0-tce-joy/otomobil-renault-clio-hatchback-1-0-tce-joy-x-tronic/21859662',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-touch/renault-clio-1-5-dci-touch-2019-model/21870379',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-2-expression/gosterisli-renault-cli-1-2-16-v-lpgli-2005-model/21870007',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-0-tce-touch/hatasiz-boyasiz-2022-model-renault-clio-1-0-tce-touch-otomatik/21869762',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-0-tce-joy/abakay-otomotiv-den-hatasiz-boyasiz-clio-1-0-tce-18-faturali/21862559',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-sporttourer-joy/hatasiz-boyasiz-sifir-ayarinda/21859577',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-grandtour-extreme/renault-clio-1-5-dci-grandtour-extreme-2012-model-antalya/21851768',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-sporttourer-joy/galeriden-renault-clio-1-5-dci-sporttourer-joy-2013-model-mugla/21812256',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-5-dci-joy/galeriden-renault-clio-1-5-dci-joy-2019-model-denizli/21803907',
 'https://www.arabam.com//ilan/galeriden-satilik-renault-clio-1-0-tce-touch/otomobil-renault-clio-hatchback-1-0-tce-touch-x-tronic/21797303'
.....]

Теперь нам нужно найти наши данные в HTML

Теперь нам нужно создать список для хранения всех этих данных об автомобилях. Это будет довольно длинный цикл. Он должен работать без ошибок. Для этого воспользуемся функцией «time.sleep». и попробуйте и ожидайте для каждой функции.

features = []
for carl in cars:
    html=getAndParseURL(carl)
    try:
        brand =html.find("ul",{"w100 cf mt12 detail-menu"}).find(text=re.compile("Marka")).findNext().text.strip()
    except:
        brand = np.nan
    try:
        model=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Model")).findNext().text.strip()
    except:
        model=np.nan
    try:
        year=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Yıl")).findNext().text.strip()
    except:
        year=np.nan
    try:
        km=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Kilometre")).findNext().text.strip()
    except:
        km=np.nan
    try:
        engsize=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Motor Hacmi")).findNext().text.strip()
    except:
        engsize=np.nan
    try:
        hp=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Motor Gücü")).findNext().text.strip()
    except:
        hp=np.nan
    try:
        fuel=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Yakıt Tipi")).findNext().text.strip()
    except:
        fuel=np.nan
    try:
        gear=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Vites Tipi")).findNext().text.strip()
    except:
        gear=np.nan
    try:
        fuelcoms=html.find("ul",{"class":"w100 cf mt12 detail-menu"}).find(text=re.compile("Yakıt Tüketimi")).findNext().text.strip()
    except:
        fuelcoms=np.nan
    try:
        price=html.find("div",{"class":"color-red4 font-default-plusmore bold fl"}).text.strip()
    except:
        price=np.nan
                    
    features.append([brand,model,year,km,engsize,hp,fuel,gear,fuelcoms,price])
    
    time.sleep(2)
[['Renault',
  '1.5 dCi Touch',
  '2018',
  '110.000 km',
  '1461 cc',
  '90 hp',
  'Dizel',
  'Yarı Otomatik',
  '3,7 lt',
  '525.000 TL'],
 ['Renault',
  '1.2 Authentique',
  '2004',
  '133.500 km',
  '1149 cc',
  '75 hp',
  'Benzin',
  'Düz',
  '5,9 lt',
  '227.000 TL'],
...............]

Concat Все данные в кадре данных.

Очистка и предварительная обработка данных

В этой части мы проведем исследовательский анализ данных
Преобразование типов данных.

  • Избавление от специальных символов.
  • Обнаружение выбросов.
  • Обнаружение значений NaN.
  • Переиндексация.
  • Проверка дубликатов

После объединения всех кадров данных у нас есть один беспорядочный кадр данных.

Для подачи нашей модели прогнозирования ваши данные должны быть числовыми. Мы хотим преобразовать набор данных в Float или Int.

all_cars["Year"]=all_cars["Year"].astype(int)
all_cars["Age"]=2023-all_cars["Year"]

all_cars["Km"]=all_cars["Km"].str.replace("km", "")
all_cars["Km"]=all_cars["Km"].str.replace(".", "")
all_cars["Km"]=all_cars["Km"].astype(float).astype(int)

all_cars["EngSize"]=all_cars["EngSize"].str.replace(" cc", "")
all_cars["EngSize"]=all_cars["EngSize"].str.replace(" cm3", "")
all_cars["EngSize"]=all_cars["EngSize"].str.replace(" -", "")
all_cars['EngSize'] = all_cars['EngSize'].str.split(" ").str[0].astype(int)
.
.
.
.

Разработка функций

  • Поиск взаимосвязей между функциями.
  • Изменение функций
  • Создание новых функций
  • Изменение цели
  • Улучшение дистрибутивов

Преобразование нечисловых данных

Мы собираемся использовать фиктивное кодирование. Прежде чем мы применим фиктивную функцию. Мы должны преобразовать наш тип данных в «категорию».

### Converting data type as category ###
cols_to_convert = ["Fuel", "Gear Type", "Brand"]
for col in cols_to_convert:
    all_cars[col] = all_cars[col].astype("category")

### Apllying Dummy Func.### 
dummies = pd.get_dummies(all_cars[cols_to_convert],drop_first=True)
all_cars = pd.concat([all_cars, dummies], axis=1)
all_cars = all_cars.drop(cols_to_convert, axis=1)

### Important Reminder For Avoiding Dummy Trap You Should Remove First row###

Поиск взаимосвязей между функциями

plt.figure(figsize=(8,4))
sns.heatmap(all_cars.corr(), cmap="YlGnBu", annot=True);
plt.show()

Парный график отображает парные отношения в наборе данных. Функция парного графика создает сетку осей, так что каждая переменная в данных будет распределяться по оси Y по одной строке и по оси X по одному столбцу. Это создает графики, как показано ниже.

Получение лучшего распределения наших данных

### Getting Rid Of Outliers###
all_cars = all_cars.loc[(all_cars["Km"] >= 2000) & (all_cars["Km"] <= 500000),:]
sns.histplot(all_cars["Km"]);

all_cars=all_cars.loc[all_cars["Year"]<=2022,:]
sns.histplot(all_cars["Year"]);

all_cars=all_cars.loc[all_cars["EngSize"]<=2000,:]
sns.histplot(all_cars["EngSize"]);

all_cars=all_cars.loc[all_cars["Price"]<=1000000,:]
sns.histplot(all_cars["Price"])
.
.
.
.

Выбор и оценка модели

  • Разделите данные по тесту и поезду
  • Проверьте переоснащение и недообучение
  • Проверьте смещение и дисперсию
  • Выбор модели
  • Сравнение моделей

Линейная, лассо, гребенчатая регрессия

### StatsModel for statistical data exploration ###
y = df_new["PriceLog"]
X = df_new.drop(columns=["PriceLog"])
X = sm.add_constant(X)
model=sm.OLS(y,X)

fit=model.fit()

fit.summary()

### Linear Regression ###
lr_model=LinearRegression()
lr_model.fit(X_train,y_train)

validation_score=lr_model.score(X_val,y_val)
validation_score

lr_model.score(X_train,y_train)

### Lasso ###
test_set_pred=lasso_model.predict(X_val)
print("R2 of Lasso Model",r2_score(y_val,test_set_pred))

### Ridge ###
test_set_pred2=ridge_model.predict(X_val)
print("R2 of Ridge Model",r2_score(yval,test_set_pred2))

Сравнение моделей

Сравнение реальной цены и прогноза

ПО СУТИ….

Вы, может быть, и не Осьминог, но авторынок для всех немного хитер!

Если вы хотите купить подержанный автомобиль, доверьтесь Power of Data!

Спасибо за ваше время!