多元線性回歸理論
相比于樣本只有一個特征值的簡單線性回歸徐绑,多元線性回歸往往更能反映研究對象的真實情況勾徽。多元線性回歸樣本有多個特征迫横,需要研究的是這多個特征與最終結果的關系。
如上圖所示吨凑,相比于簡單線性回歸捍歪,這里的變量x不再是單個特征,而是一個向量鸵钝,代表多個特征糙臼。
于是y與x的模型表達式可以為:
對于一個樣本的預測值則為:
這與簡單線性回歸是非常一致的,區(qū)別只是特征從1個變成了n個恩商。在求解參數時也和簡單線性回歸一致变逃,求得的參數要使得:
盡可能小。
令
于是對一組樣本的預測結果向量為:
同樣可以根據高等數學的知識經過簡單推導得到最優(yōu)的名眉,這里不再給出過程,直接給出最優(yōu)結果(多元線性回歸的正規(guī)方程解Normal Equation):
通過監(jiān)督學習的數據可以很輕易得到這個解撒犀,機器學習能直接得到數學解的模型是非常少的福压,而且可以不對數據作歸一化處理。但這種方式有一個問題或舞,就是時間復雜度是荆姆,盡管可以優(yōu)化到,但時間消耗仍然是比較多的映凳。在后面的學習中我們會有計算代價更小的在機器學習中應用非常廣泛的梯度下降法來求解線性回歸模型胆筒。
實現自己的多元線性回歸
在play_Ml中新建LinearRegression.py,代碼如下:
import numpy as np
from .metrics import r2_score
class LinearRegression:
def __init__(self):
self.coef_ = None
self.interception_ =None
self._theta = None
def fit_normal(self,X_train,y_train):
assert X_train.shape[0] == y_train.shape[0],"must be equal!"
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):
assert self.interception_ is not None and self.coef_ is not None,"must fit first!"
assert X_predict.shape[1] == len(self.coef_),"feature must be the same!"
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):
y_predict = self.predict(X_test)
return r2_score(y_test,y_predict)
def __repr__(self):
return "LinearRegression()"
在bsoton房產數據上測試模型诈豌,使用boston房產數據的13個特征:
'''使用boston房產數據的所有特征'''
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
boston = datasets.load_boston()
X = boston.data
y = boston.target
X = X[y < 50.0]
y = y[y < 50.0]
'''使用自己的模型'''
from play_Ml.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,seed=666)
from play_Ml.LinearRegression import LinearRegression
reg = LinearRegression()
reg.fit_normal(X_train,y_train)
'''查看求得的系數與截距'''
reg.coef_
reg.interception_
'''R方指標'''
reg.score(X_test,y_test)
注:上面的fit_normal方式是我們自己寫的基于正規(guī)化方程的腐泻,sklearn中的fit方式并不是正規(guī)化方程方式
可以看到,多元線性回歸在該數據集上R方為0.8队询,還是不錯的。這也間接反映了如果特征能很好反映與預測之間的關系的話构诚,使用更多特征蚌斩,會有更好的預測效果。
sklearn中的回歸
sklearn中的線性回歸
仍然使用和上面相同的數據集:
'''使用boston房產數據的所有特征'''
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
boston = datasets.load_boston()
X = boston.data
y = boston.target
X = X[y < 50.0]
y = y[y < 50.0]
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=666)
'''這里如果用上面自己算法的train_test_split范嘱,可以在sklearn
中的fit中得到和上面一樣的系數和截距結果'''
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
lin_reg.coef_
lin_reg.intercept_
lin_reg.score(X_test,y_test)
結果如下:
knn做回歸
knn也是可以用來做回歸任務的送膳,下面仍然用boston房產數據,進行knn的回歸:
from sklearn.neighbors import KNeighborsRegressor
knn_reg = KNeighborsRegressor()
knn_reg.fit(X_train,y_train)
knn_reg.score(X_test,y_test)
score值是0.6丑蛤,顯然效果是不如線性回歸的叠聋,不過這只是在knn回歸默認超參數情況下,下面用網格搜索找出更優(yōu)秀的超參數:
'''定義搜索參數網格'''
param_grid=[
{
'weights':['uniform'],
'n_neighbors':[i for i in range(1,11)]
},
{
'weights':['distance'],
'n_neighbors':[i for i in range(1,11)],
'p':[i for i in range(1,6)]
}
]
from sklearn.model_selection import GridSearchCV
knn_reg = KNeighborsRegressor()
grid_search = GridSearchCV(knn_reg,param_grid,n_jobs = -1,verbose = 1)
grid_search.fit(X_train,y_train)
結果如下:
score值變?yōu)?.7受裹,雖然有所提高碌补,但是和線性回歸相比還是有些差據。