什么叫做回归?回归是相对分类而言的,与我们想要预测的目标变量y的值类型有关。《统计学习》一书中指出,人们常根据输入输出变量的不同类型,对预测任务给予不同的名称:输入变量与输出变量均为连续变量的预测问题称为回归问题;输出变量为有限个离散变量的预测问题称为分类问题。
什么叫做线性回归?线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
一元线性回归与多元线性回归的定义:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归。
多元回归的通用形式: w 1 x 1 + w 2 x 2 + . . . + w d x d + b = f ( x ) {w_1}{x_1} + {w_2}{x_2} + ... + {w_d}{x_d} + b = f(x) w1x1+w2x2+...+wdxd+b=f(x)
多元回归的向量形式: ω T x + b = f ( x ) {\omega ^{\rm T}}x + b = f(x) ωTx+b=f(x) , 其中 ω = ( ω 1 ; ω 2 ; ⋯ ; ω d ; ) \omega = ({\omega _1};{\omega _2}; \cdots ;{\omega _d};) ω=(ω1;ω2;⋯;ωd;)
关于分类和回归的举例:y是分类型变量,如预测用户的性别(男、女),预测月季花的颜色(红、白、黄……),预测是否患有肺癌(是、否),那我们就需要用分类算法去拟合训练数据并做出预测;y是连续型变量,如预测用户的收入(4千,2万,10万……),预测员工的通勤距离(500m,1km,2万里……),预测患肺癌的概率(1%,50%,99%……),我们则需要用回归模型。
有时分类问题也可以转化为回归问题,例如刚刚举例的肺癌预测,我们可以用回归模型先预测出患肺癌的概率,然后再给定一个阈值,例如50%,概率值在50%以下的人划为没有肺癌,50%以上则认为患有肺癌。这种分类型问题的回归算法预测,最常用的就是逻辑回归,后面会总结到。
线性回归当中主要有两种模型,一种是线性关系,另一种是非线性关系。在这里我们只能画一个平面更好去理解,所以都用单个特征或两个特征举例子。
|
|
|
h θ ( x ) = θ 0 + θ 1 x {h_\theta }(x) = {\theta _0} + {\theta _1}x hθ(x)=θ0+θ1x
这个方程对应的图像是一条直线,称作回归线。其中, θ 1 {\theta _1} θ1为回归线的斜率, θ 0 {\theta _0} θ0为回归线的截距。此时,
θ 1 {\theta _1} θ1 > 0时,一元线性回归 正相关;
θ 1 {\theta _1} θ1 < 0时,一元线性回归 负相关;
θ 1 {\theta _1} θ1 = 0时,一元线性回归 不相关;
我们一般使用相关系数去衡量线性关系的强弱: r x y = ∑ ( X i − X ˉ ) ( Y i − Y ˉ ) ∑ ( X i − X ˉ ) 2 ∑ ( Y i − Y ˉ ) 2 {r_{xy}} = \frac{{\sum {({X_i} - \bar X)({Y_i} - \bar Y)} }}{{\sqrt {\sum {{{({X_i} - \bar X)}^2}\sum {{{({Y_i} - \bar Y)}^2}} } } }} rxy=∑(Xi−Xˉ)2∑(Yi−Yˉ)2∑(Xi−Xˉ)(Yi−Yˉ)
通过计算,左图的相关系数为0.993 ,右图的相关系数为 0.957。
相关系数(coefficient of (coefficient of)是用来描述两个变量之间的线性关系的,但决定系数的适用范围更广,可以用于描述非线性或者有两个及两个以上自变量的相关关系。它可以用来评价模型的效果。
总平方和(SST): ∑ i = 1 n ( y i − y ˉ ) 2 {\sum\nolimits_{i = 1}^n {({y_i} - \bar y)} ^2} ∑i=1n(yi−yˉ)2
回归平方和(SSR): ∑ i = 1 n ( y ^ i − y ˉ ) 2 {\sum\nolimits_{i = 1}^n {({{\hat y}_i} - \bar y)} ^2} ∑i=1n(y^i−yˉ)2
残差平方和(SSE): ∑ i = 1 n ( y ^ i − y ^ ) 2 {\sum\nolimits_{i = 1}^n {({{\hat y}_i} - \hat y)} ^2} ∑i=1n(y^i−y^)2
它们三者之间的关系是:SST=SSR+SSE
决定系数: R 2 = S S R S S T = 1 − S S E S S T R2 = \frac{{SSR}}{{SST}} = 1 - \frac{{SSE}}{{SST}} R2=SSTSSR=1−SSTSSE
简单得说,就是存在一个函数 J ( θ 0 , θ 1 ) J({\theta _0},{\theta _1}) J(θ0,θ1),想取到 min θ 0 , θ 1 J ( θ 0 , θ 1 ) \mathop {\min }\limits_{{\theta _0},{\theta _1}} J({\theta _0},{\theta _1}) θ0,θ1minJ(θ0,θ1),那么,我们该如何做呢?
|
|
正确做法:同步更新
t e m p 0 : = θ 0 − α ∂ ∂ θ 0 J ( θ 0 , θ 1 ) temp0: = {\theta _0} - \alpha \frac{\partial }{{\partial {\theta _0}}}J({\theta _0},{\theta _1}) temp0:=θ0−α∂θ0∂J(θ0,θ1)
t e m p 1 : = θ 1 − α ∂ ∂ θ 1 J ( θ 0 , θ 1 ) temp1: = {\theta _1} - \alpha \frac{\partial }{{\partial {\theta _1}}}J({\theta _0},{\theta _1}) temp1:=θ1−α∂θ1∂J(θ0,θ1)
θ 0 : = t e m p 0 {\theta _0}: = temp0 θ0:=temp0
θ 1 : = t e m p 1 {\theta _1}: = temp1 θ1:=temp1
不正确做法:
t e m p 0 : = θ 0 − α ∂ ∂ θ 0 J ( θ 0 , θ 1 ) temp0: = {\theta _0} - \alpha \frac{\partial }{{\partial {\theta _0}}}J({\theta _0},{\theta _1}) temp0:=θ0−α∂θ0∂J(θ0,θ1)
θ 0 : = t e m p 0 {\theta _0}: = temp0 θ0:=temp0
t e m p 1 : = θ 1 − α ∂ ∂ θ 1 J ( θ 0 , θ 1 ) temp1: = {\theta _1} - \alpha \frac{\partial }{{\partial {\theta _1}}}J({\theta _0},{\theta _1}) temp1:=θ1−α∂θ1∂J(θ0,θ1)
θ 1 : = t e m p 1 {\theta _1}: = temp1 θ1:=temp1
用梯度下降法求解线性回归
线性回归的模型和代价函数:
∂ ∂ θ j J ( θ 0 , θ 1 ) = \frac{\partial }{{\partial {\theta _j}}}J({\theta _0},{\theta _1}) = ∂θj∂J(θ0,θ1)=
j = 0 : ∂ ∂ θ 0 J ( θ 0 , θ 1 ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) j = 0:\frac{\partial }{{\partial \theta 0}}J({\theta _0},{\theta _1}) = \frac{1}{m}\sum\limits_{i = 1}^m {({h_\theta }({x^{(i)}}) - {y^{(i)}}) } j=0:∂θ0∂J(θ0,θ1)=m1i=1∑m(hθ(x(i))−y(i))
j = 1 : ∂ ∂ θ 1 J ( θ 0 , θ 1 ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) ⋅ x ( i ) j = 1:\frac{\partial }{{\partial \theta 1}}J({\theta _0},{\theta _1}) = \frac{1}{m}\sum\limits_{i = 1}^m {({h_\theta }({x^{(i)}}) - {y^{(i)}}) \cdot {x^{(i)}}} j=1:∂θ1∂J(θ0,θ1)=m1i=1∑m(hθ(x(i))−y(i))⋅x(i)
repeat until convergence{
θ 0 : = θ 0 − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) {\theta _0}: = {\theta _0} - \alpha \frac{1}{m}\sum\limits_{i = 1}^m {({h_\theta }({x^{(i)}}) - {y^{(i)}})} θ0:=θ0−αm1i=1∑m(hθ(x(i))−y(i))
θ 1 : = θ 1 − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) ⋅ x ( i ) {\theta _1}: = {\theta _1} - \alpha \frac{1}{m}\sum\limits_{i = 1}^m {({h_\theta }({x^{(i)}}) - {y^{(i)}})} \cdot {x^{(i)}} θ1:=θ1−αm1i=1∑m(hθ(x(i))−y(i))⋅x(i)
}
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 设置显示中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
# 设置正常显示符号
mpl.rcParams["axes.unicode_minus"] = False
# 载入数据
data = np.genfromtxt("data.csv", delimiter=",")
x_data = data[:, 0]
y_data = data[:, 1]
plt.scatter(x_data, y_data)
plt.savefig('./imgs/数据分布图.jpg')
plt.show()
# 学习率learning rate
lr = 0.0001
# 截距
b = 0
# 斜率
k = 0
# 最大迭代次数
epochs = 50
# 最小二乘法
def compute_error(b, k, x_data, y_data):
totalError = 0
for i in range(0, len(x_data)):
totalError += (y_data[i] - (k * x_data[i] + b)) ** 2
return totalError / float(len(x_data)) / 2.0
def gradient_descent_runner(x_data, y_data, b, k, lr, epochs):
# 计算总数据量
m = float(len(x_data))
# 循环epochs次
for i in range(epochs):
b_grad = 0
k_grad = 0
# 计算梯度的总和再求平均
for j in range(0, len(x_data)):
b_grad += (1 / m) * (((k * x_data[j]) + b) - y_data[j])
k_grad += (1 / m) * x_data[j] * (((k * x_data[j]) + b) - y_data[j])
# 更新b和k
b = b - (lr * b_grad)
k = k - (lr * k_grad)
# 每迭代5次,输出一次图像
if i % 5 == 0:
print("epochs:", i)
plt.plot(x_data, y_data, 'b.')
plt.plot(x_data, k * x_data + b, 'r')
plt.xlabel("x")
plt.ylabel("y")
plt.title('迭代%s次的线性回归'%(i))
plt.savefig('./imgs/迭代%s次的线性回归.jpg' %(i))
plt.show()
return b, k
print("Starting b = {0}, k = {1}, error = {2}".format(b, k, compute_error(b, k, x_data, y_data)))
print("Running...")
b, k = gradient_descent_runner(x_data, y_data, b, k, lr, epochs)
print("After {0} iterations b = {1}, k = {2}, error = {3}".format(epochs, b, k, compute_error(b, k, x_data, y_data)))
# 画图
plt.plot(x_data, y_data, 'b.')
plt.plot(x_data, k*x_data + b, 'r')
plt.xlabel("x")
plt.ylabel("y")
plt.title('迭代50次的线性回归')
plt.savefig('./imgs/迭代50次的线性回归.jpg')
plt.show()
|
|
|
|
参考bilibili: https://www.bilibili.com/video/BV1Rt411q7WJ?p=7
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 设置显示中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
# 载入数据
data = np.genfromtxt("data.csv", delimiter=",")
x_data = data[:, 0]
y_data = data[:, 1]
plt.scatter(x_data, y_data)
plt.show()
print(x_data.shape)
x_data = data[:, 0, np.newaxis]
y_data = data[:, 1, np.newaxis]
# 创建并拟合模型
model = LinearRegression()
model.fit(x_data, y_data)
# 画图
plt.plot(x_data, y_data, 'b.')
plt.plot(x_data, model.predict(x_data), 'r')
plt.xlabel("x_data")
plt.ylabel("y_data")
plt.title('sklearn——一元线性回归')
plt.savefig('./imgs/sklearn——一元线性回归.jpg')
plt.show()
# 系数(可理解为斜率)
print('系数:', model.coef_)
# 截距
print('截距:', model.intercept_)
# 决定系数 R2→1模型的数据拟合性就越好,反之,R2→0,表明模型的数据拟合度越差。
print('决定系数:', model.score(x_data, y_data))
参考1: https://www.bilibili.com/video/BV1Rt411q7WJ?p=7
参考2: https://zhuanlan.zhihu.com/p/72513104