机器学习笔记(一)线性回归模型

什么是线性回归?

1.给定由个特征描述的示例\(X=(x_1;x_2;x_3;..;x_n)\)其中\(x_i\)是x在第i个属性上面的取值,线性模型通过学得一个线性组合来进行预测的函数,如果把w和x都写成向量的形式的话,那么模型可以一般写成 \[ h(X)=W*X+b \] 其中\(w=(w_1;w_2;..;w_n)\), w和b学得以后模型就得以确定,h的值就是w和x向量的点积加上偏置b
在机器学习计算中一般都写成矩阵的形式方便计算,可以把x看成(m,n)列的矩阵 \[ x=[[x_{11},x_{12},x_{13}...,x_{1n}],...,[x_{m1},x_{m2},x_{m3},..x_{mn}]] \] m表示有m条数据集,n表示每条数据集的特征维度 \[ w=[[w_1,w_2,w_3...,w_n]] \]
这样的话写成矩阵的形式就是 \[ h(x)=X*{W.T} \tag{1} \] 在周志华的<<机器学习>>中,把向量表达的时候也有了转置的1表达式的形式,我觉得不是很严谨,向量应该没有转置的概念,只有把向量写成矩阵的形式才能用1式表达.

损失函数(loss function)

线性模型中一般用均方差作为损失函数
\[ J(\theta)=\frac{1}{m}*\sum\limits_{i=1}^{m}{(y_i-h(x_i))^2} \]

最小二乘法

最小二乘法是使得模型的预测值与真实值残差的平方和最小化的一种数学优化方法,因为损失函数是一个凸函数,所以可以通过对参数求,偏导数,当参数的斜率等于0的时候,位于损失函数的极小值点,这时候损失函数取得最小值。当\(w\)\(b\)的偏导数等于0的时候即: \[ \frac{\partial {J(\theta)}}{\partial w}={\sum\limits_{i=1}^{m}\frac{2}{m}{(y_i-h(x))}}*{\frac{\partial h(x)}{\partial w}}=0 \]
\[ \frac{\partial {J(\theta)}}{\partial b}={\sum\limits_{i=1}^{m}\frac{2}{m}{(y_i-h(x))}}*{\frac{\partial h(x)}{\partial b}}=0 \]

梯度下降法

梯度下降法(英语:Gradient descent)是一个一阶最优化算法,通常也称为最速下降法.要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索,如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点,这个过程则被称为梯度上升法梯度下降更新\(w\)\(b\) \[ w=w-{\alpha}*\frac{\partial J(\theta)}{\partial w} \] \[ b=b-{\alpha}*\frac{\partial J(\theta)}{\partial b} \]
对w求偏倒数有

\[ \begin{equation} \begin{aligned} \frac{\partial {J(\theta)}}{\partial w}&={\sum\limits_{i=1}^{m}\frac{2}{m}{(y_i-h(x))}}*{\frac{\partial h(x)}{\partial w}} \\ &={\frac{2}{m}}*{\sum\limits_{i=1}^{m}{(y_i-h(x))}}*{x_i} \\ &={\frac{2}{m}}*{\sum\limits_{i=1}^{m}{(y_i-w^T*x-b)}}*{x_i} \end{aligned} \end{equation} \]

对b求偏倒数有
\[ \begin{equation} \begin{aligned} \frac{\partial {J(\theta)}}{\partial b}&={\sum\limits_{i=1}^{m}\frac{2}{m}{(y_i-h(x))}}*{\frac{\partial h(x)}{\partial b}} \\ &={\frac{2}{m}}*{\sum\limits_{i=1}^{m}{(y_i-h(x))}}*{1}\\ &={\frac{2}{m}}*{\sum\limits_{i=1}^{m}{(y_i-w^T*x-b)}} \end{aligned} \end{equation} \]

梯度下降算法实现

1
2
3
4
5
import numpy as np
import pandas as pd
data=pd.read_csv("traintrain_x=data[["x1","x2"]].as_matrix()
train_y=data["y"].as_matrix().csv
data.head()
1
2
train_x=data[["x1","x2"]].values
train_y=data["y"].values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def graient_descent(train_x,train_y,alpha=0.01,max_iterator=100):
# init theta
w=np.zeros((1,2));
b=np.zeros((1,1));

#如果y是向量的话转化成矩阵 (n,)->(n,1)
if len(train_y.shape)==1:
train_y=train_y.reshape((train_y.shape[0],1))


for i in range(100):
y_predict=train_x.dot(w.T)+b
w_g=(train_x*( (y_predict-train_y) )).sum(axis=0)*(1/train_x.shape[0])
b_g=(y_predict-train_y).sum(axis=0)*(1/train_x.shape[0])

w=w-alpha*w_g
b=b-alpha*b_g

#print(b_g)

return w,b

graient_descent(train_x,train_y)
(array([[0.70417951, 1.22471787]]), array([[0.26234451]]))

把我们自己实现的线性回归算法和sklearn里面的线性回归算法进行下比较

1
2
3
4
from sklearn.linear_model import LinearRegression
lr=LinearRegression()
lr.fit(train_x,train_y)
lr.coef_
array([0.7, 1.4])