学习笔记之线性回归

参考文章: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的值,使均方误差( ( y ( i ) a x ( i ) b ) 2 \sum(y^{(i)}-ax^{(i)}-b)^2 )尽可能小。

使用最小二乘法,得到:
a = i = 1 N ( x ( i ) x ˉ ) ( y ( i ) y ˉ ) i = 1 N ( x ( i ) x ˉ ) 2 a=\frac{\sum_{i=1}^{N}(x^{(i)}-\bar{x})(y^{(i)}-\bar{y})}{\sum_{i=1}^{N}(x^{(i)}-\bar{x})^2}

b = y ˉ a x ˉ b=\bar{y}-a\bar{x}

什么是最小二乘法呢?基于均方误差最小化来进行模型求解的方法称为“最小二乘法(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中,学得 f ( X ) = ω T X + b f({\pmb{X}} )=\pmb{\omega}^T\pmb{X}+b ($\pmb{\omega},使得 f ( x i ) y i f(\pmb{x_i}) y_i ,称为“多元线性回归”(multivariate linear regression)。

利用最小二乘法,对 ω \pmb{\omega} 和b进行估计,即把 ω \pmb{\omega} 和b转换为向量形式 ω ^ = ( ω ; b ) \pmb{\hat{\omega}}=(\pmb{\omega};b) 。找到 : ω ^ = a r g m i n ( y X ω ^ ) T ( y X ω ^ ) \pmb{\hat{\omega}^{*}}=argmin(\pmb{y}-\pmb{X}\pmb{\hat{\omega}})^T(\pmb{y}-\pmb{X}\pmb{\hat{\omega}})

E ω ^ = ( y X ω ^ ) T ( y X ω ^ ) E_{\pmb{\hat{\omega}}}=(\pmb{y}-\pmb{X}\pmb{\hat{\omega}})^T(\pmb{y}-\pmb{X}\pmb{\hat{\omega}}) ,对 ω ^ \pmb{\hat{\omega}} 求导得到: E ω ^ ω ^ = 2 X T ( X ω ^ y ) \frac{\partial{E_{\pmb{\hat{\omega}}}}}{\partial{\pmb{\hat{\omega}}}}=2\pmb{X}^T(\pmb{X}\pmb{\hat{\omega}}-\pmb{y})

X T X \pmb{X}^T\pmb{X} 为满秩矩阵时,得到 ω ^ = ( X T X ) 1 X T y \pmb{\hat{\omega}^{*}}=(\pmb{X}^T\pmb{X})^{-1}\pmb{X}^T\pmb{y} ;令 x i ^ = ( x i ; 1 ) \pmb{\hat{x_i}}=(\pmb{x_i};1) ,学得多元线性模型是 f ( x i ^ ) = x i ^ ( X T X ) 1 X T y f(\pmb{\hat{x_i}})=\pmb{\hat{x_i}}(\pmb{X}^T\pmb{X})^{-1}\pmb{X}^T\pmb{y}

然而,现实任务中 X T X \pmb{X}^T\pmb{X} 不为满秩矩阵,许多任务中会遇到大量的变量,其数目甚至超过样例数,导致 X \pmb{X} 的列数多于行数, X T X \pmb{X}^T\pmb{X} 不会为满秩矩阵。此时 ω ^ \pmb{\hat{\omega}} 会有多个解,它们都能使均方误差最小化。选择哪一个解作为输出,由学习算法的归纳偏好决定,常规做法是引入正则化(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()"

完整代码

发布了12 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/sun91019718/article/details/104963073