【问题标题】:problems plotting two different SVMs approaches with matplotlib?使用 matplotlib 绘制两种不同的 SVM 方法时出现问题?
【发布时间】:2015-04-16 09:10:30
【问题描述】:

我想将分类算法的两种不同方法混为一谈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 中正确绘制此任务?我也试过这个,但显然这是错误的:

提前致谢,这是我用来执行此操作的 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

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

【问题讨论】:

  • 也许这个问题存在于更高的维度。我需要做 PCA 来绘制它吗?
  • 你能提供你在 pastebin 链接中使用的数据吗?
  • 我编辑了@Ffisegydd,感谢您的帮助!
  • @Ffisegydd 以下是矩阵的形状:reduce_data.shape, y.shape, X_test.shape, X_train.shape 它们分别看起来像这样:(2599, 11991) (2599,) (858 , 11991) (1741, 11991)
  • 可以把数据备份一下吗?

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


【解决方案1】:
w = clf.coef_[0]
a = -w[0] / w[1]

您的“w”列表似乎只包含一个值。这就是您在尝试访问第二个索引 w[1] 时收到错误的原因。

【讨论】:

  • 知道如何解决这个问题吗?感谢您的反馈。我编辑了
  • print w 并查看存储的值。对于您当前的a = -w[0] / w[1],它需要类似于[number, number],以免出错。
  • 我无法打印 w 的形状,我尝试打印这个:reduced_data.shape, y.shape, X_test.shape, X_train.shape 他们看起来像这样:(2599, 11991) (2599,) (858, 11991) (1741, 11991)
  • 您应该能够w = clf.coef_[0] print w a = -w[0] / w[1] 显示存储在“w”中的内容,然后它会在下一行出错。根据a = -w[0] / w[1] 行,您的数据必须 有两个要划分的值。如果使用上面显示的第二个值(2599,),则会出现错误。我会在尝试数学之前验证这些值。
  • 对不起,我对错误在哪一行感到困惑,我编辑了问题。当我打印 w 它返回一个非常大的稀疏矩阵
【解决方案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。实际上它并没有太大的区别(我的代码效率较低),但是这样可以让我说明一个要点:如果您减少到 10,000 个维度,您不会失去代表权,这意味着您有大约 2k 个无用的维度(或更多,没有尝试进一步减少 PCA)。然而,减少到 2 太过分了:那么你就剩下 0.07 的幂,这太低了,无法做任何有用的事情。正如你在情节中看到的那样。请注意,如果您在情节上放大一些激烈的东西,您的 PCA 减少的前 2 个分量之间似乎存在线性相关性。不幸的是,我不是一个足够好的统计学家来告诉你这意味着什么。如果我不得不猜测,我会说你的数据有相当多的协方差,但这完全是在黑暗中刺伤。

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()

【讨论】:

  • 在新版本中,能否请您打印w,以及w的形状?我认为w 可能仍然是一个稀疏矩阵,您必须使用w[0, 1] 访问它。关于 PCA 之后的 SVM:预计您的 SVM 将在大量减少的数据上表现不佳。您不太可能从 11k 维度减少到 2,而不会显着丢失信息和可分离性。但是您的目标是可视化您的数据,对吗?只需接受 SVM 无法正常工作,但您将能够绘制(可能毫无意义的)数据。您的 PCA(前 2 个特征值之和)的功效是多少?
  • @ml_guy: w 仍然是一个稀疏矩阵,尽管它是一个列向量,但您必须将其作为矩阵访问:w[0, 1] 以获取向量中的第二个元素。减少的力量等于与您正在使用的特征向量对应的特征值的总和。因此,当您减少到 2 维时,功率是前 2 个特征值的总和。如果您使用 sklearn 进行 PCA,这些值将存储在 explained_variance_ratio_
  • 感谢您的赏金,但这并不值得。我正在编辑一些更有用的东西。具体来说,用于绘制 PCA 的代码。但是请注意,PCA 减少到 2 维是完全没有意义的:相对于原始答案的代表能力是 0.07(这意味着原始空间中约 7% 的方差可以由这 2 维中的方差来解释) .总的来说,我同意你的最终结论:虽然并非不可能绘制,但它并不能帮助你更好地理解问题。你想弄清楚你的情节是什么?
  • 我想看看作为一个实践(我是本科生)这个问题的外观以及超平面如何分类我如何可视化这个的任何其他想法?。
  • 老实说,如果您想通过可视化来了解 SVM(或任何其他 ML 算法)是如何工作的,那么您最好坚持 2D 或 3D 问题。这将为您提供算法的基本“感觉”,并帮助您了解它使用的成本函数。一旦你明白了,你可以更好地理解这个成本函数在更高维度上,并直接使用它(以及其他指标的整个尺度)来评估该方法在你的高维度问题上的效果。这个特定的数据集对您来说重要吗?
猜你喜欢
  • 2017-09-03
  • 2021-10-13
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多