機器學習篇(五)
- 2019 年 10 月 6 日
- 筆記
補充:
分類演算法:是一種對離散型隨機變數建模或預測的監督學習演算法。使用案例包括郵件過濾、金融欺詐和預測僱員異動等輸出為類別的任務。許多回歸演算法都有與其相對應的分類演算法,分類演算法通常適用於預測一個類別(或類別的概率)而不是連續的數值。
簡而言之:分類演算法用於目標值是離散型的。
回歸演算法:回歸方法是一種對數值型連續隨機變數進行預測和建模的監督學習演算法。使用案例一般包括房價預測、股票走勢或測試成績等連續變化的案例。
回歸任務的特點是標註的數據集具有數值型的目標變數。也就是說,每一個觀察樣本都有一個數值型的標註真值以監督演算法。
簡而言之:回歸演算法用於目標值是連續型的。
例如:能不能得到銀行貸款可以使用分類演算法,而貸款的額度就可以用回歸演算法。
線性回歸

由圖可知:線性回歸就是尋找一種可以預測的趨勢。
從函數角度來說就是找到一個合適的y=kx+b函數, b表示偏置,當有多個特徵是時候變成 y =k1*x1 +k2*x2+ b,以此類推。
線性回歸就是找到合適的k1和k2。(y表示目標,x1,x2..表示特徵值,b表示偏置常用w0表示,k1,k2...表示權重常用w表示)
那麼線性關係模型就是: f(x) = w1*x1+w2*x2+...+w0
定義:線性回歸通過一個或多個自變數與因變數之間進行建模的回歸分析。
一元線性回歸:涉及到的變數(特徵)只有一個。
多元線性回歸:涉及到的變數(特徵)是多個。
權重存在多個,屬性(特徵)也有多個,這裡需要引入矩陣的概念。
矩陣就是為了滿足特定的運算需求而來。
w(權重)的矩陣就是w0,w1,w2....
x(特徵)的矩陣就是1,x1,x2....
矩陣相乘變成:
h(w) = w0*1+w1*x1+w2*x2+...就是線性關係模型。
由上圖也可以知道這種預測是不可能100%的預算準確,在分類問題中用準確率來評估一個演算法預測的好壞。
在回歸演算法中,用損失函數(誤差大小)來評估。也稱之為最小二乘法。
公式為:

簡而言之:每個預測的結果減去真實結果的平方和。
如何找到最優的權重值(也就是損失函數的最小值)是需要一步一步的迭代計算得來。
計算的方式:
1、最小二乘法的正規方程(一次直接找到損失函數最小值從而找到最優權重,不通用)
計算模組:
sklearn.linear_model.LinearRegression
2、最小二乘法的梯度下降(一點一點改變權重值找到最優權重)
計算模組:
sklearn.linear_model.SGDRegressor
實例:
波士頓房價預測
數據來源:scikit-learn中自帶數據集
數據詳情:
屬性 解釋
CRIM 該鎮犯罪率
ZN 住宅佔地比率
INOUS 非零售商業用地比例
CHAS 位置的好壞
NOX 一氧化碳濃度
RM 每棟樓平均客房數
AGE 1940年前建成的單位比例
DIS 距離就業中心的加權距離
RAD 徑向公路可達指數
TAX 財產稅率
RTRAIO 學生和教師比例
B 黑人佔比
LATAT 低收入人群比例
MEDV 同類房屋價格的中位數
目標:求出13個權重值。得出預測房價
整理思路:
1、數據獲取
2、數據分割
3、訓練與測試數據標準化
4、使用LinearRegression和SGDRegressor進行對比預測。
程式碼:
# 導出數據 from sklearn.datasets import load_boston # 導入線性回歸演算法 from sklearn.linear_model import LinearRegression, SGDRegressor,Ridge # 導入分割數據集 from sklearn.model_selection import train_test_split # 導入標準化 from sklearn.preprocessing import StandardScaler # 導入均方誤差模組 from sklearn.metrics import mean_squared_error def mylinear(): # 獲取數據 lb = load_boston() # 分割數據 x_train,x_test,y_train,y_test = train_test_split(lb.data,lb.target,test_size=0.25) # 標準化處理(特徵值和目標值都需要標準化) # 特徵值標準化 std_x = StandardScaler() x_train = std_x.fit_transform(x_train) x_test = std_x.transform(x_test) # 目標值標準化,0.18以上要求數據為二維,這裡目標值為一維需要轉換 std_y = StandardScaler() y_train = std_y.fit_transform(y_train.reshape(-1,1)) y_test = std_y.transform(y_test.reshape(-1,1)) # 回歸預測 # 正規方程預測 lr = LinearRegression() lr.fit(x_train,y_train) # 列印權重參數 print(lr.coef_) # 預測房價結果,這裡為標準化的值,還需要使用inverse_transform轉化 y_lr_predict = std_y.inverse_transform(lr.predict(x_test)) print("正規方程預測測試集的房價為:",y_lr_predict) ''' 數據較多,截取部分: [[-0.12157973 0.11723016 0.02835006 0.12766732 -0.25491009 0.23101974 0.00070696 -0.3238203 0.3036738 -0.19670105 -0.23052557 0.09048442 -0.44183499]] 正規方程預測測試集的房價為: [[22.59139843] [22.13524512] [24.98056613] [13.78823607] [29.75290977] [20.46082081] ''' # 梯度下降進行預測 sgd = SGDRegressor() sgd.fit(x_train,y_train) # 列印權重參數 print(sgd.coef_) # 預測房價結果,這裡為標準化的值,還需要使用inverse_transform轉化 y_sgd_predict = std_y.inverse_transform(sgd.predict(x_test)) print("梯度下降預測測試集的房價為:",y_sgd_predict) ''' [-0.06787717 0.06950101 -0.05363521 0.07500903 -0.11281586 0.35603079 -0.01215854 -0.22425126 0.0763868 -0.05216806 -0.2198393 0.09826212 -0.33527296] 梯度下降預測測試集的房價為: [20.25084059 26.56297835 25.26518906 26.69280554 18.04244274 23.68836509 26.1134737 12.70430044 39.9574648 16.99725142 22.80953768 35.03861297 ''' # 均方誤差計算回歸性能 print("正規方程的均方誤差:",mean_squared_error(std_y.inverse_transform(y_test),y_lr_predict)) print("梯度下降的均方誤差:",mean_squared_error(std_y.inverse_transform(y_test),y_sgd_predict)) ''' 正規方程的均方誤差: 33.299367980869704 梯度下降的均方誤差: 36.10472557919503 說明正規方程效果要好一點。 ''' if __name__ == "__main__": mylinear() 回歸性能評估
公式:

模組:
mean_squared_error(y_true,y_pred)
y_true:真實值
y_pred:預測值
欠擬合和過擬合
欠擬合:
在訓練數據上不能獲得更好的擬合,在測試的數據上也不能更好的擬合數據這種現象稱之為欠擬合現象。
(模型過於簡單)
原因:學習的特徵過少
解決方法:
增加數據的特徵數量
過擬合:在訓練數據上能夠獲得很好的擬合,但是在訓練集以外的數據不能很好地擬合數據,這種稱之為過擬合。
(模型過於複雜)
對線性模型進行訓練學習就會變成複雜模型,可能從原來的線性關係,變成非線性關係(曲線)。
原因:原始特徵過多,存在影響特徵
解決方法:
進行特徵選擇,消除關聯性大的特徵
交叉驗證
正則化
如何判斷是過擬合還是欠擬合:
1、根據定義現象判斷
2、交叉驗證,在交叉驗證的時候效果很好,在訓練集表現不好就是過擬合
二者表現都不好就是欠擬合
既然線性回歸容易出現過擬合,就出現了嶺回歸(帶有l2正則化的線性回歸)來解決過擬合
嶺回歸
什麼是正則化
簡而言之:將複雜的權重做趨近於零處理
模組:
sklearn.linera_model.Ridge(alpha=1.0)
alpha:正則化力度
正則化的力度越大,權重越趨近於零。
實例:
同樣是上面的例子,來添加嶺回歸。
添加如下程式碼:
# 導入線性回歸演算法 from sklearn.linear_model import LinearRegression, SGDRegressor,Ridge # mylinear添加如下程式碼 # 嶺回歸預測 rd = Ridge() rd.fit(x_train,y_train) # 列印權重參數 print(rd.coef_) # 預測房價結果,這裡為標準化的值,還需要使用inverse_transform轉化 y_rd_predict = std_y.inverse_transform(rd.predict(x_test)) print("嶺回歸預測測試集的房價為:",y_rd_predict) print("嶺回歸的均方誤差:",mean_squared_error(std_y.inverse_transform(y_test),y_rd_predict)) ''' [[-0.0632925 0.12363312 0.01722252 0.05482988 -0.24365054 0.27211061 0.01847566 -0.31955953 0.28390266 -0.20539899 -0.23716384 0.09414787 -0.41097606]] 嶺回歸預測測試集的房價為: [[ 7.896142 ] [30.8306591 ] ... 嶺回歸的均方誤差: 15.389314479161092 ''' 嶺回歸:回歸得到的值更符合實際,更加可靠,能讓估計參數的波動範圍變小,更加穩定。