作者|我是奔跑的键盘侠
来源|奔跑的键盘侠(ID:runningkeyboardhero)
转载请联系授权(微信ID:ctwott)
折腾了许久,觉得还是要记录点什么,不管是给有兴趣的小伙伴做参考,还是加深自己的学习理解,都是有一定裨益的。
不过,这个题目也是想了好一会,专业方向深度学习,当下啃机器学习,折磨了一个多月,才刚捋顺线性回归。
索性,就把这个系列放到Python里面吧。
当然,这个板块的内容必须是高能的!!! 反正这一个月时间,就耗这上面了,一个周学a,一个周学b,再花点时间捋顺整个过程……
基础内容直接放链接了:
Python-matplotlib画图(莫烦笔记) Chenkc,公众号:AI机器学习与深度学习算法用matplotlib简单绘图
知乎链接 https://www.zhihu.com/collection/260736383
深入浅出--梯度下降法及其实现,简书链接:https://www.jianshu.com/p/c7e642877b0e
有了前面2篇铺垫之后,就可以直接上代码了
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
# @Time : 2020-11-07 12:22
# @Author : Ed Frey
# @File : linear_regression.py
# @Software: PyCharm
import matplotlib.pyplot as plt
import numpy as np
m = 20
X0 = np.ones((m, 1))
X1 = np.arange(1, m + 1).reshape(m, 1)
X = np.hstack((X0, X1))
y = np.array([
3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,
11, 13, 13, 16, 17, 18, 17, 19, 21
]).reshape(m, 1)
xx = X1.reshape(1, m)[0]
yy = y.reshape(1, m)[0]
fig = plt.figure(figsize=(12, 10), dpi=80)
plt.ion()
alpha = 0.01
def error_function(theta, X, y):
diff = np.dot(X, theta) - y
return (1. / 2 * m) * np.dot(np.transpose(diff), diff)
def gradient_function(theta, X, y):
diff = np.dot(X, theta) - y
return (1. / m) * np.dot(np.transpose(X), diff)
def gradient_descent(X, y, alpha):
theta = np.array([1, 1]).reshape(2, 1)
gradient = gradient_function(theta, X, y)
i = 0
items = []
while not np.all(np.absolute(gradient) <= 1e-5):
theta = theta - alpha * gradient
gradient = gradient_function(theta, X, y)
u = np.linspace(-1, 22, 20)
v = theta[0][0] + theta[1][0] * u
i += 1
if i % 1000 == 1:
items.append(theta)
items.append(theta)
j = 0
for theta in items:
plt.cla()
j += 1
plt.title("linear %s" %j)
plt.scatter(xx, yy)
plt.grid(True)
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
plt.xlim(-2, 30, 20)
plt.ylim(-2, 30, 20)
u0 = 20
v0 = theta[0][0] + theta[1][0] * u0
plt.plot(u, v, linewidth=3.0, color='r')
plt.annotate(r'$%f*u + %f = v$' % (theta[1][0], theta[0][0]), xy=(u0, v0), xycoords='data',
xytext=(-200, 20), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=.2'))
plt.savefig(fname="scatter%s.png" %j)
plt.pause(1)
return theta
plt.ioff()
plt.show()
optimal = gradient_descent(X, y, alpha)
print('optimal:', optimal)
print('error function:', error_function(optimal, X, y)[0, 0])
代码就不过多解释了,基本都是简书上面拷贝过来的,简书上面解释已经足够详细了。对新手比较陌生的,是矩阵与坐标的表示形式,比如a和b两个N*1维矩阵,转成坐标以后,横坐标全在a里面,纵坐标全在b里。至于梯度下降法,是数学分析里面的基础部分。另外涉及到一丁点矩阵运算知识,当时还小卡了一下。
后面画图部分的代码,是我自己补充设计的,基本功能是:在不断迭代寻找目标最优解的过程中,将当前解的效果可视化,也就是可以通过图形查看当前参数对应的直线效果。
截取了其中输出的几幅效果图:
什么?看着没感觉?那再来一张动图吧
-END-