获取代码

点击下载本文数据&代码



如何用LDA预测文本的话题类型,本文将覆盖以下代码技术

  1. csv数据读取
  2. 文本预处理
  3. 训练(保存)lda模型
  4. 预测话题



一、读取数据

本文使用的数据集来自于 之前分享的 网络爬虫 | 知乎热门话题「全职儿女」

import pandas as pd

df = pd.read_csv('data/知乎-全职儿女.csv', encoding='utf-8')
df.dropna(subset=['content'], inplace=True)
print('记录数: ', len(df))
df.head(2)
记录数:  411



二、清洗数据

import re
import jieba

stoptext = open('data/stopwords.txt', encoding='utf-8').read()        
stopwords = stoptext.split('\n')  


def clean_text(text):
    # 用正则表达式提取中文文本
    text = ''.join(re.findall('[\u4e00-\u9fa5]+', text))   
    words = jieba.lcut(text)                               
    words = [w for w in words if w not in stopwords]   
    #整理成用空格间隔词语的文本形式(类似西方语言)
    return ' '.join(words)


test_text = "首先,我认为「全职儿女」不应该被简单地归为啃老。在目前社会环境下,随着经济、教育等发展,年轻..."
clean_text(text=test_text)

Run

    '全职 儿女 简单 地归为 啃 老 社会 环境 经济 教育 发展 年轻'

df['clean_content'] = df['content'].apply(clean_text)
df.head(1)



三、训练LDA模型

3.1 训练

根据词云图, 假设对数据比较了解,可以直接设置话题数 n_components = 4

from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation

# 构建词典,将词转为数字。将文档转为向量
vectorizer = TfidfVectorizer(max_df=0.5, min_df=20)   
doc_term_matrix = vectorizer.fit_transform(df['clean_content'])

# 构建LDA话题模型
# 初始化模型,设置话题数为4,随机状态码888
lda_model = LatentDirichletAllocation(n_components=4, random_state=888)       
lda_output = lda_model.fit_transform(doc_term_matrix)
lda_model

3.2 保存模型

如果训练过程非常久,保存模型,下次就可以跳过训练阶段,直接使用模型。

import joblib
# # 保存模型
joblib.dump(lda_model, 'output/全职儿女lda_model.pkl')
['output/全职儿女lda_model.pkl']

3.3 导入模型

import joblib

"""导入保存的模型"""
lda_model = joblib.load('output/全职儿女lda_model.pkl')
lda_model



四、使用LDA模型

4.1 查看话题特征词

获得每个话题对应的的n个特征词,方便后续对每个话题命名和解读

import numpy as np


def show_topics(vectorizer, lda_model, top_n=30):
    """
    显示每个话题最重要的n个词语
    vectorizer: 词袋法或tfidf.基于前面代码这里使用TF-IDF法
    lda_model: 训练好的lda话题模型
    top_n: 设置最重要的n个特征词,默认30个.
    """
    
    keywords = np.array(vectorizer.get_feature_names_out())
    topic_keywords = []
    for topic_weights in lda_model.components_:
        top_keyword_locs = (-topic_weights).argsort()[:top_n]
        topic_keywords.append(keywords.take(top_keyword_locs))
    return topic_keywords


"""利用show_topics函数展示全职儿女文本中的4个话题,基于每个话题最重要的20个词语为每个话题命名"""
topic_keywords = show_topics(vectorizer=vectorizer,   # 【可改动】vectorizer我们训练的词语空间
                             lda_model=lda_model,     # 【可改动】lda_model训练的lda模型
                             top_n=20)                # 【可改动】最重要的30个词语

df_topic_keywords = pd.DataFrame(topic_keywords)
df_topic_keywords.columns = ['Word-' + str(i) for i in range(df_topic_keywords.shape[1])]
df_topic_keywords.index = ['Topic-' + str(i) for i in range(df_topic_keywords.shape[0])]
df_topic_keywords


4.2 预测文本的话题id

import numpy as np

def predict_topic(text):
    doc_term_matrix = vectorizer.transform([clean_text(text)])
    topic_term_prob_matrix = lda_model.transform(doc_term_matrix)
    topic_index = np.argmax(topic_term_prob_matrix)

    return topic_index

test_text2 = "最近,“全职儿女”话题受到舆论关注。“全职儿女”是指一种新型的脱产生活方式,年轻人脱产寄居父母生活,并通过付出一定的劳动换取经济支持,同时保持学习提升或发展副业的状态。这种生活方式既有其合理性和正当性,也有其问题和风险。我们不能一概而论,也不能一味否定或肯定。"

topic_index = predict_topic(test_text2)
print("该文本所属Topic: ", topic_index)

Run

    该文本所属Topic:  0

#批量预测
df['话题ID'] = df['clean_content'].apply(predict_topic)
df.head(1)

df['话题ID'].value_counts()

Run

话题ID
0    214
1     88
3     84
2     25
Name: count, dtype: int64

#预测结果保存到csv、xlsx中。
df.to_csv('output/话题预测结果.csv', index=False)
df.to_excel('output/话题预测结果.xlsx', index=False)



获取代码

点击下载本文



广而告之