Scikit 使用 SVC 学习错误预测
Scikit learn wrong predictions with SVC
我正在尝试使用径向核使用 SVM 预测 MNIST (http://pjreddie.com/projects/mnist-in-csv/) 数据集。我想用几个例子(例如 1000)进行训练并预测更多。问题是每当我预测时,预测都是恒定的 除非 测试集的索引与训练集的索引一致。也就是说,假设我使用训练示例中的示例 1:1000 进行训练。然后,对于我的测试集 1:1000 的预测是正确的(即 SVM 尽力而为),但随后我得到了其余的相同输出。但是,如果我使用示例 2001:3000 进行训练,那么只有对应于测试集中那些行的测试示例被正确标记(即不具有相同的常量)。我完全不知所措,我认为存在某种错误,因为完全相同的代码在 LinearSVC 上工作得很好,尽管显然该方法的准确性较低。
首先,我用 501:1000 个训练数据的例子进行训练:
# dat_train/test are pandas DFs corresponding to both MNIST datasets
dat_train = pd.read_csv('data/mnist_train.csv', header=None)
dat_test = pd.read_csv('data/mnist_train.csv', header=None)
svm = SVC(C=10.0)
idx = range(1000)
#idx = np.random.choice(range(len(dat_train)), size=1000, replace=False)
X_train = dat_train.iloc[idx,1:].reset_index(drop=True).as_matrix()
y_train = dat_train.iloc[idx,0].reset_index(drop=True).as_matrix()
X_test = dat_test.reset_index(drop=True).as_matrix()[:,1:]
y_test = dat_test.reset_index(drop=True).as_matrix()[:,0]
svm.fit(X=X_train[501:1000,:], y=y_train[501:1000])
在这里你可以看到大约一半的预测是错误的
y_pred = svm.predict(X_test[:1000,:])
confusion_matrix(y_test[:1000], y_pred)
全错(即常量)
y_pred = svm.predict(X_test[:500,:])
confusion_matrix(y_test[:500], y_pred)
这是我希望看到的所有测试数据
y_pred = svm.predict(X_test[501:1000,:])
confusion_matrix(y_test[501:1000], y_pred)
您可以使用 LinearSVC 检查以上所有内容是否正确!
默认内核是 RBF,在这种情况下 gamma
很重要。如果不提供gamma
,则默认为auto
,即1/n_features。您最好 运行 网格搜索来找到最佳参数。这里我只是说明给定合适的参数结果是正常的。
In [120]: svm = SVC(C=1, gamma=0.0000001)
In [121]: svm.fit(X=X_train[501:1000,:], y=y_train[501:1000])
Out[121]:
SVC(C=1, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma=1e-07, kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
In [122]: y_pred = svm.predict(X_test[:1000,:])
In [123]: confusion_matrix(y_test[:1000], y_pred)
Out[123]:
array([[ 71, 0, 2, 0, 2, 9, 1, 0, 0, 0],
[ 0, 123, 0, 0, 0, 1, 1, 0, 1, 0],
[ 2, 5, 91, 1, 1, 1, 3, 7, 5, 0],
[ 0, 1, 4, 48, 0, 40, 1, 5, 7, 1],
[ 0, 0, 0, 0, 88, 2, 3, 2, 0, 15],
[ 1, 1, 1, 0, 2, 77, 0, 3, 1, 1],
[ 3, 0, 3, 0, 5, 4, 72, 0, 0, 0],
[ 0, 2, 3, 0, 3, 0, 1, 88, 1, 1],
[ 2, 0, 1, 2, 3, 9, 1, 4, 63, 4],
[ 0, 1, 0, 0, 16, 3, 0, 11, 1, 62]])
为 SVC 寻找合适的参数本身就是一门艺术。网格搜索可能会有所帮助,效果更好一些 population based training like in this article - 我最近尝试过。如果同时让运行,结果比GridSearch好。如果让它运行直到精度相同,它会更快。
它也有助于制作图形:让x和y轴为C和gamma,并将预测分数绘制为颜色。通常你会在两条线相交的地方找到训练结果最好的 V-Shape 。同时这一点也有低C-Values,这是可取的,因为C决定了SVC的运行时间:高C使运行时间长。
我正在尝试使用径向核使用 SVM 预测 MNIST (http://pjreddie.com/projects/mnist-in-csv/) 数据集。我想用几个例子(例如 1000)进行训练并预测更多。问题是每当我预测时,预测都是恒定的 除非 测试集的索引与训练集的索引一致。也就是说,假设我使用训练示例中的示例 1:1000 进行训练。然后,对于我的测试集 1:1000 的预测是正确的(即 SVM 尽力而为),但随后我得到了其余的相同输出。但是,如果我使用示例 2001:3000 进行训练,那么只有对应于测试集中那些行的测试示例被正确标记(即不具有相同的常量)。我完全不知所措,我认为存在某种错误,因为完全相同的代码在 LinearSVC 上工作得很好,尽管显然该方法的准确性较低。
首先,我用 501:1000 个训练数据的例子进行训练:
# dat_train/test are pandas DFs corresponding to both MNIST datasets
dat_train = pd.read_csv('data/mnist_train.csv', header=None)
dat_test = pd.read_csv('data/mnist_train.csv', header=None)
svm = SVC(C=10.0)
idx = range(1000)
#idx = np.random.choice(range(len(dat_train)), size=1000, replace=False)
X_train = dat_train.iloc[idx,1:].reset_index(drop=True).as_matrix()
y_train = dat_train.iloc[idx,0].reset_index(drop=True).as_matrix()
X_test = dat_test.reset_index(drop=True).as_matrix()[:,1:]
y_test = dat_test.reset_index(drop=True).as_matrix()[:,0]
svm.fit(X=X_train[501:1000,:], y=y_train[501:1000])
在这里你可以看到大约一半的预测是错误的
y_pred = svm.predict(X_test[:1000,:])
confusion_matrix(y_test[:1000], y_pred)
全错(即常量)
y_pred = svm.predict(X_test[:500,:])
confusion_matrix(y_test[:500], y_pred)
这是我希望看到的所有测试数据
y_pred = svm.predict(X_test[501:1000,:])
confusion_matrix(y_test[501:1000], y_pred)
您可以使用 LinearSVC 检查以上所有内容是否正确!
默认内核是 RBF,在这种情况下 gamma
很重要。如果不提供gamma
,则默认为auto
,即1/n_features。您最好 运行 网格搜索来找到最佳参数。这里我只是说明给定合适的参数结果是正常的。
In [120]: svm = SVC(C=1, gamma=0.0000001)
In [121]: svm.fit(X=X_train[501:1000,:], y=y_train[501:1000])
Out[121]:
SVC(C=1, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma=1e-07, kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
In [122]: y_pred = svm.predict(X_test[:1000,:])
In [123]: confusion_matrix(y_test[:1000], y_pred)
Out[123]:
array([[ 71, 0, 2, 0, 2, 9, 1, 0, 0, 0],
[ 0, 123, 0, 0, 0, 1, 1, 0, 1, 0],
[ 2, 5, 91, 1, 1, 1, 3, 7, 5, 0],
[ 0, 1, 4, 48, 0, 40, 1, 5, 7, 1],
[ 0, 0, 0, 0, 88, 2, 3, 2, 0, 15],
[ 1, 1, 1, 0, 2, 77, 0, 3, 1, 1],
[ 3, 0, 3, 0, 5, 4, 72, 0, 0, 0],
[ 0, 2, 3, 0, 3, 0, 1, 88, 1, 1],
[ 2, 0, 1, 2, 3, 9, 1, 4, 63, 4],
[ 0, 1, 0, 0, 16, 3, 0, 11, 1, 62]])
为 SVC 寻找合适的参数本身就是一门艺术。网格搜索可能会有所帮助,效果更好一些 population based training like in this article - 我最近尝试过。如果同时让运行,结果比GridSearch好。如果让它运行直到精度相同,它会更快。
它也有助于制作图形:让x和y轴为C和gamma,并将预测分数绘制为颜色。通常你会在两条线相交的地方找到训练结果最好的 V-Shape 。同时这一点也有低C-Values,这是可取的,因为C决定了SVC的运行时间:高C使运行时间长。