线性回归原理
一元线性回归
一元线性回归其实就是从一堆训练集中去算出一条直线,使数据集到直线之间的距离差最小。
举个栗子:
唯一特征X,共有m = 500个数据数量,Y是实际结果,要从中找到一条直线,使数据集到直线之间的距离差最小,如下图所示:
那要如何去完成这个操作呢?
线性回归所提供的思路是,先假设一条直线:
可以将特征X中每一个值都带入其中,得到对应的,定义可以将损失定义为和 之间的差值平方的和:
而为了之后计算将其修改为
接下来问题就简单了,只需要求出最小的 就可以了。
梯度下降
可以看出,现在的问题已经变成了一个求极值的问题,这里面有很多种方法,有最小二乘,标准方程方法,以及梯度下降等等,在这里只简要分析一下梯度下降法。
将和分别从(-50,50)中取值,算出其的损失值,可以做出如下图:
其中x、y轴就是和,z轴是的值,现在目标就变成了从图中找到最低点,而最低点的xy轴坐标就是我们要的。
而梯度下降,顾名思义,就是要往下走,而这个往下走,方向并不随意,而是要沿着梯度最大的位置往下走,而最大,不久是它的偏导数吗,接下来要做的就是对求偏导:
之后更新得到新的和:
在这个公式里突然多了一个,它表示的是学习率,用来限定步长的大小,也很容易理解,毕竟得到的偏导是类似斜率的东西,只是一个方向,总得加个数值,才能表示向这个方向移动的距离。
对于的取值,一般都取的比较小,但也不要太小,太小就意味着迭代步数要增加,运算时间边长。
另外,迭代的步数要自己设置。
python实现
因为并没有数据集,就自己做了一个,代码只是简单的实现了一下。
# -*- coding: utf-8 -*-
"""
Created on Wed Jun 20 17:09:13 2018
@author: 96jie
"""
#导入cv模块
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
#数据
a = np.random.standard_normal((1, 500))
x = np.arange(0,50,0.1)
y = np.arange(20,120,0.2)
y = y - a*10
y = y[0]
#梯度下降
def Optimization(x,y,theta,learning_rate):
for i in range(iter):
theta = Updata(x,y,theta,learning_rate)
return theta
def Updata(x,y,theta,learning_rate):
m = len(x)
sum = 0.0
sum1 = 0.0
alpha = learning_rate
h = 0
for i in range(m):
h = theta[0] + theta[1] * x[i]
sum += (h - y[i])
sum1 += (h - y[i]) * x[i]
theta[0] -= alpha * sum / m
theta[1] -= alpha * sum1 / m
return theta
#数据初始化
learning_rate = 0.001
theta = [0,0]
iter = 1000
theta = Optimization(x,y,theta,learning_rate)
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
'''
plt.figure(figsize=(35,35))
plt.scatter(x,y,marker='o')
plt.xticks(fontsize=40)
plt.yticks(fontsize=40)
plt.xlabel('特征X',fontsize=40)
plt.ylabel('Y',fontsize=40)
plt.title('样本',fontsize=40)
plt.savefig("样本.jpg")
'''
#可视化
b = np.arange(0,50)
c = theta[0] + b * theta[1]
plt.figure(figsize=(35,35))
plt.scatter(x,y,marker='o')
plt.plot(b,c)
plt.xticks(fontsize=40)
plt.yticks(fontsize=40)
plt.xlabel('特征X',fontsize=40)
plt.ylabel('Y',fontsize=40)
plt.title('结果',fontsize=40)
plt.savefig("结果.jpg")