此帖子后续有以下帖子:
https://cs.stackexchange.com/questions/70395/what-is-the-effect-of-hidden-layer-size
我想了解我的数据是否线性可分。根据我在上面链接的帖子中收到的评论,我决定在我的数据上运行一个硬SVM来查看分类结果。
我的输入数据X是一个(10000, 128)的矩阵,输出/目标/类别是(10000, 10)。我有10个类别,范围从1到10。
使用以下代码,我尝试了LogisticRegression(),svm.LinearSVC(C=1, loss=’hinge’)和svm.SVC(kernel=’linear’, C=1):
dataframe = read_csv('data.txt')array = dataframe.valuesX = array[:, 0:128]y = array[:,-1]plt.hist(y, bins='auto') # plt.hist passes it's arguments to np.histogramplt.title("Histogram with 'auto' bins")plt.show()models = []models.append(('LR', LogisticRegression() ))models.append(('LSVM', svm.LinearSVC(C=1, loss='hinge') ))models.append(('LSVM2', svm.SVC(kernel='linear', C=1) ))results=[]names=[]scoring = 'accuracy'for name, model in models: kfold = KFold(n_splits=10, random_state=7) cv_results = cross_val_score(model, X, y, cv=kfold, scoring=scoring) results.append(cv_results) names.append(name) msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std()) print(msg)
结果如下:
LR: 0.613360 (0.019632)LSVM: 0.307829 (0.020123)LSVM2: 1.000000 (0.000000)
我有两个问题:
(1) 我的数据是否线性可分?
(2) LSVM2的结果是否奇怪?针对这个问题,我进一步使用了
models.append(('RBFSVM', svm.SVC(kernel='rbf', gamma=0.7, C=1) ))models.append(('POLYSVM', svm.SVC(kernel='poly', degree=3, C=1) ))
并得到了以下结果:
RBFSVM: 0.797680(.015187)POLYSVM: 0.100011(0.008113)
您能帮助我获得更多直觉吗?
谢谢,
回答:
一般说明 – 线性可分的概念适用于二元数据集,不适用于10个类别。如果你有超过2个类别,就没有所谓的线性可分,因为你可以用多种方式定义它。为了回答的其余部分,我将假设我们在谈论“成对线性可分”,意思是如果你选择任意两个类别,它们可以相互线性分离(请注意,这与一对多线性可分不同,因为有一些数据集是一对一线性可分的,但不是一对多线性可分的)。
首先,要检查数据是否线性可分,不要使用交叉验证。只要将模型拟合到整个数据并检查错误,没有必要进行训练/验证/测试拆分,全部用于训练 – 全部用于测试。事实上,进行交叉验证会使其错误,因为你可能在没有线性可分的情况下获得100%的准确率(只要你足够幸运地将数据拆分成每个测试子集都是线性可分的)。
其次,关闭正则化。SVM中的“C”使其“不是硬的”,硬SVM相当于C=无穷大的SVM,所以设置C=100000至少有一些体面的分离概率。同样适用于sklearn中的逻辑回归,它也有超参数C,设置为1000000(基本上是任何巨大的值),然后重新训练。