【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归

CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。

我们每天将都会精选CSDN站内技术文章供大家学习,帮助大家系统化学习IT技术。

从机器学习到线性回归

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第1张图片

今天,我们只关注机器学习到线性回归这条线上的概念。别的以后再说。为了让大家听懂,我这次也不查维基百科了,直接按照自己的理解用大白话说,可能不是很严谨。

机器学习就是机器可以自己学习,而机器学习的方法就是利用现有的数据和算法,解出算法的参数。从而得到可以用的模型。

监督学习就是利用已有的数据(我们叫X,或者特征),和数据的标注(我们叫Y),找到x和y之间的对应关系,或者说是函数f。

回归分析是一种因变量为连续值得监督学习。

线性回归是一种x和y之间的关系为线性关系的回归分析。y = a 1 x 1 + a 2 x 2 + b y=a_1x_1+a_2x_2+by=a1​x1​+a2​x2​+b,这个叫线性关系。如果这里出现了x 2 x^2x2,l o g ( x ) log(x)log(x), s i n ( x ) sin(x)sin(x)之类的,那就不是线性关系了。

一元线性回归说的是,自变量x是一个纯量(scalar)。scalar类型的变量,是不可再分的。

我希望你能说明白这些概念的关系。不过,我自己也是花了很久才了解清楚的。如果你没听明白,也没关系。毕竟都是概念,没什么实际的例子,也很难理解。等你看完了本文,了解了一元线性回归。回过头来再看这些概念,就能更好的理解了。

问题

这里,我们的问题是,找出算法工程师和程序员之间的工资关系。这里直接给出北京,上海,杭州,深圳,广州的工资。

城市 x-程序员工资 y-算法工程师工资
北京 1.3854 2.1332
上海 1.2213 2.0162
杭州 1.1009 1.9138
深圳 1.0655 1.8621
广州 0.09503 1.8016

把他们用图打出来看看他们之间的关系。

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第2张图片

由图可见,他们之间大致是一个线性关系,这时候,我们就可以试着用一元线性回归去拟合(fit)他们之间的关系。

数学模型

一元线性回归公式

以下是公式
y = a x + b + ε y=ax+b+εy=ax+b+ε

y 为应变量 dependent variable
x 为自变量 independent variable
a 为斜率 coeffient
b 为截距 intercept
ε (读作epsilon)为误差,正态分布
线性回归的目标是,找到一组a和b,使得ε最小
y ^ = a x + b \hat{y}=ax+by^​=ax+b
ε = y − y ^ ε=y-\hat{y}ε=y−y^​

y ^ \hat{y}y^​ 读作y hat,也有人读作y帽子。这里的帽子一般表示估计值,用来区别真实值y。

下图可以更好的帮助你理解。

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第3张图片
(图片来自互联网)

黑色的点为观测样本,即y = a x + b + ε y=ax+b+εy=ax+b+ε。

x红色的线为回归线,即y ^ = a x + b \hat{y}=ax+by^​=ax+b。

x蓝色的线段为误差,即ε = y − y ^ ε=y-\hat{y}ε=y−y^​

方差 - 损失函数 Cost Function

在机器学习中,很多时候,我们需要找到一个损失函数。有了损失函数,我们就可以经过不断地迭代,找到损失函数的全局或者局部最小值(或者最大值)。损失函数使得我们的问题转化成数学问题,从而可以用计算机求解。在线性回归中,我们用方差作为损失函数。我们的目标是使得方差最小。

下面的表格解释了什么是方差。

方差

其中SSE(Sum of Square Error)是总的方差,MSE(Mean Square Error)是方差的平均值。

而这里的损失函数,用的是0.5 * MSE。即:

J ( a , b ) = 1 2 n ∑ i = 0 n ( y i − y ^ i ) 2 J(a,b)=\frac{1}{2n}\sum_{i=0}^{n}(y_i−\hat{y}_i )^2J(a,b)=2n1​∑i=0n​(yi​−y^​i​)2

记住,这里的损失函数是针对参数a和b的函数,y和y ^ \hat{y}y^​ 其实都是已知的。

优化方法 Optimization Function

有了损失函数,我们还需要一个方法,使得我们可以找到这个损失函数的最小值。机器学习把他叫做优化方法。这里的优化方法,就是算损失的方向。或者说,当我的参数变化的时候,我的损失是变大了还是变小了。如果a变大了,损失变小了。那么,说明a增大这个方向是正确的,我们可以朝着这个方向继续小幅度的前进。反之,就应该考虑往相反的方向试试看。因为每个参数(a和b)都是一维的,所以,所谓的方向,无非就是正负符号。

这里,我们需要用偏微分的方法,得到损失函数的变化量。即:

∂ J ∂ a = ∂ 1 2 n ∑ i = 0 n ( y i − y ^ i ) 2 ∂ a \frac{\partial J}{\partial a} = \frac{\partial \frac{1}{2n}\sum_{i=0}^{n}(y_i−\hat{y}_i )^2}{\partial a}∂a∂J​=∂a∂2n1​∑i=0n​(yi​−y^​i​)2​
= 1 n ∑ i = 0 n ( y i − a x i − b ) ∂ ( y i − a x i − b ) ∂ a = \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) \frac{\partial (y_i-ax_i-b)}{\partial a}=n1​∑i=0n​(yi​−axi​−b)∂a∂(yi​−axi​−b)​
= 1 n ∑ i = 0 n ( y i − a x i − b ) ( − x i ) = \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) (-x_i)=n1​∑i=0n​(yi​−axi​−b)(−xi​)
= 1 n ∑ i = 0 n x ( y ^ i − y i ) = \frac{1}{n}\sum_{i=0}^{n}x(\hat{y}_i-y_i)=n1​∑i=0n​x(y^​i​−yi​)

∂ J ∂ b = ∂ 1 2 n ∑ i = 0 n ( y i − y ^ i ) 2 ∂ a \frac{\partial J}{\partial b} = \frac{\partial \frac{1}{2n}\sum_{i=0}^{n}(y_i−\hat{y}_i )^2}{\partial a}∂b∂J​=∂a∂2n1​∑i=0n​(yi​−y^​i​)2​
= 1 n ∑ i = 0 n ( y i − a x i − b ) ∂ ( y i − a x i − b ) ∂ b = \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) \frac{\partial (y_i-ax_i-b)}{\partial b}=n1​∑i=0n​(yi​−axi​−b)∂b∂(yi​−axi​−b)​
= 1 n ∑ i = 0 n ( y i − a x i − b ) ( − 1 ) = \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) (-1)=n1​∑i=0n​(yi​−axi​−b)(−1)
= 1 n ∑ i = 0 n ( y ^ i − y i ) = \frac{1}{n}\sum_{i=0}^{n}(\hat{y}_i-y_i)=n1​∑i=0n​(y^​i​−yi​)

如果你已经忘了微积分,你暂时可以不必纠结上面的公式,只要知道公式给出了损失函数的变化就可以了。伟大的python还提供了sympy,你可以用sympy做微积分。这部分我也放在附件代码里了,有兴趣的可以看一下。

之前说到,整过迭代过程是小幅度进行的。这里,就需要一个超参数来控制这个过程。这个超参数就是α \alphaα,通常是0.01.

这时,我们就可以去更新a和b的值:
a = a − α ∂ J ∂ a a = a - \alpha \frac{\partial J}{\partial a}a=a−α∂a∂J​
b = b − α ∂ J ∂ b b = b - \alpha \frac{\partial J}{\partial b}b=b−α∂b∂J​

到这里,在你继续往下读之前,你先自己考虑一下,为什么这里是负号?

你考虑好了么,如果你考虑好了,我就公布答案了。

本身∂ J ∂ a \frac{\partial J}{\partial a}∂a∂J​ 和 ∂ J ∂ b \frac{\partial J}{\partial b}∂b∂J​ 是损失函数的变化量。如果损失函数随着a变大了,即 ∂ J ∂ a \frac{\partial J}{\partial a}∂a∂J​ 为正。说明a的增大会导致损失函数的增大。那么是不是说,a的减小会使得损失函数减小呢?而我们的目标是使得J最小,所以,这个时候,我们的a要减小一点点。

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第4张图片
(图片来自互联网)

算法步骤

  1. a和b的起始值设置为零
  2. 通过模型y ^ = a x + b \hat{y}=ax+by^​=ax+b,我们可以算出y ^ \hat{y}y^​
  3. 有了y ^ \hat{y}y^​,就可以用优化方法算去更新参数
  4. 重复2和3,直到找到J的最小值

流程图如下:

开始a=0, b=0计算模型y_hat=ax+b计算a和b的微分更新a和b找到损失函数的最小值结束yesno

下图解释了模型,损失函数和优化方法之间的关系。

模型,损失函数和优化方法之间的关系

Python 实现

理论部分先告一段落,我们现在开始写代码,实现一元线性回归。

首先是模型,这个很简单:

def model(a, b, x):
    return a*x + b

接着,是损失函数:

def cost_function(a, b, x, y):
    n = 5
    return 0.5/n * (np.square(y-a*x-b)).sum()

最后,是优化函数:

def optimize(a,b,x,y):
    n = 5
    alpha = 1e-1
    y_hat = model(a,b,x)
    da = (1.0/n) * ((y_hat-y)*x).sum()
    db = (1.0/n) * ((y_hat-y).sum())
    a = a - alpha*da
    b = b - alpha*db
    return a, b

以上三个函数中a和b是标量(scalar value),x和y是向量(vector)
至此,一元线性回归的主要部分就完成了。一共才14行代码,是不是很简单。

训练模型

有了模型,损失函数,优化函数,我们就可以训练模型了。具体过程请见附件代码。

这里给出分别训练1次,再训练5次,再训练10次,再训练100,再训练10000次的模型。

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第5张图片

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第6张图片

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第7张图片

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第8张图片

【CSDN软件工程师能力认证学习精选】python机器学习手写算法系列——线性回归_第9张图片

从上面几幅图,我们可以看到,随着训练次数的增加,回归线越来越接近样本了。我们自己写的线性回归比较简单,我只能目测,凭直觉感觉损失函数已经达到了最小值,我们就停在10000次吧。

看得再多,不如自己动手。阅读下一章节之前,请自己实现一元线性回归。

这里有现成的代码,供你参考。

http://download.csdn.net/download/juwikuang/10050886

模型评价

在机器学习中,模型的好坏是有标准的。在回归模型中,我们用R 2 R^2R2 来评价模型。公式:
R 2 = S S R / S S T R^2=SSR/SSTR2=SSR/SST
其中
S S R = ∑ i = 0 n ( y ^ i − y ˉ ) SSR=\sum_{i=0}^{n}(\hat{y}_i-\bar{y})SSR=∑i=0n​(y^​i​−yˉ​)
S S T = ∑ i = 0 n ( y i − y ˉ ) SST=\sum_{i=0}^{n}(y_i-\bar{y})SST=∑i=0n​(yi​−yˉ​)
y ˉ \bar{y}yˉ​ 读作y bar,是y的平均值。
可以证明S S T = S S R + S S E SST=SSR+SSESST=SSR+SSE,证明过程又会涉及到期望等概念,我们这里不展开了。

好了,现在你应该回到代码中去计算R 2 R^2R2 了。

用scikit-learn训练和评价模型

平时在工作中,我们不可能自己去写回归模型,最常用的第三方工具是scikit-learn。
其官网是:
http://scikit-learn.org/

以下是ipython代码。

import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
%matplotlib inline

x = [13854,12213,11009,10655,9503] #程序员工资,顺序为北京,上海,杭州,深圳,广州
x = np.reshape(x,newshape=(5,1)) / 10000.0
y =  [21332, 20162, 19138, 18621, 18016] #算法工程师,顺序和上面一致
y = np.reshape(y,newshape=(5,1)) / 10000.0
# 调用模型
lr = LinearRegression()
# 训练模型
lr.fit(x,y)
# 计算R平方
print lr.score(x,y)
# 计算y_hat
y_hat = lr.predict(x)
# 打印出图
plt.scatter(x,y)
plt.plot(x, y_hat)
plt.show()

关于CSDN软件工程师能力认证

      CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。C系列认证的宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家数字化战略贡献力量。

 

了解详情可点击:CSDN软件工程师能力认证介绍

 

本文出处:https://blog.csdn.net/juwikuang/article/details/78420337?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161413304516780269833527%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161413304516780269833527&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~hot_rank-2-78420337.pc_search_result_before_js&utm_term=python+机器学习&spm=1018.2226.3001.4187

你可能感兴趣的:(CSDN软件工程师能力认证,学习能力,机器学习,python)