Contents
  1. 1. 1. 要解决的问题
  2. 2. 2. 前情回顾
  3. 3. 3. 特征工程
    1. 3.1. 3.1 特征归一化
    2. 3.2. 3.2 最终数据集
  4. 4. 4. SVM
    1. 4.1. 4.1 核函数介绍
    2. 4.2. 4.2 SVM RBF 参数搜索
    3. 4.3. 4.3 常用核函数
    4. 4.4. 4.4 自定义核函数
  5. 5. 5. 总结
    1. 5.1. 5.1 SVM 准确率的思考
    2. 5.2. 5.2 提升 SVM 训练速度的心得
  6. 6. 参考文档

1. 要解决的问题

与「机器学习实战 — 决策树」的问题一样

2. 前情回顾

在上一次中,随机森林的效果最好,最终效果如下:
RF_finally_auc.jpg

3. 特征工程

特征工程与第二次作业一样,但增加了最后一步「特征归一化」,步骤概述如下:

  1. 特征选取
  2. 删除无用特征
  3. 空值处理
  4. 处理重要特征
  5. 特征标签化
  6. 特征归一化

3.1 特征归一化

使用 StandardScaler 和 MinMaxScaler 的差别不大,最终使用的是 StandardScaler。因为特征基本上都是符合正态分布的,而且 StandardScaler 对数据变动时引入新的极值点更友好。

1
2
3
# 使用 z-score 标准化特征
ss = preprocessing.StandardScaler()
X = ss.fit_transform(X)

特征归一化的好处有以下两点:

  1. 模型训练速度更快
    能够使参数优化时能以较快的速度收敛。
    归一化前后的 SVM(linear 核) 的耗时对比,数据集 (2783, 54),即 2783 条数据,54 个特征。归一化前后的耗时分别为:1083s,0.44s,可见归一化对计算速度的提升非常大。
  2. 模型的准确率提升
    将特征缩放到同一尺度的量级,能够使搜索的跳跃更加平滑,避免反复震荡的情况,提高准确率。可以参考下图形象化的解释:
    features_normalization_gradient_descent.jpg

对于不同数量的训练集,训练 SVM,LR,DT,RF 四个模型。随着数据集的数量增加,特征归一化后的模型,其准确率提升如下图所示:
features_normalization_analysis.jpg

通过这个图,也会发现特征归一化也不是能够提升所有模型的准确率,对于 DT 和 RF 就没有效果,这是因为决策树的分支只是计算信息熵,而不考虑整体特征的分布情况。

3.2 最终数据集

经过一系列处理后可用的数据集有 30w,但由于 SVM 运行地太慢了,从中选取 2w 数据来作为本次作业的数据集。

4. SVM

4.1 核函数介绍

常见的核函数有:

  1. linear:主要用于线性可分的情形。参数少,速度快,对于一般数据,分类效果已经很理想了。
  2. rbf:将样本映射到更高维的空间,目前应用最广的一个,对大小样本都有比较好的性能,而且参数较少。linear 是 rbf 的一个特例。
  3. poly:多项式核函数,将低维的输入空间映射到高纬的特征空间,参数多,当多项式的阶数比较高时,计算复杂度会非常大。
  4. sigmod:支持向量机实现的就是一种多层神经网络。

Andrew Ng 的建议:

  1. 如果Feature的数量很大,跟样本数量差不多,这时候选用LR或者是Linear Kernel的SVM
  2. 如果Feature的数量比较小,样本数量一般,不算大也不算小,选用SVM+Gaussian Kernel
  3. 如果Feature的数量比较小,而样本数量很多,需要手工添加一些feature变成第一种情况

本次作业的数据集特征少,数据大。结合上述建议,再加上取了少部分(1k~5k)的数据进行了初步对比,决定重点调优 rbf 的参数。

4.2 SVM RBF 参数搜索

训练集数据量: 2w。搜索最优参数,用时 12.3 小时,将 搜索过程的数据记录 绘制成下图所示,纵轴代表搜索得分,横轴代表 {C, gamma} 两个参数的取值。

SVM_GridSearch_result.jpg

C = 10, gamma = 0.1 时的效果最好。如上图中红圈所示,对于 C = 0.1, 100, 1000 时,都是gamma = 0.1 这个位置时效果最好。

4.3 常用核函数

在本次作业的数据集中,linear 核函数的运算速度相当慢,所以对于常用核函数,仅对比了 rbf,poly 和 sigmoid 三个核函数。针对 2w 条数据,运行结果如下:

SVM_normal_model_auc.jpg

其中,rbf 效果最好,AUC 有 0.82,但相比起之前 AUC 0.9 的 RF 来还是不理想。

4.4 自定义核函数

由于常用核函数的效果不够理想,所以尝试使用自定义的核函数,参考前人总结出的各种核函数,放入模型中进行尝试。核函数的公式见原代码,任取两个核函数的说明如下:

Rational quadratic kernel

1
2
3
4
5
6
7
8
9
10
"""
Rational quadratic kernel,
K(x, y) = 1 - ||x-y||^2/(||x-y||^2+c)
where:
c > 0
"""
def rational_quadratic(data_1, data_2):
_c = 1
dists_sq = euclidean_dist_matrix(data_1, data_2)
return 1. - (dists_sq / (dists_sq + _c))

Inverse multiquadratic kernel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"""
Inverse multiquadratic kernel,
K(x, y) = 1 / sqrt(||x-y||^2 + c^2)
where:
c > 0
as defined in:
"Interpolation of scattered data: Distance matrices and conditionally positive definite functions"
Charles Micchelli
Constructive Approximation
"""
def inverse_multiquadratic(data_1, data_2):
_c = 1 ** 2
dists_sq = euclidean_dist_matrix(data_1, data_2)
return 1. / np.sqrt(dists_sq + _c)

仍然是对于这 2w 条数据,将所有核函数放入 SVM 中训练,最终每个核函数的准确率和耗时对比表格如下:

SVM_model_compare.jpg

可以发现 rbf, inverse_multiquadratic 和 cauchy 这三个核函数的效果较好,其中 rbf 训练速度最快,inverse_multiquadratic 准确率最高。

5. 总结

5.1 SVM 准确率的思考

最终,使用 inverse_multiquadratic 核函数可以将 SVM 模型的 AUC Score 最高调至 0.822,相比于第二次作业中 Random Forest 模型的 AUC Score 结果 0.902 还有差距。可能是由于核函数选取的仍然不够合适,在映射后的空间中数据不是那么线性可分,降低了模型的泛化能力,导致准确率不如 RF。而对于核函数的选取,需要更多地理解特征,并列举出所有可能的核函数,再进行对比选择,在选取核函数这一点上,没有很好的捷径可走。

5.2 提升 SVM 训练速度的心得

  1. 特征标签化和归一化
  2. SVC 的 cache_size 设置到 7000 (M)
  3. 核函数是 SVM 的关键,先用少部分数据来选核函数,再用全量数据训练
  4. SVM 的 C 参数不要设置的太大

参考文档

1.4. Support Vector Machines — scikit-learn 0.20.1 documentation
RBF SVM parameters — scikit-learn 0.20.1 documentation
逻辑斯蒂回归VS决策树VS随机森林 - 简书
https://www.csie.ntu.edu.tw/~r95162/guide.pdf
https://github.com/gmum/pykernels

Contents
  1. 1. 1. 要解决的问题
  2. 2. 2. 前情回顾
  3. 3. 3. 特征工程
    1. 3.1. 3.1 特征归一化
    2. 3.2. 3.2 最终数据集
  4. 4. 4. SVM
    1. 4.1. 4.1 核函数介绍
    2. 4.2. 4.2 SVM RBF 参数搜索
    3. 4.3. 4.3 常用核函数
    4. 4.4. 4.4 自定义核函数
  5. 5. 5. 总结
    1. 5.1. 5.1 SVM 准确率的思考
    2. 5.2. 5.2 提升 SVM 训练速度的心得
  6. 6. 参考文档