机器学习实战笔记1——从线性回归到神经网络:三大经典模型的核心实验与调优
1. 线性回归:从房价预测到模型调优
记得我第一次用线性回归预测房价时,对着满屏的误差数字直挠头。当时用的就是Kaggle那个经典的房价数据集,现在想来真是新手必经之路。线性回归看似简单,但要把MAE(平均绝对误差)降到合理范围,得花不少功夫。
核心公式其实就一行 : y = wX + b 。但要让这个公式真正发挥作用,得先理解几个关键点:
-
特征工程 :我试过把房屋面积单独作为特征,MAE大概在3万左右。后来加入卧室数量、房龄、地段评分等特征,组合成多元线性回归,误差立刻降到2.1万。实测下来,这些特征组合最有效:
- 面积 + 卧室数量
- 面积 × 地段评分
- 房龄的倒数(新房的溢价更明显)
-
交叉验证 :十折交叉验证是我的标配。把数据分成10份,轮流用9份训练1份测试,最后拼起来评估。这样做的好处是能充分利用数据,还能看出模型是否稳定。有一次我发现某组特征的MAE波动很大,排查后发现是某个离群地段的数据在作怪。
-
评估指标 :新手容易只看R²分数,老手会更关注MAE和RMSE。RMSE对异常值更敏感,适合检查模型有没有严重错误。我通常会列个表格对比不同模型:
模型类型 MAE RMSE R² 一元线性回归 3.2万 4.1万 0.72 多元线性回归 2.1万 2.8万 0.86 对数线性回归 1.9万 2.6万 0.88
遇到特征量纲差异大的情况(比如面积是两位数而房价是七位数),一定要做标准化。我有次忘了这个步骤,梯度下降时参数直接飞了,损失值飙升到天文数字。后来用 sklearn 的 StandardScaler 处理后才收敛。
2. 逻辑回归:垃圾邮件分类实战
逻辑回归虽然名字带"回归",其实是分类神器。我在Dota2比赛预测和垃圾邮件分类中都用过它,最大的感受是: 特征决定上限,参数调优决定下限 。
核心差异在于sigmoid函数 :把线性输出压缩到(0,1)区间。但实际用起来有几个坑要避开:
-
评估指标陷阱 :准确率(accuracy)在样本不平衡时会骗人。比如垃圾邮件占比5%,全预测为正常邮件也有95%准确率。这时候要看精确率(precision)和召回率(recall):
- 精确率=预测为正的样本中实际为正的比例
- 召回率=实际为正的样本中被预测为正的比例
我通常会这样调参:
from sklearn.linear_model import LogisticRegression model = LogisticRegression(class_weight='balanced') # 自动处理样本不平衡 model.fit(X_train, y_train) -
特征变换 :直接扔原始文本效果很差。试过TF-IDF和词频统计后,发现组合特征更有效:
- 包含"免费"、"点击"等关键词的次数
- 发件人域名是否在白名单
- 邮件正文的标点符号比例(垃圾邮件常用大量感叹号)
-
正则化选择 :L1正则化能自动做特征选择,有次帮我从2000个特征中筛出30个关键特征。参数C越小正则化越强,一般从0.01到100之间网格搜索。
3. 决策树:剪枝的艺术
决策树最迷人的地方是可视化后能看到完整判断逻辑。但第一次用默认参数训练时,树深达到30层,简直是个"过拟合怪物"。后来学会剪枝才明白: 决策树不是越深越好 。
关键参数就两个 : max_depth (最大深度)和 min_samples_leaf (叶节点最小样本数)。我的调参经验:
-
学习曲线法 :观察不同深度下训练集和测试集的MAE变化。在房价预测任务中,深度超过15后测试集误差不再下降,这时就该停止。
-
预剪枝vs后剪枝 :
- 预剪枝:训练时提前停止分裂。速度快但可能欠拟合,适合大数据集
- 后剪枝:先完整训练再剪枝。效果更好但耗内存,适合小数据集
实测在Dota2预测中,后剪枝能让F1值提高3%左右。
-
分裂标准对比 :
- 信息增益:偏向选择取值多的特征
- 增益率:对信息增益做归一化
- 基尼系数:计算更快,效果通常与前两者相当
建议先用基尼系数,如果效果不好再试其他。
4. 神经网络:学习率的魔法
第一次用神经网络识别手写数字时,设了个learning_rate=0.1,结果损失值像过山车一样上蹿下跳。后来才知道, 学习率是神经网络的命门 。
梯度下降的三大要点 :
-
学习率选择 :用学习率扫描法找合理范围:
for lr in [0.001, 0.01, 0.1, 1]: model = MLPClassifier(hidden_layer_sizes=(64,), learning_rate_init=lr) model.fit(X_train, y_train) plot_loss_curve(model.loss_curve_) # 观察收敛情况小技巧:如果损失曲线像锯齿一样震荡,说明学习率太大;如果是平滑但下降慢,说明学习率太小。
-
批次大小 :batch_size=32是个不错的起点。但我在房价预测中发现,用全批量梯度下降反而更稳定,因为数据量本身不大。
-
隐藏层设计 :单隐藏层神经元的经验公式:
隐藏层神经元数 = (输入维度 + 输出维度) * 2/3比如MNIST输入是784维,输出是10类,可以设(784+10)*2/3 ≈ 530个神经元。
超参数组合的实战效果 :
| 学习率 | 批次大小 | 迭代次数 | 准确率 |
|---|---|---|---|
| 0.1 | 128 | 50 | 92.3% |
| 0.01 | 64 | 100 | 95.1% |
| 0.001 | 32 | 200 | 94.8% |
最后分享一个踩坑经验:神经网络对输入数据的尺度极其敏感。有次忘了对房价数据做归一化,导致梯度爆炸。现在我的代码开头必定会加上:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
更多推荐




所有评论(0)