抓取预测二手车价格的机器学习模型

一、说明

        你好,希望那里一切都好!今天在本文中,我们有三个不同的部分。1)我想与您分享一个主题故事,以便您了解该主题。2)我们将深入探讨该过程。您将学习一些网页抓取方法。3)然后当然是EDA过程。 

        在最后一部分中,您将学习 3 个主要步骤。
        - 特征工程。
        -模型选择和演变。
        -使用模型进行预测。

二、让我告诉你章鱼素数的故事

        曾几何时,在一个反乌托邦的世界里,有一个名叫章鱼的机器人。Octopus是由一群足球狂热的数据科学家创建的,他们希望在预测比赛结果方面具有优势。八达通被输入了所有统计数据,球员的表现以及有关球队及其球员的其他相关数据。

        这一切都始于一群充满激情的数据科学家。

        他们发现保罗章鱼很可爱,并决定创造他们的章鱼。他们称他为“章鱼总理”。机器人能够预测足球比赛目标。

        他们开始用所有的统计数据喂他。章鱼,开始赚钱。章鱼学得很快。这种模式开始了自己的决定。他想买一辆高档汽车。他创建了一个学习汽车价格的模型。

        章鱼有钱,但最终,他在人类世界里是一个陌生人。他开始搜索有关汽车的一切。他有点倒霉,因为他是在土耳其创造的。

        他决定专注于“2022 年最畅销的二手车”。

        为了创建一个回归模型,他首先做了网络抓取。收集完数据后,他准备喂自己!他评估了许多模型。终于找到最好的了!

        在那几天里,章鱼Prime是自由和快乐的,但它并没有像这样持续很长时间。

        在很短的时间内,政府控制了它并利用它来为自己谋取利益,导致民众普遍的不信任和恐惧。

        章鱼曾经是体育爱好者的工具,现在被它所拥有的权力所腐蚀,并开始为了自己的利益操纵比赛的结果,把它变成了一个邪恶的实体。

三、用于网页抓取的数据源和工具

        对于进行网页抓取过程,我们将在 Python 中使用 urllib 和 beautifulsoup 库。土耳其二手车网站“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',
......]

3.1 是时候收集页面中的所有汽车链接了

        该属性指定链接转到的页面的 URL。href

        如果该属性不存在,则标记将不是超链接。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'
.....]

3.2 现在我们必须在 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'],
...............]

3.3 合并数据框中的所有数据。

3.4 数据清洗和预处理

        在这一部分中,我们将进行探索性数据分析
        转换数据类型。

  • 摆脱特殊字符。
  • 检测异常值。
  • 检测 NaN 值。
  • 重新索引。
  • 检查重复项

        连接所有数据帧后,我们有一个凌乱的数据帧。

        对于我们的预测模型,您的数据必须是数字。我们想将数据集转换为浮点型或整数型。

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)
.
.
.
.

3.5 特征工程

  • Looking to relationships between Features.
  • Modifying on Features
  • Creating new Features
  • Modifying on Target
  • Getting Distributions Better

3.6 非数值数据的转化

        我们要做虚拟编码。在我们应用虚拟函数之前。我们必须将数据类型转换为“类别”。

### 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###

3.7 查看特征之间的关系

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

        配对图绘制数据集中的成对关系。 pairplot 函数创建一个轴网格,以便数据中的每个变量将在单行的 y 轴和单列的 x 轴上共享。这将创建如下所示的图。


3.8 更好地分配我们的数据

### 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"])
.
.
.
.

3.9 模型选择和评估

  • 按测试和训练拆分数据
  • 检查过拟合和欠拟合
  • 检查偏差和方差
  • 型号选择
  • 型号比较

3.10 线性 , 套索 , 岭回归

### 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))

3.11 模型效果比较

3.12 真实价格和预测比较

基本上。。。。

如果您想购买二手车,请相信数据的力量!

四、后记

        以上本文呈现一个实际需求(购买二手车)的例子,诠释网络数据爬取的过程,因为爬取是一个复杂多样的过程,多阅读案例就越出现多的经验技术,我们将提供更多案例,以足够的案例增长我们的经验。希克迈特·埃姆雷·古勒

猜你喜欢

转载自blog.csdn.net/gongdiwudu/article/details/132270958
今日推荐