最近打算重新学习机器学习,为数据分析打好基础,本章记录线性回归以及梯度下降的内容。
在机器学习中,线性回归是一个较简单的模型,属于监督学习。先给定一个训练集,根据这个训练集学习出一个线性函数,然后测试此函数是否足够拟合训练集数据,挑选出最好的函数(代价最小)即可。
一、概念:
1、线性回归的假设模型:
为了评估假设模型,需要引入代价函数(cost function)的概念。
2、线性回归的最小二乘的损失函数(cost function):
用梯度下降的方法来更新权值,使得代价函数最小。梯度下降分为:批量梯度下降、随机梯度下降和小批量随机梯度下降。
3、批量梯度下降:它的具体思路是在更新每一个参数时使用所有的样本来进行更新,它得到的是一个全局最优解,但是每迭代一步,都要用到训练集所有的数据,具体的伪代码如下:
4、随机梯度下降:用样本中的一个例子来近似我所有的样本,来调整 θ ,会带来一定的问题,因为计算得到的并不是准确的一个梯度,容易陷入到局部最优解中,具体的伪代码如下:
5、小批量随机梯度:其实批量的梯度下降就是一种折中的方法,用一些小样本来近似全部的,即随机选择一定数量的样本来表示全部的。具体的伪代码是:
二、代码
1、批量梯度下降的demo:
import numpy as np
import matplotlib.pyplot as plt
import mathimport numpy as np
x_train = np.array([[1,2],[2,1],[2,3],[3,5],[1,3],[4,2],[7,3],[4,5],[11,3],[8,7]])
y_train = np.array([7, 8, 10, 14, 8, 13, 20, 16, 28, 26])
test_train=np.array([[1,3],[2,2],[3,2]])
k1=k2=k3=k4=k0=0
rating=0.0001
i=s1=0
s0=0
while i<100000:
sum_k1=sum_k2=sum_k3=s1=0
for x,y in zip(x_train,y_train):
s1=s1+(k3+k1*x[0]+k2*x[1]-y)*(k3+k1*x[0]+k2*x[1]-y)/2
sum_k1=sum_k1+(k3+k1*x[0]+k2*x[1]-y)*x[0]
sum_k2=sum_k2+(k3+k1*x[0]+k2*x[1]-y)*x[1]
sum_k3=sum_k3+(k3+k1*x[0]+k2*x[1]-y)
k1=k1-rating*sum_k1
k2=k2-rating*sum_k2
k3=k3-rating*sum_k3
if math.fabs(s1-s0)<0.000001:
print(k3,k1,k2)
print(i)
break
else:
s0=s1
i=i+1
2、随机梯度下降:
import random
import math
#This is a sample to simulate a function y = theta1*x1 + theta2*x2
x_train = [[1,4], [2,5], [5,1], [4,2]]
y_train = [19,26,19,20]
theta = [1,1]
rating= 0.001
j=s0=0
while(j<100000):
s1=0
#每一次选取随机的一个点进行权重的更新
i = random.randint(0,3)
pred_y = theta[0]*x_train[i][0]+theta[1]*x_train[i][1]
theta[0] = theta[0] - rating * (pred_y - y_train[i]) * x_train[i][0]
theta[1] = theta[1] - rating * (pred_y - y_train[i]) * x_train[i][1]
for x,y in zip(x_train,y_train):
pred_y = theta[0]*x[0]+theta[1]*x[1]
s1=s1+(pred_y-y)*(pred_y-y)/2
if(math.fabs(s1-s0)<0.00001):
print(theta)
break
else:
s0=s1
j=j+1
3、小批量梯度下降
import random
import math
#This is a sample to simulate a function y = theta1*x1 + theta2*x2
x_train = [[1,4], [2,5], [5,1], [4,2]]
y_train = [19,26,19,20]
theta = [1,1]
rating= 0.001
eps =0.0001
j=s0=0
while(j<100000):
s1=0
#选取随机的2个点进行权重的更新
i = random.randint(0,2)
pred_y = theta[0]*x_train[i][0]+theta[1]*x_train[i][1]
theta[0] = theta[0] - rating * (pred_y - y_train[i]) * x_train[i][0]
theta[1] = theta[1] - rating * (pred_y - y_train[i]) * x_train[i][1]
i=i+1
pred_y = theta[0]*x_train[i][0]+theta[1]*x_train[i][1]
theta[0] = theta[0] - rating * (pred_y - y_train[i]) * x_train[i][0]
theta[1] = theta[1] - rating * (pred_y - y_train[i]) * x_train[i][1]
for x,y in zip(x_train,y_train):
pred_y = theta[0]*x[0]+theta[1]*x[1]
s1=s1+(pred_y-y)*(pred_y-y)/2
if(math.fabs(s1-s0)<0.00001):
print(theta)
print(j)
break
else:
s0=s1
j=j+1