⼿写算法—Python代码实现⼀元线性回归
Python代码实现⼀元线性回归
python基础代码实例
简述
线性回归模型是机器学习⾥⾯最基础的⼀种模型,是为了解决回归问题,学习机器学习从线性回归开始最好,⽹上关于机器学习的概述有很多,这⾥不再详细说明,本博⽂主要关注初学者常见的⼀些问题以及本⼈的⼀些思考和⼼得,然后会⽤Python代码实现线性回归,并对⽐sklearn实现的线性回归,会以实例的⽅式展现出来。
假设函数、损失函数和梯度下降法
⾸先,我们利⽤sklearn包来⽣成⼀组⼀元回归数据集
import numpy as np
import pandas as pd
from sklearn import datasets  #sklearn⽣成数据集都在这⾥
from matplotlib import pyplot as plt
#⽣成⼀个特征的回归数据集
x,y=datasets.make_regression(n_features=1,noise=15,random_state=2020)
plt.scatter(x,y)
plt.show()
make_regression⽤于⽣成回归数据集,在jupyter⾥⾯是⽤Shift+Tab查看参数,⼤家如果想查什么资料,强烈建议⼤家多去看看官⽹的说明⽂档。
如上所⽰,我们⽤⾁眼⼤概觉得下⾯的这条红⾊回归线⽐较合适
那是怎么求得的呢?
本样本集属于⼀元线性回归问题,我们假设(markdown实在是耗费时间,关键是我还不太会⽤,o(╥﹏╥)o,只能写在纸上贴出来)
问题⼀:为什么要⽤均⽅误差,⽽不⽤平均绝对误差?
java工具类怎么创建
回答:其实平均绝对误差也可以代表损失,只不过后⾯我们要⽤梯度下降法求参数k,b的偏导,⽽平均绝对误差带有绝对值,不⽅便求偏导(在0处不可导),因此选⽤均⽅误差,也好理解。
在机器学习中,损失函数要求可微可导,某些损失函数还要求⼆阶可导,例如xgboost,后⾯讲到xgboost时再展开。
问题⼆:为什么损失函数前⾯是1/2m,m个样本不是除以m就可以了吗?
回答:主要是为了求梯度时⽐较好看,抵消平⽅提出来的2,其实不影响最终的参数,因为加上2,只是相当于学习率(步长)变⼩了,不加上2,学习率就不⽤除以2,但是对于这个凸函数优化⽽⾔,最终都可以得到最⼩值,参数不会变化。这个问题在后⾯讲标准⽅程法时,我会具体证明:这个2对参数没有影响。
思考:使⽤均⽅误差作为线性回归的损失函数,有什么特点?
回答:对异常值⾮常敏感,由于带平⽅,如果有1个异常数据远离样本点,在平⽅的作⽤下,这个点和正常的回归线之间误差很⼤,⽽均⽅误差是基于整体误差最⼩,可能因为这⼀个异常点,⽽导致线性回归模型参数的改变。
还有⼀种为什么⽤均⽅误差的解释,看这⾥
链接: .
foreach语法结构
问题⼆的解释,请看:
链接:
我们都知道这个损失函数是⼀个关于系数k,b的平⽅函数(因为只有⼀个特征),平⽅函数也是凸函数,因此采⽤梯度下降法,沿着负梯度改变,⼀定可以取到最⼩值,不存在局部最⼩值的问题(关于什么是凸函数,不懂的同学还请⾃⾏了解,这个⽐较重要,可以简单理解成单调函数)。
梯度下降法这块,相关的博⽂也很多(了解什么是随机梯度下降法,批量梯度下降法,⼩批量梯度下降法,这⾥⽤的是批量梯度下降法),这⾥只讲⼀点,为什么沿着负梯度的⽅向,可以取到最⼩值?
对系数求偏导,就是链式法则求复合函数导数,忘记的同学⾃⼰复习⼀下,这⾥不再展开。
直接贴图,写了这么久,才写了这么点,想详细点有⼼⽆⼒哇,/(ㄒoㄒ)/~~
这⾥⾯的θ0和θ1就是上⾯的b,k
十进制小数转二进制转换器Python实现⼀元线性回归
根据上⾯的推导公式,现在⽤Python来实现⼀元线性回归
class one_variable_linear():
#初始化参数,k为斜率,b为截距,a为学习率,n为迭代次数    def __init__(self,k,b,a,n):
self.k =k
self.b=b
self.a=a
self.n = n
#梯度下降法迭代训练模型参数
def fit(self,x,y):
#计算总数据量
m=len(x)
mips汇编例题#循环n次
for i in range(self.n):
b_grad=0
k_grad=0
#计算梯度的总和再求平均
for j in range(m):
b_grad += (1/m)*((self.k*x[j]+self.b)-y[j])
k_grad += (1/m)*((self.k*x[j]+self.b)-y[j])*x[j]
#更新k,b
self.b=self.b-(self.a*b_grad)
self.k=self.k-(self.a*k_grad)
#每迭代10次,就输出⼀次图像
if i%10==0:
print('迭代{0}'.format(i)+'次')
plt.plot(x,y,'b.')
plt.plot(x,self.k*x+self.b,'r')
plt.show()
self.params= {'k':self.k,'b':self.b}
#输出系数
return self.params
#预测函数
def predict(self,x):
y_pred =self.k * x + self.b
return y_pred
lr=one_variable_linear(k=1,b=1,a=0.1,n=60)
lr.fit(x,y)
下⾯是迭代过程:
businesses

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。