使用matplotlib绘制两种不同SVM方法的问题?

时间:2015-02-15 21:49:08

标签: python python-2.7 numpy matplotlib scikit-learn

我想将分类算法的两种不同方法分解为documentation example。这就是我试过的:

from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
tfidf_vect= TfidfVectorizer(use_idf=True, smooth_idf=True, sublinear_tf=False, ngram_range=(2,2))

import pandas as pd
df = pd.read_csv('/data.csv',
                     header=0, sep=',', names=['SentenceId', 'Sentence', 'Sentiment'])



X = tfidf_vect.fit_transform(df['Sentence'].values)
y = df['Sentiment'].values


from sklearn import cross_validation
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X,
                                                    y, test_size=0.33)
from sklearn.svm import SVC
#first svm
clf = SVC(kernel='linear')
clf.fit(reduced_data, y)
prediction = clf.predict(X_test)
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-10, 10)
yy = a * xx - clf.intercept_[0] / w[1]


# get the separating hyperplane using weighted classes

#second svm
wclf = SVC(kernel='linear', class_weight={5: 10},C=1000)
wclf.fit(reduced_data, y)
weighted_prediction = wclf.predict(X_test)



#PCA
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(X)


ww = wclf.coef_[0]
wa = -ww[0] / ww[1]
wyy = wa * xx - wclf.intercept_[0] / ww[1]

# plot separating hyperplanes and samples
import matplotlib.pyplot as plt
h0 = plt.plot(xx, yy, 'k-', label='no weights')
h1 = plt.plot(xx, wyy, 'k--', label='with weights')
plt.scatter(reduced_data[:, 0], reduced_data[:, 1], c=y, cmap=plt.cm.Paired)
plt.legend()

plt.axis('tight')
plt.show()

但我得到以下例外:

Traceback (most recent call last):
  File "file.py", line 25, in <module>
    a = -w[0] / w[1]
  File "/usr/local/lib/python2.7/site-packages/scipy/sparse/csr.py", line 253, in __getitem__
    return self._get_row_slice(row, col)
  File "/usr/local/lib/python2.7/site-packages/scipy/sparse/csr.py", line 320, in _get_row_slice
    raise IndexError('index (%d) out of range' % i)
IndexError: index (1) out of range

如何使用matplotlib在2-D或3-D中正确绘制此任务?我也试过这个,但显然这是错误的:

enter image description here

在此先感谢,这是data我用来做这件事。

当我打印w时,会发生这种情况:

     (0, 911)   -0.352103548716
    a = -w[0] / w[1]
  (0, 2346) -1.20396753467
  File "/usr/local/lib/python2.7/site-packages/scipy/sparse/csr.py", line 253, in __getitem__
  (0, 2482) -0.352103548716
  (0, 2288) -0.733605938797
  (0, 1175) -0.868966214318
  (0, 1936) -0.500071158622
  (0, 2558) -0.40965370142
  (0, 788)  -0.485330735934
  (0, 322)  -0.575610464517
  (0, 453)  -0.584854414882
  (0, 1913) -0.300076915818
  (0, 2411) -0.419065159403
  (0, 2017) -0.407926583824
  (0, 2363) -0.407926583824
  (0, 815)  -1.09245625795
  (0, 543)  -0.248207856236
  (0, 1082) -0.366433457602
  (0, 1312) -0.286768829333
  (0, 1525) -0.286768829333
  (0, 1677) -0.286768829333
  (0, 2679) -0.688619491265
  (0, 413)  -0.101096807406
  (0, 1322) -0.13561265293
  (0, 1488) -0.120403497624
  (0, 1901) -0.337806267742
  : :
  (0, 1609) 0.100116485705
  (0, 581)  0.276579777388
  (0, 2205) 0.241642287418
  (0, 1055) 0.0166785719624
  (0, 2390) 0.349485515339
  (0, 1866) 0.357035248059
  (0, 2098) 0.296454010725
  (0, 2391) 0.45905660273
  (0, 2601) 0.357035248059
  (0, 619)  0.350880030278
  (0, 129)  0.287439419266
  (0, 280)  0.432180530894
  (0, 1747) -0.172314049543
  (0, 1211) 0.573579514463
  (0, 86)   0.3152907757
  (0, 452)  0.305881204557
  (0, 513)  0.212678772368
  (0, 946)  -0.347372778859
  (0, 1194) 0.298193025133
  (0, 2039) 0.34451957335
  (0, 2483) 0.245366213834
  (0, 317)  0.355996551812
  (0, 977)  0.355996551812
  (0, 1151) 0.284383826645
  (0, 2110) 0.120512273328

它返回了一个非常大的稀疏矩阵。

2 个答案:

答案 0 :(得分:2)

w = clf.coef_[0]
a = -w[0] / w[1]

看起来你的'w'列表只包含一个值。这是您在尝试访问第二个索引w [1]时收到错误的原因。

答案 1 :(得分:2)

如果w是稀疏矩阵,则必须按原样访问它。尝试:

a = -w[0,0] / w[0, 1]

虽然我必须警告你:你关注的可视化示例是一个非常简单的2D问题。对于您可以想到的可视化而言,您必须在可视化问题之前执行降维(例如PCA)。虽然您可以明显地绘制12k维度的前2个坐标,但这些发生的可能性最大的信息几乎为0。

编辑:看看你的w矩阵,这仍然无效,但至少现在应该给出除零问题,而不是超出范围的索引。考虑一下,我不太清楚如何解决你的问题。如果您的目标是可视化您的数据,您可以使用PCA首先将数据减少到2D,然后运行SVM以查找分隔符(有和没有权重),但您的SVM参数不太可能推广到您的实际问题。另一方面,您可以在更高的维度上运行SVM,并使用它来为您的PCA中的解决方案着色。最好的情况是,这将为您提供两个相当分离的彩色组:在这种情况下,您的SVM工作得非常好,并且PCA维护您问题的大部分结构。但是,如果这两个条件中的一个不成立(特别是后者不太适用于大多数问题),你的颜色会得到一个几乎随机的模式。在这种情况下,你根本无法得出任何结论。

编辑2:我写了一个简短的脚本,用于提取2个PCA维度并为您绘制它们。请注意,我没有减少到2,我减少到10000,然后提取第一个2.实际上它没有很大的区别(我的代码效率较低),但这样它允许我要说明一点:如果你减少到10000维度,你就失去了代表性的力量,这意味着你有大约2k无用的维度(或者更多,没有尝试进一步减少PCA)。然而,减少到2太远了:那么你剩下的功率为0.07,这太低了,无法做任何有用的东西。正如你在情节中看到的那样。请注意,如果放大图中的某些内容,则PCA减少的前两个组件之间似乎存在线性相关性。不幸的是,我不是一个足够好的统计学家,告诉你这意味着什么。如果我不得不猜测,我会说你的数据中有很多协方差,但这是在黑暗中完全刺伤。

from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
tfidf_vect= TfidfVectorizer(use_idf=True, smooth_idf=True, sublinear_tf=False, ngram_range=(2,2))

import pandas as pd
df = pd.read_csv('corpus.txt',
                     header=0, sep=',', names=['SentenceId', 'Sentence', 'Sentiment'])



X = tfidf_vect.fit_transform(df['Sentence'].values)
y = df['Sentiment'].values


from sklearn.decomposition import PCA
pca = PCA(n_components=10000)
reduced = pca.fit_transform(X.toarray())
print sum(pca.explained_variance_ratio_)
print pca.explained_variance_ratio_[0] + pca.explained_variance_ratio_[1]

from matplotlib import pyplot as plt

by_class = {}
for i in range(0, len(y)):
  if not y[i] in by_class:
    by_class[y[i]] = []
  by_class[y[i]].append(reduced[i])

for c in by_class:
  toplt = np.array(by_class[c]).T
  plt.plot(toplt[0], toplt[1], linestyle='', marker='o')

plt.show()

Plot generated by above code