机器学习系列(十三)——多元线性回归及knn做回归

多元线性回归理论

相比于样本只有一个特征值的简单线性回归,多元线性回归往往更能反映研究对象的真实情况。多元线性回归样本有多个特征,需要研究的是这多个特征与最终结果的关系。


多元线性回归

如上图所示,相比于简单线性回归,这里的变量x不再是单个特征,而是一个向量,代表多个特征。
于是y与x的模型表达式可以为:
y=\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}+...+\theta_{n}x_{n}

对于一个样本X^{(i)}的预测值则为:
\widehat{y}^{(i)}=\theta_{0}+\theta_{1}X_{1}^{(i)}+\theta_{2}X_{2}^{(i)}+...+\theta_{n}X_{n}^{(i)}

这与简单线性回归是非常一致的,区别只是特征从1个变成了n个。在求解参数\theta=(\theta_{0},\theta_{1},...,\theta_{n})^{T}时也和简单线性回归一致,求得的参数要使得:
\sum_{i=1}^m(y^{(i)}-\widehat{y}^{(i)})^{2}

尽可能小。

\begin{equation} X_{b}= \begin{pmatrix} 1,X_{1}^{(1)} , X_{2}^{(1)},...,X_{n}^{(1)}\\1,X_{1}^{(2)} , X_{2}^{(2)},...,X_{n}^{(2)}\\...\\1,X_{1}^{(m)} , X_{2}^{(m)},...,X_{n}^{(m)} \end{pmatrix} \end{equation}

于是对一组样本的预测结果向量为:\widehat{y}=X_{b}\bullet\theta
同样可以根据高等数学的知识经过简单推导得到最优的\theta,这里不再给出过程,直接给出最优结果(多元线性回归的正规方程解Normal Equation):
\theta=({X_{b}^{T}X_{b}}^{-1})X_{b}^{T}y

通过监督学习的数据可以很轻易得到这个解,机器学习能直接得到数学解的模型是非常少的,而且可以不对数据作归一化处理。但这种方式有一个问题,就是时间复杂度是O(n^{3}),尽管可以优化到O(n^{2.4}),但时间消耗仍然是比较多的。在后面的学习中我们会有计算代价更小的在机器学习中应用非常广泛的梯度下降法来求解线性回归模型。


实现自己的多元线性回归

在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方式是我们自己写的基于正规化方程的,sklearn中的fit方式并不是正规化方程方式

coef_inter

可以看到,多元线性回归在该数据集上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)

结果如下:

result

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回归默认超参数情况下,下面用网格搜索找出更优秀的超参数:

'''定义搜索参数网格'''
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)

结果如下:

knn_Regressor

score值变为0.7,虽然有所提高,但是和线性回归相比还是有些差据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容