检查我的数据是否线性可分
Check if my data are linearly separable
此 post 后面是下面的 post:
https://cs.stackexchange.com/questions/70395/what-is-the-effect-of-hidden-layer-size
我想知道我的数据是否线性可分。根据我在上面的 post 链接中收到的评论,我决定 运行 对我的数据进行硬 SVM 以查看分类结果。
我的输入数据,X 是 (10000, 128) 的矩阵,output/target/classes 是 (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.values
X = array[:, 0:128]
y = array[:,-1]
plt.hist(y, bins='auto') # plt.hist passes it's arguments to np.histogram
plt.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 类 就没有线性可分性这样的东西,因为你可以用很多方式定义它。为了剩下的答案,我假设我们正在谈论 "pairwise linearly separable",这意味着如果您选择任何两个 类,它们可以彼此线性分离(请注意,这是不同的具有一对一线性可分性的事情,因为有些数据集是一对一线性可分的,而不是一对一线性可分的。
首先检查数据是否线性可分不要使用交叉验证。只需将您的模型拟合到整个数据并检查错误,不需要 train/validation/test 拆分,对所有内容进行训练 - 对所有内容进行测试。事实上,进行交叉验证会使它 错误 ,因为您可以在没有线性可分性的情况下获得 100%(只要您有幸以每个测试子集线性可分的方式拆分数据).
其次关闭正则化。 "C"在SVM中使得"not hard",hard SVM等价于C=infinity的SVM,所以设置C=100000至少有一些不错的分离概率。这同样适用于 sklearn 中的逻辑回归,它也有一个超参数 C,将其设置为 1000000(基本上任何巨大的)然后重新训练。
此 post 后面是下面的 post:
https://cs.stackexchange.com/questions/70395/what-is-the-effect-of-hidden-layer-size
我想知道我的数据是否线性可分。根据我在上面的 post 链接中收到的评论,我决定 运行 对我的数据进行硬 SVM 以查看分类结果。
我的输入数据,X 是 (10000, 128) 的矩阵,output/target/classes 是 (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.values
X = array[:, 0:128]
y = array[:,-1]
plt.hist(y, bins='auto') # plt.hist passes it's arguments to np.histogram
plt.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 类 就没有线性可分性这样的东西,因为你可以用很多方式定义它。为了剩下的答案,我假设我们正在谈论 "pairwise linearly separable",这意味着如果您选择任何两个 类,它们可以彼此线性分离(请注意,这是不同的具有一对一线性可分性的事情,因为有些数据集是一对一线性可分的,而不是一对一线性可分的。
首先检查数据是否线性可分不要使用交叉验证。只需将您的模型拟合到整个数据并检查错误,不需要 train/validation/test 拆分,对所有内容进行训练 - 对所有内容进行测试。事实上,进行交叉验证会使它 错误 ,因为您可以在没有线性可分性的情况下获得 100%(只要您有幸以每个测试子集线性可分的方式拆分数据).
其次关闭正则化。 "C"在SVM中使得"not hard",hard SVM等价于C=infinity的SVM,所以设置C=100000至少有一些不错的分离概率。这同样适用于 sklearn 中的逻辑回归,它也有一个超参数 C,将其设置为 1000000(基本上任何巨大的)然后重新训练。