【机器学习】线性回归:动手实现一个线性回归模型

已有知识:

  1. 线性回归(统计学)
  2. 线性回归(机器学习)

回归问题简单说就是给出一组特征,模型需要给出一个回答,这个回答是个连续的数值,也就是说模型的输出应该是个实数。
因此回归问题的模型是一个实函数。

线性回归则是用线性函数 f(x_1,x_2,...,x_n) = x_1 w_1 + x_2 w_2+... +x_n w_n + b 来建立模型。

写成向量形式就是(一维向量均是列向量):
f(\boldsymbol{X}) = \boldsymbol{X}^T W + \boldsymbol{b} \tag{1}

回归本身是个估计问题,没有对错之分,所以需要一个评价标准来评价一个回归模型的好坏。常见的评价标准有MSE,SAE,SSE等

误差度量标准 优缺点
SSE(误差平方和) 样本多时数值会累加到很大, 处理起来不便
SAE(绝对误差和) 绝对值性质很差,难以进行数学运算
MSE(均方误差) 数值不爆炸,数学性质好(凸性)

记训练集第i个样本为X_i, 对应标签为Y_i
因此,此处选择MSE作为模型好坏的度量标准。

MSE = \sum_{i \in 样本集} {(W X_i + b - Y_i)}^2

于是问题转化为优化问题:
\min_{W, b \in \mathcal{R}} MSE

要求多元函数MSE(W, b )的最小值,一个必要不充分条件是求出某点使得其各个方向偏导数均为零,又由于这个函数性质良好(参见凸优化相关内容),于是这就成了充要条件。因此根据这个条件可以求得方程组并且解之,实际上一元的线性回归就是这么做的,初中课本上还有一元线性回归的公式,多元的情况类似,但是运算更复杂,在此不赘述。

为了简化运算,将式(1)写成完全的矩阵形式:
f(\boldsymbol{X}) =( \boldsymbol{X}^T, 1 ) \begin{bmatrix} W \\ \boldsymbol{b} \end{bmatrix}

根据线性代数的结论,倘若有n个样本, label对应为Y,上式成为

AW = Y
其中A为:
W为:

参见wikipedia,或者其他文献,keywords:广义逆矩阵

它的误差的二范数(就是MSE)极小的解为A = A^{\dagger}Y
A^{\dagger}A的广义逆矩阵。

首先导入需要用到的库:


import numpy as np

# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import

import matplotlib.pyplot as plt
import numpy as np

然后随机生成一些数据作为样本集:

#特征数量和样本数量
feature_num = 2
num_examples = 100

#预设的w和b
preset_w =np.array([2.2, 7.5])

preset_b = 2.8

#假数据
fake_data_X = np.random.rand(num_examples, feature_num)


#通过预设的w和b算出对应的labels

labels = fake_data_X.dot( preset_w.reshape(2,1) )+ preset_b



#给labels加个随机误差
labels += np.random.normal(loc=0, scale=0.01,size=(num_examples, 1))



#开始训练模型
#对应上述几个公式来看
#
fake_data_X_with_one = np.column_stack( (fake_data_X,  np.ones((num_examples, 1))) )

persudo_invert_X_with_one = np.linalg.pinv(fake_data_X_with_one)

model_params = persudo_invert_X_with_one.dot(labels)

#输出模型参数
model_params
array([[2.20471427],
       [7.50252716],
       [2.79889165]])

对比可以发现算出的模型参数和预设值相差不算太大。

绘制一下原始数据和回归结果的图形直观感受一下:


output_8_0.png

这3D图太难操作了,画出来还这么抽象........可以看到我们的样本点分布在回归曲面的附近就够了。



fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.scatter(fake_data_X[:,0], fake_data_X[:,1], labels, color='r')


u = np.linspace(0, 1, 15)
v = np.linspace(0, 1, 15)
x, y = np.meshgrid(u, v )
xy1 = np.column_stack((x.reshape(15*15, 1), y.reshape(15*15, 1), np.ones((15*15, 1)) ))
#通过模型算出回归结果
z = x*model_params[0] + y*model_params[1] + model_params[2]
ax.plot_surface(x, y , z , alpha=0.5, color='b')
ax.view_init(elev=15, 
             azim=45 )

plt.show()
回归结果和原始数据对比

可以看到计算的结果和我们预设的值非常接近。可见我们的结果是有效的。

有些读者肯定不服了,你这怕是是假机器学习,直接用公式就算出来了也算数?训练过程呢?梯度下降呢?

这种方法的确和现代机器学习的原理大相径庭,它通过数学原理直接算出了模型需要的参数,但是它的缺陷也是显然的:它需要所有的数据来参与运算,如果有新的数据到来,它只能推倒重算,无法利用已有的结果。另外它只适用于性质很好(在数学领域研究透彻了)的函数。

作为入门的第一课,我只是想借助这个例子说明机器学习的本质:

你假设一个模型 f(x,\sigma) 能够解决问题,但是参数 \sigma 是未知的,你只要用某种方法求得一个误差可接受的参数 \hat{\sigma} 即可。

如果使用成熟的机器学习框架来训练,它的结果会是多少呢?

from sklearn import  linear_model
#创建一个随机梯度下降的线性回归模型并且训练
regress = linear_model.SGDRegressor(max_iter=2000)
regress.fit(fake_data_X,  labels.reshape(1,num_examples)[0])
#输出训练结果
print("线性模型系数W为", regress.coef_)
print("线性模型常数项b为", regress.intercept_)
线性模型系数W为 [2.20029992 7.49111373]
线性模型常数项b为 [2.80727725]

可以看出,随机梯度下降法(SGD)在迭代2000次的情况下得到了一个还算精确的结果。

ref:
[1] 监督学习-线性模型(sklearn)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 143,639评论 1 302
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,591评论 1 258
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 95,050评论 0 213
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 41,169评论 0 180
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 48,976评论 1 258
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,876评论 1 178
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,476评论 2 273
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,229评论 0 167
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 29,095评论 6 234
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,579评论 0 213
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,356评论 2 215
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,698评论 1 232
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,272评论 0 32
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,168评论 2 214
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,605评论 3 210
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,645评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,035评论 0 166
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,609评论 2 232
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,698评论 2 233

推荐阅读更多精彩内容