未验证 提交 3731741f 编写于 作者: 飞龙 提交者: GitHub

Merge pull request #363 from qinhanmin2014/1.4

1.4 支持向量机 (0.21.3)
......@@ -6,6 +6,7 @@
        [@子浪](https://github.com/apachecn/scikit-learn-doc-zh)
        [@小瑶](https://github.com/apachecn/scikit-learn-doc-zh)
[@Loopy](https://github.com/loopyme)
[@qinhanmin2014](https://github.com/qinhanmin2014)
翻译者:
        [@Damon](https://github.com/apachecn/scikit-learn-doc-zh)
        [@Leon晋](https://github.com/apachecn/scikit-learn-doc-zh)
......@@ -25,7 +26,7 @@
* 支持向量机不直接提供概率估计,这些都是使用昂贵的五次交叉验算计算的. (详情见 [得分和概率](#1412-得分和概率)).
在 scikit-learn 中,支持向量机提供 dense(`numpy.ndarray` ,可以通过 `numpy.asarray` 进行转换) 和 sparse (任何 `scipy.sparse`) 样例向量作为输出.然而,要使用支持向量机来对 sparse 数据作预测,它必须已经拟合这样的数据.使用 C 代码`numpy.ndarray` (dense) 或者带有 `dtype=float64``scipy.sparse.csr_matrix` (sparse) 来优化性能.
在 scikit-learn 中,支持向量机提供 dense(`numpy.ndarray` ,可以通过 `numpy.asarray` 进行转换) 和 sparse (任何 `scipy.sparse`) 样例向量作为输出.然而,要使用支持向量机来对 sparse 数据作预测,它必须已经拟合这样的数据.使用行优先存储(C-order)`numpy.ndarray` (dense) 或者带有 `dtype=float64``scipy.sparse.csr_matrix` (sparse) 来优化性能.
## 1.4.1. 分类
......@@ -44,7 +45,7 @@
>>> clf = svm.SVC()
>>> clf.fit(X, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',
decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
......@@ -65,7 +66,7 @@ SVMs 决策函数取决于训练集的一些子集, 称作支持向量. 这些
>>> clf.support_vectors_
array([[ 0., 0.],
[ 1., 1.]])
>>> # 获得支持向量的索引get indices of support vectors
>>> # 获得支持向量的索引
>>> clf.support_
array([0, 1]...)
>>> # 为每一个类别获得支持向量的数量
......@@ -76,7 +77,7 @@ array([1, 1]...)
### 1.4.1.1. 多元分类
[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC) 为多元分类实现了 “one-against-one” 的方法 (Knerr et al., 1990) 如果 `n_class` 是类别的数量, 那么 `n_class * (n_class - 1) / 2` 分类器被重构, 而且每一个从两个类别中训练数据. 为了给其他分类器提供一致的交互, `decision_function_shape` 选项允许聚合 “one-against-one” 分类器的结果成 `(n_samples, n_classes)` 的大小到决策函数:
[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC) 为多元分类实现了 “one-against-one” 的方法 (Knerr et al., 1990) 如果 `n_class` 是类别的数量, 那么 `n_class * (n_class - 1) / 2` 分类器被重构, 而且每一个从两个类别中训练数据. 为了提供与其他分类器一致的接口, `decision_function_shape` 选项允许聚合 “one-against-one” 分类器的结果成 `(n_samples, n_classes)` 的大小到决策函数:
```py
>>> X = [[0], [1], [2], [3]]
......@@ -84,7 +85,7 @@ array([1, 1]...)
>>> clf = svm.SVC(decision_function_shape='ovo')
>>> clf.fit(X, Y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovo', degree=3, gamma='auto', kernel='rbf',
decision_function_shape='ovo', degree=3, gamma='scale', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
>>> dec = clf.decision_function([[1]])
......@@ -184,7 +185,7 @@ LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
>>> y = [0.5, 2.5]
>>> clf = svm.SVR()
>>> clf.fit(X, y)
SVR(C=1.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.1, gamma='auto',
SVR(C=1.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.1, gamma='scale',
kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)
>>> clf.predict([[1, 1]])
array([ 1.5])
......@@ -209,22 +210,24 @@ array([ 1.5])
## 1.4.5. 使用诀窍
* **避免数据复制**: 对于 [`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`SVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html#sklearn.svm.SVR)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC)[`NuSVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR), 如果数据是通过某些方法而不是用 C 有序的连续双精度,那它先会调用底层的 C 命令再复制。 您可以通过检查它的 `flags` 属性,来确定给定的 numpy 数组是不是 C 连续的。
* **避免数据复制**: 对于 [`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`SVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html#sklearn.svm.SVR)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC)[`NuSVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR), 如果数据是通过某些方法而不是用行优先存储(C-order)的双精度,那它会在调用底层的 C 命令前先被复制。 您可以通过检查它的 `flags` 属性,来确定给定的 numpy 数组是不是行优先存储(C-order)的。
对于 [`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC) (和 [`LogisticRegression`](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression "sklearn.linear_model.LogisticRegression")) 的任何输入,都会以 numpy 数组形式,被复制和转换为 用 liblinear 内部稀疏数据去表达(双精度浮点型 float 和非零部分的 int32 索引)。 如果您想要一个适合大规模的线性分类器,又不打算复制一个密集的 C-contiguous 双精度 numpy 数组作为输入, 那我们建议您去使用 [`SGDClassifier`](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html#sklearn.linear_model.SGDClassifier "sklearn.linear_model.SGDClassifier") 类作为替代。目标函数可以配置为和 [`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC) 模型差不多相同的。
对于 [`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC) (和 [`LogisticRegression`](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression "sklearn.linear_model.LogisticRegression")) 的任何输入,都会以 numpy 数组形式,被复制和转换为 用 liblinear 内部稀疏数据去表达(双精度浮点型 float 和非零部分的 int32 索引)。 如果您想要一个适合大规模的线性分类器,又不打算复制一个密集的行优先存储(C-order)双精度 numpy 数组作为输入, 那我们建议您去使用 [`SGDClassifier`](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html#sklearn.linear_model.SGDClassifier "sklearn.linear_model.SGDClassifier") 类作为替代。目标函数可以配置为和 [`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC) 模型差不多相同的。
* **内核的缓存大小**: 在大规模问题上,对于 [`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC), [`SVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html#sklearn.svm.SVR), `nuSVC`[`NuSVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR), 内核缓存的大小会特别影响到运行时间。如果您有足够可用的 RAM,不妨把它的 `缓存大小` 设得比默认的 200(MB) 要高,例如为 500(MB) 或者 1000(MB)。
* **惩罚系数C的设置**:在合理的情况下, `C` 的默认选择为 `1` 。如果您有很多混杂的观察数据, 您应该要去调小它。 `C` 越小,就能更好地去正规化估计。
* 支持向量机算法本身不是用来扩大不变性,所以 **我们强烈建议您去扩大数据量**. 举个例子,对于输入向量 X, 规整它的每个数值范围为 [0, 1] 或 [-1, +1] ,或者标准化它的为均值为0方差为1的数据分布。请注意, 相同的缩放标准必须要应用到所有的测试向量,从而获得有意义的结果。 请参考章节 [预处理数据](preprocessing.html#preprocessing) ,那里会提供到更多关于缩放和规整。
* **惩罚系数C的设置**:在合理的情况下, `C` 的默认选择为 `1` 。如果您有很多混杂的观察数据, 您应该要去调小它。 `C` 越小,就能更好地去正规化估计。
当C值较大时,[`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC)和[`LinearSVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVR.html#sklearn.svm.LinearSVR)对C值较不敏感,即当C值大于特定阈值后,模型效果将会停止提升。同时,较大的C值将会导致较长的训练时间,Fan et al.(2008)的论文显示,训练时间的差距有时会达到10倍。
* 支持向量机算法本身不能够很好地支持非标准化的数据,所以 **我们强烈建议您将数据标准化**。 举个例子,对于输入向量 X, 规整它的每个数值范围为 [0, 1] 或 [-1, +1] ,或者标准化它的为均值为0方差为1的数据分布。请注意, 相同的缩放标准必须要应用到所有的测试向量,从而获得有意义的结果。 请参考章节 [预处理数据](preprocessing.html#preprocessing) ,那里会提供到更多关于缩放和规整。
*[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC)/[`OneClassSVM`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM)/[`NuSVR`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVR.html#sklearn.svm.NuSVR) 内的参数 `nu` , 近似是训练误差和支持向量的比值。
*[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC), ,如果分类器的数据不均衡(就是说,很多正例很少负例),设置 `class_weight='balanced'` 与/或尝试不同的惩罚系数 `C`
* 在拟合模型时,底层 [`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC) 操作使用了随机数生成器去选择特征。 所以不要感到意外,对于相同的数据输入,也会略有不同的输出结果。如果这个发生了, 尝试用更小的 tol 参数。
* **底层实现的随机性**:[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC)的底层实现仅使用随机数生成器来打乱数据顺序进行概率估计(当概率设置为True时)。这种随机性可以用`random_state`参数来控制。如果将概率设为False,这些估计器就不是随机的,random_state对结果没有影响。底层的[`OneClassSVM`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM)实现类似于[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC)的实现。由于[`OneClassSVM`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM)没有提供概率估计,所以它不是随机的。
*[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC), ,如果分类器的数据不均衡(例如,很多正例很少负例),设置 `class_weight='balanced'` 与/或尝试不同的惩罚系数 `C`
* **底层实现的随机性**:[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC)的底层实现仅使用随机数生成器来打乱数据顺序进行概率估计(当`probability`被设置为True时)。这种随机性可以用`random_state`参数来控制。如果将`probability`设为False,这些估计器就不是随机的,random_state对结果没有影响。底层的[`OneClassSVM`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM)实现类似于[`SVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC)[`NuSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.NuSVC.html#sklearn.svm.NuSVC)的实现。由于[`OneClassSVM`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.OneClassSVM.html#sklearn.svm.OneClassSVM)没有提供概率估计,所以它不是随机的。
底层的[`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC)实现使用随机数生成器来选择特征,当用双坐标下降(当`dual`被设置为True)。因此,对于相同的输入数据,结果略有不同并不罕见。如果发生这种情况,尝试使用较小的`tol`参数。这种随机性也可以通过`random_state`参数来控制。当`dual`设置为False时,[`LinearSVC`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC)的底层实现不是随机的,`random_state`对结果没有影响。
* 使用由 `LinearSVC(loss='l2', penalty='l1', dual=False)` 提供的 L1 惩罚去产生稀疏解,也就是说,特征权重的子集不同于零,这样做有助于决策函数。 随着增加 `C` 会产生一个更复杂的模型(要做更多的特征选择)。可以使用 [`l1_min_c`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.l1_min_c.html#sklearn.svm.l1_min_c "sklearn.svm.l1_min_c") 去计算 `C` 的数值,去产生一个”null” 模型(所有的权重等于零)。
* 使用由 `LinearSVC(loss='l2', penalty='l1', dual=False)` 提供的 L1 惩罚去产生稀疏解,也就是说,特征权重的子集不同于零,这样做有助于决策函数。 随着增加 `C` 会产生一个更复杂的模型(有更多的特征被选择)。可以使用 [`l1_min_c`](https://scikit-learn.org/stable/modules/generated/sklearn.svm.l1_min_c.html#sklearn.svm.l1_min_c "sklearn.svm.l1_min_c") 去计算 `C` 的数值,去产生一个”null” 模型(所有的权重等于零)。
> **参考资料**:
>* Fan, Rong-En, et al., “[LIBLINEAR: A library for large linear classification.](https://www.csie.ntu.edu.tw/~cjlin/papers/liblinear.pdf)”, Journal of machine learning research 9.Aug (2008): 1871-1874.
......@@ -256,7 +259,7 @@ array([ 1.5])
自定义内核的分类器和别的分类器一样,除了下面这几点:
* 空间 `support_vectors_` 现在是空的, 只有支持向量的索引被存储在 `support_`
* 空间 `support_vectors_` 现在是空的, 只有支持向量的索引被存储在 `support_`
* 请把 `fit()` 模型中的第一个参数的引用(不是副本)存储为将来的引用。 如果在 `fit()``predict()` 之间有数组发生改变,您将会碰到意料外的结果。
#### 1.4.6.1.1. 使用 python 函数作为内核
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册