一、集成学习方法之随机森林
集成学习的基本思想就是将多个分类器组合,从而实现一个预测效果更好的集成分类器。集成算法可以说从一方面验证了中国的一句老话:三个臭皮匠,赛过诸葛亮。集成算法大致可以分为:Bagging,Boosting 和 Stacking 三大类型。
(1)每次有放回地从训练集中取出 n 个训练样本,组成新的训练集;
(2)利用新的训练集,训练得到M个子模型;
(3)对于分类问题,采用投票的方法,得票最多子模型的分类类别为最终的类别;
随机森林就属于集成学习,是通过构建一个包含多个决策树(通常称为基学习器或弱学习器)的森林,每棵树都在不同的数据子集和特征子集上进行训练,最终通过投票或平均预测结果来产生更准确和稳健的预测。这种方法不仅提高了预测精度,也降低了过拟合风险,并且能够处理高维度和大规模数据集
1.1 算法原理
- 样本随机:对于一个总体训练集 T,其中共有 N 个样本,每次有放回地随机选择n个样本,用这 n个样本来训练一个决策树。这种有放回的抽样方式被称为自助采样(Bootstrap Sampling)。
- 特征随机:假设训练集的特征个数为d ,每次仅选择 k(k<d)个特征来构建决策树。这样可以增加决策树之间的差异性,提高模型的泛化能力。
- 森林构建:由于样本和特征的随机性,可以生成多个不同的决策树,这些决策树共同构成随机森林。
- 优点:随机森林可以处理具有高维特征的输入样本,而且不需要降维,同时使用平均或者投票的方式来提高预测精度和控制过拟合。
1.2 Sklearn API
在 sklearn
库中,可以使用 RandomForestClassifier
类来实现随机森林分类器。以下是该类的主要参数:
python
from sklearn.ensemble import RandomForestClassifier
# 创建随机森林分类器实例
estimator = RandomForestClassifier(
n_estimators=100, # 森林中树木的数量(决策树个数),默认值为 100
criterion="gini", # 决策树属性划分算法选择,可选 "gini"(基尼不纯度)或 "entropy"(信息增益),默认值为 "gini"
max_depth=None # 树的最大深度,默认值为 None,表示不限制树的深度
)
1.3 示例:泰坦尼克号乘客生存预测
python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
# 1、获取数据
titanic = pd.read_csv("src/titanic/titanic.csv")
# 筛选特征值和目标值
x = titanic[["pclass", "age", "sex"]]
y = titanic["survived"]
# 2、数据处理
# 1)缺失值处理
x["age"].fillna(x["age"].mean(), inplace=True)
# 2) 转换成字典
x = x.to_dict(orient="records")
# 3) 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# 4) 字典特征抽取
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 3、预估:加网格搜索与交叉验证的代码
estimator = RandomForestClassifier()
# 参数准备
param_dict = {
"n_estimators": [120, 200, 300, 500, 800, 1200], # 树的数量
"max_depth": [5, 8, 15, 25, 30] # 树的最大深度
}
# 加入网格搜索与交叉验证,cv=3 表示 3 次交叉验证
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)
# 训练
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法 1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法 2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
# 输出最佳参数、最佳结果、最佳估计器和交叉验证结果
print("最佳参数:\n", estimator.best_params_)
print("最佳结果:\n", estimator.best_score_)
print("最佳估计器:\n", estimator.best_estimator_)
print("交叉验证结果:\n", estimator.cv_results_)
二、线性回归算法
1 回归的基本概念
回归的目的是预测数值型的目标值 。最直接的办法是依据输入x 写出一个目标值 y的计算公式,这个公式就是回归方程。
2 线性回归
线性回归意味着可以将输入项分别乘以一些常量,再将结果加起来得到输出。线性回归是机器学习中一种有监督学习的算法,主要关注因变量(需要预测的值)和一个或多个数值型的自变量(预测变量)之间的关系。
2.2.1 简单示例:包子价格预测
已知 1 个包子是 2 元,3 个包子是 6 元,预测 5 个包子的价格。设回归方程为y=wx+b ,代入数据可得:
解得w=2 ,b=2,则模型为y=2*x+0 。当 x=5 时,target(y) = 2*5+0=10元。
2.2.2 实际数据中的线性回归
在实际数据中,往往找不到一个完美的方程式来 100% 满足所有的 y 目标,需要找出一个最接近真理的方程式。例如,有一组植物在不同温度下生长高度的数据,我们希望找到一条直线来拟合这些数据点,从而通过环境温度大概判断植物在某个温度下的生长高度。
3 损失函数
为了找到最符合数据的直线,需要定义一个损失函数来衡量预测值与真实值之间的误差。常见的损失函数是均方差(Mean Squared Error,MSE),即每个点到线的竖直方向的距离平方求和再平均,当损失函数的值最小时,对应的直线就是最优直线。
假设回归方程为y=wx+b ,对于数据点(x1,y1),(x2,y2),......(xn,yn) ,损失函数为:
为了简化问题,先假设 b=0,通过求损失函数关于w 的导数为 0 时的 w 值,来找到损失函数的最小值。例如,当求得 w=0.795 时损失函数取得最小值,则最终的最优解函数为 y=0.795x+0。
4 多参数回归
在实际情况中,影响结果 y 的因素往往不止一个,这时x 就从一个变成了 n 个,即x1,x2,...xn 。多元线性回归的方程为:
其中, 是截距,也可以使用 来表示,只要是个常量就行。则损失函数为:
5 最小二乘法(MSE)
最小二乘法是一种求解线性回归参数的常用方法,其目标是使损失函数最小化。设h(x)=w1x1+w2x2+..+wnxn+w0x0 ,则最小二乘法的损失函数为:
其中, X是输入特征矩阵, W是权重向量,y 是目标向量。
为了找到使损失函数最小的W 值,对损失函数求导并令导数为 0:
解得:
6. Sklearn API
在 sklearn
库中,可以使用 LinearRegression
类来实现普通最小二乘法线性回归。
python
from sklearn.linear_model import LinearRegression
import numpy as np
# 示例数据
data = np.array([
[0, 14, 8, 0, 5, -2, 9, -3, 399],
[-4, 10, 6, 4, -14, -2, -14, 8, -144],
[-1, -6, 5, -12, 3, -3, 2, -2, 30],
[5, -2, 3, 10, 5, 11, 4, -8, 126],
[-15, -15, -8, -15, 7, -4, -12, 2, -395],
[11, -10, -2, 4, 3, -9, -6, 7, -87],
[-14, 0, 4, -3, 5, 10, 13, 7, 422],
[-3, -7, -2, -8, 0, -6, -5, -9, -309]
])
x = data[:, 0:8]
y = data[:, 8:]
# 创建线性回归模型实例
estimator = LinearRegression(fit_intercept=False)
# 训练模型
estimator.fit(x, y)
# 输出权重系数和偏置
print("权重系数为:\n", estimator.coef_)
print("偏置为:\n", estimator.intercept_)
# 预测新数据
x_new = [[11, 14, 8, 10, 5, 10, 8, 1]]
y_predict = estimator.predict(x_new)
print("预测结果:\n", y_predict)
7 梯度下降
7.1 梯度下降概念
正规方程求解线性回归参数的缺点是:当损失函数不是凸函数时,设置导数为 0 会得到很多个极值,不能确定唯一解;而且当数据量和特征较多时,矩阵计算量太大。因此,梯度下降算法更常用。
梯度下降是一种通用的优化算法,用于帮助机器学习算法求解最优解。其基本思想是:假设你在一个陌生星球的山地上,想找到一个谷底,需要沿着最陡峭的坡向下行走,每走一步都找到当前位置最陡峭的下坡方向,然后朝着该方向迈进一小步,直到到达谷底(局部或全局最优点)。
在机器学习中,梯度表示损失函数对于模型参数的偏导数。通过计算损失函数对参数的梯度,梯度下降算法能够根据梯度的信息来调整参数,朝着减少损失的方向更新模型,从而逐步优化模型。
7.2 梯度下降步骤
- 随机初始化参数:随机生成一组成正态分布的数值w0,w1,w2...wn 作为初始参数。
- 求梯度:计算损失函数对于参数的梯度g ,梯度代表曲线某点上的切线的斜率。
- 更新参数:根据梯度的正负来更新参数,若 g<0,则w 变大;若g>0 ,则 w变小。更新公式为:w=w-a*g,其中a 是学习率。
- 判断收敛:判断是否达到收敛条件,收敛的判断标准是:随着迭代进行查看损失函数 Loss 的值,变化非常微小甚至不再改变,即认为达到收敛。也可以固定迭代次数。
7.3 学习率
学习率 a控制着每次参数更新的幅度。如果学习率设置过大,可能会导致参数更新幅度过大,越过最优解,使得损失函数来回震荡;如果学习率设置过小,参数更新速度会很慢,导致迭代次数增加,收敛时间变长。一般会把学习率设置成一个小数,如 0.1、0.01、0.001、0.0001 等,并根据情况进行调整。
7.4 自己实现梯度下降
python
import numpy as np
import matplotlib.pyplot as plt
# 1. 单个特征的梯度下降示例
# 列损失函数
loss = lambda w_1: (w_1 - 3.5) ** 2 - 4.5 * w_1 + 10
w_1 = np.linspace(0, 11.5, 100)
plt.plot(w_1, loss(w_1))
# 求这个损失函数的最小值:梯度下降
def cb():
g = lambda w_1: 2 * (w_1 - 3.5) - 4.5 # 导函数
t0, t1 = 1, 100
alpha = t0 / t1 # 学习率
w_1 = np.random.randint(0, 10, size=1)[0] # 随机初始值
# 控制更新次数
for i in range(1000):
alpha = t0 / (i + t1) # 控制学习率逐步变小
w_1 = w_1 - alpha * g(w_1) # 梯度下降公式
print("更新后的 w_1:", w_1)
cb()
# 2. 两个特征的梯度下降示例
# 列损失函数
loss = lambda w_1, w_2: (w_1 - 3.5) ** 2 + (w_2 - 2) ** 2 + 2 * w_2 - 4.5 * w_1 + 3 * w_1 * w_2 + 20
# 求这个损失函数的最小值:梯度下降
def cb2():
t0, t1 = 1, 100
alpha = t0 / t1 # 学习率
w_1 = 10 # 随机初始值
w_2 = 40 # 随机初始值
dw_1 = lambda w_1, w_2: 2 * (w_1 - 3.5) + 3 * w_2 - 4.5 # w_1 的导函数
dw_2 = lambda w_1, w_2: 3 * w_1 + 2 * w_2 - 2 # w_2 的导函数
# 控制更新次数
for i in range(100):
alpha = t0 / (i + t1) # 控制学习率逐步变小
w_1_ = w_1 # 保存起来,防止梯度下降过程中 w_1 和 w_2 的值发生改变
w_2_ = w_2
w_1 = w_1 - alpha * dw_1(w_1_, w_2_) # 梯度下降公式
w_2 = w_2 - alpha * dw_2(w_1_, w_2_)
print("更新后的 w_1, w_2:", w_1, w_2)
cb2()
7.5 sklearn梯度下降
官方的梯度下降API常用有三种:
批量梯度下降BGD(Batch Gradient Descent)
小批量梯度下降MBGD(Mini-BatchGradient Descent)
随机梯度下降SGD(Stochastic Gradient Descent)。
三种梯度下降有什么不同呢?
- Batch Gradient Descent (BGD): 在这种情况下,每一次迭代都会使用全部的训练样本计算梯度来更新权重。这意味着每一步梯度更新都是基于整个数据集的平均梯度。这种方法的优点是每次更新的方向是最准确的,但缺点是计算量大且速度慢,尤其是在大数据集上。
- Mini-Batch Gradient Descent (MBGD): 这种方法介于批量梯度下降和随机梯度下降之间。它不是用全部样本也不是只用一个样本,而是每次迭代从数据集中随机抽取一小部分样本(例如,从500个样本中选取32个),然后基于这一小批样本的平均梯度来更新权重。这种方法在准确性和计算效率之间取得了一个平衡。
- Stochastic Gradient Descent (SGD): 在随机梯度下降中,每次迭代仅使用随机单个样本(或有时称为“例子”)来计算梯度并更新权重。这种方法能够更快地收敛,但由于每次更新都基于单个样本,所以会导致权重更新路径不稳定。
7.6批量梯度下降BGD
批量梯度下降是一种用于机器学习和深度学习中的优化算法,它用于最小化损失函数(目标函数)。批量梯度下降使用整个训练数据集来计算梯度并更新模型参数。
原理
批量梯度下降的基本思想是在每个迭代步骤中使用所有训练样本来计算损失函数的梯度,并据此更新模型参数。这使得更新方向更加准确,因为它是基于整个数据集的梯度,而不是像随机梯度下降那样仅基于单个样本。
更新规则
特点
- 准确性:由于使用了所有训练样本,所以得到的梯度是最准确的,这有助于找到全局最小值。
- 计算成本:每次更新都需要遍历整个数据集,因此计算量较大,特别是在数据集很大的情况下。
- 收敛速度:虽然每一步的更新都是准确的,但由于计算成本较高,实际收敛到最小值的速度可能不如其他方法快。
- 内存需求:需要在内存中存储整个数据集,对于大型数据集来说可能成为一个问题。
使用场景
- 小数据集:当数据集较小时,批量梯度下降是一个不错的选择,因为它能保证较好的收敛性和准确性。
- 不需要实时更新:如果模型不需要实时更新,例如在离线训练场景下,批量梯度下降是一个合理的选择。
实现注意事项
- 选择合适的学习率:选择合适的学习率对于快速且稳定的收敛至关重要。如果学习率太小,收敛速度会很慢;如果太大,则可能会导致不收敛。
- 数据预处理:对数据进行标准化或归一化,可以提高批量梯度下降的效率。
- 监控损失函数:定期检查损失函数的变化趋势,确保算法正常工作并朝着正确的方向前进。
API
批量梯度下降通常不是首选方法,因为它在大数据集上的计算成本较高。如果你确实需要批量梯度下降,那么可以考虑自己实现。
7.7随机梯度下降SGD
随机梯度下降(Stochastic Gradient Descent, SGD)是一种常用的优化算法,在机器学习和深度学习领域中广泛应用。与批量梯度下降(BGD)和小批量梯度下降(MBGD)相比,SGD 每一步更新参数时仅使用单个训练样本,这使得它更加灵活且计算效率更高,特别是在处理大规模数据集时。
基本步骤
数学公式
更新规则
注意事项
- 学习率 : 需要适当设置,太大会导致算法不收敛,太小则收敛速度慢。
- 随机性: 每次迭代都从训练集中随机选择一个样本,这有助于避免陷入局部最小值。
- 停止条件: 可以是达到预定的最大迭代次数,或者梯度的范数小于某个阈值。
随机梯度下降的一个关键优势在于它能够快速地进行迭代并适应较大的数据集。然而,由于每次只使用一个样本进行更新,梯度估计可能较为嘈杂,这可能导致更新过程中出现较大的波动。在实际应用中,可以通过减少学习率(例如采用学习率衰减策略)来解决这个问题。
API
sklearn.linear_model.SGDRegressor()
功能:梯度下降法线性回归
参数:
loss: 损失函数,默认为 ’squared_error’
fit_intercept: 是否计算偏置, default=True
eta0: float, default=0.01学习率初始值
learning_rate: str, default=’invscaling’
The learning rate schedule:
‘constant’: eta = eta0 学习率为eta0设置的值,保持不变
‘optimal’: eta = 1.0 / (alpha * (t + t0))
‘invscaling’: eta = eta0 / pow(t, power_t)
‘adaptive’: eta = eta0, 学习率由eta0开始,逐步变小
max_iter: int, default=1000 经过训练数据的最大次数(又名epoch)
shuffle=True 每批次是否洗牌
penalty: {‘l2’, ‘l1’, ‘elasticnet’, None}, default=’l2’
要使用的惩罚(又称正则化项)。默认为' l2 ',这是线性SVM模型的标准正则化器。' l1 '和'
elasticnet '可能会给模型(特征选择)带来' l2 '无法实现的稀疏性。当设置为None时,不添加惩罚。
属性:
coef_ 回归后的权重系数
intercept_ 偏置
案例:
加载加利福尼亚住房数据集,进行回归预测, 注意网络
# 线性回归 加载加利福尼亚住房数据集,进行回归预测
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge
from sklearn.metrics import mean_squared_error
from sklearn.datasets import fetch_california_housing
# 1)加载数据
housing = fetch_california_housing(data_home="./src")
print(housing)
# 2)划分训练集与测试集
x_train, x_test, y_train, y_test = train_test_split(housing.data, housing.target, random_state=22)
# 3)标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)线性回归预估器
estimator = SGDRegressor(learning_rate="constant", eta0=0.01, max_iter=1000, penalty="l1",loss="squared_error")
estimator.fit(x_train, y_train)
# 5)得出模型
print("权重系数为:\n", estimator.coef_) #权重系数与特征数一定是同样的个数。
print("偏置为:\n", estimator.intercept_)
# 6)模型评估
y_predict = estimator.predict(x_test)
print("预测的数据集:\n", y_predict)
print("得分:\n",estimator.score(x_test, y_test))
error = mean_squared_error(y_test, y_predict)
print("均方误差为:\n", error)
7.8小批量梯度下降MBGD
小批量梯度下降是一种介于批量梯度下降(BGD)与随机梯度下降(SGD)之间的优化算法,它结合了两者的优点,在机器学习和深度学习中被广泛使用。
原理
小批量梯度下降的基本思想是在每个迭代步骤中使用一小部分(即“小批量”)训练样本来计算损失函数的梯度,并据此更新模型参数。这样做的好处在于能够减少计算资源的需求,同时保持一定程度的梯度准确性。
更新规则
特点
- 计算效率:相比于批量梯度下降,小批量梯度下降每次更新只需要处理一部分数据,减少了计算成本。
- 梯度估计:相比于随机梯度下降,小批量梯度下降提供了更准确的梯度估计,这有助于更稳定地接近最小值。
- 内存需求:相比批量梯度下降,小批量梯度下降降低了内存需求,但仍然比随机梯度下降要高。
- 收敛速度与稳定性:小批量梯度下降能够在保持较快的收敛速度的同时,维持相对较高的稳定性。
使用场景
- 中等规模数据集:当数据集大小适中时,小批量梯度下降是一个很好的折衷方案,既能够高效处理数据,又能够保持良好的收敛性。
- 在线学习:在数据流式到达的场景下,小批量梯度下降可以有效地处理新到来的数据批次。
- 分布式环境:在分布式计算环境中,小批量梯度下降可以更容易地在多台机器上并行执行。
实现注意事项
- 选择合适的批量大小:批量大小的选择对性能有很大影响。较大的批量可以减少迭代次数,但计算成本增加;较小的批量则相反。
- 选择合适的学习率:选择合适的学习率对于快速且稳定的收敛至关重要。如果学习率太小,收敛速度会很慢;如果太大,则可能会导致不收敛。
- 数据预处理:对数据进行标准化或归一化,可以提高小批量梯度下降的效率。
- 监控损失函数:定期检查损失函数的变化趋势,确保算法正常工作并朝着正确的方向前进。
API
还是使用sklearn.linear_model.SGDRegressor()
只是训练时我们分批次地训练模型,调用partial_fit函数训练会直接更新权重,而不需要调fit从头开始训练。通常情况下,我们会将数据分成多个小批量,然后对每个小批量进行训练。
案例
# 线性回归 加载加利福尼亚住房数据集,进行回归预测
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge
from sklearn.metrics import mean_squared_error
from sklearn.datasets import fetch_california_housing
# 1)加载数据
housing = fetch_california_housing(data_home="./src")
print(housing)
# 2)划分训练集与测试集
x_train, x_test, y_train, y_test = train_test_split(housing.data, housing.target, random_state=22)
# 3)标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)线性回归预估器
estimator = SGDRegressor(learning_rate="constant", eta0=0.01, max_iter=1000,shuffle=True, penalty="l1")
# 小批量梯度下降
batch_size = 50 # 批量大小
n_batches = len(x_train) // batch_size # 批次数量
for epoch in range(estimator.max_iter):
indices = np.random.permutation(len(x_train)) # 随机打乱样本顺序
for i in range(n_batches):
start_idx = i * batch_size
end_idx = (i + 1) * batch_size
batch_indices = indices[start_idx:end_idx]
X_batch = x_train[batch_indices]
y_batch = y_train[batch_indices]
estimator.partial_fit(X_batch, y_batch) # 更新模型权重
# 5)得出模型
print("权重系数为:\n", estimator.coef_) #权重系数与特征数一定是同样的个数。
print("偏置为:\n", estimator.intercept_)
# 6)模型评估
y_predict = estimator.predict(x_test)
print("得分:\n",estimator.score(x_test, y_test))
print("预测的数据集:\n", y_predict)
error = mean_squared_error(y_test, y_predict)
print("均方误差为:\n", error)
7.9梯度下降优化
1.标准化
前期数据的预处理,之前讲的
2.正则化
防止过拟合
8.欠拟合过拟合
8.1欠拟合
欠拟合是指模型在训练数据上表现不佳,同时在新的未见过的数据上也表现不佳。这通常发生在模型过于简单,无法捕捉数据中的复杂模式时。欠拟合模型的表现特征如下:
- 训练误差较高。
- 测试误差同样较高。
- 模型可能过于简化,不能充分学习训练数据中的模式。
8.2过拟合
过拟合是指模型在训练数据上表现得非常好,但在新的未见过的数据上表现较差。这通常发生在模型过于复杂,以至于它不仅学习了数据中的真实模式,还学习了噪声和异常值。过拟合模型的表现特征如下:
-
训练误差非常低。
-
测试误差较高。
-
模型可能过于复杂,以至于它对训练数据进行了过度拟合。
8.3正则化
正则化就是防止过拟合,增加模型的鲁棒性,鲁棒是Robust 的音译,也就是强壮的意思。就像计算机软件在面临攻击、网络过载等情况下能够不死机不崩溃,这就是软件的鲁棒性,鲁棒性调优就是让模型拥有更好的鲁棒 性,也就是让模型的泛化能力和推广能力更加的强大。
比如,下面两个方程描述同一条直线,哪个更好?
第一个更好,因为下面的公式是上面的十倍,当w越小公式的容错的能力就越好。我们都知道人工智能中回归是有误差的,为了把误差降低而拟合出来的一个接近真实的公式,比如把一个测试数据[10,20]带入计算得到的值跟真实值会存在一定的误差,但是第二个方程会把误差放大,公式中y=wTx,当x有一点错误,这个错误会通过w放大。但是w不能太小,当w太小时(比如都趋近0),模型就没有意义了,无法应用。想要有一定的容错率又要保证正确率就要由正则项来发挥作用了! 所以正则化(鲁棒性调优)的本质就是牺牲模型在训练集上的正确率来提高推广、泛化能力,W在数值上越小越好,这样能抵抗数值的扰动。同时为了保证模型的正确率W又不能极小。因此将原来的损失函数加上一个惩罚项使得计算出来的模型W相对小一些,就是正则化。这里面损失函数就是原来固有的损失函数,比如回归的话通常是MSE,然后在加上一部分惩罚项来使得计算出来的模型W相对小一些来带来泛化能力。
常用的惩罚项有L1正则项或者L2正则项:
9.岭回归Ridge
9.1 损失函数公式
岭回归是失损函数通过添加所有权重的平方和的乘积(L2)来惩罚模型的复杂度。
均方差除以2是因为方便求导,指所有的权重系数, λ指惩罚型系数,又叫正则项力度
特点:
- 岭回归不会将权重压缩到零,这意味着所有特征都会保留在模型中,但它们的权重会被缩小。
- 适用于特征间存在多重共线性的情况。
- 岭回归产生的模型通常更为平滑,因为它对所有特征都有影响。
9.2 API
具有L2正则化的线性回归-岭回归。
sklearn.linear_model.Ridge()
1 参数:
(1)alpha, default=1.0,正则项力度
(2)fit_intercept, 是否计算偏置, default=True
(3)solver, {‘auto’, ‘svd’, ‘cholesky’, ‘lsqr’, ‘sparse_cg’, ‘sag’, ‘saga’, ‘lbfgs’}, default=’auto’
当值为auto,并且数据量、特征都比较大时,内部会随机梯度下降法。
(4)normalize:,default=True, 数据进行标准化,如果特征工程中已经做过标准化,这里就该设置为False
(5)max_iterint, default=None,梯度解算器的最大迭代次数,默认为15000
2 属性
coef_ 回归后的权重系数
intercept_ 偏置
说明:SGDRegressor也可以做岭回归的事情,比如SGDRegressor(penalty='l2',loss="squared_loss"),但是其中梯度下降法有些不同。所以推荐使用Ridge实现岭回归
9.3 示例
岭回归 加载加利福尼亚住房数据集,进行回归预测
# 岭回归 加载加利福尼亚住房数据集,进行回归预测
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge
from sklearn.metrics import mean_squared_error
from sklearn.datasets import fetch_california_housing
# 1)加载数据
housing = fetch_california_housing(data_home="./src")
print(housing)
# 2)划分训练集与测试集
x_train, x_test, y_train, y_test = train_test_split(housing.data, housing.target, random_state=22)
# 3)标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)岭回归预估器
estimator = Ridge(alpha=0.5, max_iter=10000)
estimator.fit(x_train, y_train)
# 5)得出模型
print("权重系数为:\n", estimator.coef_) #权重系数与特征数一定是同样的个数。
print("偏置为:\n", estimator.intercept_)
# 6)模型评估
y_predict = estimator.predict(x_test)
print("预测的数据集:\n", y_predict)
error = mean_squared_error(y_test, y_predict)
print("均方误差为:\n", error)
10.拉索回归Lasso
10.1 损失函数公式
Lasso回归是一种线性回归模型,它通过添加所有权重的绝对值之和(L1)来惩罚模型的复杂度。
Lasso回归的目标是最小化以下损失函数:
其中:
特点:
- 拉索回归可以将一些权重压缩到零,从而实现特征选择。这意味着模型最终可能只包含一部分特征。
- 适用于特征数量远大于样本数量的情况,或者当特征间存在相关性时,可以从中选择最相关的特征。
- 拉索回归产生的模型可能更简单,因为它会去除一些不重要的特征。
10.2 API
sklearn.linear_model.Lasso()
参数:
-
alpha (float, default=1.0):
- 控制正则化强度;必须是非负浮点数。较大的 alpha 增加了正则化强度。
-
fit_intercept (bool, default=True):
- 是否计算此模型的截距。如果设置为 False,则不会使用截距(即数据应该已经被居中)。
-
precompute (bool or array-like, default=False):
- 如果为 True,则使用预计算的 Gram 矩阵来加速计算。如果为数组,则使用提供的 Gram 矩阵。
-
copy_X (bool, default=True):
- 如果为 True,则复制数据 X,否则可能对其进行修改。
-
max_iter (int, default=1000):
- 最大迭代次数。
-
tol (float, default=1e-4):
- 精度阈值。如果更新后的系数向量减去之前的系数向量的无穷范数除以 1 加上更新后的系数向量的无穷范数小于 tol,则认为收敛。
-
warm_start (bool, default=False):
- 当设置为 True 时,再次调用 fit 方法会重新使用之前调用 fit 方法的结果作为初始估计值,而不是清零它们。
-
positive (bool, default=False):
- 当设置为 True 时,强制系数为非负。
-
random_state (int, RandomState instance, default=None):
- 随机数生成器的状态。用于随机初始化坐标下降算法中的随机选择。
-
selection ({'cyclic', 'random'}, default='cyclic'):
- 如果设置为 'random',则随机选择坐标进行更新。如果设置为 'cyclic',则按照循环顺序选择坐标。
属性:
-
coef_
- 系数向量或者矩阵,代表了每个特征的权重。
-
intercept_
- 截距项(如果 fit_intercept=True)。
-
n_iter_
- 实际使用的迭代次数。
-
n_features_in_ (int):
- 训练样本中特征的数量。
10.3 示例
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import numpy as np
# 加载波士顿房价数据集
data = fetch_california_housing(data_home="./src")
X, y = data.data, data.target
# 划分训练集和测试集
X_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建Lasso回归模型
lasso = Lasso(alpha=0.1) # alpha是正则化参数
# 训练模型
lasso.fit(X_train, y_train)
# 得出模型
print("权重系数为:\n", lasso.coef_) #权重系数与特征数一定是同样的个数。
print("偏置为:\n", lasso.intercept_)
#模型评估
y_predict = lasso.predict(x_test)
print("预测的数据集:\n", y_predict)
error = mean_squared_error(y_test, y_predict)
print("均方误差为:\n", error)