线性回归算法

  • 主要用于解决回归问题
  • 思想简单,实现容易
  • 许多强大的非线性模型的基础
  • 结果具有很好的可解释性

寻找一条直线,最大程度的拟合样本特征和样本输出标记之间的关系

对于样本的特征只有一个,称为简单线性回归

样本特征有多个,称为多元线性回功

简单线性回归

假设我们找到了最佳拟合的直线方程:y = ax + b

则对于每个样本点下回归直线方程怎么做图 回归直线方程简单算法_特征向量

回归直线方程怎么做图 回归直线方程简单算法_回归直线方程怎么做图_02

真值为:回归直线方程怎么做图 回归直线方程简单算法_拟合_03

我们希望回归直线方程怎么做图 回归直线方程简单算法_特征向量_04回归直线方程怎么做图 回归直线方程简单算法_拟合_03的差距尽量小
为了防止正负抵消,且需要函数可导,可以得到表达回归直线方程怎么做图 回归直线方程简单算法_拟合_03回归直线方程怎么做图 回归直线方程简单算法_特征向量_04 的差距:回归直线方程怎么做图 回归直线方程简单算法_回归直线方程怎么做图_08

考虑所有样本,我们推导出:
回归直线方程怎么做图 回归直线方程简单算法_拟合_09

目标:找到a和b,使得 回归直线方程怎么做图 回归直线方程简单算法_线性回归_10

一类机器学习算法的基本思路

我们所谓的建模过程,其实就是找到一个模型,最大程度的拟合我们的数据。 在简单线回归问题中,模型就是我们的直线方程:y = ax + b 。

要想最大的拟合数据,本质上就是找到没有拟合的部分,也就是损失的部分尽量小,就是损失函数(loss function)(也有算法是衡量拟合的程度,称函数为效用函数(utility function)),损失函数描述了单个样本预测值和真实值之间误差的程度。用来度量模型一次预测的好坏:
回归直线方程怎么做图 回归直线方程简单算法_特征向量_11

因此,推导思路为:
通过分析问题,确定问题的损失函数或者效用函数;
通过最优化损失函数或者效用函数,获得机器学习的模型

近乎所有的参数学习算法都是这个套路:线性回归、SVM、多项式回归、神经网络…

目标:找到a和b,使得 回归直线方程怎么做图 回归直线方程简单算法_线性回归_10 尽可能的小

典型的最小二乘法问题:最小化误差的平方

通过最小二乘法可以求出a、b的表达式

回归直线方程怎么做图 回归直线方程简单算法_回归直线方程怎么做图_13

简单线性回归算法的实现

回归直线方程怎么做图 回归直线方程简单算法_拟合_14


代码实现

import numpy as np

class SimpleLinearRegression1:
    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 len(x_train) == len(y_train), \
            "特征向量的长度和标签的长度相同"
        x_mean = np.mean(x_train)
        y_mean = np.mean(y_train)
        num = 0.0
        d =0.0
        for x, y in zip(x_train, y_train):
            num += (x - x_mean) * (y - y_mean)
            d += (x - x_mean) ** 2

        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.array([self._predict(x) for x in x_predict])

    def _predict(self, x_single):
        """给定单个待预测数据x_single,返回x_single的预测结果值"""
        return self.a_ * x_single + self.b_

    def __repr__(self):
        """返回一个可以用来表示对象的可打印字符串"""
        return "SimpleLinearRegression1()"

#向量化方式替代for循环
class SimpleLinearRegression2:
    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 len(x_train) == len(y_train), \
            "特征向量的长度和标签的长度相同"
        x_mean = np.mean(x_train)
        y_mean = np.mean(y_train)
        num = (x_train - x_mean).dot(y_train - y_mean)  # 分子
        d = (x_train - x_mean).dot(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.array([self._predict(x) for x in x_predict])

    def _predict(self, x_single):
        """给定单个待预测数据x_single,返回x_single的预测结果值"""
        return self.a_ * x_single + self.b_

    def __repr__(self):
        """返回一个可以用来表示对象的可打印字符串"""
        return "SimpleLinearRegression2()"

多元线性回归

样本特征有多个,称为多元线性回归

多元线性回归预测值: 回归直线方程怎么做图 回归直线方程简单算法_回归直线方程怎么做图_15
目标:找到回归直线方程怎么做图 回归直线方程简单算法_特征向量_16, 使得回归直线方程怎么做图 回归直线方程简单算法_回归直线方程怎么做图_17

推导出可以得到多元线性回归的正规方程解:
回归直线方程怎么做图 回归直线方程简单算法_最小二乘法_18