Scikit-learn SVC 在随机数据交叉验证中总是给出准确度 0
Posted
技术标签:
【中文标题】Scikit-learn SVC 在随机数据交叉验证中总是给出准确度 0【英文标题】:Scikit-learn SVC always giving accuracy 0 on random data cross validation 【发布时间】:2016-08-20 04:41:14 【问题描述】:在下面的代码中,我创建了一个大小为 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】:好的,我想我刚刚想通了!这一切都归结于我们的老机器学习敌人 - 多数派。
更详细:我选择了一个包含 25 个真值和 25 个假值的目标 - 完美平衡。在执行留一法时,这会导致类别不平衡,例如 24 True 和 25 False。由于 SVC 被设置为默认参数,并且在随机数据上运行,它可能找不到任何方法来预测结果,除了选择多数类,在本次迭代中这将是 False!因此,在每次迭代中,不平衡都会针对当前遗漏的样本。
总而言之 - 很好的机器学习课程,以及与您的朋友分享的出色数学谜语 :)
【讨论】:
不错的收获!这就解释了为什么我在使用y_val = np.random.rand(50) < 0.5
创建目标向量时无法重现问题。以上是关于Scikit-learn SVC 在随机数据交叉验证中总是给出准确度 0的主要内容,如果未能解决你的问题,请参考以下文章
如何在 scikit-learn 中执行随机森林模型的交叉验证?
在 scikit-learn 中将数据加载到 SVC 模型时尝试避免 .toarray()