【人工智能机器学习基础篇】——深入详解监督学习之回归与分类:理解线性回归、逻辑回归、支持向量机(SVM)、决策树、随机森林、梯度提升机(GBM)等算法
深入详解监督学习之回归与分类
监督学习是机器学习的核心分支之一,主要分为回归(Regression)和分类(Classification)两大任务。回归任务旨在预测连续的数值输出,而分类任务则是将输入数据分配到离散的类别中。本文将深入探讨监督学习中的几种关键算法,包括线性回归、逻辑回归、支持向量机(SVM)、决策树、随机森林和梯度提升机(GBM),帮助读者全面理解这些常用算法的原理、应用场景及其优缺点。
目录
深入详解监督学习之回归与分类
1. 线性回归
1.1 概述
1.2 原理与公式
1.3 损失函数
1.4 优化方法
1.5 优缺点
1.6 示例代码
2. 逻辑回归
2.1 概述
2.2 原理与公式
2.3 损失函数
2.4 优化方法
2.5 优缺点
2.6 多分类逻辑回归
2.7 示例代码
3. 支持向量机(Support Vector Machine, SVM)
3.1 概述
3.2 原理与公式
3.2.1 线性SVM
3.2.2 软间隔SVM
3.2.3 核函数与非线性SVM
3.3 损失函数
3.4 优化方法
3.5 优缺点
3.6 应用场景
3.7 示例代码
4. 决策树(Decision Tree)
4.1 概述
4.2 原理与结构
4.3 划分标准
4.4 优缺点
4.5 剪枝技术
4.6 应用场景
4.7 示例代码
5. 随机森林(Random Forest)
5.1 概述
5.2 原理与构建
5.3 优缺点
5.4 参数调优
5.5 应用场景
5.6 示例代码
6. 梯度提升机(Gradient Boosting Machine, GBM)
6.1 概述
6.2 原理与构建
6.3 损失函数
6.4 优缺点
6.5 常用实现
6.6 应用场景
6.7 示例代码
7. 总结
参考资料
1. 线性回归
1.1 概述
线性回归是一种用于预测连续输出变量的基本回归算法。它假设目标变量与一个或多个特征之间存在线性关系。通过拟合一条最佳直线(或超平面)来最小化预测值与真实值之间的误差,从而实现对新样本的预测。
1.2 原理与公式
对于单变量线性回归,模型可以表示为:
\[
y = \beta_0 + \beta_1 x + \epsilon
\]
\( y \) 是目标变量。
\( x \) 是输入特征。
\( \beta_0 \) 是截距。
\( \beta_1 \) 是斜率(权重)。
\( \epsilon \) 是误差项。
对于多变量线性回归,模型扩展为:
\[
y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_n x_n + \epsilon
\]
1.3 损失函数
常用的损失函数是均方误差(Mean Squared Error, MSE):
\[
MSE = \frac{1}{m} \sum_{i=1}^{m} (y_i - \hat{y}_i)^2
\]
其中,\( m \) 是样本数量,\( y_i \) 是真实值,\( \hat{y}_i \) 是预测值。
1.4 优化方法
最常用的优化方法是普通最小二乘法(Ordinary Least Squares, OLS),通过解析解直接求解权重参数:
\[
\boldsymbol{\beta} = (\mathbf{X}^T \mathbf{X})^{-1} \mathbf{X}^T \mathbf{y}
\]
另外,**梯度下降法**也是常用的优化方法,特别适用于大规模数据集。
1.5 优缺点
优点:
- 简单易懂,计算效率高。
- 模型可解释性强,易于理解各特征的影响。
- 对于线性关系的数据表现良好。
缺点:
- 只能模拟线性关系,无法捕捉复杂的非线性模式。
- 对异常值敏感,可能导致模型偏差。
- 假设特征之间相互独立,实际中往往不满足。
1.6 示例代码
以下是使用Python的Scikit-learn库实现线性回归的示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
from sklearn.metrics import mean_squared_error
# 生成示例数据
X, y = make_regression(n_samples=100, n_features=1, noise=15, random_state=42)
# 拆分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建线性回归模型
model = LinearRegression()
# 训练模型
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 评估模型
mse = mean_squared_error(y_test, y_pred)
print(f'均方误差: {mse:.2f}')
# 可视化
plt.scatter(X_test, y_test, color='blue', label='真实值')
plt.plot(X_test, y_pred, color='red', linewidth=2, label='预测值')
plt.legend()
plt.xlabel('特征 X')
plt.ylabel('目标变量 Y')
plt.title('线性回归示例')
plt.show()
2. 逻辑回归
2.1 概述
逻辑回归(Logistic Regression)是一种用于二分类(或多分类)问题的监督学习算法。尽管名称中带有“回归”二字,其实质上是一种分类算法。它通过估计事件发生的概率来进行分类。
2.2 原理与公式
逻辑回归使用逻辑函数(Logistic Function),也称为Sigmoid函数,将线性组合的输入特征映射到[0,1]范围内,表示为事件发生的概率:
\[
P(y=1|x) = \sigma(z) = \frac{1}{1 + e^{-z}}
\]
其中,
\[
z = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_n x_n
\]
2.3 损失函数
逻辑回归通常使用对数损失函数(Log Loss),也称为交叉熵损失(Cross-Entropy Loss):
\[
L = -\frac{1}{m} \sum_{i=1}^{m} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)]
\]
2.4 优化方法
逻辑回归通常使用梯度下降法或**拟牛顿法(如L-BFGS)**进行参数优化,因为没有解析解。
2.5 优缺点
优点:
- 简单高效,适用于二分类问题。
- 输出概率,易于解释。
- 对线性可分的数据表现良好。
缺点:
- 只能捕捉线性关系,无法处理复杂的非线性模式。
- 对于类别不平衡的数据,性能可能下降。
- 容易受到异常值的影响。
2.6 多分类逻辑回归
通过一对多(One-vs-Rest)或多项式逻辑回归(Multinomial Logistic Regression),逻辑回归也可以扩展到多分类问题。
2.7 示例代码
以下是使用Python的Scikit-learn库实现逻辑回归的示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
from sklearn.metrics import classification_report, confusion_matrix
# 生成示例数据
X, y = make_classification(n_samples=100, n_features=2, n_redundant=0,
n_clusters_per_class=1, random_state=42)
# 可视化数据
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='bwr', alpha=0.7)
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title('逻辑回归示例数据')
plt.show()
# 拆分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建逻辑回归模型
model = LogisticRegression()
# 训练模型
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 评估模型
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
# 可视化决策边界
import matplotlib.colors as colors
h = .02 # 网格步长
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.3, cmap='bwr')
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='bwr', edgecolor='k')
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title('逻辑回归决策边界')
plt.show()
3. 支持向量机(Support Vector Machine, SVM)
3.1 概述
支持向量机(SVM)是一种强大的分类和回归算法,特别适用于高维数据。SVM通过寻找一个最优的超平面,将不同类别的数据尽可能分开,同时最大化边界(即支持向量)与最近样本点的距离。
3.2 原理与公式
3.2.1 线性SVM
对于线性可分的数据,SVM通过以下优化问题寻找最优超平面:
\[
\min_{\mathbf{w}, b} \frac{1}{2} \|\mathbf{w}\|^2
\]
\[
\text{subject to } y_i (\mathbf{w} \cdot \mathbf{x}_i + b) \geq 1, \quad \forall i
\]
其中,\(\mathbf{w}\) 是权重向量,\(b\) 是偏置,\(y_i\) 是标签(+1 或 -1),\(\mathbf{x}_i\) 是样本特征。
3.2.2 软间隔SVM
对于线性不可分的数据,引入松弛变量 \(\xi_i\),允许部分样本违背间隔要求:
\[
\min_{\mathbf{w}, b, \xi} \frac{1}{2} \|\mathbf{w}\|^2 + C \sum_{i=1}^{m} \xi_i
\]
\[
\text{subject to } y_i (\mathbf{w} \cdot \mathbf{x}_i + b) \geq 1 - \xi_i, \quad \xi_i \geq 0, \quad \forall i
\]
其中,\(C\) 是正则化参数,控制模型的复杂度和容忍误差的程度。
3.2.3 核函数与非线性SVM
通过引入核函数(如径向基函数RBF、多项式核等),SVM可以在高维甚至无限维的特征空间中进行线性分割,从而实现非线性分类。
\[
K(\mathbf{x}_i, \mathbf{x}_j) = \phi(\mathbf{x}_i) \cdot \phi(\mathbf{x}_j)
\]
3.3 损失函数
SVM的损失函数包含两个部分:间隔最大化和误分类损失(如铰链损失):
\[
\text{Loss} = \frac{1}{2} \|\mathbf{w}\|^2 + C \sum_{i=1}^{m} \max(0, 1 - y_i (\mathbf{w} \cdot \mathbf{x}_i + b))
\]
3.4 优化方法
常用的优化方法包括**序列最小优化算法(Sequential Minimal Optimization, SMO)**和各种凸优化算法,用于解决SVM的二次规划问题。
3.5 优缺点
优点:
- 在高维空间中表现优异,适用于复杂的分类任务。
- 有效防止过拟合,尤其在特征数量大于样本数时。
- 通过核函数扩展,实现非线性分类。
缺点:
- 对于大规模数据集,训练时间较长,计算资源消耗大。
- 核函数的选择和参数调优较为复杂,影响模型性能。
- 对噪声和异常值敏感,尤其在类别不平衡时效果下降。
3.6 应用场景
- 图像分类与识别
- 文本分类与情感分析
- 医学诊断
- 生物信息学
3.7 示例代码
以下是使用Python的Scikit-learn库实现SVM的示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
from sklearn.metrics import classification_report, confusion_matrix
# 选择鸢尾花数据集中的两个特征
iris = datasets.load_iris()
X = iris.data[:, :2] # 取前两个特征:萼片长度和宽度
y = iris.target
# 只选择前两个类别,便于可视化(Setosa 和 Versicolor)
X = X[y != 2]
y = y[y != 2]
y = np.where(y == 0, -1, 1) # 标签转换为-1和1
# 创建SVM模型
model = svm.SVC(kernel='linear', C=1.0)
# 训练模型
model.fit(X, y)
# 预测
y_pred = model.predict(X)
# 评估模型
print(confusion_matrix(y, y_pred))
print(classification_report(y, y_pred))
# 可视化决策边界
def plot_svm_decision_boundary(X, y, model):
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='bwr', alpha=0.7, edgecolor='k')
# 获取支持向量
sv = model.support_vectors_
plt.scatter(sv[:, 0], sv[:, 1], s=100, facecolors='none', edgecolors='g', label='Support Vectors')
# 绘制决策边界
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# 创建网格
xx = np.linspace(xlim[0], xlim[1], 200)
yy = np.linspace(ylim[0], ylim[1], 200)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = model.decision_function(xy).reshape(XX.shape)
# 绘制决策边界和间隔
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
plt.legend()
plt.xlabel('萼片长度')
plt.ylabel('萼片宽度')
plt.title('线性SVM决策边界')
plt.show()
plot_svm_decision_boundary(X, y, model)
4. 决策树(Decision Tree)
4.1 概述
决策树是一种基于树结构进行决策和预测的监督学习算法,适用于分类和回归任务。决策树通过一系列的决策规则,将数据集递归地划分为更小的子集,直到满足停止条件。
4.2 原理与结构
决策树由内部节点(Internal Nodes)、**分支(Branches)和叶节点(Leaf Nodes)**组成:
- 内部节点:表示一个特征的测试或决策。
- 分支:表示从一个节点到另一个节点的路径。
- 叶节点:表示最终的决策结果或预测值。
4.3 划分标准
在构建决策树时,需要选择最佳的特征和划分点,以最大化信息的增益或纯度。常用的划分标准包括:
-
信息增益(Information Gain):基于熵(Entropy)的度量,选择能够最大化信息增益的特征。
\[
IG(D, A) = Entropy(D) - \sum_{v \in \text{Values}(A)} \frac{|D^v|}{|D|} Entropy(D^v)
\] -
基尼指数(Gini Index):衡量数据集的纯度,选择使基尼指数最小化的特征。
\[
Gini(D) = 1 - \sum_{i=1}^{C} p_i^2
\] -
方差减少(Variance Reduction):用于回归任务,通过减少目标变量的方差来选择特征。
4.4 优缺点
优点:
- 直观易懂,易于可视化和解释。
- 可以处理数值型和类别型数据。
- 不需要大量的数据预处理,如特征缩放。
缺点:
- 容易过拟合,尤其是深层决策树。
- 对于类别不平衡的数据,可能偏向于多数类。
- 对于一些特征值较多的特征,决策偏向这些特征。
4.5 剪枝技术
为了防止决策树过拟合,可以采用剪枝技术,包括:
- 预剪枝(Pre-Pruning):在树构建过程中,设置停止条件,如最大深度、最小样本数等。
- 后剪枝(Post-Pruning):先构建完整的决策树,然后剪除不必要的分支。
4.6 应用场景
- 客户分类与细分
- 信用评分
- 疾病诊断
- 营销策略制定
4.7 示例代码
以下是使用Python的Scikit-learn库实现决策树分类的示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report, confusion_matrix
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
class_names = iris.target_names
# 拆分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建决策树模型
model = DecisionTreeClassifier(max_depth=3, random_state=42)
# 训练模型
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 评估模型
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
# 可视化决策树
plt.figure(figsize=(20,10))
plot_tree(model, feature_names=feature_names, class_names=class_names, filled=True)
plt.title('决策树示意图')
plt.show()
5. 随机森林(Random Forest)
5.1 概述
随机森林是一种集成学习方法,通过构建多个决策树,并结合它们的预测结果来提高模型的准确性和鲁棒性。随机森林通过引入随机性,如随机选择特征和样本,来减少单个决策树的过拟合。
5.2 原理与构建
随机森林的构建过程包括:
- Bootstrap采样:从原始数据集中有放回地随机抽取多个子样本集,每个子样本集用于训练一棵决策树。
- 特征随机选择:在每个节点分裂时,随机选择一部分特征进行评估,选择最佳特征进行分裂。
- 集成预测:
- 分类:采用投票机制,选择出现次数最多的类别作为最终预测结果。
- 回归:取所有决策树预测值的平均作为最终结果。
5.3 优缺点
优点:
- 高准确性:通过集成多个模型,减少单一模型的误差。
- 抗过拟合:随机性引入,提高模型的泛化能力。
- 特征重要性评估:可以评估各特征对预测的贡献。
- 处理高维数据:适用于特征数量较多的数据集。
缺点:
- 计算资源消耗大:训练多个决策树需要较多的计算资源和时间。
- 模型复杂性高:难以解释和可视化整个森林。
- 对噪声敏感:虽然抗过拟合,但对于噪声和异常值仍有一定敏感性。
5.4 参数调优
随机森林有多个超参数需要调优,包括:
- 树的数量(n_estimators):更多的树通常带来更好的性能,但增加计算成本。
- 最大深度(max_depth):限制树的深度,防止过拟合。
- 特征选择数(max_features):每次分裂时考虑的特征数量,控制随机性和多样性。
- 最小样本分裂数(min_samples_split):节点分裂所需的最小样本数。
5.5 应用场景
- 客户分类与细分
- 金融风险评估
- 医疗诊断
- 图像分类与处理
5.6 示例代码
以下是使用Python的Scikit-learn库实现随机森林分类的示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
class_names = iris.target_names
# 拆分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建随机森林模型
model = RandomForestClassifier(n_estimators=100, max_depth=3, random_state=42)
# 训练模型
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 评估模型
print(f'准确率: {accuracy_score(y_test, y_pred):.2f}')
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
# 特征重要性
importances = model.feature_importances_
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(10,6))
plt.title('特征重要性')
plt.bar(range(X.shape[1]), importances[indices], align='center')
plt.xticks(range(X.shape[1]), [feature_names[i] for i in indices], rotation=90)
plt.xlabel('特征')
plt.ylabel('重要性')
plt.show()
6. 梯度提升机(Gradient Boosting Machine, GBM)
6.1 概述
梯度提升机(Gradient Boosting Machine, GBM)是一种强大的集成学习方法,通过逐步构建多个弱学习器(通常是决策树),每个新的学习器都试图拟合前一学习器的残差(误差),从而逐步提高模型的准确性。
6.2 原理与构建
GBM的构建过程包括:
- 初始化模型:通常为一个简单的常数模型,如目标变量的均值。
- 迭代训练:
- 计算当前模型的残差(真实值与预测值的差)。
- 训练一个新的弱学习器来拟合这些残差。
- 更新模型,将新学习器的预测加入到整体模型中,通常使用学习率(learning rate)控制更新步长。
- 重复迭代:直到达到最大树数或误差收敛。
6.3 损失函数
GBM通过最小化指定的损失函数来优化模型。常见的损失函数包括:
- 均方误差(MSE):用于回归任务。
- 交叉熵损失(Log Loss):用于二分类任务。
- 指数损失(Exponential Loss):用于AdaBoost等算法。
6.4 优缺点
优点:
- 高准确性:通过逐步优化模型,通常具有很强的预测能力。
- 灵活性:可以优化多种损失函数,适用于不同类型的任务。
- 处理不平衡数据:在适当调整参数后,能够较好地处理类别不平衡的问题。
缺点:
- 计算资源消耗大:训练多个决策树需要较多的时间和计算资源。
- 易过拟合:尤其是在树的深度较大或学习率较高时。
- 参数调优复杂:需要谨慎设置学习率、树的深度、树的数量等超参数。
6.5 常用实现
- XGBoost:高效的实现,支持并行计算和正则化。
- LightGBM:适用于大规模数据集,采用基于梯度的单边采样和直方图算法。
- CatBoost:专注于处理类别特征,减少类别编码的错误。
6.6 应用场景
- 金融风险预测
- 销售预测
- 医疗诊断
- 推荐系统
6.7 示例代码
以下是使用Python的Scikit-learn库实现梯度提升机分类的示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
class_names = iris.target_names
# 拆分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建梯度提升机模型
model = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)
# 训练模型
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 评估模型
print(f'准确率: {accuracy_score(y_test, y_pred):.2f}')
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
# 特征重要性
importances = model.feature_importances_
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(10,6))
plt.title('特征重要性')
plt.bar(range(X.shape[1]), importances[indices], align='center')
plt.xticks(range(X.shape[1]), [feature_names[i] for i in indices], rotation=90)
plt.xlabel('特征')
plt.ylabel('重要性')
plt.show()
补充说明:
- 可以通过调整
n_estimators
(树的数量)、learning_rate
(学习率)、max_depth
(树的深度)等参数来优化模型性能。 - 支持早停(
staged_predict
)以防止过拟合。
7. 总结
监督学习中的回归与分类算法各有其独特的原理和应用场景。以下是对本文介绍的几种算法的简要总结:
- 线性回归:适用于简单的线性关系预测任务,模型简单易懂,但无法捕捉非线性模式。
- 逻辑回归:适用于二分类和多分类任务,输出概率,解释性强,但只能处理线性可分的数据。
- 支持向量机(SVM):适用于高维和复杂的分类任务,通过核函数实现非线性分类,但计算资源消耗大。
- 决策树:直观易懂,可处理多种数据类型,但容易过拟合,模型可解释性有限。
- 随机森林:通过集成多个决策树提高准确性和鲁棒性,抗过拟合能力较强,但模型复杂且难以解释。
- 梯度提升机(GBM):强大的集成学习方法,具有高准确性和灵活性,但训练时间长,参数调优复杂。
在实际应用中,选择合适的算法需根据具体任务的特点、数据的性质及计算资源进行权衡。常见的做法是尝试多种算法,通过交叉验证和性能评估指标选择最佳模型。此外,模型的调优和特征工程也是提升算法性能的重要步骤。
参考资料
- 《机器学习》(周志华 著)
- 《统计学习方法》(李航 著)
- Scikit-learn官方文档:scikit-learn: machine learning in Python — scikit-learn 0.16.1 documentation
- 《Python机器学习》(Sebastian Raschka 著)
- 《集体智慧编程》(Toby Segaran 著)
本文旨在为读者提供监督学习中回归与分类算法的深入理解。如需进一步学习,建议结合实际数据集进行实践,并参考相关书籍和课程以巩固知识。