前言
提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。
分类与回归算法
机器学习中的分类与回归算法是两种主要的监督学习任务,它们分别用于解决不同类型的问题。以下是这两种算法的总结:
分类算法:
分类算法用于将数据分成不同的类别,适用于输出为离散标签的问题。常见的分类算法包括:
- 逻辑回归:使用逻辑函数来估计概率,用于二分类问题,也可以扩展到多分类问题。
- 支持向量机(SVM):通过找到最优的决策边界来最大化样本的分类准确率,适用于高维数据。
- 决策树:通过树结构来进行决策,每个节点代表一个特征的选择,叶子节点代表分类结果。
- 随机森林:由多个决策树组成的集成学习方法,通过投票来决定最终分类结果。
- 梯度提升决策树(GBDT):通过构建和结合多个弱学习器来形成强学习器,适用于分类和回归问题。
- 朴素贝叶斯:基于贝叶斯定理,假设特征之间相互独立,适用于文本分类等场景。
- K近邻(KNN):根据样本之间的距离进行分类,适用于小规模数据集。
- 神经网络:通过多层感知机学习数据的复杂模式,适用于图像、语音等复杂分类问题。
回归算法:
回归算法用于预测连续数值输出,适用于输出为连续变量的问题。常见的回归算法包括:
- 线性回归:通过拟合一条直线来预测目标变量的值,是最简单的回归方法。
- 岭回归:线性回归的扩展,通过引入L2正则化项来防止过拟合。
- Lasso回归:线性回归的另一种扩展,通过引入L1正则化项来进行特征选择。
- 弹性网回归:结合了岭回归和Lasso回归,同时引入L1和L2正则化项。
- 决策树回归:使用决策树结构来进行回归预测,适用于非线性关系。
- 随机森林回归:由多个决策树组成的集成学习方法,通过平均来决定最终回归结果。
- 梯度提升决策树回归(GBDT回归):通过构建和结合多个弱学习器来形成强学习器,适用于回归问题。
- 支持向量回归(SVR):支持向量机在回归问题上的应用,通过找到最优的决策边界来最大化样本的回归准确率。
- 神经网络回归:通过多层感知机学习数据的复杂模式,适用于复杂的回归问题。
分类与回归算法的比较:
- 输出类型:分类算法输出离散标签,回归算法输出连续数值。
- 评估指标:分类算法常用准确率、召回率、F1分数等指标,回归算法常用均方误差(MSE)、均方根误差(RMSE)等指标。
- 问题类型:分类算法适用于类别预测问题,如垃圾邮件检测;回归算法适用于数值预测问题,如房价预测。 在实际应用中,选择分类还是回归算法取决于问题的性质和需求。有时,可以将回归问题转化为分类问题,或者将分类问题转化为回归问题,具体取决于问题的特点和目标。
Lasso回归
Lasso 回归(Least Absolute Shrinkage and Selection Operator Regression)是一种线性回归模型,通过引入 L1 正则化项(即 Lasso 惩罚项),对模型中的系数进行压缩,使某些系数缩减至零,从而实现特征选择和模型稀疏性。
线性回归具体可参见:python回归算法_线性回归
数学公式
-
普通最小二乘法(OLS):
- 目标是最小化残差平方和(RSS):
RSS = ∑ i = 1 n ( y i − x i T β ) 2 \text{RSS} = \sum_{i=1}^{n} (y_i - x_i^T \beta)^2 RSS=i=1∑n(yi−xiTβ)2
- 目标是最小化残差平方和(RSS):
-
Lasso 回归:
- 在 OLS 的基础上,添加一个 L1 正则化项:
min β ( ∑ i = 1 n ( y i − x i T β ) 2 + α ∑ j = 1 p ∣ β j ∣ ) \min_{\beta} \left( \sum_{i=1}^{n} (y_i - x_i^T \beta)^2 + \alpha \sum_{j=1}^{p} |\beta_j| \right) βmin(i=1∑n(yi−xiTβ)2+αj=1∑p∣βj∣) - 其中, α \alpha α 是正则化参数,用于控制惩罚项的权重。较大的 α \alpha α 会使更多的系数缩减至零,从而实现特征选择。
- 在 OLS 的基础上,添加一个 L1 正则化项:
-
梯度下降法
-
为了最小化目标函数,可以使用梯度下降法。梯度下降的更新规则如下:
β j ← β j − α step ⋅ ( − 2 ∑ i = 1 n x i j ( y i − x i T β ) + α reg ⋅ sign ( β j ) ) \beta_j \leftarrow \beta_j - \alpha_{\text{step}} \cdot \left( -2 \sum_{i=1}^{n} x_{ij} (y_i - x_i^T \beta) + \alpha_{\text{reg}} \cdot \text{sign}(\beta_j) \right) βj←βj−αstep⋅(−2i=1∑nxij(yi−xiTβ)+αreg⋅sign(βj))
这里, α step \alpha_{\text{step}} αstep 是学习率,用于控制梯度下降的步长; α reg \alpha_{\text{reg}} αreg 是正则化参数,用于控制 L1 正则化项的强度。 -
普通最小二乘项的梯度是:
∂ ∂ β j ∑ i = 1 n ( y i − x i T β ) 2 = − 2 ∑ i = 1 n x i j ( y i − x i T β ) \frac{\partial}{\partial \beta_j} \sum_{i=1}^{n} (y_i - x_i^T \beta)^2 = -2 \sum_{i=1}^{n} x_{ij} (y_i - x_i^T \beta) ∂βj∂i=1∑n(yi−xiTβ)2=−2i=1∑nxij(yi−xiTβ) -
正则化项的梯度稍微复杂一些,因为 L1 范数的导数在零点不连续。其导数形式是:
∂ ∂ β j α reg ∑ j = 1 p ∣ β j ∣ = α reg ⋅ sign ( β j ) \frac{\partial}{\partial \beta_j} \alpha_{\text{reg}} \sum_{j=1}^{p} |\beta_j| = \alpha_{\text{reg}} \cdot \text{sign}(\beta_j) ∂βj∂αregj=1∑p∣βj∣=αreg⋅sign(βj) -
综合以上两部分,我们得到 Lasso 回归的梯度更新规则:
β j ← β j − α step ⋅ ( − 2 ∑ i = 1 n x i j ( y i − x i T β ) + α reg ⋅ sign ( β j ) ) \beta_j \leftarrow \beta_j - \alpha_{\text{step}} \cdot \left( -2 \sum_{i=1}^{n} x_{ij} (y_i - x_i^T \beta) + \alpha_{\text{reg}} \cdot \text{sign}(\beta_j) \right) βj←βj−αstep⋅(−2i=1∑nxij(yi−xiTβ)+αreg⋅sign(βj))
这样,公式中的两个参数 α step \alpha_{\text{step}} αstep 和 α reg \alpha_{\text{reg}} αreg 的含义更加明确,避免了混淆。
算法流程
-
初始化参数:
- 设置学习率 α step \alpha_{\text{step}} αstep和正则化参数 α reg \alpha_{\text{reg}} αreg 。
- 初始化回归系数 β \beta β 为零或小的随机值。
-
迭代更新
- 计算预测值:
y ^ i = x i T β \hat{y}_i = x_i^T \beta y^i=xiTβ - 计算误差:
e i = y i − y ^ i e_i = y_i - \hat{y}_i ei=yi−y^i - 计算梯度:
∇ β j = − 2 ∑ i = 1 n x i j e i + α reg ⋅ sign ( β j ) \nabla \beta_j = -2 \sum_{i=1}^{n} x_{ij} e_i + \alpha_{\text{reg}} \cdot \text{sign}(\beta_j) ∇βj=−2i=1∑nxijei+αreg⋅sign(βj) - 更新参数:
β j ← β j − α step ⋅ ∇ β j \beta_j \leftarrow \beta_j - \alpha_{\text{step}} \cdot \nabla \beta_j βj←βj−αstep⋅∇βj - 重复上述步骤直到收敛(即参数变化很小或达到最大迭代次数)。
- 输出结果
- 最终的回归系数 β \beta β。
优点
-
特征选择:
- Lasso 回归通过将某些系数缩减至零,实现了特征选择,从而减少了模型的复杂性。
-
减少过拟合:
- 正则化项可以防止模型在训练数据上过拟合,从而提高泛化能力。
-
更简单的模型:
- 通过选择少量的重要特征,Lasso 回归能够生成更简单、可解释性更强的模型。
算法实现
手动实现
import numpy as np
import matplotlib.pyplot as plt
class LassoRegression:
def __init__(self, alpha=0.01, lambda_=1.0, num_iterations=1000):
self.alpha = alpha # 学习率
self.lambda_ = lambda_ # 正则化参数
self.num_iterations = num_iterations
self.theta = None
def fit(self, X, y):
m, n = X.shape
self.theta = np.zeros(n)
for _ in range(self.num_iterations):
predictions = X.dot(self.theta)
errors = predictions - y
# 计算梯度
gradient = (1/m) * (X.T.dot(errors)) + self.lambda_ * np.sign(self.theta)
# 更新参数
self.theta -= self.alpha * gradient
def predict(self, X):
return X.dot(self.theta)
# 可视化函数
def plot_results(X, y, model):
plt.scatter(X[:, 1], y, color='blue', label='Actual data')
# 生成预测值
x_range = np.linspace(X[:, 1].min(), X[:, 1].max(), 100)
X_range = np.c_[np.ones_like(x_range), x_range] # 添加常数项
y_pred = model.predict(X_range)
plt.plot(x_range, y_pred, color='red', label='Lasso Regression prediction', linewidth=2)
plt.title('Lasso')
plt.xlabel('X')
plt.ylabel('y')
plt.legend()
plt.show()
# 示例:使用 Lasso 回归
if __name__ == "__main__":
# 创建一个简单的数据集
X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
y = np.array([1, 1.5, 2, 2.5])
# 初始化 Lasso 回归模型
model = LassoRegression(alpha=0.1, lambda_=0.1, num_iterations=1000)
# 拟合模型
model.fit(X, y)
# 预测
predictions = model.predict(X)
print("Outcome prediction:", predictions)
print("Regression coefficients:", model.theta)
# 可视化结果
plot_results(X, y, model)
运行结果:
python函数库实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
# 生成示例数据
np.random.seed(0)
X = np.random.rand(100, 1) * 10 # 100个样本,1个特征
y = 2.5 * X.flatten() + np.random.randn(100) * 2 # 添加一些噪声
# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
# 初始化 Lasso 回归模型
lasso_model = Lasso(alpha=0.1) # 设置正则化参数 alpha
# 拟合模型
lasso_model.fit(X_train, y_train)
# 预测
y_pred = lasso_model.predict(X_test)
# 可视化结果
plt.scatter(X_test, y_test, color='blue', label='Actual data')
plt.plot(X_test, y_pred, color='red', label='Lasso Regression prediction', linewidth=2)
plt.title('Lasso')
plt.xlabel(' X')
plt.ylabel(' y')
plt.legend()
plt.show()
# 打印回归系数
print("回归系数:", lasso_model.coef_)
print("截距:", lasso_model.intercept_)
运行结果: