①课程介绍
课程名称:Python3入门机器学习 经典算法与应用 入行人工智能
课程章节:6-6,6-7,6-8
主讲老师:liuyubobobo
内容导读
- 第一部分 自己实现的随机梯度下降法
- 第二部分 与梯度下降算法进行效率精度的比较
- 第三部分 使用真实的数据进行随机梯度下降
- 第四部分 sklearn中的随机梯度下降
②课程详细
第一部分 自己实现的随机梯度下降法
随机梯度下降法就是,对单个数据进行求导,也就是根据一个数据找到求导的方向,找到最终的最小值J会弯弯曲曲地
导入函数
import numpy as np
import matplotlib.pyplot as plt
创建一个系数是4,3的数据
m = 10000
x = np.random.normal(size=m)
X = x.reshape(-1,1)
y = 4.* x +3.+ np.random.normal(0.,3.,size=m)
编写随机梯度下降代码,其实和批量梯度下降类似,就是改变了一点
def dJ_sgd(theta, X_b_i, y_i):
return X_b_i.T.dot(X_b_i.dot(theta) - y_i ) * 2
#eta不用传了,应为由tot1和循环次数决定
def sgd(X_b, y, initial_theta, n_iters):
t0 = 5
t1 = 50
def learning_rate(t):
return t0 / (t + t1)
theta = initial_theta
for cur_iter in range(n_iters):
rand_i = np.random.randint(len(X_b))
grandient = dJ_sgd(theta, X_b[rand_i], y[rand_i])
theta = theta - learning_rate(cur_iter) * grandient
return theta
%%time
X_b = np.concatenate([np.ones((len(X), 1)), X], axis=1)
# 随机化系数
initial_theta = np.array(np.random.randint(1, 100, X_b.shape[1]))
theta = sgd(X_b, y, initial_theta, n_iters=len(X_b) // 3)
CPU times: total: 46.9 ms
Wall time: 52.1 ms
theta = array([2.90570961, 4.01299263])
精度很高,效率很快,但是看不太出来与批量梯度下降的区别,第二部分我对二者进行比较,从而更清晰的认知什么情况下用什么算法。
第二部分 与梯度下降算法进行效率精度的比较
def J(theta, X_b, y):
try:
return np.sum(((y - X_b.dot(theta)) ** 2) / len(X_b))
except:
return float('inf')
def dJ(theta, X_b, y):
return X_b.T.dot(X_b.dot(theta) - y) * 2. / len(y)
def gradient_descent(X_b, y,initial_theta, eta, n_iters=1e4, epsilon=1e-8):
# 初始化,theta的值,运行次数的值,theta历史的数字
theta = initial_theta
i_iter = 0
# 运行次数超过1万次就退出循环条件1
while i_iter < n_iters:
# 求导数
gradient = dJ(theta, X_b, y)
# 赋值历史theta,用于判断退出循环条件2
last_theta = theta
# 梯度下降,
theta = theta - eta * gradient
# 推出条件,J与上一个J的值差距小于1e-8
if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
break
# 用于记录运行次数
i_iter += 1
return theta
运行
%%time
X_b = np.concatenate([np.ones((len(X), 1)), X], axis=1)
# 随机化系数
initial_theta = np.array(np.random.randint(1, 100, X_b.shape[1]))
theta = gradient_descent(X_b, y, initial_theta, eta=0.01)
CPU times: total: 188 ms
Wall time: 166 ms
查看准确率
theta
array([2.9568346 , 4.03816809])
精度来看批量梯度下降算法更准确,随机梯度下降算法没那么准确
从时间上来看随机梯度下降法更快,快3倍左右
第三部分 使用真实的数据进行随机梯度下降
导入波士顿房价信息并进行调解
import numpy as np
from sklearn import datasets
boston = datasets.load_boston()
X = boston.data
y = boston.target
X = X[y <= 50]
y = y[y <= 50]
进行分割与数据归一化处理
from nike.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, seed=666)
from sklearn.preprocessing import StandardScaler
pre = StandardScaler()
pre.fit(X_train)
X_train_standand = pre.transform(X_train)
X_test_standand = pre.transform(X_test)
创建对象
from nike.LinearRegression import LinearRegression
lin_reg1 = LinearRegression()
多次运行观察准确率情况
t=0
for i in range(10):
lin_reg1.fit_sgd(X_train_standand,y_train,n_iters=5)
t=lin_reg1.score(X_test_standand, y_test)+t
t
7.3560009203655365
准确率很稳定,没有较大的波动
单次运行随机梯度下降
lin_reg1.fit_sgd(X_train_standand,y_train,n_iters=50)
%time lin_reg1.score(X_test_standand, y_test)
CPU times: total: 0 ns
Wall time: 0 ns
运行速度非常之快,快到没朋友
第四部分 sklearn中的随机梯度下降
from sklearn.linear_model import SGDRegressor
lin_reg2 = SGDRegressor()
%time lin_reg2.fit(X_train_standand, y_train)
lin_reg2.score(X_test_standand, y_test)
CPU times: total: 15.6 ms
Wall time: 11 ms
0.7754687426835838
③课程思考
- 在程序运行地特别的慢地时候,舍弃一部分精度转而寻求速度,改用随机梯度下降法是一个很好的选择。
- 随机梯度下降法,和批量梯度下降法理论上的区别在于梯度下降的方向,批量梯度下降法考虑全局的关于这个样本偏导数,方向一定是准确的,随机梯度下降法,考虑单个样本倒数的方向,方向不一定是准确的,但是遍历一遍之后,损失函数整体能呈现一种波动下降的方式,这就是随机的威力和魅力。