监督学习中,如果预测的变量是离散的,我们称其为分类(如决策树,支持向量机等),如果预测的变量是连续的,我们称其为回归。回归分析是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。在回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。
简单来讲就是给一些离散的点,求出一条预测直线 h ( x ) = w x + b h(x)=wx+b h(x)=wx+b,这条直线的要求是基本满足这些点的变化趋势,那么我们用什么来衡量这条直线选取的好坏呢?可以通过损失函数来衡量。 J ( w , b ) = 1 m ∗ ∑ i = 1 m ( h ( x i ) − y i ) 2 = 1 m ∗ ∑ i = 1 m ( w x i + b − y i ) 2 J(w,b)=\frac{1}{m}*\sum_{i=1}^m(h(x^i)-y^i)^2=\frac{1}{m}*\sum_{i=1}^m(wx^i+b-y^i)^2 J(w,b)=m1∗i=1∑m(h(xi)−yi)2=m1∗i=1∑m(wxi+b−yi)2
线性回归算法的目的是使 J ( w , b ) J(w,b) J(w,b)最小,也就是我们所得到的预测直线越准确。具体方法可以用梯度下降法和最小二乘法,梯度下降上一篇博客已经给出,这里我们用最小二乘法来求预测直线。(1)
J ( w , b ) = 1 m ∗ ∑ i = 1 m ( w x i + b − y i ) 2 J(w,b)=\frac{1}{m}*\sum_{i=1}^m(wx^i+b-y^i)^2 J(w,b)=m1∗i=1∑m(wxi+b−yi)2(2) x ˉ = ∑ i = 1 m x i m \bar{x}=\frac{\sum_{i=1}^mx^i}{m} xˉ=m∑i=1mxi y ˉ = ∑ i = 1 m y i m \bar{y}=\frac{\sum_{i=1}^my^i}{m} yˉ=m∑i=1myi(3) ∂ J ( w , b ) ∂ b = 2 ( w x ˉ + b − y ˉ ) \frac{\partial J(w,b)}{\partial b}=2(w\bar{x}+b-\bar{y}) ∂b∂J(w,b)=2(wxˉ+b−yˉ) ∂ J ( w , b ) ∂ w = 2 m ( w ∑ i = 1 m ( x i 2 − x ˉ 2 ) + m x ˉ y ˉ − ∑ i = 1 m x i y i ) \frac{\partial J(w,b)}{\partial w}=\frac{2}{m}(w\sum_{i=1}^m(x_i^2-\bar{x}^2)+m\bar{x}\bar{y}-\sum_{i=1}^mx^iy^i) ∂w∂J(w,b)=m2(wi=1∑m(xi2−xˉ2)+mxˉyˉ−i=1∑mxiyi)(4)令 ∂ J ( w , b ) ∂ b = 0 , ∂ J ( w , b ) ∂ w = 0 \frac{\partial J(w,b)}{\partial b}=0,\frac{\partial J(w,b)}{\partial w}=0 ∂b∂J(w,b)=0,∂w∂J(w,b)=0可得: b = y ˉ − w x ˉ b=\bar{y}-w\bar{x} b=yˉ−wxˉ w = ∑ i = 1 m ( x i − x ˉ ) ( y i − y ˉ ) ∑ i = 1 m ( x i − x ˉ ) 2 w=\frac{\sum_{i=1}^m(x^i-\bar{x})(y^i-\bar{y})}{\sum_{i=1}^m(x^i-\bar{x})^2} w=∑i=1m(xi−xˉ)2∑i=1m(xi−xˉ)(yi−yˉ)手工详细推导如下:
代码实现:
#利用最小二乘法求线性回归i
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
x = np.array([150,200,250,300,350,400,600])
y = np.array([6450,7450,8450,9450,11450,15450,18450])
plt.scatter(x,y)#打印原始数据
plt.title("原始数据集")
plt.xlabel("X(面积)")
plt.ylabel("Y(价格)")
plt.show()
x_mean=np.mean(x)
y_mean=np.mean(y)
m=len(x)
x_a=0#(xi-x_mean)*(yi-y_mean)
x_b=0#(xi-x_mean)**2
for i in range(m):
x_a+=(x[i]-x_mean)*(y[i]-y_mean)
x_b+=(x[i]-x_mean)**2
w=x_a/x_b
b=y_mean-w*x_mean
print("单变量线性回归函数为y={} x + {}".format(w,b))
#画线性函数
plt.scatter(x,y)
lx=np.linspace(0,600)
ly=w*lx+bplt.plot(lx,ly)
plt.title("原始数据集")
plt.xlabel("X(面积)")
plt.ylabel("Y(价格)")
plt.show()