找到暗淡为 3 的数组。估计器预期 <= 2
Posted
技术标签:
【中文标题】找到暗淡为 3 的数组。估计器预期 <= 2【英文标题】:Found array with dim 3. Estimator expected <= 2 【发布时间】:2018-01-16 10:12:36 【问题描述】:我在一个简单的文档集合上使用 LDA。我的目标是提取主题,然后使用提取的主题作为特征来评估我的模型。
我决定使用多项式 SVM 作为评估器。不知道好不好?
import itertools
from gensim.models import ldamodel
from nltk.tokenize import RegexpTokenizer
from nltk.stem.porter import PorterStemmer
from gensim import corpora, models
from sklearn.naive_bayes import MultinomialNB
tokenizer = RegexpTokenizer(r'\w+')
# create English stop words list
en_stop = 'a'
# Create p_stemmer of class PorterStemmer
p_stemmer = PorterStemmer()
# create sample documents
doc_a = "Brocolli is good to eat. My brother likes to eat good brocolli, but not my mother."
doc_b = "My mother spends a lot of time driving my brother around to baseball practice."
doc_c = "Some health experts suggest that driving may cause increased tension and blood pressure."
doc_d = "I often feel pressure to perform well at school, but my mother never seems to drive my brother to do better."
doc_e = "Health professionals say that brocolli is good for your health."
# compile sample documents into a list
doc_set = [doc_a, doc_b, doc_c, doc_d, doc_e]
# list for tokenized documents in loop
texts = []
# loop through document list
for i in doc_set:
# clean and tokenize document string
raw = i.lower()
tokens = tokenizer.tokenize(raw)
# remove stop words from tokens
stopped_tokens = [i for i in tokens if not i in en_stop]
# stem tokens
stemmed_tokens = [p_stemmer.stem(i) for i in stopped_tokens]
# add tokens to list
texts.append(stemmed_tokens)
# turn our tokenized documents into a id <-> term dictionary
dictionary = corpora.Dictionary(texts)
# convert tokenized documents into a document-term matrix
corpus = [dictionary.doc2bow(text) for text in texts]
# generate LDA model
#ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=2, id2word=dictionary, passes=20)
id2word = corpora.Dictionary(texts)
# Creates the Bag of Word corpus.
mm = [id2word.doc2bow(text) for text in texts]
# Trains the LDA models.
lda = ldamodel.LdaModel(corpus=mm, id2word=id2word, num_topics=4,
update_every=1, chunksize=10000, passes=1)
# Assigns the topics to the documents in corpus
a=[]
lda_corpus = lda[mm]
for i in range(len(doc_set)):
a.append(lda_corpus[i])
print(lda_corpus[i])
merged_list = list(itertools.chain(*lda_corpus))
print(a)
#my_list.append(my_list[i])
sv=MultinomialNB()
yvalues = [0,1,2,3]
sv.fit(a,yvalues)
predictclass = sv.predict(a)
testLables=[0,1,2,3]
from sklearn import metrics, tree
#yacc=metrics.accuracy_score(testLables,predictclass)
#print (yacc)
当我运行这段代码时,它会抛出主题中提到的错误。
这也是我提供给 SVM 的 LDA 模型(主题文档分布)的输出:
[[(0, 0.95533888404477663), (1, 0.014775921798986477), (2, 0.015161897773308793), (3, 0.014723296382928375)], [(0, 0.019079556242721694), (1, 0.017932434792585779), (2, 0.94498655991579728), (3, 0.018001449048895311)], [(0, 0.017957955483631164), (1, 0.017900184473362918), (2, 0.018133572636989413), (3, 0.9460082874060165)], [(0, 0.96554611572184923), (1, 0.011407838337200715), (2, 0.011537900721487016), (3, 0.011508145219463113)], [(0, 0.023306931039431281), (1, 0.022823706054846005), (2, 0.93072240824085961), (3, 0.023146954664863096)]]
我这里的标签是 0,1,2,3 。
我找到了回复here
但是当我写下来时:
nsamples, nx, ny = a.shape
d2_train_dataset = a.reshape((nsamples,nx*ny))
根据我的情况,它不起作用。其实a没有shape方法。
整个回溯错误
Traceback (most recent call last):
File "/home/saria/PycharmProjects/TfidfLDA/test3.py", line 87, in <module>
sv.fit(a,yvalues)
File "/home/saria/tfwithpython3.6/lib/python3.5/site-packages/sklearn/naive_bayes.py", line 562, in fit
X, y = check_X_y(X, y, 'csr')
File "/home/saria/tfwithpython3.6/lib/python3.5/site-packages/sklearn/utils/validation.py", line 521, in check_X_y
ensure_min_features, warn_on_dtype, estimator)
File "/home/saria/tfwithpython3.6/lib/python3.5/site-packages/sklearn/utils/validation.py", line 405, in check_array
% (array.ndim, estimator_name))
ValueError: Found array with dim 3. Estimator expected <= 2.
【问题讨论】:
哪段代码导致错误? @vealkind 感谢您的评论 :) 我用回溯更新了问题,非常感谢您的时间 @saria- 在a
中,您将数据存储为每个文档的元组列表。每个文档中的编号 0、1、2、3 是否有意义?我认为您遇到了一个问题,因为 MultinomialNB
期望一个类似矩阵的对象作为输入,并且您使用元组列表作为每个文档的输入。
@vealkind 谢谢,是的,它们是 topic0、topic1、topic2、topic3,所以它们应该是标签。我的意思是,例如 LDA 模型生成了 4 个主题(每个主题有 10 个分布词),因此这些主题将被视为 SVM 的特征,它们是实现准确性的标签
还有一个矩阵,行是我的文档,列是特征
【参考方案1】:
尝试在MultinomialNB
上调用fit
时出现错误,因为a
中包含的数据大于二维。正如现在构造的那样,a
正在为每个文档提供一个元组列表,这是模型不允许的。
由于元组的第一部分只是主题标签,您可以从元组中删除该值并将数据重建为二维矩阵。下面的代码会做到这一点,
new_a = []
new_y = []
for x in a:
temp_a = []
sorted_labels = sorted(x, key=lambda x: x[1], reverse=True)
new_y.append(sorted_labels[0][0])
for z in x:
temp_a.append(z[1])
new_a.append(temp_a)
new_a
将是文档列表,其中每个文档将包含主题 0、1、2 和 3 的分数。然后您可以调用 sv.fit(new_a, yvalues)
以适应您的模型。
【讨论】:
我不知道该怎么感谢你,真的真的真的很感谢你的帮助我有点失望。如果我有任何问题,我也可以请你回答我的问题,直到明天。我将更改此代码以从文件集合中读取,而不是从代码中的一些示例中读取,我可能会遇到严重的错误,我希望它顺利进行,没有任何问题。再次非常感谢救生员:) 一点问题都没有!如果您有任何问题,请告诉我。需要注意的一件事是,在上面的代码中,我根据您的示例数据做出了两个假设,您需要确保它们适用于更大的数据集。首先,我假设所有文档对每个主题都有一个值(0、1、2、3 等)。其次,我假设每个文档中的主题已经按顺序排序。如果对于较大的数据集,其中任何一个都不正确,则会进行一些小的调整。 非常感谢您关注我的问题。实际上,很难解释一个问题是标签问题。当我们使用 LDA 时,我们会在每个主题中生成带有术语分布的主题。最后,我有一个以主题为标签的文档。所以在输出矩阵中,行是 DOC,但列应该是 features。到目前为止,一切都很好。问题是 SVM 需要每一行的标签。所以当我想要 4 个标签并且我有 30 行时,我应该给 30 个标签来运行。似乎当我创建矩阵时,我必须以一种方式将其更改为一列用于标签。我说的清楚吗? 我的意思是我不应该丢失主题标签。在构建新矩阵时,应添加一列并将该数据保存在那里。我可以听听你的看法吗:) 谢谢 当您在MultinomialNB
上调用fit
时,您必须为每个文档提供一个标签。如果不为每个文档提供正确的标签,模型就无法适合您的数据。您是否有一组文档,您知道每个文档的标签?如果您没有针对一组文档的正确标签来训练您的模型,那么您应该尝试某种聚类算法,该算法将仅根据您的输入数据返回相似文档的集群,而没有标签。以上是关于找到暗淡为 3 的数组。估计器预期 <= 2的主要内容,如果未能解决你的问题,请参考以下文章
ValueError:找到暗淡3的数组。估计器预期<= 2。使用numpy数组时
ValueError:找到暗淡 3 的数组。估计器预期 <= 2。>>>
ValueError:找到暗淡为 3 的数组。预计估计器 <= 2。(Keras,Sklearn)
sklearn KNeighborsClassifier“ValueError:找到暗淡为 4 的数组。预计估计器 <= 2。”