决策树是机器学习中最直观的算法之一,它的工作原理就像我们日常做决策的过程。想象一下你要决定周末是否去爬山:首先看天气,如果是雨天就取消;如果是晴天,接着查看空气质量;如果PM2.5高于100就改室内运动...这种分步骤的判断逻辑就是决策树的本质。
我刚开始接触决策树时,最惊讶的是它处理数据的方式。算法会自动找到最佳分裂特征和分裂点,比如在用户分类任务中,它可能发现"年龄>30岁"是最有效的第一个判断条件。这种特性让决策树成为探索性数据分析的利器,我经常用它快速发现数据中的关键特征。
决策树的核心参数其实很好理解:
实际项目中,我常用sklearn快速构建一个基础决策树:
python复制from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=3)
clf.fit(X_train, y_train)
print(f"测试集准确率:{clf.score(X_test, y_test):.2f}")
决策树最大的优势是可解释性。你可以直接把训练好的模型可视化:
python复制from sklearn.tree import plot_tree
plt.figure(figsize=(12,8))
plot_tree(clf, feature_names=X.columns, class_names=True, filled=True)
plt.show()
但决策树有个致命弱点——高方差。我在电商用户流失预测项目中就吃过亏:同样的数据训练两次,得到的树结构差异很大。这是因为微小的数据变化会导致完全不同的分裂路径。这也引出了我们需要讨论的下一个主题:随机森林。
随机森林就像组建一个专家委员会,让多棵决策树共同投票做决定。我第一次用它完成销售预测时,效果比单棵决策树稳定了27%,这让我深刻理解了"三个臭皮匠顶个诸葛亮"的道理。
随机森林的创新点在于两个"随机":
这种设计带来了三大优势:
实际使用时,有几个关键参数需要关注:
python复制from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(
n_estimators=100, # 树的数量
max_features='sqrt', # 每次分裂考虑的特征数
oob_score=True # 使用未参与训练的样本评估模型
)
rf.fit(X_train, y_train)
print(f"OOB评分:{rf.oob_score_:.2f}")
在金融风控项目中,我发现随机森林的特征重要性输出特别有用:
python复制importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]
for f in range(X_train.shape[1]):
print(f"{X_train.columns[indices[f]]}: {importances[indices[f]]:.4f}")
不过随机森林也有局限。当处理超高维稀疏数据(如文本特征)时,它的表现可能不如线性模型。这时就需要考虑更复杂的神经网络了。
神经网络的发展就像一场进化史。最初的单层感知机(1958年)只能解决线性问题,直到加入了隐藏层和非线性激活函数,才真正展现出强大能力。我在图像分类任务中对比过,简单CNN的准确率就能比随机森林高出15-20%。
理解神经网络的关键是掌握三个核心概念:
一个简单的全连接网络可以用PyTorch这样实现:
python复制import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 128) # 输入层到隐藏层
self.fc2 = nn.Linear(128, 10) # 隐藏层到输出层
def forward(self, x):
x = torch.relu(self.fc1(x))
return self.fc2(x)
现代神经网络有几个重要发展:
在实际部署时,我发现批归一化(BatchNorm)和Dropout是两个神器:
python复制self.bn1 = nn.BatchNorm1d(128) # 加速训练收敛
self.dropout = nn.Dropout(0.5) # 防止过拟合
神经网络的调参是个技术活,我的经验是:
模型评估是确保机器学习系统可靠的关键环节。记得我第一次部署用户分群模型时,线上效果比测试时差了近30%,后来发现是评估指标选择不当——分类准确率在类别不平衡时极具误导性。
常见的评估指标矩阵包括:
对于不平衡分类问题,我常用分类报告和混淆矩阵:
python复制from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))
from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_estimator(model, X_test, y_test)
交叉验证是另一个重要技术。我习惯使用分层K折交叉验证:
python复制from sklearn.model_selection import cross_val_score
scores = cross_val_score(model, X, y, cv=5, scoring='f1_macro')
print(f"F1均值:{np.mean(scores):.2f} (±{np.std(scores):.2f})")
在实践中,我发现这些常见陷阱需要特别注意:
集成学习的核心思想是"多样性带来鲁棒性"。在Kaggle比赛中,我通过组合决策树、神经网络和线性模型,最终排名提升了200多位。
集成方法主要分为三类:
XGBoost是我最常用的Boosting实现:
python复制import xgboost as xgb
model = xgb.XGBClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
subsample=0.8
)
model.fit(X_train, y_train)
对于Stacking,这个实现框架很实用:
python复制from sklearn.ensemble import StackingClassifier
estimators = [
('rf', RandomForestClassifier()),
('svm', SVC(probability=True))
]
stack = StackingClassifier(
estimators=estimators,
final_estimator=LogisticRegression()
)
集成学习虽然强大,但也面临挑战:
在实际业务中,我通常会做这样的选择: