手把手教你实现线性回归模型

来源:互联网 发布:js删除对象元素 编辑:程序博客网 时间:2024/05/18 14:13


声明:版权所有,转载请联系作者并注明出处 http://blog.csdn.net/u013719780?viewmode=contents



最近打算实现一些机器学习算法,一来希望可以帮助一些刚刚入门的小伙伴~其次,通过实现算法,加深自己对算法理论的理解!

机器学习(Machine Learning,ML)是一门多领域交叉学科,涉及概率论、统计学、计算机、优化理论等多门学科。是专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。它是人工智能的核心,是使计算机具有智能的根本途径。它的应用已遍及人工智能的各个分支,如自动驾驶、专家系统、自动推理、自然语言理解、模式识别、计算机视觉、智能机器人等领域。其中尤其典型的是专家系统中的知识获取瓶颈问题,人们一直在努力试图采用机器学习的方法加以克服。(摘自百度百科)

机器学习这门学科所关注的问题是:计算机程序如何随着经验积累自动提高性能对于某类任务T和性能度量P,如果一个计算机程序在T上以P衡量的性能随着经验E而自我完善,那么我们称这个计算机程序在从经验E学习。机器学习有很多学习方法,比如监督学习supervised learning,无监督学习unsupervised learning,半监督学习Semi-supervised Learning,强化学习reinforcement learning等。经常有些小伙伴问我关于机器学习如何入门之类的问题,现在拥有很多的开源工具,如tensorflow、keras、pytorch、caffe,paddlepaddle,scikit-learn等等, 我们到底要不要对机器学习的理论搞的很透彻呢?关于这个问题,知乎上有很多的人都参与了讨论,当然,我的观点是,如果你是一个刚刚入门机器学习的小伙伴,你选择一两个适合自己的开源工具跑跑模型就ok的,但是对于想要对机器学习一探究竟的你应该自己彻底弄明白机器学习理论,同时应该自己将学习到的算法亲手实现一遍。

这样做对你的帮助大概有以下几个方面:1) 对算法细节的理解更加深刻了,同时弄清楚了数学语言如何转换为计算机语言。2) 可以了解很多看书学不到的各种trick。所有算法几乎都有坑。比如hyper-parameter什么意义怎么设,怎么初始化,numerical stability的怎么保证,如何保证矩阵正定,计算机rounding error的影响,numerical underflow和overflow问题等等。3) 对整个领域各个算法的关联有更深刻的了解,思维形成一个关系网。看到一个算法就会自然的去想跟其他算法的联系,怎么去扩展。如果一篇paper我不能把它纳入到这个关系网里,我就觉得自己没懂。要么推出联系,要么推出矛盾证明这篇paper垃圾。另一个side effect就是我看paper从来不根据实验好坏判断优劣。虽然自己动手实现算法有好处,但是性价比几何还是个见仁见智的问题,毕竟这是一个很费时的过程。我并不认为一定有必要自己实现书上所有算法,毕竟每个人所能关注的领域还是有限的,懂得算法大致原理,具体用的时候在细研究就可以。很多算法我也是写完了从来没用过。几年过去后,我在回头看自己的代码也很难看的懂,细节还得看公式。但是对于自己的研究领域我建议还是有必要把经典算法动手实现一遍加深理解。(摘自知乎陈默)

本文我们首先实现一下线性回归算法

首先我们生成数据集,同时将生成的数据集用散点图画出来。

In [1]:
import numpy as npimport matplotlib.pyplot as plt%matplotlib inlinedef generate_data():    X = np.linspace(-3, 3, 200).reshape(200, 1)    y = 2 * X + 3 + (np.random.rand(200, 1) - 0.5)    return X, yX, y = generate_data()fig = plt.figure(figsize=(12, 8))ax = fig.add_subplot(1,1,1)ax.scatter(X, y, c= 'r')ax.plot(X, 2 * X + 3, c='g', linewidth=2)plt.show()

上图中那条绿色的直线就是我们要让算法去学习的。初中数学老师就已经告诉过我们,一条直线是由斜率w和截距b决定的,截距b也就是机器学习里常说的偏置,它们是同一个概念,只是叫法不一样而已。下面看看用代码如何去学习参数w和b。

In [2]:
def learn_para(X, y, batch_size = 5, epoch_num  = 5):        batch_num = X.shape[0] / batch_size    X = X[:batch_size * batch_num]    y = y[:batch_size * batch_num]            cost = 0    w = 0    b = 0    learn_rate = 0.05    for i in range(epoch_num):                X_y = np.concatenate((X, y), axis=1)        np.random.shuffle(X_y)        X, y = X_y[:, 0].reshape(200, 1), X_y[:, 1].reshape(200, 1)        for index in range(0, len(X), batch_size):            batch_X = X[index: index+batch_size].reshape(batch_size, 1)            batch_y = y[index: index+batch_size].reshape(batch_size, 1)            #yield batch_X, batch_y                        predict = w * batch_X + b            cost = np.power((predict - batch_y), 2).sum()/(2*batch_size)                        w = w - learn_rate * (-(batch_y-predict)*batch_X).mean()            b = b - learn_rate * (-(batch_y-predict)).mean()    return w, b
In [3]:
w, b = learn_para(X, y)predict = w * X + bfig = plt.figure(figsize=(12, 8))ax = fig.add_subplot(1,1,1)ax.scatter(X, y, c= 'r')ax.plot(X, 2 * X + 3, c='g', linewidth=2)ax.plot(X, predict, c='y', linewidth=2)plt.show()

从上图中,我们看到,我们学习出来的参数w和b还是挺不错的。