当前位置:   article > 正文

python实现一元线性回归_一元线性回归python

一元线性回归python

这个专栏主要是自己用python入门深度学习和图像识别的一些学习笔记和心得体会。既有一些算法理论的理解,也有python代码的实现,争取对一个问题做到知其然并知其所以然,理论和实践并进。大家一起加油!栏目的框架主要从最基础的机器学习开始,到神经网络的基础,再用pytorch实现图像分类,目标检测,分割,产生式模型等。使用的工具主要是numpy和pytorch。

1.线性回归模型介绍

线性回归是机器学习中最为简单的模型。首先介绍两个概念,线性和回归。

线性:即变量之间的关系为一次函数,也就是说当因变量x和自变量y的关系画在平面上是一条直线。

回归:即预测一个连续问题的数值。举个很简单的例子,假设已知我国过去五个年份的人口,可以预测未来几年的人口。就是根据年份和人口数量可能呈线性关系来预测拟合的。

因此一元线性回归就很好理解了,就是我们的自变量和因变量只有一个。(例如例子里的年份和人口),当自变量有多个的时候(例如每个人的年龄,收入),一元线性回归就拓展成了多元线性回归。

2.一元线性回归最直观数学理解

讲白了,一元线性回归要我们干的事情就是你已知了一大堆互相对应的x和y,(并且发现了他们之间是近似于线性关系的,可以通过画散点图来看,spss非常方便!),你希望对于未知的x,你也能预测出对应的y。

用数学模型表示就是y=a*x+b,你希望在训练过程中求解出那个最完美的a,b,得到a,b后,你再来一个新的x值,预测的y值也是比较准确的。

那么最直观地想法就是我需要让我的预测值和真实值差值最小。即求min(y_predict-y),乍一眼看去没问题。但是你细细一想,y_predict一定是有正有负的,累计求和后正负是会抵消的,这显然与现实不符。

那马上就会想到,求(|y_predict-y|),这是没有问题的,但是我们要求参数的最小值必然要求导。绝对值函数我们知道它是不连续的,故无法求导又舍弃了。

因此,最完美的方法就是求sum((y_predict-y)^2)/n,这里就是对预测值和真实值的差求平方,因为有多个值,我们对他求和后除以样本的数量。

再把y=a*x+b带入就得我们的目标式子,专业名词叫误差函数:

在这里插入图片描述

那么我要去求参数a和b的最小值,就是分别对a和b求偏导。推导的过程就不列了,各大博客都有,这里直接给出结果:

在这里插入图片描述
在这里插入图片描述

这里的x_mean,y_mean就是平均值。至此,我们训练的任务也就完成了。

那么下一步就是需要对我们的模型做个评估,它究竟准确率如何呢?我们可以通过前面的误差函数来打分,但这里给出一个更为科学的评估函数,专门针对线性函数的R Square,也叫拟合优度。

在这里插入图片描述
这个公式科学在哪呢,仔细观察发现它的分子衡量的是y的预测值和真实值之间的差,分母衡量的是y的平均值和y的差,分母代表的是基准模型。也就是说当我们的模型预测出的值和基准模型一样时,r_square=0,当模型预测值和真实值一模一样,r_square=1,如果r_square<0,说明连基准模型都达不到。

3.python实现一元线性回归

有了理论的公式推导,我们完全可以实现它,总体思路如下:
1.将一元线性回归封装到类中
初始化参数a,b
训练函数,训练出a,b
预测函数,对于给定的x向量,可以输出y_predict
打分函数,利用r_square评估我们的模型
2.在主函数中输入数据集进行测试,并画出散点图

代码和注释如下:


```python
import numpy as np
import matplotlib.pyplot as plt

class SingleLinearRegression:
    def __init__(self):   #初始化a,b
        self.a_=None;
        self.b_=None;

    def fit(self,x_train,y_train):  #训练函数,训练出a,b
        x_mean = np.mean(x_train)
        y_mean = np.mean(y_train)  # 求x和y的平均值

        fenzi = 0.0;
        fenmu = 0.0;  # 对分子分母初始化
        for x_i, y_i in zip(x_train, y_train):  # 将x,y打包成元组的形式
            fenzi += (x_i - x_mean) * (y_i - y_mean)  # 根据最小二乘法求出参数
            fenmu += (x_i - x_mean) ** 2

        self.a_ = fenzi / fenmu
        self.b_ = y_mean - self.a_ * x_mean  #得到a,b

        return self

    def predict(self,x_test_group):  #预测函数,用户输入一组x(为一维向量),可以进行y的预测
        result=[]  #初始化一个列表,用来储存预测的y值
        for x_test in x_test_group:  #对于每个输入的x都计算它对应的预测y值并加入列表中
            result.append(self.a_*x_test+self.b_)
        y_predict=np.array(result)  #将列表转换为矩阵向量形式方便运算

        return y_predict

    def r_square(self,y_true,y_predict):  #打分函数,评估该模型的准确率
        mse=np.sum((y_true-y_predict)**2)/len(y_true)  #计算均方误差mse
        var=np.var(y_true)  #计算方差
        r=1-mse/var #计算拟合优度r的平方
        return r

if __name__=='__main__':
    x = np.array([1, 2, 4, 6, 8])
    y = np.array([2, 5, 7, 8, 9])
    l=SingleLinearRegression()  #创建一个对象,接下来调用对象的方法
    l.fit(x,y)
    print('6,8对应的的预测值是:')
    print(l.predict([6,8]))
    print('该模型的评估分数为:')
    print(l.r_square([8,9],l.predict([6,8])))

    #画出散点图和预测图
    plt.scatter(x, y, color='b')  # 画出原来值得散点图
    plt.plot(x,l.predict(x), color='r')  # 画出预测后的线

    plt.xlabel('x')  # 写上标签
    plt.ylabel('y')

    plt.show()  # 作图函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

结果是:
在这里插入图片描述
在这里插入图片描述

3.心得体会与收获

一元线性回归无论是原理理解还是代码实现应该都不太难,但是在代码实现中还是涉及到一些技巧,例如:

1.模型都应该封装到类中,一些需要训练的参数在类中初始化并训练。

2.可以使用python语法的zip将两对向量打包成元组的形式便于计算。

3.此题中的r_square可以转化为误差函数/方差的形式便于编程。

基本就这些,下一篇准备在一元线性回归的基础上更进一步,实现多元线性回归。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/683711
推荐阅读
相关标签
  

闽ICP备14008679号