例子描述:
通過(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ú)立
- 采用單個(gè)特征(面積)進(jìn)行訓(xùn)練,可圖形表示
- 采用兩個(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)。