多元線性回歸和正規方程解
在真實世界中,真實的樣本是有很多的特征值的,這種也是可以使用線性回歸解決的,通常我們稱這種為多元線性回歸問題
我們設一個樣本的特征為xi,則
那么對應的y就是
這種直線仍然有截距,即
如果我們可以學習到這多個樣本的話,那么我們就可以求出我們的多元線性回歸對應的預測值
與簡單線性基本一致,只是變成了多元的情況
其思想也是基本一致,其目的仍然是讓其中的損失函數盡可能的小
與簡單不一樣的是,其中的有一部分是不同的
那么就可以確定多元線性回歸的目標
對於這個式子,其就是一個列向量
那么我們對這個式子可以進行改變,在截距后面增加一個第0號特征,一般上來說,特征是從1開始的,為了能夠和截距結合在一起,讓我們計算起來比較方便,在這里我們虛構一個第0特征,其恆等於1
這樣變化以后,我們可以將xi變為(其為行向量)
這樣我們就變成了一個矩陣,每一行代表一個樣本,每一列代表一個特征,那么我們就可以將其寫成
我們將其推廣到全部的樣本上
那么我們就得到了關於這個參數相應的x中的每一個樣本的預測的結果
那么我們的多元線性回歸的問題的目標就可以變成
那么我們怎么計算呢,思路是一樣的,使用最小二乘法的思路,對每一個進行求導(矩陣)
推導結果(不用管推導過程,不影響使用)
這個式子被稱為多元線性回歸的正規方程解,這樣的式子看起來不錯
但是有個問題,其式子的時間復雜度高,是O(n³),可以優化,但是也很高,會出現效率問題,但是也有解決方案
其優點是不需要對數據做歸一化處理,對多元線性回歸沒有必要進行這一步
一般實際操作的時候,有的時候,最終報告給用戶是將截距和系數分開報告,這個系數可以用於描述對於最終樣本相應的貢獻的程度,截距是和樣本不相關的
我們在LinearRegression.py中寫入我們想要封裝的代碼,廣義上的多元線性回歸問題
其中
self.coef_系數
self.interception_截距
self._theta整體計算出的向量
代碼如下
import numpy as np
from metrics import r2_score
class LinearRegression:
def __init__(self):
"""初始化LinearRegression模型"""
self.coef_ = None
self.interception_ = None
self._theta = None
def fit_normal(self, X_train, y_train):
"""根據訓練數據集X_train, y_train訓練LinearRegression模型"""
assert X_train.shape[0] == y_train.shape[0], \
"the size of X_ _train must be equal to the size of y_train"
X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train);
self.interception_ = self._theta[0]
self.coef_ = self._theta[1:]
return self
def predict(self, X_predict):
"""給定待預測數據集X_predict, 返回表示X_predict的結果向量"""
assert self.interception_ is not None and self.coef_ is not None, \
"must fit before predict!"
assert X_predict.shape[1] == len(self.coef_), \
"the feature number of x_predict must be equal to X_train"
X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
return X_b.dot(self._theta)
def score(self, X_test, y_test):
"""根據測試數據集X_test和y_test確定當前模型的准確度"""
y_predict = self.predict(X_test)
return r2_score(y_test, y_predict)
def __repr__(self):
return "LinearRegression()"
在notebook中
操作同前筆記
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
采用波士頓數據
boston = datasets.load_boston()
X = boston.data
y = boston.target
大小范圍為小於50
X = X[y < 50.0]
y = y[y < 50.0]
X對應的shape
X.shape
使用隨機種子666
from model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,seed=666)
引用並實例化后再fit
from LinearRegression import LinearRegression
reg = LinearRegression()
reg.fit_normal(X_train,y_train)
模型渲染好了以后簡單地查看一下
reg.coef_
reg.interception_
我們可以調用score來看看預測結果的值是多少
reg.score(X_test,y_test)
可以看出來,預測值高了不少,通過對比,說明使用的數據越多,對於預測值是越准的