回归算法
线型回归(Linear regression)
概念 及 回归方程
概念:利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模
特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归
数学公式:
线性回归当中主要有两种模型,一种是线性关系,另一种是非线性关系。
- 线性回归:单特征与目标值的关系呈直线关系,两个特征与目标值呈现平面的关系
- 非线性回归:表现则是曲线或曲面(包含高次项)
损失函数
由于目标值时连续的,无法根据正确率进行判别,而是计算 损失量(预测值和真实值差的平方和) 来判断
损失越小,回归模型越好
优化算法
通过优化各个自变量的权重(w
),使得损失降到最小
常见的优化算法:
- 正规方程 数学方式直接计算(通过微分为零,直接计算出最优权重)
- 梯度下降 通过迭代一步步求解
- 正则化
正规方程 及其 API
正规方程:
X
为特征值矩阵,y
为目标值矩阵- 接求到最好的结果,但当特征过多过复杂时,求解速度太慢并且可能出现无解情况
正规方程的推导
- 把该损失函数转换成矩阵写法:
其中y
是真实值矩阵,X
是特征值矩阵,w
是权重矩阵
对其求解关于w
的最小值,起止y,X
均已知二次函数直接求导,导数为零的位置,即为最小值。
- 求得最优的权重矩阵
sklearn API
代码实现
导入模块:from sklearn.linear_model import LinearRegression
正规方程API:LinearRegression(fit_intercept=True)
- 参数
fit_intercept
:是否计算偏置normalize
:数据是否进行标准化,默认不标准化
可以在特征工程调用preprocessing.StandardScaler
标准化数据
- 属性
LinearRegression对象.coef_
:回归系数LinearRegression对象.intercept_
:偏置
梯度下降 及其 API
梯度:
- 在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率
- 在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向
梯度下降:以随机位置为基准,寻找这个位置梯度,往下移动,都反复采用该方法,最后就能成功的抵达(微分为0)最小值位置
梯度下降方程:
其中:
α
为学习率或者步长,通过控制α
决定每一步走的距离α
为超参数,可以自己指定,但其严重影响梯度下降的结果- 若步长过长,会错过了最低点
- 步长过小,迭代完毕仍未到最低点
常见的梯度下降算法有:
- 全梯度下降算法(
FG
)
计算训练集所有样本的最优权重,对其求平均值作为目标函数
优点:可以准确找到最优解
缺点:计算量大,花费时间长,内存消耗大,效率低下 - 随机梯度下降算法(
SG
)
仅仅计算训练集中随机的一个样本的最优权重,并作为目标函数
优点:容易陷入局部最优解(慎重选择步长)
缺点:速度快,计算量小 - 随机平均梯度下降算法(
SAG
)
在内存中保存每次SG
获得的梯度,每次训练结果:新样本与旧样本 所得 所有梯度的平均值,进而更新了参数
缺点:初期表现不佳(因为我们常将初始梯度设为0),优化速度较慢
优点:速度快,计算量小,迭代会越来越精确 - 小批量梯度下降算法(
Mini-batch
)
从训练样本集中随机抽取一个小样本集,在抽出来的小样本集上采用FG
迭代获取权重
样本点的个数(batch_size
),通常设置为2
的幂次方,更有利于GPU
加速处理
有效的解决了局部最优解的问题,效率也有所提高,为常用的梯度下降算法,是使用最多的梯度下降算法,正是因为它避开了FG
运算效率低成本大和SG
收敛效果不稳定的缺点
sklearn API
代码实现
SGDRegressor
类实现了随机梯度下降学习,它支持不同的loss
函数和 正则化拟合线性回归模型
导入模块:from sklearn.linear_model import SGDRegressor
梯度下降API:SGDRegressor(loss="squared_loss", fit_intercept=True,penalty='l2', learning_rate ='optimal', eta0=0.01)
-
参数:
loss
:损失函数类型loss="squared_loss"
:普通最小二乘法
fit_intercept
:是否计算偏置penalty='l2'
:正则化方式。{‘l2’, ‘l1’, ‘elasticnet’}
l2
岭回归 常用l2
Lasso
回归 少用elasticnet
:弹性网络,综合了岭回归
和Lasso回归
用于少数特征有效时
normalize
:数据是否进行标准化,默认不标准化
可以在特征工程调用preprocessing.StandardScaler
标准化数据learning_rate
: 学习率(α
)填充方式constant
: 学习率为常数,并通过eta0=0.01
指定optimal
:学习率=1.0 / (alpha * (t + t0))
默认使用invscaling
: 学习率=eta0 / pow(t, power_t)
、power_t=0.25
:存在父类当中max_iter=1000
:int
,通过训练数据的最大次数tol = 1e-3
:停止训练的精度标准
-
专属属性:
SGDRegressor.coef_
:回归系数 (线性回归方程中的权重W
)SGDRegressor.intercept_
:偏置 (线性回归方程中的常数项b
)
正则化(岭回归 及其 API)
概念:算法在学习时尽量减少 影响模型复杂度或者异常点较多 的特征(甚至删除)
-
岭回归(具有
L2
正则化的线性回归)
在原来的线性回归的方程 中添加 正则项,使不重要特征 和 高次项特征 的权重 尽可能小:
sklearn API
代码实现导入模块:
from sklearn.linear_model import Ridge, RidgeCV
岭回归API:
Ridge(alpha=1.0, *, fit_intercept=True, normalize=False , solver='auto', random_state=None)
带有交叉验证的岭回归API:RidgeCV(alphas=(0.1, 1.0, 10.0),...)
- 参数:
alpha
:正则化力度,也叫λ
,λ
取值:0~1
、1~10
fit_intercept=True
:计算偏置solver
:会根据数据自动选择优化方法。{'auto','svd','cholesky','lsqr','sparse_cg','sag','saga'}
sag
:如果数据集、特征都比较大,选择该随机梯度下降优化normalize
:数据是否进行标准化,默认不标准化
可以在特征工程调用preprocessing.StandardScaler
标准化数据max_iter=1000
:int
,通过训练数据的最大次数tol = 1e-3
:停止训练的精度标准
- 专属属性:
Ridge/RidgeCV.coef_
:回归系数 (线性回归方程中的权重W
)Ridge/RidgeCV.intercept_
:偏置 (线性回归方程中的常数项b
)Ridge.n_iter_
:每个目标的实际迭代次数RidgeCV.alpha_
:估计的正则化参数RidgeCV.best_score_
:具有最佳alpha
值的基本估算器 得分RidgeCV.cv_values_
:每个Alpha
的交叉验证值(仅当store_cv_values=True
和cv=None
时可用 )
- 参数:
注:Ridge
方法相当于SGDRegressor(penalty='l2', loss="squared_loss")
,只不过SGDRegressor
实现了一个普通的随机梯度下降学习(SG
),而Ridge
实现了SAG
-
Lasso
回归
在原来的线性回归的方程 中添加L1
正则项,将 不重要特征 和 高次项特征 的权重 置为0
也就是说,Lasso回归
能够自动进行特征选择,输出一个稀疏模型(只有少数 特征权重 不是零) -
Elastic Net
(弹性网络)
弹性网络在岭回归
和Lasso回归
中进行了折中,通过 混合比r
进行控制:
r=0
:弹性网络变为岭回归r=1
:弹性网络便为Lasso回归
分类算法
K近邻算法
算法简介 及 工作流程
核心为:样本在特征空间中的 k个最相邻样本 中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别的特性。
如图所示:
样本a在特征空间中的5(K值)个最相邻样本中大多数属于类别1,因此我们就认为样本a属于类别1,并具有类别1的特性
算法工作流程
- 选取与当前样本点 最近 的k个样本点
- 统计这k个样本点所在的类别出现的频率
- 返回这k个样本点出现频率最高的类别作为当前点的预测分类
选出最近k
个临近样本点的方法:
-
线型扫描(穷举搜索)
计算 所有已知类别样本点 与 当前预测样本点之间的距离,按距离递增次序排序,从而获取k
个最邻近样本点
缺点:计算量过大,耗时 -
kd 树
(类似二叉树的数据结构)
把距离信息保存在一棵树里,这样在计算之前从树里查询距离信息,尽量避免重新计算
一维
二维
- 构建
kd 树
- 选出首次切割维度(选择离散程度大的维度,即 标准差大)
- 选择首次切割点(中位数),将所有数据切为两个超矩形区域
- 垂直于上次切割维度,再次寻找中位数 切割。直至所有样本点均切割
- 最近领域的搜索(候选超球 和 回溯对列)
- 因为每次仅能将样本精确到两个样本之间,究竟距离那个样本更近需要确认
- 样本点 从
kd 树
始节点 开始 比较当前切割维度值的大小(小选左子节点,大选右子节点) ,直至选到终节点。并将经过的每个节点都放置到 回溯队列 - 以样本点为中心,以与终结点的距离为半径 画圆,若与 以往的切割超平面相交,则将相交切割超平面所在比较节点另一侧子节点都放入回溯队列
- 计算回溯队列中的每个点与样本的距离,选出最小的前 K 个
- 构建
KNN算法 API (sklearn)
导包:from sklearn.neighbors import KNeighborsClassifier
实例化API:estimator = KNeighborsClassifier(n_neighbors=5, weights=’uniform’, algorithm=’auto’, leaf_size=30, **kwargs)
参数:
n_neighbors
便是K值
,其中的数值是自定义的,但K值
的数值直接影响预测结果,K值
过小:
容易受到异常点的影响
就相当于用较小的领域中的训练实例进行预测,“学习”近似误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是“学习”的估计误差会增大,换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合k值
过大:
受到样本均衡的问题
就相当于用较大领域中的训练实例进行预测,其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误,且K值的增大就意味着整体的模型变得简单,容易欠拟合- 在实际应用中,
K值
一般取一个比较小的数值,然后采用交叉验证法(简单来说,就是把训练数据在分成两组:训练集和验证集)来选择最优的K值
weights
: 预测时使用的权重、可选、默认为uniform
uniform
:平权,每个邻域中所有点的权重均相等。distance
:权重点按其距离的倒数表示。在这种情况下,查询点的近邻比远处的近邻具有更大的影响力。callable
:用户定义的函数,它接受距离数组,并返回包含权重的相同形状的数组。
algorithm
: 用于计算最近邻居的算法,可选{'auto','ball_tree','kd_tree','brute'}
:kd_tree
将使用KD-树
ball_tree
将使用BallTree
,对kd- 树
高维失效现象进行了优化brute
将使用线型扫描暴力搜索,仅限小数据集使用auto
将 尝试根据传递给fit方法的值来决定最合适的算法
leaf_size
:BallTree
或KDTree
的叶大小、int型
、可选、默认为30
这会影响构造和查询的速度,以及存储树所需的内存。最佳值取决于问题的性质。
优缺点
优点:
- 简单有效
- 重新训练的代价低
- 适合类域交叉样本
KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。 - 适合大样本自动分类
该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
缺点:
-
惰性学习
KNN算法是懒散学习方法(lazy learning,基本上不学习),一些积极学习的算法要快很多 -
类别评分不是规格化
不像一些通过概率评分的分类 -
输出可解释性不强
-
对不均衡的样本不擅长
当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。 -
计算量较大