from http://www.javashuo.com/article/p-kabizhvn-bd.htmljavascript
就算是簡單的算法,也須要跑通整個流程,經過一個簡單的迴歸的例子,能夠看到: 數據的準備 ,數據的維度? 用哪一個模型,如何訓練,如何評價,可視化? 有一系列的東西須要去落地,推導理解十一方面,同時也要會用。 就這個迴歸的例子,和以前的 GMM 的例子很像,整個一套流程的東西很像,可是這裏咱們是用 sklearn 這個框架來完成的。css
這裏咱們用 UCI 大學公開的機器學習數據來跑線性迴歸。html
數據的介紹在這: http://archive.ics.uci.edu/ml/datasets/Combined+Cycle+Power+Planthtml5
數據的下載地址在這: http://archive.ics.uci.edu/ml/machine-learning-databases/00294/java
裏面是一個循環發電場的數據,共有 9568 個樣本數據,每一個數據有 5 列,分別是: AT(溫度), V(壓力), AP(溼度), RH(壓強), PE(輸出電力)。咱們不用糾結於每項具體的意思。python
咱們的問題是獲得一個線性的關係,對應 PE 是樣本輸出,而 AT/V/AP/RH 這 4 個是樣本特徵, 機器學習的目的就是獲得一個線性迴歸模型,即:jquery
PE=θ0+θ1∗AT+θ2∗V+θ3∗AP+θ4∗RHPE=θ0+θ1∗AT+θ2∗V+θ3∗AP+θ4∗RHlinux
而須要學習的,就是θ0,θ1,θ2,θ3,θ4θ0,θ1,θ2,θ3,θ4 這 5 個參數。android
下載後的數據能夠發現是一個壓縮文件,解壓後能夠看到裏面有一個 xlsx 文件,咱們先用 excel 把它打開,接着 「另存爲 「」csv 格式,保存下來,後面咱們就用這個 csv 來運行線性迴歸。css3
打開這個 csv 能夠發現數據已經整理好,沒有非法數據,所以不須要作預處理。可是這些數據並無歸一化,也就是轉化爲均值 0,方差 1 的格式。也不用咱們搞,後面 scikit-learn 在線性迴歸時會先幫咱們把歸一化搞定。
好了,有了這個 csv 格式的數據,咱們就能夠大幹一場了。
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import pandas as pd
from sklearn import datasets, linear_model
data = pd.read_csv('Folds5x2_pp.csv')
data.head()
y = data[['PE']]
print(type(y))
y.head()
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
print(X_train.shape,y_train.shape,X_test.shape,y_test.shape,type(X_train))
終於到了臨門一腳了,咱們能夠用scikit-learn的線性模型來擬合咱們的問題了。scikit-learn的線性迴歸算法使用的是最小二乘法來實現的。代碼以下:
from sklearn.linear_model import LinearRegression
linreg = LinearRegression()
linreg.fit(X_train, y_train)
print(linreg.intercept_) #在線性模型的屬性裏。
print(linreg.coef_)
也就是說 PE 和其餘 4 個變量的關係以下:
PE=447.06297099−1.97376045∗AT−0.23229086∗V+0.0693515∗AP−0.15806957∗RH
咱們須要評估咱們的模型的好壞程度,對於線性迴歸來講,咱們通常用均方差(Mean Squared Error, MSE)或者均方根差 (Root Mean Squared Error, RMSE) 在測試集上的表現來評價模型的好壞。
咱們看看咱們的模型的 MSE 和 RMSE,代碼以下:
#模型擬合測試集
y_pred = linreg.predict(X_test)
from sklearn import metrics
# 用scikit-learn計算MSE
print("MSE:",metrics.mean_squared_error(y_test, y_pred))
# 用scikit-learn計算RMSE
print("RMSE:",np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
獲得了 MSE 或者 RMSE,若是咱們用其餘方法獲得了不一樣的係數,須要選擇模型時,就用 MSE 小的時候對應的參數。
好比此次咱們用 AT, V,AP 這 3 個列做爲樣本特徵。不要 RH, 輸出仍然是 PE。代碼以下:
X = data[['AT', 'V', 'AP']]
y = data[['PE']]
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
from sklearn.linear_model import LinearRegression
linreg = LinearRegression()
linreg.fit(X_train, y_train)
#模型擬合測試集
y_pred = linreg.predict(X_test)
from sklearn import metrics
# 用scikit-learn計算MSE
print("MSE:",metrics.mean_squared_error(y_test, y_pred))
# 用scikit-learn計算RMSE
print("RMSE:",np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
能夠看出,去掉RH後,模型擬合的沒有加上RH的好,MSE變大了。
咱們能夠經過交叉驗證來持續優化模型,代碼以下,咱們採用10折交叉驗證,即cross_val_predict中的cv參數爲10:
X = data[['AT', 'V', 'AP', 'RH']]
y = data[['PE']]
from sklearn.model_selection import cross_val_predict
predicted = cross_val_predict(linreg, X, y, cv=10)
# 用scikit-learn計算MSE
print("MSE:",metrics.mean_squared_error(y, predicted))
# 用scikit-learn計算RMSE
print("RMSE:",np.sqrt(metrics.mean_squared_error(y, predicted)))
能夠看出,採用交叉驗證模型的 MSE 比第 6 節的大,主要緣由是咱們這裏是對全部折的樣本作測試集對應的預測值的 MSE,而第 6 節僅僅對 25% 的測試集作了 MSE。二者的先決條件並不一樣。
2018-01-04 14:10 小北潛行
你好~ 真的很是感謝你的文章。理論和實際使用相結合,好理解不少~~ 有個問題,就是不太明白 8. 交叉驗證這一部分的做用 上文中 8 使用的數據集和前面計算均方差的數據集不同,因此獲得的數值不同 可是若是使用相同的數據集,那和前面計算出來的數值沒有差別 那這部分的做用體如今哪裏呢?
[樓主] 2018-01-05 10:52 劉建平 Pinard
@ 小北潛行 你好,這是一個簡單的例子,主要是說均方差能夠用來衡量模型的好壞,能夠怎麼用,通常在交叉驗證的時候不用看 MSE。
何時用 MSE 呢?在作模型測試的時候。
針對訓練集和測試集,第一次選擇合適參數 (好比優化方法,正則化參數等),訓練集交叉驗證出來的模型 A,來預測測試集,能夠計算 MSE-A,第二次選擇合適參數,訓練集交叉驗證出來的模型 B,來預測測試集,能夠計算 MSE-B,經過 MSE-A 和 MSE-B 的大小,能夠衡量模型 A 和 B 的好壞。
2018-03-18 18:50 TinyLaughing
博主,您好! 對於第 8 節的 10 折交叉驗證有點不明白。 個人理解是 10 折交叉驗證,獲得了 10 個不一樣的模型,每個模型有各自的係數、截距以及 MSE。(這樣理解不知道對不對?) 那麼,博主文中計算的 MSE 是 10 個模型的 MSE 的平均值,仍是 10 個模型中最優模型的 MSE(即 10 個 MSE 的最小值)? [樓主] 2018-03-25 18:51 劉建平 Pinard
@ TinyLaughing 你好,就是 10 個模型中最優模型的 MSE(即 10 個 MSE 的最小值)。 由於交叉驗證的目的是找到最好的模型參數,而如何評判呢?對於這個例子就看這 10 折交叉驗證中哪一次的 MSE 最好,那麼對應的模型參數咱們認爲是最優的。
對於你說的需求,直接使用 skearn 單個 API 是沒法獲得的。 可行的作法是: 1)用 sklearn.model_selection.KFold 將數據分紅 K 折。 2) 本身作一個循環(共 K 次),每次合併其中的 K-1 折的數據作訓練集,另 1 折作測試集,按第 6 節的方法訓練,打印模型參數和 MSE。 3)選擇最小 MSE 對應的模型參數。
這裏畫圖真實值和預測值的變化關係,離中間的直線 y=x 直接越近的點表明預測損失越低。代碼以下:
fig, ax = plt.subplots()
ax.scatter(y, predicted)
ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=4) #lw表示線寬
ax.set_xlabel('Measured')
ax.set_ylabel('Predicted')
plt.show()