前言
提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。
文章目录
分类与回归算法
机器学习中的分类与回归算法是两种主要的监督学习任务,它们分别用于解决不同类型的问题。以下是这两种算法的总结:
分类算法:
分类算法用于将数据分成不同的类别,适用于输出为离散标签的问题。常见的分类算法包括:
- 逻辑回归:使用逻辑函数来估计概率,用于二分类问题,也可以扩展到多分类问题。
- 支持向量机(SVM):通过找到最优的决策边界来最大化样本的分类准确率,适用于高维数据。
- 决策树:通过树结构来进行决策,每个节点代表一个特征的选择,叶子节点代表分类结果。
- 随机森林:由多个决策树组成的集成学习方法,通过投票来决定最终分类结果。
- 梯度提升决策树(GBDT):通过构建和结合多个弱学习器来形成强学习器,适用于分类和回归问题。
- 朴素贝叶斯:基于贝叶斯定理,假设特征之间相互独立,适用于文本分类等场景。
- K近邻(KNN):根据样本之间的距离进行分类,适用于小规模数据集。
- 神经网络:通过多层感知机学习数据的复杂模式,适用于图像、语音等复杂分类问题。
回归算法:
回归算法用于预测连续数值输出,适用于输出为连续变量的问题。常见的回归算法包括:
- 线性回归:通过拟合一条直线来预测目标变量的值,是最简单的回归方法。
- 岭回归:线性回归的扩展,通过引入L2正则化项来防止过拟合。
- Lasso回归:线性回归的另一种扩展,通过引入L1正则化项来进行特征选择。
- 弹性网回归:结合了岭回归和Lasso回归,同时引入L1和L2正则化项。
- 决策树回归:使用决策树结构来进行回归预测,适用于非线性关系。
- 随机森林回归:由多个决策树组成的集成学习方法,通过平均来决定最终回归结果。
- 梯度提升决策树回归(GBDT回归):通过构建和结合多个弱学习器来形成强学习器,适用于回归问题。
- 支持向量回归(SVR):支持向量机在回归问题上的应用,通过找到最优的决策边界来最大化样本的回归准确率。
- 神经网络回归:通过多层感知机学习数据的复杂模式,适用于复杂的回归问题。
分类与回归算法的比较:
- 输出类型:分类算法输出离散标签,回归算法输出连续数值。
- 评估指标:分类算法常用准确率、召回率、F1分数等指标,回归算法常用均方误差(MSE)、均方根误差(RMSE)等指标。
- 问题类型:分类算法适用于类别预测问题,如垃圾邮件检测;回归算法适用于数值预测问题,如房价预测。 在实际应用中,选择分类还是回归算法取决于问题的性质和需求。有时,可以将回归问题转化为分类问题,或者将分类问题转化为回归问题,具体取决于问题的特点和目标。
梯度提升决策树
数学原理
以下是分类算法梯度提升决策树的原理及其数学公式的详细介绍:
-
初始化模型:
- 用一个常数模型进行初始化,通常是最小化损失函数的值。例如,对于平方损失,这通常是目标变量的均值。
F 0 ( x ) = arg min c ∑ i = 1 n L ( y i , c ) F_0(x) = \arg\min_{c} \sum_{i=1}^{n} L(y_i, c) F0(x)=argcmini=1∑nL(yi,c)
这里, F 0 ( x ) = c F_0(x) = c F0(x)=c,其中 c c c 是使损失最小的常数值。
- 用一个常数模型进行初始化,通常是最小化损失函数的值。例如,对于平方损失,这通常是目标变量的均值。
-
迭代过程:
- 对于每次迭代
m
=
1
m = 1
m=1 到
M
M
M:
- 计算残差:损失函数
L
L
L 关于
F
m
−
1
(
x
)
F_{m-1}(x)
Fm−1(x) 的负梯度给出了最陡峭的下降方向。
r i m = − ∂ L ( y i , F m − 1 ( x i ) ) ∂ F m − 1 ( x i ) r_{im} = -\frac{\partial L(y_i, F_{m-1}(x_i))}{\partial F_{m-1}(x_i)} rim=−∂Fm−1(xi)∂L(yi,Fm−1(xi))
这里, r i m r_{im} rim 表示第 i i i 个样本在第 m m m 次迭代时的残差。 - 训练决策树:训练一个新的树
h
m
(
x
)
h_m(x)
hm(x) 来拟合这些残差。
h m ( x ) = arg min h ∑ i = 1 n ( r i m − h ( x i ) ) 2 h_m(x) = \arg\min_{h} \sum_{i=1}^{n} (r_{im} - h(x_i))^2 hm(x)=arghmini=1∑n(rim−h(xi))2
这意味着我们正在寻找一个树 h h h,使其预测值 h ( x i ) h(x_i) h(xi) 尽可能接近残差 r i m r_{im} rim。 - 确定最优步长:通过一个线性搜索来确定一个最优步长
γ
m
\gamma_m
γm,以最小化损失函数。
γ m = arg min γ ∑ i = 1 n L ( y i , F m − 1 ( x i ) + γ h m ( x i ) ) \gamma_m = \arg\min_{\gamma} \sum_{i=1}^{n} L\left(y_i, F_{m-1}(x_i) + \gamma h_m(x_i)\right) γm=argγmini=1∑nL(yi,Fm−1(xi)+γhm(xi))
这个步骤确保我们朝损失函数梯度的反方向移动,同时控制步长以避免过拟合。 - 更新模型:
F m ( x ) = F m − 1 ( x ) + γ m h m ( x ) F_m(x) = F_{m-1}(x) + \gamma_m h_m(x) Fm(x)=Fm−1(x)+γmhm(x)
这个迭代更新逐步改进模型,使其更准确地拟合数据。
- 计算残差:损失函数
L
L
L 关于
F
m
−
1
(
x
)
F_{m-1}(x)
Fm−1(x) 的负梯度给出了最陡峭的下降方向。
- 对于每次迭代
m
=
1
m = 1
m=1 到
M
M
M:
-
最终模型:
- 在
M
M
M 次迭代后,组合所有树来形成最终的预测模型。
F M ( x ) = F 0 ( x ) + ∑ m = 1 M γ m h m ( x ) F_M(x) =F_0(x)+ \sum_{m=1}^{M} \gamma_m h_m(x) FM(x)=F0(x)+m=1∑Mγmhm(x)
这个最终模型是所有单个决策树的加权组合,每个树都针对前一个模型的残差进行优化。
- 在
M
M
M 次迭代后,组合所有树来形成最终的预测模型。
具体损失函数:
- 平方损失(回归):
L ( y , F ( x ) ) = ( y − F ( x ) ) 2 L(y, F(x)) = (y - F(x))^2 L(y,F(x))=(y−F(x))2
这里的负梯度是:
r i m = y i − F m − 1 ( x i ) r_{im} = y_i - F_{m-1}(x_i) rim=yi−Fm−1(xi) - 对数损失(二元分类):
L ( y , F ( x ) ) = log ( 1 + e − y F ( x ) ) L(y, F(x)) = \log(1 + e^{-y F(x)}) L(y,F(x))=log(1+e−yF(x))
这里的负梯度是:
r i m = − y i 1 + e y i F m − 1 ( x i ) r_{im} = \frac{-y_i}{1 + e^{y_i F_{m-1}(x_i)}} rim=1+eyiFm−1(xi)−yi
通过这种方式,GBDT 通过逐步添加针对残差的树来最小化损失函数,构建了一个强大的分类或回归模型。
总结:
GBDT通过迭代优化模型,最小化损失函数
L
(
y
,
F
(
x
)
)
。
初始化
F
0
(
x
)
为最小化
∑
i
=
1
n
L
(
y
i
,
c
)
的常数值
c
。
对于每次迭代
m
=
1
到
M
:
1.
计算残差
r
i
m
=
−
∂
L
(
y
i
,
F
m
−
1
(
x
i
)
)
∂
F
m
−
1
(
x
i
)
。
2.
训练一个决策树
h
m
(
x
)
来拟合
r
i
m
,最小化
∑
i
=
1
n
(
r
i
m
−
h
(
x
i
)
)
2
。
3.
确定最优步长
γ
m
=
arg
min
γ
∑
i
=
1
n
L
(
y
i
,
F
m
−
1
(
x
i
)
+
γ
h
m
(
x
i
)
)
。
4.
更新模型
F
m
(
x
)
=
F
m
−
1
(
x
)
+
γ
m
h
m
(
x
)
。
经过
M
次迭代后,最终模型为
F
M
(
x
)
=
F
0
(
x
)
+
∑
m
=
1
M
γ
m
h
m
(
x
)
。
\mathbf{ \begin{aligned} &\text{GBDT通过迭代优化模型,最小化损失函数 } L(y, F(x)) \text{。} \\ &\text{初始化 } F_0(x) \text{ 为最小化 } \sum_{i=1}^{n} L(y_i, c) \text{ 的常数值 } c \text{。} \\ &\text{对于每次迭代 } m = 1 \text{ 到 } M\text{:} \\ &\quad 1.\ \text{计算残差 } r_{im} = -\frac{\partial L(y_i, F_{m-1}(x_i))}{\partial F_{m-1}(x_i)} \text{。} \\ &\quad 2.\ \text{训练一个决策树 } h_m(x) \text{ 来拟合 } r_{im} \text{,最小化 } \sum_{i=1}^{n} (r_{im} - h(x_i))^2 \text{。} \\ &\quad 3.\ \text{确定最优步长 } \gamma_m = \arg\min_{\gamma} \sum_{i=1}^{n} L\left(y_i, F_{m-1}(x_i) + \gamma h_m(x_i)\right) \text{。} \\ &\quad 4.\ \text{更新模型 } F_m(x) = F_{m-1}(x) + \gamma_m h_m(x) \text{。} \\ &\text{经过 } M \text{ 次迭代后,最终模型为 } F_M(x) =F_0(x)+ \sum_{m=1}^{M} \gamma_m h_m(x) \text{。} \end{aligned} }
GBDT通过迭代优化模型,最小化损失函数 L(y,F(x))。初始化 F0(x) 为最小化 i=1∑nL(yi,c) 的常数值 c。对于每次迭代 m=1 到 M:1. 计算残差 rim=−∂Fm−1(xi)∂L(yi,Fm−1(xi))。2. 训练一个决策树 hm(x) 来拟合 rim,最小化 i=1∑n(rim−h(xi))2。3. 确定最优步长 γm=argγmini=1∑nL(yi,Fm−1(xi)+γhm(xi))。4. 更新模型 Fm(x)=Fm−1(x)+γmhm(x)。经过 M 次迭代后,最终模型为 FM(x)=F0(x)+m=1∑Mγmhm(x)。
手动实现
import numpy as np
from sklearn.tree import DecisionTreeRegressor
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
class GBDTClassifier:
def __init__(self, n_estimators=100, learning_rate=0.1, max_depth=3):
self.n_estimators = n_estimators
self.learning_rate = learning_rate
self.max_depth = max_depth
self.trees = []
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def fit(self, X, y):
# 初始化预测值为 0
f0 = np.zeros(len(y))
self.f0 = f0
for _ in range(self.n_estimators):
# 计算负梯度(残差)
y_pred = self.sigmoid(f0)
residuals = y - y_pred
# 训练一棵决策树来拟合残差
tree = DecisionTreeRegressor(max_depth=self.max_depth)
tree.fit(X, residuals)
# 更新预测值
f0 += self.learning_rate * tree.predict(X)
# 保存决策树
self.trees.append(tree)
def predict_proba(self, X):
# 初始预测值
f = np.zeros(len(X)) + self.f0[0]
for tree in self.trees:
f += self.learning_rate * tree.predict(X)
return self.sigmoid(f)
def predict(self, X):
y_pred_proba = self.predict_proba(X)
return (y_pred_proba > 0.5).astype(int)
# 示例
if __name__ == "__main__":
# 生成一个二分类数据集
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=0, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建并训练 GBDT 分类器
gbdt = GBDTClassifier(n_estimators=100, learning_rate=0.1, max_depth=3)
gbdt.fit(X_train, y_train)
# 进行预测
y_pred = gbdt.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")
运行结果:
python函数库实现
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score
# 创建一个二分类数据集
X, y = make_classification(n_samples=1000, n_features=20, n_informative=2, n_redundant=10, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 初始化GBDT分类器
gbdt = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)
# 训练模型
gbdt.fit(X_train, y_train)
# 预测测试集
y_pred = gbdt.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy}")
# 输出预测概率
print("Predicted probabilities:", gbdt.predict_proba(X_test)[:5]) # 只展示前5个样本的概率
运行结果:
GBDT实现多元分类
1. One-vs-All(OvA)策略
在 One-vs-All 策略中,对于每个类别,训练一个二分类模型,将该类别与其他所有类别区分开来。具体步骤如下:
-
数据预处理:
- 对输入数据进行标准化处理,确保数据在相同的尺度上。
-
模型训练:
- 对于每个类别 k k k,训练一个二分类模型,将类别 k k k 标记为正类,其他类别标记为负类。
- 使用 GBDT 训练每个二分类模型。
-
预测:
- 对新的输入数据,计算每个二分类模型的预测概率。
- 选择概率最高的类别作为最终预测结果。
2. Softmax 多分类策略
在 Softmax 多分类策略中,直接将 GBDT 扩展为多分类模型,通过 Softmax 函数计算每个类别的概率。具体步骤如下:
-
数据预处理:
- 对输入数据进行标准化处理,确保数据在相同的尺度上。
-
模型训练:
- 使用 GBDT 训练一个多分类模型,损失函数采用 Softmax 损失(交叉熵损失)。
- 每次迭代中,计算每个类别的残差,并训练一个决策树来拟合这些残差。
-
预测:
- 对新的输入数据,计算每个类别的预测值。
- 使用 Softmax 函数将预测值转换为概率,选择概率最高的类别作为最终预测结果。
python函数库实现
以下是一个基于 sklearn
的 GBDT 多分类实现示例,使用 One-vs-All
策略:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.preprocessing import LabelBinarizer
from sklearn.metrics import accuracy_score
# 加载数据集
data = load_iris()
X = data.data
y = data.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 初始化 GBDT 分类器
gbdt = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3)
# 训练模型
gbdt.fit(X_train, y_train)
# 预测测试集
y_pred = gbdt.predict(X_test)
# 评估模型
print("Accuracy:", accuracy_score(y_test, y_pred))
运行结果: