首页 > 解决方案 > 使用 Spacy 进行主题建模 - 没有做出很好的预测

问题描述

我正在做一个主题建模任务,我正在接受人们的反馈(文本)并试图从中提取重要的主题。

反馈很短,我不知道这是否是给我们带来问题的原因。下面是我的代码,我错过了什么非常明显的东西吗?

我正在删除停用词、词形还原、仅保留名词并删除停用词。但是我将这些传递到模型中,它并没有像我希望的那样工作

其中一个大问题是语义,客户可以以不同的方式引用同一个概念:商店、精品店、商店、超市等……它们都指的是商店,但 LDA 将这些视为不同的概念并转储他们分成不同的话题,尽管“我爱这家商店”和“我爱这家商店”是同一个说法。

import spacy
import pandas as pd
from textblob import TextBlob

#set display options
pd.set_option('display.max_colwidth', 0)
pd.set_option('display.max_rows', 0)

#ingest data
df = pd.read_csv('surv.csv')

#import spacy language library and stopword dictionary
nlp = spacy.load('en_core_web_sm')
all_stopwords = nlp.Defaults.stop_words

#Limit DF to columns of interest and drop nulls
responses = df[['Comment', 'score']]
responses = responses.dropna()

#lemmatize the strings
def cleanup(row):
    comment = row['Comment']
    comment = nlp(comment)
    sent = []
    for word in comment:
        sent.append(word.lemma_)    
    return " ".join(sent)

#keep only nouns
def only_nouns(row):
    comment = row['nostops']
    blob = TextBlob(comment)
    x = blob.noun_phrases
    return " ".join(x)

def pos(row):
    comment = row['nostops']
    comment = nlp(comment)
    nouns = []
    i=0
    while i < len(comment)-1:
        if comment[i].pos_ == 'NOUN':
            nouns.append(comment[i])
        i=i+1
    return nouns
        
#remove the stop words
def remove_stops(row):
    comment = row['Comment']
    comment = comment.split(' ')  
    rem = []
    for word in comment:
        if word not in all_stopwords:
            rem.append(word)
    return " ".join(rem)

#What entities are defined in the document
def split_entities(row):
    comment = row['Comment']
    comment = nlp(comment)
    entities = []
    for ent in comment.ents:
        entities.append(ent)
    return entities          

#Call functions
responses['lemmas'] = responses.apply(cleanup,axis=1)            
responses['nostops'] = responses.apply(remove_stops,axis=1)
responses['nouns'] = responses.apply(pos, axis=1)
responses['nouns2'] = responses.apply(only_nouns, axis=1)
responses['entities'] = responses.apply(split_entities,axis=1)


from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
cv = CountVectorizer(max_df=0.9, min_df=2, stop_words='english') 
document_term_matrix = cv.fit_transform(responses['nouns'])
lda = LatentDirichletAllocation(n_components=4, random_state=42)
lda.fit(document_term_matrix)
topic_results = lda.transform(document_term_matrix) 

标签: python-3.xnlpspacy

解决方案


一般建议:您是否尝试在 sklearn 中添加 TF-IDF?这是一种基于单词在文档中和跨文档出现的频率来衡量单词的通用方法,它提高了 LDA 输出的质量。您可以将它与“CountVectorizer”一起添加。这是来自sklearn 文档的一个很好的完整示例。

针对您希望将其视为同义词(“商店、精品店、商店、超市”)的问题的具体建议:我想我会添加一个预处理步骤,用完全相同的标记替换所有这些单独的词(例如,将所有出现的“商店、精品店、商店、超市”转换为“商店”)。它需要手动创建同义词列表,但这是解决问题的简单方法。


推荐阅读