多特征線性回歸詳解
多特征線性回歸
在單特征線性回歸模型中,我們通過一個(gè)特征對(duì)目標(biāo)變量進(jìn)行預(yù)測(cè),例如通過房子的大小來預(yù)測(cè)房?jī)r(jià)。但實(shí)際現(xiàn)實(shí)生活中,影響房?jī)r(jià)的因素往往不止面積一個(gè),例如還有房間數(shù)、樓層、位置等等,所以我們需要用到多特征的模型來對(duì)房?jī)r(jià)進(jìn)行預(yù)測(cè)。
一、規(guī)定符號(hào)
xj:第j個(gè)特征
n:特征的數(shù)量
x(i):第i個(gè)訓(xùn)練樣本,是一個(gè)包含n個(gè)特征的行向量
xj(i):表示第i個(gè)樣本的第j個(gè)特征
二、模型

三、向量化
使用向量化可以簡(jiǎn)化模型,減少計(jì)算量和代碼量,提升代碼的執(zhí)行速度。

四、梯度下降

五、正規(guī)方程
線性回歸中一種尋找參數(shù)w、b的方式,該方法不用進(jìn)行多次迭代梯度下降,直接使用高級(jí)線性代數(shù)知識(shí)求解。但是正規(guī)方程無法推廣到其他機(jī)器學(xué)習(xí)算法,且當(dāng)樣本特征數(shù)量非常大時(shí),運(yùn)行速度非常慢。某些機(jī)器學(xué)習(xí)庫(kù)會(huì)在后臺(tái)使用這種方法解出w、b,但是大多數(shù)情況下都不會(huì)使用。
六、特征縮放
1、什么是特征縮放?
特征縮放是機(jī)器學(xué)習(xí)中一項(xiàng)重要的技術(shù),可大大提升梯度下降的速度。
在預(yù)測(cè)房?jī)r(jià)的例子中,假設(shè)有兩個(gè)影響房?jī)r(jià)的特征,面積和房間數(shù),面積的取值范圍是300-5000,房間數(shù)的取值范圍是0-5,我們會(huì)發(fā)現(xiàn)面積和房間數(shù)的取值范圍相差過大。當(dāng)我們選擇參數(shù)時(shí),如果面積的參數(shù)(也稱為權(quán)重)較大而房間數(shù)的參數(shù)較小,這樣會(huì)導(dǎo)致最終預(yù)測(cè)的價(jià)格與實(shí)際的價(jià)格偏差較大,因?yàn)槊娣e因素占的權(quán)重較大,對(duì)房?jī)r(jià)的影響占主要部分。為預(yù)測(cè)更精準(zhǔn),面積的參數(shù)應(yīng)該選擇較小的,房間數(shù)的參數(shù)應(yīng)該選擇較大的。
特征縮放對(duì)梯度下降會(huì)產(chǎn)生很大的影響,如圖

特征的范圍差異過大時(shí),在散點(diǎn)圖中,樣本點(diǎn)都集中特征范圍較大的那一側(cè),在在成本函數(shù)等高線圖中,圖形變得長(zhǎng)且窄,梯度下降很可能越過全局最小值左右橫跳。
2、如何實(shí)現(xiàn)特征縮放?
1、最大值

2、均值歸一化

3、Z-score標(biāo)準(zhǔn)化(Z-score歸一化/規(guī)范化)

? ?注:分母為該特征的標(biāo)準(zhǔn)差
3、特征縮放的范圍

七、判斷梯度下降是否收斂
1、繪制學(xué)習(xí)曲線
通過繪制成本函數(shù)學(xué)習(xí)曲線圖,可直觀地觀察到梯度下降是否收斂,同時(shí)也可觀察到趨于收斂時(shí)的迭代次數(shù)。

2、自動(dòng)收斂測(cè)試
設(shè)置一個(gè)很小的值e,例如令它為0.001,判斷每一次梯度下降對(duì)成本函數(shù)的改變是否小于或等于這個(gè)極小值,如果是則說明梯度下降現(xiàn)在比較平緩,也就是趨于收斂。但這個(gè)極小值e是很難選擇的,所以一般更推薦繪制學(xué)習(xí)曲線。
八、選擇合適的學(xué)習(xí)率
當(dāng)學(xué)習(xí)率過小時(shí),下降的步子過小,導(dǎo)致到達(dá)最低點(diǎn)需要很多步,需要的時(shí)間也更多;
當(dāng)學(xué)習(xí)率過大時(shí),下降的步子較大,可能越過最低點(diǎn),導(dǎo)致越來越遠(yuǎn),甚至永遠(yuǎn)也到達(dá)不了最低點(diǎn)。
為什么我們可以采用固定的學(xué)習(xí)率?因?yàn)樵娇拷畹忘c(diǎn),斜率將會(huì)越來越小,等于邁的步子越來越小了,最終也會(huì)慢慢靠近最低點(diǎn)。
如何選擇合適的學(xué)習(xí)率呢?通常,可使用一些常見的值例如0.001、0.01、0.1、1.......,每次將學(xué)習(xí)率提高十倍,再結(jié)合學(xué)習(xí)曲線來判斷學(xué)習(xí)率是否得當(dāng)。

?

九、特征工程
特征工程指的是為算法選擇或設(shè)計(jì)最合適的特征。
例如在預(yù)測(cè)房?jī)r(jià)的例子中,房子有長(zhǎng)和寬兩個(gè)特征,但是我們知道房子的面積是等于長(zhǎng)乘以寬,因此會(huì)預(yù)感到面積更能預(yù)測(cè)房?jī)r(jià),因此我們可以構(gòu)建一個(gè)新的特征即面積,加入到模型中。
我們可以結(jié)合知識(shí)以及實(shí)際設(shè)計(jì)新的特征,使其幫助算法更簡(jiǎn)單、更準(zhǔn)確的做出預(yù)測(cè)。
十、多項(xiàng)式回歸
在此之前,我們都是選擇使用直線來擬合數(shù)據(jù)集,但是在有的情況下,使用曲線或其他函數(shù)可能更好的擬合數(shù)據(jù)集,所以就需要采用多項(xiàng)式回歸。例如,模型中包含二次項(xiàng)、三次項(xiàng)、根號(hào)項(xiàng)等,根據(jù)實(shí)際情況構(gòu)造合適的多項(xiàng)式,使其更好地?cái)M合。
十一、實(shí)現(xiàn)
部分?jǐn)?shù)據(jù)集合和代碼
2104,3,3999001600,3,3299002400,3,3690001416,2,2320003000,4,5399001985,4,2999001534,3,3149001427,3,1989991380,3,2120001494,3,2425001940,4,2399992000,3,3470001890,3,3299994478,5,6999001268,3,259900......
import numpy as npimport pandas as pdimport matplotlib.pyplot as pltalpha = 0.01 ?# 學(xué)習(xí)速率αiters = 1000 ?# 要執(zhí)行的迭代次數(shù)。path = './data/ex1data2.txt'data = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])data.head() ?# 輸出前五行# 特征縮放data = (data - data.mean()) / data.std() ?# Z-score標(biāo)準(zhǔn)化# data = (data - data.max()) / (data.max() - data.min()) ?# max-min歸一化# data = data / (np.abs(data.max())) ?# MaxAbs標(biāo)準(zhǔn)化# 在訓(xùn)練集中添加一列,以便我們可以使用向量化的解決方案來計(jì)算代價(jià)和梯度data.insert(0, 'One', 1)# 獲取列數(shù)cols = data.shape[1]X = data.iloc[:, 0:cols - 1] ?# 所有行,不包含最后一列y = data.iloc[:, cols - 1:cols] ?# 所有行,只包含最后一列# np.matrix()函數(shù)用于從類數(shù)組對(duì)象或數(shù)據(jù)字符串返回矩陣X = np.matrix(X.values)y = np.matrix(y.values)# 初始化參數(shù)矩陣theta = np.matrix(np.array([0, 0, 0])) ?# 1x3矩陣def computeCost(X, y, theta):"""代價(jià)函數(shù)"""num = len(X)inner = np.power(((X * theta.T) - y), 2)cost = np.sum(inner) / (2 * num)return costdef gradientDescent(X, y, theta, alpha, iters):"""梯度下降"""temp = np.matrix(np.zeros(theta.shape))parameters = int(theta.ravel().shape[1])cost = np.zeros(iters)for i in range(iters):error = (X * theta.T) - yfor j in range(parameters):term = np.multiply(error, X[:, j])temp[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term))theta = tempcost[i] = computeCost(X, y, theta)return theta, costdef normalEqn(X, y):"""正規(guī)方程"""# np.linalg.inv():矩陣求逆theta = np.linalg.inv(X.T @ X) @ X.T @ y ?# @等價(jià)于 X.T.dot(X)return theta.T# 執(zhí)行梯度下降g, cost = gradientDescent(X, y, theta, alpha, iters)# 使用正規(guī)方程求參g1 = normalEqn(X, y)cost1 = computeCost(X, y, g1)# 未訓(xùn)練前的代價(jià)print("梯度下降代價(jià)值:", computeCost(X, y, g))print("正規(guī)方程代價(jià)值:", computeCost(X, y, g1))# 繪制訓(xùn)練曲線fig, ax = plt.subplots(figsize=(12, 8))ax.plot(np.arange(iters), cost, 'r')ax.set_xlabel('Iterations')ax.set_ylabel('Cost')ax.set_title('Error vs. Training Epoch')plt.show()