自己动手做ML算法系列(1)– Gradient Descent
Gradient Descent大家都很熟悉了, 这个学习笔记记录我的一次尝试。 语言:python, 用到的包: numpy
直接上代码:
import numpy as np
X_train = np.array([[1, 6], [1, 8], [1, 10], [1, 14], [1, 18]])
y_train = np.array([[7], [9], [13], [17.5], [18]])
X_test = np.array([[1, 6], [1, 8], [1, 11], [1, 16]])
y_test = np.array([[8], [12], [15], [18]])
w = 2*np.random.random(2) - 1
np.random.seed(1)
alpha = 0.01
for iter in xrange(100000):
# Stochastic Gradient Descent: pick an instance
i = np.random.randint(5)
# print 'picking i:', i
l = np.dot(w, X_train[i])
# print 'dot product is: ', l
l_error = y_train[i][0] - l
# print 'error is: ', l_error
l_delta = alpha * l_error * X_train[i]
# print 'delta is: ', l_error
w += l_delta
# print 'w is:', w
print 'Test:', np.dot(w, X_test[0])
结果:
Test: 6.88059010909
原值是8, 我们的输出是6.88, 可以说还是有不少误差。
我想,如果让我们把整个过程画出来,我们可能会更清楚它具体是如何收敛的。
为了取得中间值, 我们需要创造一个np.array来储存每次更新前后的w值
代码如下:
import numpy as np
X_train = np.array([[1, 6], [1, 8], [1, 10], [1, 14], [1, 18]])
y_train = np.array([[7], [9], [13], [17.5], [18]])
X_test = np.array([[1, 6], [1, 8], [1, 11], [1, 16]])
y_test = np.array([[8], [12], [15], [18]])
w = 2*np.random.random(2) - 1
np.random.seed(1)
alpha = 0.01
store_w = [] # 用来储存中间的w
for iter in xrange(5000):
# Stochastic Gradient Descent: pick an instance
i = np.random.randint(5)
# print 'picking i:', i
l = np.dot(w, X_train[i])
# print 'dot product is: ', l
l_error = y_train[i][0] - l
# print 'error is: ', l_error
l_delta = alpha * l_error * X_train[i]
# print 'delta is: ', l_error
store_w.append(w.copy())
w += l_delta
# print 'w is:', w
print 'Test:', np.dot(w, X_test[0])
%matplotlib notebook
import matplotlib.pyplot as plt
plt.figure()
tmp = []
for i in xrange(0,len(store_w),20): #每隔20次更新才取值,这样效果比较明显,并且减少内存消耗
tmp.append(store_w[i])
store_w = tmp
w_0s = [i[0] for i in store_w] # 取出w的第一项, 作为横坐标
w_1s = [i[1] for i in store_w] # 取出w的第二项,作为纵坐标
plt.plot(w_0s, w_1s)
plt.scatter(w_0s, w_1s, c='r', edgecolors='None')
plt.show()
出图:
能发现虽然它收敛得比较混乱,但是最后还是稳定到了一个特定区间。
从准确性的角度来观测收敛情况
我选取一个特定的样本, 在同一张图上画出每次更新后预测值和样本值
中间的黑线表示样本值,横坐标表示更新次数
虽然不太知道中间发生了什么(笑),不过好歹收敛了。
本文通过Python实现梯度下降法解决线性回归问题,并利用matplotlib可视化每轮迭代过程中的参数变化,以此观察算法的收敛过程。
741

被折叠的 条评论
为什么被折叠?



