1 、基本概念
谈到梯度,童鞋们在学高数时见过,就表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。当然这是定义了。我们现在谈的梯度是酱紫的。
见图1
现在想求theta让他尽快到达底端,也就是函数导数为0的位置。
如何去做呢,现在我用三种梯度下降方法去做这件事。
2、批量梯度下降(BGD)
没有代码说jb啊,贴出代码。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score
import pandas as pd
import time
pdData = pd.read_csv('random_data.txt', header=None, names=['X', 'y'])
orig_data = pdData.values # 将取到的数据转化为数组的形式
cols = orig_data.shape[1] # 得到列数的数值
X = orig_data[:, 0:cols - 1] # 取每一行的第一列到倒数第二列的数据
y = orig_data[:, cols - 1:cols] # 取每一行的最后一列的数据
x_b = np.c_[np.ones((100, 1)), X]
learning_rate = 0.1
n_iterations = 10000
m = len(X)
theta = np.random.randn(2, 1)
count = 0
init_time = time.time() # 初始化时间
for iteration in range(n_iterations):
count += 1
# 2,接着求梯度gradient
gradients = 1/m * x_b.T.dot(x_b.dot(theta)-y)
# 3,应用公式调整theta值,theta_t + 1 = theta_t - grad * learning_rate
theta = theta - learning_rate * gradients
print("迭代的时间:", time.time() - init_time) # 迭代的时间
y_pred = x_b.dot(theta)
# 解释方差得分 1 是完美预测
print('Variance score: %.2f' % r2_score(y, y_pred))
plt.scatter(X, y, color='black')
plt.plot(X, y_pred, color='blue', linewidth=3)
plt.xlabel('x_test')
plt.ylabel('y_pred')
print("迭代的次数:", count)
print("得到的权重参数:", theta)
plt.show()
编译结果:
迭代的时间: 0.07683420181274414
Variance score: 0.44
迭代的次数: 10000
得到的权重参数: [[3.92391528]
[3.20786631]]
这里的迭代时间是用来对比三种梯度下降方法所需的时间,按道理说批量梯度下降的所需时间最长,但我在这次实验中竟然最短,尼玛,希望大神指点。
3、随机梯度下降(SGD)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score
import pandas as pd
import time
pdData = pd.read_csv('random_data.txt', header=None, names=['X', 'y'])
orig_data = pdData.values # 将取到的数据转化为数组的形式
cols = orig_data.shape[1] # 得到列数的数值
X = orig_data[:, 0:cols - 1] # 取每一行的第一列到倒数第二列的数据
y = orig_data[:, cols - 1:cols] # 取每一行的最后一列的数据
x_b = np.c_[np.ones((100, 1)), X]
learning_rate = 0.1
n_iterations = 10000
theta = np.random.randn(2, 1)
count = 0
init_time = time.time()
for i in range(n_iterations):
count += 1
loss = x_b.dot(theta)-y
m = np.random.randint(1, 100, 1)
gradients = loss[m] * x_b[m]
theta = theta - learning_rate * gradients.T
print("迭代的时间:", time.time() - init_time) # 迭代的时间
y_pred = x_b.dot(theta)
# 解释方差得分 1 是完美预测
print('Variance score: %.2f' % r2_score(y, y_pred))
plt.scatter(X, y, color='black')
plt.plot(X, y_pred, color='blue', linewidth=3)
plt.xlabel('x_test')
plt.ylabel('y_pred')
print("迭代的次数:", count)
print("得到的权重参数:", theta)
plt.show()
编译结果:
迭代的时间: 0.1137397289276123
Variance score: 0.33
迭代的次数: 10000
得到的权重参数: [[3.42439112]
[3.3517127 ]]
4、小批量梯度下降(MBGD)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score
import pandas as pd
import random
import time
pdData = pd.read_csv('random_data.txt', header=None, names=['X', 'y'])
orig_data = pdData.values # 将取到的数据转化为数组的形式
cols = orig_data.shape[1] # 得到列数的数值
X = orig_data[:, 0:cols - 1] # 取每一行的第一列到倒数第二列的数据
y = orig_data[:, cols - 1:cols] # 取每一行的最后一列的数据
x_b = np.c_[np.ones((100, 1)), X]
learning_rate = 0.1
n_iterations = 10000
theta = np.random.randn(2, 1)
count = 0
init_time = time.time() # 初始化时间
for i in range(n_iterations):
count += 1
loss = x_b.dot(theta)-y
m = random.randrange(1, 90)
loss_l = list(loss)
loss_l = loss_l[m:(m+10)]
loss_s = np.array(loss_l)
x_b_l = list(x_b)[m:(m+10)]
x_b_s = np.array(x_b_l)
gradients = 1/10*x_b_s.T.dot(loss_s)
theta = theta - learning_rate * gradients
print("迭代的时间:", time.time() - init_time) # 迭代的时间
y_pred = x_b.dot(theta)
# 解释方差得分 1 是完美预测
print('Variance score: %.2f' % r2_score(y, y_pred))
plt.scatter(X, y, color='black')
plt.plot(X, y_pred, color='blue', linewidth=3)
plt.xlabel('x_test')
plt.ylabel('y_pred')
print("迭代的次数:", count)
print("得到的权重参数:", theta)
plt.show()
编译结果:
迭代的时间: 0.4085395336151123
Variance score: 0.43
迭代的次数: 10000
得到的权重参数: [[3.82729008]
[3.22677617]]
当然只有好人才会在给出代码和附上数据集
https://pan.baidu.com/s/1K1-vq7dJE2KFfxARMj7NnA