機器學習的模型泛化
1、機器學習的模型誤差主要含有三個方面的誤差:模型偏差、模型方差以及不可避免的誤差。
2、對於機器學習訓練模型的偏差主要因為對於問題本身的假設不對,比如非線性誤差假設為線性誤差進行訓練和預測,算法層面上欠擬合是產生較大偏差的主要原因。另外主要來自於特征參量與最終結果的相關性,如果相關性很低或者高度不相關的話也會導致較大的偏差。
3、對於機器學習模型的方差主要是來自於數據的擾動以及模型的過於復雜,在算法層面上過擬合是引起模型方差較大的主要原因,因為過擬合會導致整體模型的復雜度太高,從而引起方差很大。
4、對於不同的算法其存在誤差種類是不同的,有些算法是天生的高方差算法,比如KNN算法,非參數算法一般都是高方差算法,因為它不對問題的前提進行假設。有些算法天生是高偏差的算法,比如線性回歸算法,參數學習算法一般都屬於高偏差算法,因為它對數據具有極強的假設。
5、大多數算法都可以通過調節其中的超參數調整模型的方差和偏差,並且一般情況下模型的方差和偏差是矛盾的,降低偏差,會增大方差,降低方差,也會增大偏差。
6、機器學習的主要挑戰主要來自於方差,當然這樣的結論主要局限於算法層面,解決機器學習算法模型的方差的主要方式有以下幾個方面:
(1)降低模型的復雜度;
(2)減小數據的維度:PCA算法進行降維和降噪;
(3)增加數據的樣本數;
(4)評測算法的准確度時需要采用驗證集,即使用交叉驗證方式;
(5)模型的正則化。
7、模型的正則化主要是指對於復雜的模型的特征參數的系數進行一定的限制,使其不要太大,采取的方式主要是改變損失函數,在損失函數中加入模型的正則化項,從而在使得損失函數最最小時限制相應的參數的大小.
圖 正則函數表達式
8、具體來講,模型的正則化主要含有兩種方式:嶺回歸Ridge Regression和LASSO Regression,兩者的損失函數表達式有所不同,這也造成了兩者在超參數a從0增大到正無窮時各項特征系數變化以及擬合模型曲線變化的不同特點。
圖
(1)Ridge模型:因為其損失函數后面添加項的梯度變化的連續性,所以當它的超參數alhpa不斷增大時,它的各項特征系數是連續慢慢地趨向於0的;因此它的擬合結果始終是一種光滑的曲線形式。
(2)LASSO模型:因為后面損失函數添加項是一個絕對值函數,因此在梯度下降法求取最小值時,它的導數是一個階躍函數sign(x),因此,當超參數a不斷增大時,其theta各項特征系數中會有一部分趨向於變為0,這也使得LASSO模型可以用來做特征選用。它的擬合結果隨着超參數a的增大,會越來越趨近於一條直線,這也說明特征參數的部分系數會變為0.
圖注:左邊為Ridge嶺回歸結果,右邊為LASSO回歸結果
9、彈性網:彈性網是一種復合型的正則化方式,它是在損失函數的基礎上既添加了嶺回歸的L1正則項,又添加了LASSO回歸的正則化項L2正則項,包含了嶺回歸和LASSO回歸的綜合優點,其具體的數學表達式如下:
10、模型正則化的兩種算法模型嶺回歸和LASSO回歸正則化的實現代碼具體如下:
#(1)使用嶺回歸的正則化方式減小模型方差,將其封裝為一個函數
import numpy as np
import matplotlib.pyplot as plt
x=np.random.uniform(-3,3,size=100)
X=x.reshape(-1,1)
y=0.5*x**2+x+2+np.random.normal(0,1,size=100)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(X,y,random_state=666)
from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error
def Ridgeregression(degree,alpha):
return Pipeline([("poly", PolynomialFeatures(degree=degree)),
("std_scaler", StandardScaler()),
("Ridge_reg", Ridge(alpha=alpha))
])
r1=Ridgeregression(20,10000)
r1.fit(x_train,y_train)
y11=r1.predict(x_test)
print(mean_squared_error(y11,y_test))
plt.figure()
plt.scatter(X,y)
x1=np.linspace(-3,3,100).reshape(100,1)
y1=r1.predict(x1)
plt.plot(x1,y1,"r")
#plt.axis([-3,3,-1,10])
plt.show()
#(2)使用LASSO回歸的正則化方式減小模型方差,將其封裝為一個函數
#采用LASSO回歸進行訓練和預測
from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error
def lassoregression(degree,alpha):
return Pipeline([("poly", PolynomialFeatures(degree=degree)),
("std_scaler", StandardScaler()),
("LASSO_reg", Lasso(alpha=alpha))
])
LA1=lassoregression(20,1) #當a的值從0開始增大時,其擬合曲線的模型會越來越平直,慢慢會接近一條直線,區別於嶺回歸的曲線,這是由LASSO正則化數學式子決定的
LA1.fit(x_train,y_train)
y11=LA1.predict(x_test)
print(mean_squared_error(y11,y_test))
plt.figure()
plt.scatter(X,y)
x1=np.linspace(-3,3,100).reshape(100,1)
y1=LA1.predict(x1)
plt.plot(x1,y1,"r")
#plt.axis([-3,3,-1,10])
plt.show()
#(3)采用普通多項式回歸進行預測
import numpy as np
import matplotlib.pyplot as plt
x=np.random.uniform(-3,3,size=100)
X=x.reshape(-1,1)
y=0.5*x**2+x+2+np.random.normal(0,1,size=100)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(X,y,random_state=666)
from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
def polynomialRegression(degree):
return Pipeline([("poly",PolynomialFeatures(degree=degree)),
("std_scaler",StandardScaler()),
( "lin_reg",LinearRegression())
])
poly2_reg=polynomialRegression(20)
poly2_reg.fit(X,y)
y2=poly2_reg.predict(X)
print(mean_squared_error(y,y2))
print(poly2_reg.score(X,y))
plt.figure()
plt.scatter(X,y)
x1=np.linspace(-3,3,100).reshape(100,1)
y11=poly2_reg.predict(x1)
plt.plot(x1,y11,"r")
#plt.axis([-3,3,-1,10])
plt.show()
注:左為嶺回歸方式,右為普通多項式回歸方式
注:左為普通多項式回歸,右為LASSO回歸方式