給定由n個屬性描述的樣本x=(x0, x1, x2, ... , xn),線性模型嘗試學習一個合適的樣本屬性的線性組合來進行預測任務,如:f(x) = w1x1 + w2x2 + ... + wnxn + b = w.T @ x + b。經過必定方法學得向量w和常數b後,模型即可以肯定下來。
而對於給定數據集D={(x1, y1), (x2, y2), ... (xm, ym)},xm=(x1, x2, ..., xn),線性迴歸則嘗試學得一個線性模型來儘量準確地預測樣本的真實輸出標記。python
E越小,則模型對真實標記的擬合程度越好,因此線性迴歸的參數W,b的求解即可以轉化爲求解如下函數:機器學習
前面已經提到過了,線性迴歸模型創建的關鍵就是求解:函數
求解w,b使E最小化的過程,稱爲線性迴歸模型的最小二乘「參數估計」(parameter estimation)。咱們將E分別對w和b求偏導:學習
而後令上述兩個式子爲0則能夠求得w和b最優解的閉式解:測試
上述閉式解的推導過程以下:spa
經過上述推導出的閉式解求解出參數w和b即可以肯定最終的線性迴歸模型。code
在機器學習中經常以向量和矩陣的形式來進行計算從而提升模型的效率,因此這裏再講講最小二乘法的向量表示。爲了便於推導,這裏將b合併進入w,並在X中添加了常數列。此時,均方偏差的表示變成了:orm
求解:blog
這裏涉及矩陣求導,因此先介紹兩個經常使用的矩陣求導公式:get
如今將E對w求導:
令上述導數爲0即可以求出w最優解的閉式解。可是須要注意的是,此處涉及了矩陣求逆的運算,因此須要進行簡單的討論。
1)若\(X^TX\)爲滿秩矩陣或者正定矩陣,則能夠求得:
2)若\(X^TX\)不是滿秩矩陣,例如特徵數量大於樣本數量時,即可以解出多個w,此時便須要從中選擇出一個解來做爲模型的參數。
import numpy as np class LinearRegression(object): def __init__(self): self.W = None def _linear_func(self, X): return X @ self.W[1:] + self.W[0] # z = w0 + w1 * x1 + w2 * x2... = W.T @ x def _least_square(self, X, y): X0 = np.ones((X.shape[0], 1)) X = np.hstack([X0, X]) self.W = np.linalg.inv(X.T @ X) @ X.T @ y # W = (X.T @ X)^-1 @ X.T @ y def fit(self, X, y): self._least_square(X, y) return self def predict(self, X): return self._linear_func(X)
導入波士頓房價數據集進行測試:
if __name__ == "__main__": from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error boston = datasets.load_boston() X = boston.data y = boston.target scaler = MinMaxScaler().fit(X) X = scaler.transform(X) X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, test_size=0.3) lr = LinearRegression().fit(X_train, y_train) y_pred = lr.predict(X_test) print(mean_squared_error(y_test, y_pred)) plt.figure() plt.plot(range(len(y_test)), y_test) plt.plot(range(len(y_pred)), y_pred) plt.legend(["test", "pred"]) plt.show()
均方偏差:
擬合曲線: