一、概述:
初次接触机器学习,发现最困难的一点是对于各种算法的理解,本系列博客将总结自己学到的机器学习相关算法以及简单的代码实现。首先是回归算法的相关心得。
二、线性回归:
1.定义:
线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商品的大小,y代表为销售量;当月份x =5时,我们就能根据线性模型预测出 y =11销量;对于上面的简单的例子来说,我们可以粗略把 y =2x+1看到回归的模型;对于给予的每个商品大小都能预测出销量;当然这个模型怎么获取到就是我们下面要考虑的线性回归内容;并且在现实中影响销量(y)的因素好有很多,我们就拿商品大小(x₁),商品价格为例 (x₂)为例:
在机器学习之前,获取数据是第一步(无米难巧妇之炊),假定我们的样本如下:其中x1 为商品的大小,x2 为商品的价格,y 为商品的销量
x1 x2 y
3 5 10
2 8 14
2.模型推导:
为了推导模型,在假设数据满足线性模型条件下,可以设定线性模型为;x1特征为商品的大小,X2特征为商品的价格;
模型假定好后,我们把训练数据代入上面的设定模型中,可以通过模型预测一个样本最终值;
然后样本真实值 y 和模型训练预测的值之间是有误差 ε ,再假设训练样本的数据量很大的时候,根据中心极限定律可以得到 ∑ε 满足 (u ,δ²)高斯分布的;由于方程有截距项 ,故使用可以 u =0; 故满足(0,δ²)的高斯分布;
取对数化简之后可以得到:
以上就得到了回归的损失函数最小二乘法的公式,对于好多介绍一般对线性回归的线性损失函数就直接给出了上面的公式二乘法。下面我们就对上面做了阶段性的总结:线性回归,根据大数定律和中心极限定律假定样本无穷大的时候,其真实值和预测值的误差ε 的加和服从u=0,方差=δ²的高斯分布且独立同分布,然后把ε =y-Øx 代入公式,就可以化简得到线性回归的损失函数;
第二步:对损失函数进行优化也就是求出w,b,使的损失函数最小化;第一种方法使用矩阵(需要满足可逆条件)
以上就是按矩阵方法优化损失函数,但上面方法有一定的局限性,就是要可逆;待会我会说一说另外一个优化方法 梯度下降法;
3.最小二乘意义下参数的最优解
当模型复杂度提高的时候,对训练集的数据拟合很好,但会出现过度拟合现象,为了防止这种过拟合现象的出现,我们在损失函数中加入了惩罚项,根据惩罚项不同分为以下:
最后一个为Elastic Net 回归,把 L1 正则和 L2 正则按一定的比例结合起来:
L1会趋向于产生少量的特征,而其他的特征都是0,而L2会选择更多的特征,这些特征都会接近于0。Lasso在特征选择时候非常有用,而Ridge就只是一种规则化而已。在所有特征中只有少数特征起重要作用的情况下,选择Lasso比较合适,因为它能自动选择特征。而如果所有特征中,大部分特征都能起作用,而且起的作用很平均,那么使用Ridge也许更合适。
此λ参数在θ表达式上的体现为:
3.交叉验证:
在机器学习和数据使用中,我们一般有三种方式:
(1)全部数据用作训练数据,训练出θ。
(2)一部分数据用作训练,一部分用作测试。
(3)如果要测定λ,通过训练是无法得到的,讲训练数据分一部分数据去验证λ。
通常用第三种方式,此方式按照将数据分成的几份通常叫做几折交叉验证 一般用五折
4.梯度下降算法:
总体流程就如上所示,就是求出每个变量的梯度;然后顺着梯度方向按一定的步长a,进行变量更新;下面我们就要求出每个变量的梯度,下面对每个θ进行梯度求解公式如下:
如上我们求出变量的梯度;然后迭代代入下面公式迭代计算就可以了:
上面每次更新变量,都要把所有的样本的加起来,数据量大的时候效率不高,下面还有一种就是按单个样本进行优化,就是随机梯度下降:
5.代码及图像:
按上面优化步骤就可以求出w,b,就可以获得优化的特征方程:说这么多先上个代码:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso, Ridge
from sklearn.model_selection import GridSearchCV # 交叉验证
if __name__ == "__main__":
# pandas读入
data = pd.read_csv('8.Advertising.csv') # TV、Radio、Newspaper、Sales
x = data[['TV', 'Radio', 'Newspaper']]
# x = data[['TV', 'Radio']]
y = data['Sales']
print(x)
print(y)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1)
# print x_train, y_train
model = Lasso()
# model = Ridge() # 指标较好 防止过拟合,即添加的λ参数
alpha_can = np.logspace(-3, 2, 10) # 从10的-3次方到10的-2次方 等比取10个数
lasso_model = GridSearchCV(model, param_grid={'alpha': alpha_can}, cv=5) # 进行5折交叉验证
lasso_model.fit(x, y)# 开始拟合
print('验证参数:\n', lasso_model.best_params_)
y_hat = lasso_model.predict(np.array(x_test))
mse = np.average((y_hat - np.array(y_test)) ** 2) # Mean Squared Error取均方误差
rmse = np.sqrt(mse) # Root Mean Squared Error 开根号
print(mse, rmse)
t = np.arange(len(x_test))
plt.plot(t, y_test, 'r-', linewidth=2, label='Test')
plt.plot(t, y_hat, 'g-', linewidth=2, label='Predict')
plt.legend(loc='upper right')
plt.grid()
plt.show()
如上是在Lasso模式下的输出为
{'alpha': 2.1544346900318843}
1.9152263138298533 1.383917018404591
即λ参数为2.1544…