参考文章:1、https://mp.weixin.qq.com/s/ESKQKi_1K_WPXNistizDVw
2、https://mp.weixin.qq.com/s/siFRKWLhGOGJCCMjzB7R7A
3、https://mp.weixin.qq.com/s/gJU4oJufOFNF_I3MO7gYlA
参考文献:《机器学习》(周志华著) 第三章线性模型
线性回归模型是最重要的数学模型之一,很多模型都是建立在它的基础之上。
概念解释:
所谓线性,是指方程是线性的;所谓回归,是指用方程来模拟变量之间是如何关联的。顾名思义,简单线性回归就是只有一个样本特征。Y值是连续型变量,如销售额、股票价格、房价等。
我们先从简单线性回归开刀,一层一层地剖析线性回归这颗大洋葱。
一 简单线性回归
即一元线性回归。
1、数学原理
就是说,我们需要找到一条直线,最大程度的拟合样本特征和样本数据标记之间的关系。 在二维平面中,这条直线的方程就是 y = ax + b。
所以,我们在训练模型时,需要找到最优的(a,b),获得拟合度最佳的线性模型 y = ax + b。
即:已知训练数据样本x、y,找到a和b的值,使均方误差( )尽可能小。
使用最小二乘法,得到:
什么是最小二乘法呢?基于均方误差最小化来进行模型求解的方法称为“最小二乘法(least square method)”。在线性回归中,最小二乘法是试图找到一条直线,使所有样本到直线上的欧氏距离之和最小。
2、代码实现
import numpy as np
class SimpleLinearRegression:
def __init__(self):
"""模型初始化函数"""
self.a_=None
self.b_=None
def fit(self,x_train,y_train):
"""根据训练数据集x_train,y_train训练模型"""
assert x_train.ndim==1,\
"""简单线性回归模型仅能够处理一维特征向量"""
assert x_train.shape[0]==y_train.shape[0],\
"""特征向量的长度和标签的长度相同"""
x_mean=np.mean(x_train)
y_mean=np.mean(y_train)
num=np.dot(x_train - x_mean,y_train - y_mean) # 分子
d=np.dot(x_train - x_mean,x_train - x_mean) # 分母
self.a_=num/d
self.b_=y_mean - self.a_ * x_mean
return self
def predict(self,x_predict):
"""给定待预测数据集x_predict,返回表示x_predict的结果向量"""
assert x_predict.ndim==1,\
"""简单线性回归模型仅能够处理一维特征向量"""
assert self.a_ is not None and self.b_ is not None,\
"""先训练之后才能预测"""
return np.dot(x_predict,self.a_)+self.b_
def predict_single(self, x_single):
"""给定单个待预测数据x_single,返回x_single的预测结果值"""
return self.a_ * x_single + self.b_
def __repr__(self):
"""返回一个可以用来表示对象的可打印字符串"""
return "SimpleLinearRegression()"
二、多元线性回归
1、数学原理
定义:从训练集D中,学得 ($\pmb{\omega},使得 ,称为“多元线性回归”(multivariate linear regression)。
利用最小二乘法,对 和b进行估计,即把 和b转换为向量形式 。找到 : 。
令 ,对 求导得到: 。
当 为满秩矩阵时,得到 ;令 ,学得多元线性模型是 。
然而,现实任务中 不为满秩矩阵,许多任务中会遇到大量的变量,其数目甚至超过样例数,导致 的列数多于行数, 不会为满秩矩阵。此时 会有多个解,它们都能使均方误差最小化。选择哪一个解作为输出,由学习算法的归纳偏好决定,常规做法是引入正则化(regularization)。
2、代码实现
import numpy as np
from myML_Algorithm.metrics import r2_score
class linearRegression:
def __init__(self):
"""初始化Linear Regression模型"""
self.coef_=None # 系数(theta0~1 向量)
self.interception_=None # 截距(theta0 数)
self._theta=None # 整体计算出的向量theta
def fit(self,X_train,y_train):
"""根据训练数据X_train,y_train训练Linear Regression模型"""
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((X_train.shape[0],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]==self.coef_.shape[0],\
"the feature number of X_predict must be equal to X_train"
X_b=np.hstack([np.ones((X_predict.shape[0],1)),X_predict])
y_predict=X_b.dot(self._theta)
return y_predict
def score(self,X_test,y_test):
"""根据测试集X_test和y_test确定当前模型的准确率"""
y_predict=self.predict(X_test)
return r2_score(y_test,y_predict)
#return 1-np.sum((y_test-y_predict)**2)/(y_test.shape[0]*np.var(y_test))
def __repr__(self):
return "LinearRegression()"