Scikit-learn SVC 总是在随机数据交叉验证上给出准确度 0

Scikit-learn SVC always giving accuracy 0 on random data cross validation

在下面的代码中,我创建了一个大小为 50 的随机样本集,每个样本集包含 20 个特征。然后我生成一个由一半真值和一半假值组成的随机目标向量。

所有值都存储在 Pandas 个对象中,因为这模拟了以这种方式提供数据的真实场景。

然后我在循环内执行手动留一法,每次选择一个索引,删除其各自的数据,使用默认 SVC 拟合其余数据,最后 运行 预测在遗漏的数据上。

import random
import numpy as np
import pandas as pd
from sklearn.svm import SVC

n_samp = 50
m_features = 20

X_val = np.random.rand(n_samp, m_features)
X = pd.DataFrame(X_val, index=range(n_samp))
# print X_val

y_val = [True] * (n_samp/2) + [False] * (n_samp/2)
random.shuffle(y_val)
y = pd.Series(y_val, index=range(n_samp))
# print y_val

seccess_count = 0
for idx in y.index:
    clf = SVC()  # Can be inside or outside loop. Result is the same.

    # Leave-one-out for the fitting phase
    loo_X = X.drop(idx)
    loo_y = y.drop(idx)
    clf.fit(loo_X.values, loo_y.values)

    # Make a prediction on the sample that was left out
    pred_X = X.loc[idx:idx]
    pred_result = clf.predict(pred_X.values)
    print y.loc[idx], pred_result[0]  # Actual value vs. predicted value - always opposite!
    is_success = y.loc[idx] == pred_result[0]
    seccess_count += 1 if is_success else 0

print '\nSeccess Count:', seccess_count  # Almost always 0!

现在这是奇怪的部分 - 我希望得到大约 50% 的准确度,因为这是随机数据,但我几乎总是准确地得到 0!我总是说 几乎,因为每运行大约 10 次这个确切的代码,我就会得到一些正确的命中。

真正令我疯狂的是,如果我选择与预测相反的答案,我将获得 100% 的准确率。关于随机数据!

我在这里错过了什么?

好的,我想我刚刚弄明白了!这一切都归结为我们的老对手机器学习 - 多数 class.

更详细:我选择了一个包含 25 个 True 值和 25 个 False 值的目标 - 完美平衡。在执行留一法时,这会导致 class 不平衡,比如 24 True 和 25 False。由于 SVC 被设置为默认参数,并且 运行 随机数据,因此除了选择大多数 class 之外,它可能找不到任何方法来预测结果,这在本次迭代中将是 False!因此,在每次迭代中,不平衡都会针对当前遗漏的样本进行调整。

总而言之 - 很好的机器学习课程,以及与朋友分享的绝妙数学谜语:)