这里重点学习一下回归算法

机器学习基础

机器学习 vs. 传统编程

![image.png](https://img-blog.csdnimg.cn/img_convert/2f58b529d7d93bbf6b48f3c1a4de8793.png#clientId=u5bee9120-247f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=304&id=u4452b774&margin=[object Object]&name=image.png&originHeight=304&originWidth=450&originalType=binary&ratio=1&rotation=0&showTitle=false&size=53348&status=done&style=none&taskId=u3851b853-50e0-48a2-a098-b603878fff9&title=&width=450)

三种类别

根据使用场景不同,有可以划分为三大类

监督学习

监督学习是根据已知的方法和规律,对新样本进行分类和预测。
监督学习就好比学生在学校学习各种知识和理论的过程。整个过程是在老师的监督下完成,所学知识的应用体现在平时的测试中,并且可以通过对比“标准”答案来不断改进和巩固学习成果,在下一次的测试中取得更好的成绩(预测效果)。根据目的不同,可以有分类和回归(预测)两种:

  • 分类 —— 根据事物特征将其划分到已知的类别。

    • 根据事物的特征,将新遇到的事物(新样本)归类到已知的某个类别。
  • 回归(预测)—— 根据事物的特征和预测将来的发展趋势。
    • 根据事物的特征和发展规律,预测将来的发展趋势。

非监督学习

非监督学习与监督学习正好相反,在过程中并不清楚有哪些特征标签,而是通过对样本的观察、分析和总结,去发现其中的特征,从看似杂乱无章的数据中发现共性。然后对新样本进行归类。

归类/聚类(clustering)—— 对大量看似无特征的样本进行分类。

经常会说非监督学习是归类或聚类(clustering)。与分类不同,聚类在划分之前并不知道有哪些类别,以及类别的特征,而是通过对样本的各种特征进行分析,将相似的样本划分为一组,进行“物以类聚”的划分。是一个从无到有的发现过程。

半监督学习

介于监督和非监督学习之间。是基于监督学习获得理论和知识,对非监督学习的样本(无特征标签)进行分类。可以理解为我们走出学校以后根据在课堂上学到的知识和理论,对生活中遇到的事物进行分类和预测。

Python sklearn (scikit-learn)

Scikit-learn是一个用于Python的免费开源机器学习库。

机器学习三大步骤

机器学习的本质就是让机器使用特定的算法对输入数据进行类似人的智能学习(找规律),根据同样的模型对新样本进行进行预测。具体到python中的sklearn,是通过一下三大步骤实现的。

  1. 准备数据——对输入数据进行预处理
  2. 选择、训练和测试模型——使用处理后的样本数据,针对特定模型进行拟合、训练
    1. 模型的选择,可以根据要解决的问题和使用场景,scikit-learn提供了一张图(选择正确的估计器)来详细描述模型选择的流程,最终指向机器学习的集中主要使用场景,回归、分类聚类,以及scikit-learn提供的数据降维方法。

![image.png](https://img-blog.csdnimg.cn/img_convert/478368d184a7fd370f466e9c86165377.png#clientId=u35127f2c-c93a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=662&id=ub44cc5c2&margin=[object Object]&name=image.png&originHeight=1323&originWidth=2122&originalType=binary&ratio=1&rotation=0&showTitle=false&size=947070&status=done&style=none&taskId=u2b053fd0-4a43-435e-8fc4-e91720b522f&title=&width=1061)

  1. 使用模型预测——使用训练后的模型对新样本进行预测,并根据预测结果过进一步优化

scikit-learn (sklearn) 实现

sklearn中内置了常用的机器学习算法和模型,以及基本的预处理方法。分别由**预测(估计)器(estimator)预处理器(preprocessing)**实现,并且它们继承自同一个基础预测器。

转换器和预处理器

预处理器和转换器主要负责对原始数据的预处理和转换,从而消除不同数据之间的绝对差异。

from sklearn.preprocessing import StandardScaler# ...
# X = [...]StandardScaler().fit().transform(X)

预测器

sklearn中提供的数十种内置机器学习算法和模型,都通过估算器提供。可以通过引入相应的估算器来使用对应的模型。

from sklearn.ensemble import RandomForestClassifier# 初始化估算器
clf = RandomForestClassifier(random_state=0)# 使用训练数据进行模型拟合
clf.fit(X, y)# 预测
clf.predict(...) #

管道

管道用来将转换器和预测器组合成一个同一的对象,表示一个完整的数据流处理过程(管道)。然后使用管道的fit和predict来进行训练和预测。同时,使用管道还可以防止数据泄露。

from sklearn.preprocessing import StandardScaler # 预处理器
from sklearn.linear_model import LogisticRegression # 预测器
from sklearn.pipeline import make_pipeline # 管道# 创建管道
pipe = make_pipeline(StandardScaler(),LogisticRegression(random_state=0)
)#准备数据...# 像使用预测器一样使用管道
# 1) 训练整个pipeline
pipe.fit(X_train, y_train)# 2) 使用管道预测
pipe.predict(X_test)# ...

模型评估

针对不同类型的算法和模型,对应评估指标也不相同。

回归算法指标

回归算法的核心思想是评估预测值和观察值之间的误差。从最原始的残差(residual)到基于残差的各种变形,以便后续的数学运算和处理。

  • Mean Absolute Error 平均绝对误差:对残差做绝对值处理,避免残差正负导致的相互抵消。
  • Mean Squared Error 均方误差:为了便于求导,对平均绝对误差进行平方。
  • Root Mean Squared Error 均方根误差:如果目标变量的量纲保持一致,可以对均方误差进行开放。
  • Coefficient of determination 决定系数:进一步去除对量纲的依赖。

分类算法指标

相比较回归算法的各种残差指标,分类算法更多的则是关注分类的精度,即预测正确的样本数量占总预测样本的比例。然后,预计不同的场景,从不同角度来看精度对结果的影响。

  • Accuracy 精度:每一个分类中预测正确的样本数占总样本的比例。
  • 混淆矩阵 Confusion Matrix
  • 准确率(查准率) Precision
  • 召回率(查全率)Recall
  • Fβ Score
  • AUC Area Under Curve
  • KS Kolmogorov-Smirnov

关于各个指标的详细说明,可以参考知乎——机器学习评估指标。

参数搜索

所有预测器都有可以调整的参数,也叫超参数。其特指不能通过学习得到的参数。在使用各种不同模型时,需要将超参数作为参数传递给预测器。
sklearn中提供了在参数集中搜索最佳超参数的方法,其基于最佳交叉验证(CV, Cross-Validation)分数获取对应的超参数。sklearn中最简单的方法是调用cross_val_score函数。

估算器中的任意参数都可以通过参数搜索来获得最佳参数。

参数搜索的基本要素

  • 参数搜索方法
  • 评估方法

sklearn中两种抽样搜索最佳参数的方法:

GridSearchCV 网格搜索方法

计算参数集中所有参数的组合。GridSearchCV通过使用param_grid参数来指定参数候选值。
例如下边的例子指定搜索两个参数候选值。通过GridSearchCV的fitting接口拟合后,会对所有候选参数进行评估,保留最优参数组合。

# 选择模型
clf = ...# 指定网格搜索的参数
param_grid = [{'C': [1, 10, 100, 1000], 'kernel': ['linear']},{'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},] # 运行网格搜索
grid_search = GridSearchCV(clf, param_grid=param_grid)# ...
grid_search.fit(X, y)

RandomizedSearchCV 随机搜索方法

从具有制定分布的参数空间中抽样出定量的参数候选。RandomizedSearchCV会在指定范围内,使用某个特定分布抽取参数值进行评估。用字典形式来指定参数的具体抽样范围,针对每一个参数,可以指定

  • 具体的参数
  • 采样分布——可以使用scipy.stats模块,其中包含了很多采样分布,如expon,gamma,uniform或者randint。
  • 离散选项列表

例子

# 选择模型
clf = ...# RandomizedSearchCV 参数设置示例
param_dist = {'C': scipy.stats.expon(scale=100),  # 取值分布'gamma': scipy.stats.expon(scale=.1),'kernel': ['rbf'], # 离散列表'class_weight':['balanced', None] # 离散列表
} # 运行随机搜索
n_iter_search = 20
random_search = RandomizedSearchCV(clf, param_distributions=param_dist,n_iter=n_iter_search)# ...
random_search.fit(X, y)

评估方法(指标)

参数搜索默认使用估计器的score函数来评估参数的设置。默认为

  • sklearn.metrics.accuracy_score 用于分类
  • sklearn.metrics.r2_score 应用于回归

当然,sklearn还提供了其它一些评估函数可供不从场景使用。同时,也可以将多种评估指标结合起来使用。

回归算法

从sklearn模型流程可以很清楚得看到回归算法的使用场景。
![image.png](https://img-blog.csdnimg.cn/img_convert/6496b061a2d99c9d00a9e8e5ab14c0a6.png#clientId=u35127f2c-c93a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=251&id=u408eadf1&margin=[object Object]&name=image.png&originHeight=884&originWidth=1378&originalType=binary&ratio=1&rotation=0&showTitle=false&size=385245&status=done&style=none&taskId=u53cf04fe-fc69-4ea8-a6c1-e6402c87324&title=&width=391)
使用场景

  • 样本数大于50
  • 需要预测将来的某个具体数据(而不是对数据分类)

然后根据样本数据数据和特征标签的特点选择对应的算法

  • 样本数大于100K时,推荐使用SGDRegressor
  • 样本数小于100K时,则推荐使用Ridge, Lasso, 或者ElasticNet等;然后根据样本数据特征标签的权重,进行进一步选择。
    • 如果样本数据的特征标签同等重要,可以选择RidgeRegression或SVR;
    • 如果样本数据的某些特征更重要,对结果影响更大,可以使用Lasso和ElasticNet;

回归分析(Regression Analysis)

在搞清楚线性回归之前,我们首先要弄明白什么是回归分析。在统计学中,是指确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。
按照涉及的变量多少,可以分为一元回归多元回归;按照因变量的多少,可分为简单回归分析多重回归分析;按照自变量和因变量之间的关系类型,可分为线性回归分析非线性回归分析

线性回归(Liner Regression)基础

线性回归假设目标值(因变量)是特征值(自变量)的线性组合。线性回归使用最佳的拟合直线在因变量(YYY)和一个或多个自变量(XXX)之间建立一种关系。因变量是连续的,自变量可以是连续的也可以是离散的,回归线的性质是线性的。
在数学中,即为由特征值组成的多元一次方程。
Y=b+w1x1+...+wpxp+ϵY=b+w_1x_1+...+w_px_p+\epsilonY=b+w1​x1​+...+wp​xp​+ϵ
如果将自变量表示为X=(x1,...xp)X=(x_1,...x_p)X=(x1​,...xp​),系数表示为W=(w1,...,wp)W=(w_1, ..., w_p)W=(w1​,...,wp​),就能明白为什么它叫线性回归了。
Y=b+WTX+ϵY=b+W^TX+\epsilonY=b+WTX+ϵ
其中WWW是回归线的斜率,w0w_0w0​则表示回归线在Y轴上的截距,ϵ\epsilonϵ表示误差项。
上边的表示中,我们默认自变量和因变量都是多元的。这里我们限制因变量的个数为一个,则可以直接表示为
y=b+WTX+ϵy=b+W^TX+\epsilony=b+WTX+ϵ
线性回归就是通过各种算法去找到这样一个多元一次方程y^(x)=b+wX\hat{y}(x)=b+wXy^​(x)=b+wX,使其尽量接近观真实值yyy(残差ϵ\epsilonϵ尽量小)。而拟合的过程,就是去不断优化和估计方程的斜率系数,所以也叫“回归系数(coefficient)”。
这里要注意模型偏差bias和**残差(噪声)**的区别。

  • 偏差bbb——指排除噪声影响下,预测结果与真实值之间的差异。其主要是由模型的拟合度不够导致的(不是随机的,并且可通过一定的特征工程进行预测)。
  • 残差ϵ\epsilonϵ——预测结果与真实值之间的差异。在模型完全拟合的情况下,与真实值之间的差异,因此可以理解为噪声(随机、不可预测的)。

预测值和真实值的距离

那么,如何衡量预测的准确性,即衡量预测值y^(x)\hat{y}(x)y^​(x)与真实值yyy之间的差异呢?最直观的方法就是看真实值和预测值之间的差(残差)。回归模型的目的就是使模型预测出来的值无限接近真实值(测量值)。
ϵ^=y−y^(x)\hat{\epsilon} = y - \hat{y}(x)ϵ^=y−y^​(x)
但是在实际预测中,残差值有正有负,不可能直接使用残差之和最小的方式来衡量一种方法的好坏。
因此,整个回归问题的本质,就是使用均方误差,求使DDD最小时的WWW和ddd。
D=E(y−y^(x))2D=E(y-\hat{y}(x))^2D=E(y−y^​(x))2

1. 残差平方和SSE

由于残差本身有正有负,故可以使用平方和来避免正负抵消问题。
dist(Pi,Pj)=∑k=1n(Pik−Pjk)2dist(P_i, P_j) = \sum_{k=1}^n(P_ik-P_jk)^2dist(Pi​,Pj​)=∑k=1n​(Pi​k−Pj​k)2
问题:

  1. 使用平方后会放大(差>1)部分的误差,同时缩小(-1<差<1)部分的误差;
  2. 当不同维度的度量差异很大时无法处理;
2. 欧氏距离

为了解决误差平方和的问题,我们可以使用欧式距离。
dist(Pi,Pj)=∑k=1n(Pik−Pjk)2dist(P_i, P_j) = \sqrt{\sum_{k=1}^n(P_ik-P_jk)^2}dist(Pi​,Pj​)=∑k=1n​(Pi​k−Pj​k)2​
问题:

  1. 求解麻烦;
  2. 不同问题的度量差异很大时无法处理;
3. 曼哈顿距离

曼哈顿距离直接使用绝对值来消除根号开方的求解麻烦问题。
dist(Pi,Pj)=∑k=1n∣Pik−Pjk∣dist(P_i, P_j) = \sum_{k=1}^n\vert P_ik-P_jk\vertdist(Pi​,Pj​)=∑k=1n​∣Pi​k−Pj​k∣
问题:

  1. 不是连续函数,求导很麻烦,计算不方便,只能计算垂直、水平距离

适合场景:数据稀疏(自带归一化处理)

4. 马氏距离(Mahalanobis Distance)

马氏距离是对欧式距离的另外一种修正,修正了欧氏距离中各个维度尺度不一致且相关的问题。
dist(Pi,Pj)=(Pik−Pjk)TΣ−1(Pik−Pjk)dist(P_i, P_j) = \sqrt{(P_ik-P_jk)^T\Sigma^{-1}(P_ik-P_jk)}dist(Pi​,Pj​)=(Pi​k−Pj​k)TΣ−1(Pi​k−Pj​k)​
马氏距离已经不像前边的几种那么好理解,具体推导过程可以参考马氏距离。总之,其较好的解决了不同维度尺度不一致且相关的问题。

5. 其它

其它还有一些距离如汉明距离(Hamming Distance)、编辑距离(Levenshtein Distance)等,这里不做一一说明。

普通最小二乘法(Ordinary Least Square, OLS)

最小二乘法直接使用残差的平方和作为衡量标准,通过拟合WWW使残差ϵ\epsilonϵ的平方和最小。数学上表示为下边的形式:
min∥Xw−y∥22min{\Vert Xw-y\Vert _2^2}min∥Xw−y∥22​
![image.png](https://img-blog.csdnimg.cn/img_convert/d0c3002ba1d041e6be8c62cb632b4f64.png#clientId=u21aa29a4-be78-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=240&id=u4b140a9b&margin=[object Object]&name=image.png&originHeight=480&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=16055&status=done&style=none&taskId=u8ca7bced-72e2-4a40-9fbd-7e1386524b6&title=&width=320)
在sklearn的线性回归模型LinearRegression中,使用fit()fit()fit()函数拟合模型,并在模型的coef_中存储拟合后的相关系数www。

import numpy as np
from sklearn import datasets, linear_model# ...准备数据,选择特征列,拆分训练、测试数据集..# Create linear regression object
regr = linear_model.LinearRegression()# Train the model using the training sets
regr.fit(diabetes_X_train, diabetes_y_train)# Make predictions using the testing set
diabetes_y_pred = regr.predict(diabetes_X_test)# The coefficients
print("Coefficients: \n", regr.coef_)
# The mean squared error
print("Mean squared error: %.2f" % mean_squared_error(diabetes_y_test, diabetes_y_pred))
# The coefficient of determination: 1 is perfect prediction
print("Coefficient of determination: %.2f" % r2_score(diabetes_y_test, diabetes_y_pred))
非负最小方差

在最小二乘法法返回的系数中,默认是不会对系数的正负进行限制的。但是在实际问题中,很多时候我们需要所有的相关系数非负,例如频次、商品价格等。这时候可以直接设置LinearRegression的positive参数为True来限制相关系数的正负。

from sklearn.linear_model import LinearRegressionreg_nnls = LinearRegression(positive=True)
y_pred_nnls = reg_nnls.fit(X_train, y_train).predict(X_test)
r2_score_nnls = r2_score(y_test, y_pred_nnls)
print("NNLS R2 score", r2_score_nnls)

问题
普通最小二乘的系数估计依赖于特征的独立性。当特征相关且设计矩阵的列之间具有近似线性相关性时, 设计矩阵趋于奇异矩阵,最小二乘估计对观测目标的随机误差高度敏感,可能产生很大的方差。例如,在没有实验设计的情况下收集数据时,就可能会出现这种多重共线性的情况。

过拟合(Overfitting)和欠拟合(Underfitting)

过拟合和欠拟合是使用实际数据进行分析时可能会遇到的两种基本问题。
![image.png](https://img-blog.csdnimg.cn/img_convert/b6faa6bc3c5d1428f48a67ceede6b7b0.png#clientId=u21aa29a4-be78-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=126&id=lBmXy&margin=[object Object]&name=image.png&originHeight=252&originWidth=735&originalType=binary&ratio=1&rotation=0&showTitle=false&size=13524&status=done&style=none&taskId=u4de5531d-82e5-408a-82fb-0cc2a39a43e&title=&width=367.5)

  • 欠拟合——指模型在训练集中的表现就很差了,经验误差很大。

欠拟合出现的原因是模型复杂度太低,比如自变量太少等。针对欠拟合,要做的就是增大模型复杂度,增加自变量,或者改变模型(线性到非线性)等。

  • 过拟合——指模型在训练集中表现良好,而测试集中表现很差,即泛化误差大于了经验误差,拟合过度,模型泛化能力降低,只能够适用于训练集,通用性不强。

过拟合的原因是模型复杂度太高,或者训练数据集太少,比如自变量过多等。针对过拟合,除了增加训练集数据外,正则化就是常用的一种处理方法。

正则化