【笔记】多元线性回归和正规方程解
多元线性回归和正规方程解
在真实世界中,真实的样本是有很多的特征值的,这种也是可以使用线性回归解决的,通常我们称这种为多元线性回归问题
我们设一个样本的特征为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)
可以看出来,预测值高了不少,通过对比,说明使用的数据越多,对于预测值是越准的