公衆號:尤而小屋
作者:Peter
編輯:Peter
大家好,我是Peter~
今天帶來的是機器學習的一篇實戰文章:利用機器學習庫scikit-learn實戰線性迴歸模型。
機器學習實戰—線性迴歸
在理想的狀態下,任何非線性的東西都是可以通過線性的東西來擬合的(參考泰勒公式)。而且線性模型本質上是均值預測,而大部分事物的變化都只是圍繞着均值來波動(參考大數定理),所以線性模型能夠模擬絕大部分的現象。
文章目錄
基本形式
基本表達
假設x是由d個屬性來描述:;其中表示第i個屬性上的取值。線性模型是通過各個屬性之間的組合來得到一個進行預測的函數,可表示爲:
如果用向量表示爲:
其中稱之爲權重,b稱之爲偏置
不同形式
不同尺度下的線性函數f(x):
- f(x)取離散的值:線性多分類模型
- f(x)取實數域上實值函數:線性迴歸模型
- f(x)爲對數:對數線性模式
- f(x)進行sigmoid非線性變換:對數機率迴歸
本文中重點講解的是線性迴歸問題,參考資料:《周志華-機器學習》和李航《統計學習方法》,還有datawhale的《南瓜書》公式部分。
線性迴歸
給定數據集。
線性迴歸linear regression試圖學得一個線性模型,儘可能使得預測值和實際值之間的差別最小
衡量方法
使用均方誤差來衡量:找到合適的w和b,滿足
均方誤差對應的就是常用的歐幾里得距離(歐式距離)。基於均方誤差最小化來進行模型求解的方法稱之爲:最小二乘法。
在線性迴歸模型中,最小二乘法就是試圖找到一條直線,使得所有樣本到直線上的歐氏距離之和最小
參數求解
求解w和b使達到最小,這個過程稱之爲最小二乘法的參數估計
E(w,b)對w和b單獨求導的過程,具體推導過程參考:https://datawhalechina.github.io/pumpkin-book/#/chapter3/chapter3
令上面的兩個求導出來的結果等於0,我們可以得到w和b的兩個結果:
sklearn實戰線性迴歸
我們通過網上的一個公開的數據集,來實現如何利用機器學習庫sklearn進行線性迴歸學習線性迴歸問題。
數據來源
數據探索
數據處理
運行sklearn的線性模型
模型評估
模型優化
可視化展示結果
數據來源
1、數據的介紹看這裏: http://archive.ics.uci.edu/ml/datasets/Combined+Cycle+Power+Plant
2、數據的下載地址請移步 http://archive.ics.uci.edu/ml/machine-learning-databases/00294/
數據中有4個字段屬性用來描述發電廠的輸出電力,最後一個是真實的輸出電力值。
我們現在需要做的是利用線性迴歸模型找到4個因素對輸出電力的影響,來預測後期的發電力。
數據探索
import pandas as pd
import numpy as np
from sklearn import datasets, linear_model
from sklearn.linear_model import LinearRegression # 導入線性迴歸模型
import matplotlib.pyplot as plt
%matplotlib inline
1、讀取數據
2、數據信息查看
3、數據統計信息查看
數據處理
1、選擇需要的樣本數據X,也就是前4個字段的信息
2、選擇我們的樣本輸出標籤數據y,也就是最後一個屬性字段的數據
數據集劃分
數據集的劃分:一部分變成訓練集,另一部分劃分成測試集
from sklearn.model_selection import train_test_split # 從模型選擇模塊中導入訓練、測試集模塊
X_train,X_test,y_train,y_test = train_test_split(X, y, random_state=1)
X_train # 7176條數據訓練數據
測試集的數據是2392條:
樣本的輸出值的行記錄是和對應的X相同的;同時我們也發現:本次案例有75%的數據作爲了訓練集,25%作爲了測試集
擬合實例化對象
line.fit(X_train,y_train)
LinearRegression()
查看我們模擬出來的係數:
print(line.intercept_) # 相當於是d;類似於截距
print(line.coef_) # 相當於是每個w的取值
[460.05727267]
[[-1.96865472 -0.2392946 0.0568509 -0.15861467]]
到這裏,我們就已經模擬出來了線性迴歸的表達式:也就是PE和前面4個變量之間的關係式子:
模型評價
通過訓練集的數據我們得到了線性迴歸的表達式,現在我們通過該表達式來模擬我們之前產生的測試集數據。
一個模型的評估,對於線性迴歸通常就是用上面我們介紹的均方差(Mean Squared Error, MSE)或者均方根差(Root Mean Squared Error, RMSE)在測試集上的表現來評價模型的好壞。下面通過代碼來進行測試:
y_pred = line.predict(X_test) # 對測試集數據進行預測
y_pred
array([[457.26722361],
[466.70748375],
[440.33763981],
...,
[457.39596168],
[429.37990249],
[438.16837983]])
len(y_pred)
2392
預測到結果之後,我們將預測值和實際值進行比較:
from sklearn import metrics # 對比模塊
# 輸出MSE
print("MSE:",metrics.mean_squared_error(y_test,y_pred))
MSE: 20.837191547220346
# 輸出RMSE:MSE開根號的結果
print("RMSE: ",np.sqrt(metrics.mean_squared_error(y_test,y_pred)))
RMSE: 4.564777272465804
使用交叉驗證優化模型
交叉驗證法:將全部的數據樣本D劃分成k個大小相似的互斥子集。每個子集儘量保持數據分佈的一致性。然後用用k-1個子集作爲訓練集,剩下的那個作爲測試集。
這樣就可以獲取k組訓練集/測試集,從而進行k次的訓練和測試,最終返回k次訓練的均值。
我們可以使用sklearn中自帶的交叉驗證方法來優化我們得到的模型,下面的例子中,採用的10折交叉驗證:
line
LinearRegression()
from sklearn.model_selection import cross_val_predict # 導入交叉驗證模塊
y_predicted = cross_val_predict(line,X,y,cv=10)
y_predicted # 通過交叉驗證得到的預測值
array([[467.24487977],
[444.06421837],
[483.53893768],
...,
[432.47556666],
[443.07355843],
[449.74395838]])
len(y_predicted)
9568
通過交叉驗證得到的預測值predicted和真實值求MSE和RMSE:
# 輸出MSE
print("MSE:",metrics.mean_squared_error(y,y_predicted))
MSE: 20.79367250985753
print("RMSE: ",np.sqrt(metrics.mean_squared_error(y,y_predicted)))
RMSE: 4.560007950635342
我們發現:通過使用交叉驗證後的均方誤差優於未使用情況下的誤差
繪圖
最後,我們畫出真實的樣本值和預測值之間的圖形,當點距離中間y=x的值越近,說明預測損失越低。
下面是使用matplotlib繪圖的代碼和效果:
fig, ax = plt.subplots()
ax.scatter(y, y_predicted)
ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=3)
ax.set_xlabel('Measured') # 真實值
ax.set_ylabel('Predicted') # 預測值
plt.show()
我把數據用Plotly_express重新繪製了一遍,看看效果:
data = pd.concat([pd.DataFrame(y),pd.DataFrame(y_predicted)],axis=1)
data.columns = ["Measured", "Predicted"]
data
import plotly_express as px
fig = px.scatter(data,
x="Measured", # 真實值
y="Predicted", # 預測值
trendline="ols", # 趨勢線
trendline_color_override="red" # 顏色
)
fig.show()