Ошибка моделирования темы слишком много значений для распаковки

#python #dataframe #dataset #data-science #topic-modeling

#python #фрейм данных #набор данных #наука о данных #тема-моделирование

Вопрос:

Я пытаюсь выполнить моделирование темы lda с помощью tsne и pyldavis в качестве визуализаций. Однако после выполнения lda при получении доминирующих тем выдается ошибка слишком большого количества значений для распаковки. Код и ошибка приведены ниже. Любая помощь высоко ценится.

Код для моделирования темы LdaMulticore:

 import sys
# !{sys.executable} -m spacy download en
import re, numpy as np, pandas as pd
from pprint import pprint

# Gensim
import gensim, spacy, logging, warnings
import gensim.corpora as corpora
from gensim.utils import lemmatize, simple_preprocess
from gensim.models import CoherenceModel
import matplotlib.pyplot as plt

# NLTK Stop words
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use', 'not', 'would', 'say', 'could', '_', 'be', 'know', 'good', 'go', 'get', 'do', 'done', 'try', 'many', 'some', 'nice', 'thank', 'think', 'see', 'rather', 'easy', 'easily', 'lot', 'lack', 'make', 'want', 'seem', 'run', 'need', 'even', 'right', 'line', 'even', 'also', 'may', 'take', 'come'])
def Make_String(text):
    return str(text)

#Reviews.columns=['Reviews']
#print(Reviews.head(10))

df['text']=df['text'].apply(lambda x: Make_String(x))
%matplotlib inline
warnings.filterwarnings("ignore",category=DeprecationWarning)
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.ERROR)
# Import Dataset
#df = pd.read_json('https://raw.githubusercontent.com/selva86/datasets/master/newsgroups.json')
#df = df.loc[df.target_names.isin(['soc.religion.christian', 'rec.sport.hockey', 'talk.politics.mideast', 'rec.motorcycles']) , :]
df=pd.read_csv("/content/drive/My Drive/Negative_data.csv", encoding="ISO-8859-1")

print(df.shape)  #> (2361, 3)
df.head()

    # Create Dictionary
    id2word = corpora.Dictionary(data_ready)
    from gensim.models import LdaMulticore
    
    # Create Corpus: Term Document Frequency
    corpus = [id2word.doc2bow(text) for text in data_ready]
    lda_model = LdaMulticore( corpus, num_topics=10, id2word=id2word , passes=2, workers=2)
    
    pprint(lda_model.print_topics())
    #> [(0,
    #>   '0.017*"write"   0.015*"people"   0.014*"organization"   0.014*"article"   '
    #>   '0.013*"time"   0.008*"give"   0.008*"first"   0.007*"tell"   0.007*"new"   '
    #>   '0.007*"question"'),
    #>  (1,
    #>   '0.008*"christian"   0.008*"believe"   0.007*"god"   0.007*"law"   '
    #>   '0.006*"state"   0.006*"israel"   0.006*"israeli"   0.005*"exist"   '
    #>   '0.005*"way"   0.004*"bible"'),
    #>  (2,
    #>   '0.024*"armenian"   0.012*"bike"   0.006*"kill"   0.006*"work"   '
    #>   '0.005*"well"   0.005*"year"   0.005*"sumgait"   0.005*"soldier"   '
    #>   '0.004*"way"   0.004*"ride"'),
    #>  (3,
    #>   '0.019*"team"   0.019*"game"   0.013*"hockey"   0.010*"player"   '
    #>   '0.009*"play"   0.009*"win"   0.009*"nhl"   0.009*"year"   0.009*"hawk"   '
    #>   '0.009*"season"')]

Output:

    [(0,
      '0.340*"seriously"   0.017*"time"   0.015*"samsung"   0.014*"day"   '
      '0.013*"phone"   0.012*"order"   0.012*"wait"   0.011*"week"   0.011*"damn" '
      '  0.011*"next"'),
     (1,
      '0.081*"puma"   0.068*"shoe"   0.046*"adida"   0.017*"site"   0.017*"como"   '
      '0.014*"wear"   0.014*"ugly"   0.011*"shirt"   0.010*"era"   0.009*"pumas"'),
     (2,
      '0.033*"watch"   0.021*"hate"   0.021*"wear"   0.020*"shit"   0.020*"buy"   '
      '0.016*"game"   0.014*"man"   0.014*"stop"   0.014*"time"   0.013*"still"'),
     (3,
      '0.037*"bad"   0.014*"year"   0.013*"pay"   0.013*"feel"   0.011*"thing"   '
      '0.011*"really"   0.011*"last"   0.011*"ever"   0.009*"never"   '
      '0.009*"people"'),
     (4,
      '0.332*"com"   0.173*"twitter"   0.078*"pic"   0.036*"status"   '
      '0.036*"https"   0.029*"nintendo"   0.015*"apple"   0.008*"pue"   '
      '0.006*"photo"   0.004*"iphone"'),
     (5,
      '0.162*"http"   0.028*"pace"   0.027*"low"   0.019*"new"   0.019*"price"   '
      '0.017*"crushed_km"   0.017*"size"   0.014*"video"   0.012*"sale"   '
      '0.012*"dlvr"'),
     (6,
      '0.062*"nike"   0.019*"phone"   0.019*"drop"   0.018*"work"   0.013*"tell"   '
      '0.013*"hard"   0.012*"call"   0.011*"crazy"   0.011*"lol"   0.010*"ass"'),
     (7,
      '0.036*"sin"   0.036*"die"   0.024*"kill"   0.018*"pero"   0.012*"android"   '
      '0.012*"pro"   0.009*"death"   0.008*"igual"   0.008*"final"   '
      '0.008*"problem"'),
     (8,
      '0.039*"black"   0.036*"http"   0.034*"netflix"   0.020*"fire"   '
      '0.018*"dead"   0.014*"son"   0.013*"lose"   0.011*"tv"   0.011*"tinyurl"   '
      '0.010*"steal"'),
     (9,
      '0.299*"live"   0.295*"alone"   0.038*"seriously"   0.013*"switch"   '
      '0.008*"mad"   0.006*"screen"   0.006*"wrong"   0.006*"season"   '
      '0.005*"hour"   0.005*"people"')]
  

Код для доминирующих тем:

 # Sentence Coloring of N Sentences
def topics_per_document(model, corpus, start=0, end=1):
    corpus_sel = corpus[start:end]
    dominant_topics = []
    topic_percentages = []
    for i, corp in enumerate(corpus_sel):
        topic_percs, wordid_topics, wordid_phivalues = model[corp]
        dominant_topic = sorted(topic_percs, key = lambda x: x[1], reverse=True)[0][0]
        dominant_topics.append((i, dominant_topic))
        topic_percentages.append(topic_percs)
    return(dominant_topics, topic_percentages)

dominant_topics, topic_percentages = topics_per_document(model=lda_model, corpus=corpus, end=-1)            

# Distribution of Dominant Topics in Each Document
df = pd.DataFrame(dominant_topics, columns=['Document_Id', 'Dominant_Topic'])
dominant_topic_in_each_doc = df.groupby('Dominant_Topic').size()
df_dominant_topic_in_each_doc = dominant_topic_in_each_doc.to_frame(name='count').reset_index()

# Total Topic Distribution by actual weight
topic_weightage_by_doc = pd.DataFrame([dict(t) for t in topic_percentages])
df_topic_weightage_by_doc = topic_weightage_by_doc.sum().to_frame(name='count').reset_index()

# Top 3 Keywords for each Topic
topic_top3words = [(i, topic) for i, topics in lda_model.show_topics(formatted=False) 
                                 for j, (topic, wt) in enumerate(topics) if j < 3]

df_top3words_stacked = pd.DataFrame(topic_top3words, columns=['topic_id', 'words'])
df_top3words = df_top3words_stacked.groupby('topic_id').agg(', n'.join)
df_top3words.reset_index(level=0,inplace=True)  
  

Ошибка:

 <ipython-input-13-5ea2ada44643> in topics_per_document(model, corpus, start, end)
      5     topic_percentages = []
      6     for i, corp in enumerate(corpus_sel):
----> 7         topic_percs, wordid_topics, wordid_phivalues = model[corp]
      8         dominant_topic = sorted(topic_percs, key = lambda x: x[1], reverse=True)[0][0]
      9         dominant_topics.append((i, dominant_topic))

ValueError: too many values to unpack (expected 3)
  

Большое спасибо

Ответ №1:

model[corp] не возвращает кортеж (topic_percs, wordid_topics, wordid_phivalues) , который ожидает ваш код. Вместо этого он возвращает вектор принадлежности corp , т. Е. вероятность для каждой темы в вашей модели, которая corp была сгенерирована из этой темы. Вот corp отдельный документ из corpus , который вы повторяете enumerate(corpus[0:1]) , поэтому вы запрашиваете вектор членства для каждого документа в corpus .

Это видно из примера, приведенного в документации (для родительского класса LdaModel of LdaMulticore , но они возвращают один и тот же объект):

 >>> from gensim.test.utils import common_corpus
>>> from gensim.models.ldamodel import LdaModel
>>> lda = LdaModel(common_corpus, num_topics=10, iterations=1)
>>> doc_bow = [(1, 0.3), (2, 0.1), (0, 0.09)]
>>> doc_lda = lda[doc_bow]
>>> doc_lda
[(0, 0.08579318),
 (1, 0.0858944),
 (2, 0.079572774),
 (3, 0.09752562),
 (4, 0.08426655),
 (5, 0.1231114),
 (6, 0.17063272),
 (7, 0.08766636),
 (8, 0.083353266),
 (9, 0.102183744)]
  

Похоже, вы хотите вызвать
model.get_document_topics(corp) для каждого пакета слов документа (который вы вызываете corp ) в корпусе.
Это возвращает 3-кортеж распределения темы для всего документа,
наиболее вероятные темы для слова,
и значения релевантности phi, умноженные на длину объекта для каждой комбинации слово-тема.

В противном случае вы могли бы изменить

 topic_percs, wordid_topics, wordid_phivalues = model[corp]
  

Для

 topic_percs = model[corp]
  

или даже понятнее для

 topic_percs = model.get_document_topics(corp)
  

Если wordid_topics предполагается, что вероятность каждого wordid в каждой теме,
затем вы могли бы вызвать, model.get_topic_terms(topicid) чтобы вернуть пары вероятностей для наиболее релевантных слов, сгенерированных темой, или model.get_topics() чтобы получить матрицу терминов-тем.

Комментарии:

1. Привет, спасибо, это очень четко определенный ответ. Я пытаюсь создать tsne, однако в последней ячейке все еще отображается ошибка. было бы действительно полезно, если бы вы могли запустить и изучить это colab.research.google.com/drive /…

2. Если вы зададите другой вопрос, я могу опубликовать код о том, как заставить TSNE работать.

Ответ №2:

Вы должны изменить topic_percs, wordid_topics, wordid_phivalues = model[corp] на topic_percs, wordid_topics, wordid_phivalues = model.get_document_topics(corp_cur, per_word_topics = True)