1. 線性回歸
線性回歸又名普通二成最小法(ordinary least squares, OLS),是回歸問題最簡單也是最經(jīng)典的線性方法袒炉。線性回歸尋找參數(shù)w和b,使得對訓練集的預測值與真實的回歸目標值y之間的均方誤差最小灰羽。線性回歸沒有參數(shù)李丰,這是一個優(yōu)點,但也因此無法控制模型的復雜度苗桂。
線性回歸的用法與近鄰算法相似药磺,如下:
import numpy as np
import pandas as pd
import mglearn
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
# 線性回歸在sklearn的linear_model模塊的LinearRegression類中實現(xiàn)
from sklearn.linear_model import LinearRegression
# 生成數(shù)據(jù)
X, y = mglearn.datasets.make_wave(n_samples=60)
# 拆分數(shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# 實例化LinearRegression對象并用fit函數(shù)訓練集數(shù)據(jù)進行模型擬合
lr = LinearRegression().fit(X_train, y_train)
# 調(diào)用LinearRegression對象的predict函數(shù)對測試集進行預測
print("Test set predictions:\n{}".format(lr.predict(X_test)))
# 調(diào)用LinearRegression對象的score函數(shù)對模型性能進行評估
print("Test set acurracy:{:.2f}".format(lr.score(X_test, y_test)))
print("Train set acurracy:{:.2f}".format(lr.score(X_train, y_train)))
Test set predictions:
[-0.3283204 -0.84483835 -0.49358667 0.35230624 -0.71167167 0.19957573
1.02910669 0.07859229 0.75390167 -0.75032857 -0.47681266 1.07802761
-0.8104986 0.2013684 1.00692209]
Test set acurracy:0.66
Train set acurracy:0.67
訓練集和測試集上的分數(shù)非常相近,且不是太好誉察,說明可能存在欠擬合与涡。
斜率參數(shù)w也叫權(quán)重或系數(shù)被保存在LinearRegression對象的coef_屬性中惹谐,偏移或截距(b)被保存在intercept_屬性中:
print("lr.coef_:{}".format(lr.coef_))
print("lr.intercept_:{}".format(lr.intercept_))
lr.coef_:[0.39390555]
lr.intercept_:-0.031804343026759746
注意使用的wave數(shù)據(jù)是一維數(shù)據(jù)集持偏,模型的性能不是很好驼卖,對于更高維的數(shù)據(jù)集,線性模型將變動更加強大鸿秆。
下面使用更復雜的數(shù)據(jù)集boston房價酌畜,數(shù)據(jù)集有506個樣本和105特征,驗證線性回歸在高維數(shù)據(jù)集上的表現(xiàn):
# 加載數(shù)據(jù)集
X, y = mglearn.datasets.load_extended_boston()
# 拆分數(shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# 實例化LinearRegression對象并用fit函數(shù)訓練集數(shù)據(jù)進行模型擬合
lr = LinearRegression().fit(X_train, y_train)
# 調(diào)用LinearRegression對象的score函數(shù)對模型性能進行評估
print("Train set acurracy:{:.2f}".format(lr.score(X_train, y_train)))
print("Test set acurracy:{:.2f}".format(lr.score(X_test, y_test)))
Train set acurracy:0.95
Test set acurracy:0.61
線性回歸在高維數(shù)據(jù)集上的表象明顯好于一維數(shù)據(jù)集卿叽,但在訓練集和測試集上的得分差異較大桥胞,是過擬合的明顯標志。
2. 嶺回歸
嶺回歸也是一種用于回歸的線性模型考婴。在嶺回歸模型中贩虾,對系數(shù)(w)的選擇不僅要在訓練集上得到較好的效果,而且還要擬合附加約束沥阱,使得w盡量小缎罢,及w的所有元素都要接近于0。這種約束即是正則化考杉。正則化是指對模型進行顯示約束策精,以避免過擬合。嶺回歸用到的這種被稱為L2正則化崇棠。
嶺回歸在sklearn的linear_model的Ridge類中實現(xiàn)咽袜。下面是嶺回歸在boston房價數(shù)據(jù)集上的效果。
import numpy as np
import pandas as pd
import mglearn
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
# 線性回歸在sklearn的linear_model模塊的Ridge類中實現(xiàn)
from sklearn.linear_model import Ridge
# 加載數(shù)據(jù)
X, y = mglearn.datasets.load_extended_boston()
# 拆分數(shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# 實例化Ridge對象并用fit函數(shù)訓練集數(shù)據(jù)進行模型擬合
rg = Ridge().fit(X_train, y_train)
# 調(diào)用Ridge對象的score函數(shù)對模型性能進行評估
print("Train set acurracy:{:.2f}".format(rg.score(X_train, y_train)))
print("Test set acurracy:{:.2f}".format(rg .score(X_test, y_test)))
Training set scroe:0.89
Test set score:0.75
Ridge在訓練集上的得分低于LinearRegression枕稀,但在測試集上的得分要高询刹。
Ridge模型在模型的簡單性(w接近0)與訓練集性能之間做權(quán)衡。模型的簡單性和訓練集性能的權(quán)衡可通過設置參數(shù)alpha來指定抽莱。alpha的最佳值取決于具體的數(shù)據(jù)集范抓。增大alpha的值會使得w更加趨向0,即模型更簡單食铐,從而降低訓練集性能匕垫,但可能提高泛化性能。**
rg10 = Ridge(alpha=10).fit(X_train, y_train)
print("Training set scroe:{:.2f}".format(rg10.score(X_train, y_train)))
print("Test set score:{:.2f}".format(rg10.score(X_test, y_test)))
Training set scroe:0.79
Test set score:0.64
減小alpha可以讓w收到的限制更小虐呻,對于非常小的alpha象泵,w幾乎沒有收到限制,會得到一個與LinearRegression類似的模型斟叼。
rg01 = Ridge(alpha=0.1).fit(X_train, y_train)
print("Training set scroe:{:.2f}".format(rg01.score(X_train, y_train)))
print("Test set score:{:.2f}".format(rg01.score(X_test, y_test)))
Training set scroe:0.93
Test set score:0.77
下面查看不同alpha取值對模型coef_屬性的影響偶惠,觀察alpha參數(shù)是如何影響模型。
plt.plot(rg.coef_, 's', label="Ridge alpha=1")
plt.plot(rg10.coef_, '^', label="Ridge alpha=10")
plt.plot(rg01.coef_, 'v', label="Ridge alpha=0.1")
plt.plot(lr.coef_, 'o', label="LinearRegression")
plt.xlabel("Cofficient index")
plt.ylabel("Cofficient magnitude")
plt.hlines(0, 0, len(lr.coef_))
plt.ylim(-25, 25)
plt.legend()
從上圖中可以看出alpha越大朗涩,w的范圍越集中且趨于0忽孽。
另外一種理解正則化的影響,就是固定alpha的值,但是改變訓練數(shù)據(jù)量兄一。
mglearn.plots.plot_ridge_n_samples()
無論是嶺回歸還是線性回歸厘线,訓練分數(shù)都要高于測試分數(shù)。由于嶺回歸是正則化的出革,因此它的訓練分數(shù)低于線性回歸造壮,但是測試分數(shù)要高于線性回歸。尤其是較小的數(shù)據(jù)集時骂束,從上圖可看出數(shù)據(jù)點少于400時耳璧,線性回歸學習不到任何內(nèi)容。隨著模型可用數(shù)據(jù)的增多展箱,兩個模型的性能都在提升旨枯,最終線性回歸的性能會追上嶺回歸。即在有足夠的的訓練數(shù)據(jù)的情況下混驰,正則化變得不那么重要召廷。
3. lasso
lasso也是一種正則化的線性回歸模型,與Ridge的不同之處在于它使用的是L1正則化账胧,結(jié)果是使某些系數(shù)剛好為0竞慢。這說明某些特征被模型完全忽略,可看作是一種自動化的特征選擇治泥。
import numpy as np
import pandas as pd
import mglearn
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
# lasso 在sklearn的linear_model模塊的Lasso類中實現(xiàn)
from sklearn.linear_model import Lasso
# 加載boston房價數(shù)據(jù)
X, y = mglearn.datasets.load_extended_boston()
# 拆分數(shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# 實例化Lasso對象并用測試集數(shù)據(jù)擬合模型
la = Lasso().fit(X_train, y_train)
# 調(diào)用Lasso對象的score函數(shù)進行模型評估
print("Training set score:{:.2f}".format(la.score(X_train, y_train)))
print("Test set score:{:.2f}".format(la.score(X_test, y_test)))
# 統(tǒng)計模型使用的特征數(shù)筹煮,及Lasso對象coef_屬性不為0的
print("Number of features used:{}".format(np.sum(la.coef_!=0)))
Training set score:0.29
Test set score:0.21
Number of features used:4
如上lasso在訓練集和測試集上的得分都很低,標識存在欠擬合居夹,模型只用到了105個特征中的4個败潦。與Ridge相似,lasso也有alpha參數(shù)可以控制系數(shù)趨向0的強度准脂。上面的代碼中alpha參數(shù)使用默認值1.0劫扒。下面嘗試減小alpha,降低欠擬合狸膏,從而得到一個更復雜的模型沟饥。減小alpha的同時需要增大max_iter(運行迭代的最大次數(shù))的值:
# 實例化Lasso對象并用測試集數(shù)據(jù)擬合模型
la001 = Lasso(alpha=0.01, max_iter=10000).fit(X_train, y_train)
# 調(diào)用Lasso對象的score函數(shù)進行模型評估
print("Training set score:{:.2f}".format(la001.score(X_train, y_train)))
print("Test set score:{:.2f}".format(la001.score(X_test, y_test)))
# 統(tǒng)計模型使用的特征數(shù),及Lasso對象coef_屬性不為0的
print("Number of features used:{}".format(np.sum(la001.coef_!=0)))
Training set score:0.90
Test set score:0.77
Number of features used:33
alpha值變小后湾戳,lasso在訓練集和測試集上的得分都明顯提高贤旷。但是如果把alpha設置太小,就會消化正則化的效果砾脑,并出現(xiàn)過擬合幼驶,得到于LinearRegression類似的結(jié)果:
# 實例化Lasso對象并用測試集數(shù)據(jù)擬合模型
la00001 = Lasso(alpha=0.0001, max_iter=100000).fit(X_train, y_train)
# 調(diào)用Lasso對象的score函數(shù)進行模型評估
print("Training set score:{:.2f}".format(la00001.score(X_train, y_train)))
print("Test set score:{:.2f}".format(la00001.score(X_test, y_test)))
# 統(tǒng)計模型使用的特征數(shù),及Lasso對象coef_屬性不為0的
print("Number of features used:{}".format(np.sum(la00001.coef_!=0)))
Training set score:0.95
Test set score:0.64
Number of features used:94
from sklearn.linear_model import Ridge
rg01 = Ridge(alpha = 0.1).fit(X_train, y_train)
print("Training set score:{:.2f}".format(rg01.score(X_train, y_train)))
print("Test set score:{:.2f}".format(rg01.score(X_test, y_test)))
Training set score:0.93
Test set score:0.77
下面作圖觀察不同alpha值對模型系數(shù)的影響情況:
plt.plot(la.coef_, 's', label="lasso alpha=1")
plt.plot(la001.coef_, '^', label="lasso alpha=0.01")
plt.plot(la00001.coef_, 'v', label="lasso alpha=0.0001")
plt.plot(rg01.coef_, 'o', label="ridge alpha=0.1")
plt.legend(ncol=2, loc=(0, 1.05))
plt.ylim(-25, 25)
plt.xlabel("Coefficient index")
plt.ylabel("Coefficient magnitude")
lasso alpha=1 系數(shù)基本都為0韧衣,只有幾個不為0且范圍較小
lasso alpha=0.01系數(shù)大部分都為0盅藻,范圍增大
lasso alpha=0.0001系數(shù)很小一部分為0购桑,范圍更大
ridge alpha=0.1所有系數(shù)均不為0