简单线性回归(一个特征)学习笔记

简单线性回归(一个特征)的思路

 

思路:

简单线性回归(一个特征)学习笔记_第1张图片

假设x^{i} ,y^{^{i }} 基本符合 线性的关系,所以找到一条直线 y = ax+b  最大程度的拟合 x^{i} , y^{^{i }} ;

这样当给出新的x^{i} 时,就可以预测出 \hat{y^{i}}  = ax^{i} +b ;

目标: x 和 y 都是已知的 , 需要求出 a:斜率 、b:截距。

方法:

最小二乘法(最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。)

误差的平方(y^{^{i}}-\hat{y^{i}})^{2}  ;   考虑所有的样本    : 使  \sum_{i=1}^{m} (y^{^{i}}-\hat{y^{i}})^{2} 尽可能小; 

将  \hat{y^{i}}  = ax^{i} +b 带进  上面的式子 , 目标:找到 a  和 b 使得 \sum_{i=1}^{m} (y^{^{i}}-ax^{i}-b)^{2} 尽可能小 ;  这个函数称为损失函数。

最小二乘法:

 简单线性回归(一个特征)学习笔记_第2张图片 

称这个损失函数为 J(a , b ),目标是使这个函数J(a , b ) 最小 ;

对 J(a , b )  求导, 根据导数的定义,当简单线性回归(一个特征)学习笔记_第3张图片 

就是J(a , b )极值的地方。

根据推到得到,当J(a , b )处于极值时:

简单线性回归(一个特征)学习笔记_第4张图片

 

编写一个简单线性回归的函数算法

通过传入 x_train ,y_train ,求出 a 和 b ; 并且可以当给定新的 x (向量)时候,预测出新的 y。

import numpy as np
class SimpleLinearRegression1:
    def __init__(self):
        '''初始化 Simple Linear Regression 模型'''
        self.a_ = None
        self.b_ = None
    def fit(self , x_train , y_train):
        assert x_train.ndim ==1
        assert x_train.shape[0] == y_train.shape[0]

        num = 0
        d = 0
        for x_i ,y_i in zip(x_train,y_train):
            num += (x_i -np.mean(x_train)) *(y_i -np.mean(y_train))
            d += (x_i - np.mean(x_train))**2

        self.a_ = num/d
        self.b_ = np.mean(y_train) - self.a_ *np.mean(x_train)
        return self

    def predict(self ,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):
        return self.a_ *x_single +self.b_

    def __repr__(self):
        return "SimpleLinearRegression1()"

向量化算法

在上面的算法中,求 a 的方法是使用 for 循环;可以改进为使用 向量的点乘 来加快算法的运算速度。

点乘:两个向量的点乘 ,每个对应的元素 相乘 再 相加。

观察a 的分子分母 ,可以发现分子分母实际都是 两个向量 点乘 的结果 ;

只需要改动 原代码中 fit 部分即可,其余代码保持不变:

    def fit(self , 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 = (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

 

你可能感兴趣的:(机器学习算法)