Scikit-learn SVC始终在随机数据交叉验证中给出准确度0

时间:2016-04-26 11:21:18

标签: python python-2.7 random scikit-learn svm

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

所有值都存储在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%的准确性。随机数据!

我在这里缺少什么?

1 个答案:

答案 0 :(得分:4)

好的,我想我刚想通了!这一切都归结为我们的旧机器学习敌人 - 多数人类

更详细:我选择了包含25个真值和25个假值的目标 - 完美平衡。当执行留一法时,这导致了类不平衡,例如24真和25假。由于SVC设置为默认参数,并在随机数据上运行,因此除了选择多数类之外,它可能找不到任何预测结果的方法,在此迭代中它将为False!因此,在每次迭代中,不平衡都与当前剩下的样本相对应。

总而言之 - 机器学习的好教训,以及与朋友分享的优秀数学谜题:)