《数据挖掘》第二课笔记
提示:以下是本篇文章正文内容,下面案例仅供参考
一、数学知识
二、线性回归
1.基础介绍
2.梯度下降优化算法与批梯度下降(BGD)
3.SGD随机梯度下降法和小批量梯度下降
BGD(全样本梯度下降)把所有样本输入进去作为做成一个L函数,然后求算L函数的梯度,利用L梯度进行梯度下降。优点:单调下降的函数;缺点:计算量大,计算速度慢,容易收敛到局部最优解。
随机梯度下降SGD指的是每个样本计算一次梯度的方法,这种方法更新速度比较快,相对于BGD来说不需要一次计算很多样本,速度优势,而且一般情况下结果都是可以接受的。
缺点是,因为每个样本计算梯度,所以相对于平均的min-bathSGD类似以这种,误差会被放大,从而导致收敛曲线会波动很大,而且有时候会卡在局部值的点。
4.code(BGD/SGD)
4.1 举例数据
5,3,13.5
6,3.5,15
7,4,16.5
5,2.5,13
8,4,17.5
5,3,14
7,4,16
8,4.55,18
9,5,19
10,6,21
4.2 code
(1)数据预处理
from numpy import genfromtxt
import random
# 读入数据
data = genfromtxt(r"ddddd.csv", delimiter=',') # 自定义分隔符(custom delimiter)
#print(data)#输出数据# 切分数据,二维数组切片
x_data = data[:, :-1]#导入前两列
y_data = data[:, -1]#导入最后一列
#print(x_data)#输出前两列
#print(y_data)#输出最后一列
(2)设置一些默认参数
#学习率
alpha = 0.0001
#参数
theta0 = 0#建立参数theta0
theta1 = 0#建立参数theta1
theta2 = 0#建立参数theta2
#最大迭代次数
epochs = 10000
(3) 构造损失函数
def compute_error(theta0, theta1, theta2, x_data, y_data):#自定义函数
total = 0#建立总和total
m = float(len(x_data))
for i in range(0, len(x_data)):#循环
total += (y_data[i] - (theta1 * x_data[i, 0] + theta2 * x_data[i, 1] + theta0)) ** 2
return total /(2*m)
(4) 训练(BGD)
def gradient_descent_runner(x_data, y_data, theta0, theta1, theta2, alpha, epochs):#定义函数
m = float(len(x_data))
# 循环epochs次
for i in range(epochs):
theta0_grad = 0#建立参数theta0_grad
theta1_grad = 0
theta2_grad = 0
# 梯度下降优化算法
for j in range(0, len(x_data)):
theta0_grad +=((theta1 * x_data[j, 0] + theta2 * x_data[j, 1] + theta0)-y_data[j])#对theta0_grad进行优化
theta1_grad +=x_data[j, 0] * ((theta1 * x_data[j, 0] + theta2 * x_data[j, 1] + theta0) - y_data[j])
theta2_grad += x_data[j, 1] * ((theta1 * x_data[j, 0] + theta2 * x_data[j, 1] + theta0) - y_data[j])
# 更新参数
theta0 = theta0 - (alpha * (1/m)*theta0_grad)
theta1 = theta1 - (alpha * (1/m)*theta1_grad)
theta2 = theta2 - (alpha * (1/m)*theta2_grad)
return theta0, theta1, theta2
(5) 训练(SGD)
def stochastic_gradient_descent_runner(x_data, y_data, theta0, theta1, theta2, alpha, epochs):#SGD
m = float(len(x_data))
for epoch in range(epochs):
for i in range(len(x_data)):
# 选择随机的数据点
random_index = random.randint(0, len(x_data) - 1)
x = x_data[random_index]
y = y_data[random_index]
# 计算当前数据点的梯度
theta0_grad = (theta1 * x[0] + theta2 * x[1] + theta0) - y
theta1_grad = x[0] * ((theta1 * x[0] + theta2 * x[1] + theta0) - y)
theta2_grad = x[1] * ((theta1 * x[0] + theta2 * x[1] + theta0) - y)
# 更新参数
theta0 = theta0 - (alpha * theta0_grad)
theta1 = theta1 - (alpha * theta1_grad)
theta2 = theta2 - (alpha * theta2_grad)
return theta0, theta1, theta2
(6) 输出
print("初值 theta0 = {0}, theta1 = {1}, theta2 = {2}, error = {3}".
format(theta0, theta1, theta2, compute_error(theta0, theta1, theta2, x_data, y_data)))#首次输出
print("Running...")
#多次迭代计算
theta0, theta1, theta2 = gradient_descent_runner(x_data, y_data, theta0, theta1, theta2, alpha,epochs)#进行梯度下降优化算法,可修改GD方式
print("经过{0}次计算 theta0 = {1}, theta1 = {2}, theta2 = {3}, error = {4}".
format(epochs, theta0, theta1, theta2, compute_error(theta0, theta1, theta2, x_data, y_data)))#输出更新后的值
4.3 结果
(1)BGD
(2)SGD
三、总结
实际训练过程(BDG)中,如果按照本文公式进行训练,会产生数据溢出的情况。因此在code部分中,进行修改,引入数据个数m,因而公式修改为:
提示:以下是一张水图