機(jī)器學(xué)習(xí)案例-鏈家租房房?jī)r(jià)預(yù)測(cè)(線(xiàn)性回歸算法)

例子描述:

通過(guò)編寫(xiě)爬蟲(chóng)程序,獲取鏈家網(wǎng)站的租房信息。通過(guò)獲取到的租房信息進(jìn)行訓(xùn)練和預(yù)測(cè)。

所需環(huán)境:Python3.6 + scikit-learn ,

安裝環(huán)境:

pip install lxml    #用于網(wǎng)頁(yè)解析
pip install requests   #用于發(fā)送http請(qǐng)求
pip install numpy   #用于科學(xué)計(jì)算
pip install sklearn  #機(jī)器學(xué)習(xí)庫(kù)
為了簡(jiǎn)化問(wèn)題,可圖形化表示,采用2個(gè)方案,相互獨(dú)立
  1. 采用單個(gè)特征(面積)進(jìn)行訓(xùn)練,可圖形表示
  2. 采用兩個(gè)特征(面積,臥室數(shù)量)進(jìn)行訓(xùn)練,可圖形表示,可推廣到多特征

1. 采用單個(gè)特征(面積)進(jìn)行訓(xùn)練,可圖形表示(2維平面顯示)

from sklearn.linear_model import LinearRegression
from matplotlib import pyplot as plt
from matplotlib import font_manager
import numpy as np
import requests
import re
from lxml import etree
import time
#設(shè)置字體,讓圖形支持中文
myfont = font_manager.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')

#下面是爬蟲(chóng)代碼
page = 1
x = [] #存放所有的x,就是房屋面積
y = [] #存放所有的y,就是租房?jī)r(jià)格
base_url = "https://su.lianjia.com"  
while page < 2: #這里設(shè)置獲取多少頁(yè)房產(chǎn)信息
    time.sleep(1) #休眠1秒
    #每一頁(yè)的url地址,page參數(shù)是頁(yè)碼
    request_url = base_url + "/zufang/gongyeyuan/pg" + str(page) + "/#contentList"
    print(request_url)
    headers = {
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"
    }
    respnose = requests.get(request_url,headers=headers) #發(fā)請(qǐng)求加入U(xiǎn)ser-Agent頭信息,不然鏈家會(huì)拒絕請(qǐng)求
    html = respnose.content.decode("utf-8") #獲取html網(wǎng)頁(yè)字節(jié)內(nèi)容并轉(zhuǎn)換為字符串
    selector = etree.HTML(html)
    list = selector.xpath('//div[@class="content__list--item"]')
    for item in list:
        title = item.xpath("./div/p[1]/a/text()")[0].strip() #通過(guò)xpath獲取標(biāo)題
        price = item.xpath("./div/span/em/text()")[0].strip() #通過(guò)xpath獲取價(jià)格,價(jià)格y值
        price = price.split("-")[0]
        # 通過(guò)xpath獲取價(jià)格,房屋面積作為樣本特征x
        area = item.xpath("./div/p[2]/text()")
        area = "".join(area).replace("\n","")
        m = re.match(r'.* (\d{1,4})㎡', area) #通過(guò)正則匹配價(jià)格
        if m != None:
            x.append(int(m.group(1))) #獲取面積
            y.append(int(price)) #獲取價(jià)格
    page = page + 1

#下面是訓(xùn)練代碼
linearReg = LinearRegression()
X = np.array([x])
y = np.array([y])
X = X[y <= 10000] #只考慮租房?jī)r(jià)格10000元以?xún)?nèi)的房子
y = y[y <= 10000] #只考慮租房?jī)r(jià)格10000元以?xún)?nèi)的房子
X = X.reshape(-1,1) #轉(zhuǎn)成二維數(shù)組,固定1列(一個(gè)特征),行為自動(dòng)
plt.scatter(X,y,color="b")  #根據(jù)矩陣X和向量y,把訓(xùn)練及的點(diǎn)畫(huà)在圖形上
linearReg.fit(X,y)  #根據(jù)矩陣X和向量y,進(jìn)行訓(xùn)練
k = linearReg.coef_[0]  #系數(shù)
b = linearReg.intercept_ #截距
plt.plot(X,k * X + b,color="r")  # 根據(jù)訓(xùn)練所得的系數(shù)k和截距b,畫(huà)出所得模型,其實(shí)就是直線(xiàn)方程 y = kX + b
plt.xlabel("房子面積",fontproperties = myfont)
plt.ylabel("租房?jī)r(jià)格",fontproperties = myfont)

#下面是預(yù)測(cè)代碼
predict_x = [[50],[120]] #分別預(yù)測(cè)面積未50和120的租房?jī)r(jià)格
predict_y = linearReg.predict(predict_x)
print(predict_y)
plt.scatter(predict_x,predict_y,color="g") #預(yù)測(cè)的兩個(gè)點(diǎn)畫(huà)到圖形上

plt.legend()
plt.show() #顯示圖形

圖形表示如下:


1個(gè)特征線(xiàn)性回歸

說(shuō)明:1個(gè)特征線(xiàn)性回歸,藍(lán)色的點(diǎn)表示樣本點(diǎn),紅色的直線(xiàn)表示訓(xùn)練的模型,綠色的點(diǎn)表示預(yù)測(cè)的點(diǎn)。

2. 采用兩個(gè)特征(面積,臥室數(shù)量)進(jìn)行訓(xùn)練,可圖形表示(3維空間顯示)

from matplotlib import pyplot as plt
from matplotlib import font_manager
import numpy as np
import requests
import re
from lxml import etree
import time
#設(shè)置字體,讓圖形支持中文
myfont = font_manager.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')

#下面是爬蟲(chóng)代碼
page = 1
X = [[],[]]#存放所有的x,就是房屋面積
y = []#存放所有的y,就是租房?jī)r(jià)格
base_url = "https://su.lianjia.com"
while page < 2: #這里設(shè)置獲取多少頁(yè)房產(chǎn)信息
    time.sleep(1) #休眠1秒
    #每一頁(yè)的url地址,page參數(shù)是頁(yè)碼
    request_url = base_url + "/zufang/gongyeyuan/pg" + str(page) + "/#contentList"
    print(request_url)
    headers = {
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"
    }
    respnose = requests.get(request_url,headers=headers) #發(fā)請(qǐng)求加入U(xiǎn)ser-Agent頭信息,不然鏈家會(huì)拒絕請(qǐng)求
    html = respnose.content.decode("utf-8") #獲取html網(wǎng)頁(yè)字節(jié)內(nèi)容并轉(zhuǎn)換為字符串
    selector = etree.HTML(html)
    list = selector.xpath('//div[@class="content__list--item"]')
    for item in list:
        title = item.xpath("./div/p[1]/a/text()")[0].strip() #通過(guò)xpath獲取標(biāo)題
        price = item.xpath("./div/span/em/text()")[0].strip() #通過(guò)xpath獲取價(jià)格,價(jià)格y值
        price = price.split("-")[0]
        # 通過(guò)xpath獲取價(jià)格,房屋面積作為樣本特征x
        area = item.xpath("./div/p[2]/text()")
        area = "".join(area).replace("\n","")
        m = re.match(r'.* (\d{1,4})㎡.* (\d{1,2})室(\d{1,1})廳(\d{1,1})衛(wèi)', area)
        if m != None:
            X[0].append(int(m.group(1)))#獲取面積
            X[1].append(int(m.group(2)))#獲取臥室數(shù)量
            y.append(int(price))#獲取價(jià)格

    page = page + 1

#下面是訓(xùn)練代碼
from sklearn.linear_model import LinearRegression #線(xiàn)性回歸模型
from mpl_toolkits.mplot3d import Axes3D #支持3D空間中繪制圖形
X = np.array(X)
y = np.array(y)
X = X.T #X轉(zhuǎn)置,為了配置X和y的行數(shù)一致
X = X[y <= 10000] #只考慮租房?jī)r(jià)格10000元以?xún)?nèi)的房子
y = y[y <= 10000] #只考慮租房?jī)r(jià)格10000元以?xún)?nèi)的房子
linearRegression = LinearRegression()
linearRegression.fit(X,y)
print(linearRegression.coef_)
print(linearRegression.intercept_)
fig = plt.figure()
ax = fig.gca(projection="3d")
ax.scatter(X[:,0],X[:,1],y,color="r") #三維空間中繪制樣本數(shù)據(jù)

a_ = linearRegression.coef_[0] #系數(shù)a
b_ = linearRegression.coef_[1] #系數(shù)b
c_ = linearRegression.intercept_ #截距
x_ = X[:,0]  #取所有樣本第1個(gè)特征值(面積)
y_ = X[:,1]  #取所有樣本第2個(gè)特征值(臥室數(shù)量)
x_,y_ = np.meshgrid(x_,y_) #把x_和y_的二維坐標(biāo)轉(zhuǎn)換為三維坐標(biāo),可以在三維空間中顯示
z_ = a_ * x_ + b_ * y_ + c_ #訓(xùn)練所得模型,其實(shí)就是三維空間的平面方程:z = ax + by + c
ax.plot_surface(x_,y_,z_,color="y",alpha=0.1) #三維空間中畫(huà)一個(gè)平面
predict_x = np.array([[80,3]]) #預(yù)測(cè)房?jī)r(jià)輸入值,這里有1個(gè)樣本,2個(gè)特征(面積和臥室數(shù)量)
predict_y = linearRegression.predict(predict_x) #預(yù)測(cè)面積為80,臥室數(shù)為3的租房?jī)r(jià)格

#三維空間中繪制預(yù)測(cè)房?jī)r(jià)的那個(gè)點(diǎn)
x1 = predict_x[:,0]
y1= predict_x[:,1]
z1 = predict_y
print(x1,y1,z1)
ax.scatter(x1,y1,z1,color="g") #預(yù)測(cè)的兩個(gè)點(diǎn)畫(huà)到圖形上,如果綠色點(diǎn)被蓋住,轉(zhuǎn)動(dòng)一下圖像就可以看到了

plt.xlabel("房子面積",fontproperties = myfont)
plt.ylabel("房子的臥室數(shù)量",fontproperties = myfont)
plt.show()

圖形表示如下:


2特征預(yù)測(cè)房?jī)r(jià)
轉(zhuǎn)動(dòng)后效果,可以看到綠色的預(yù)測(cè)點(diǎn)

說(shuō)明:2個(gè)特征線(xiàn)性回歸,紅色的點(diǎn)表示樣本點(diǎn),黃色的平面表示訓(xùn)練的模型,綠色的點(diǎn)表示預(yù)測(cè)的點(diǎn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容