在下面的代码中,我创建了一个大小为 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%的准确性。随机数据!
我在这里错过了什么?
好吧,我想我刚刚想通了!这一切都归结为我们旧的机器学习对手 - 多数阶级。
更详细地说:我选择了一个包含 25 个真值和 25 个假值的目标 - 完美平衡。在执行留一时,这会导致类不平衡,例如 24 个真和 25 个假。由于 SVC 设置为默认参数,并在随机数据上运行,因此除了选择多数类之外,它可能找不到任何方法来预测结果,在此迭代中为 False!因此,在每次迭代中,不平衡都会针对当前遗漏的样本进行调整。
总而言之 - 机器学习的好课,以及与您的朋友分享的出色数学谜语:)