基于某评论的TF-IDF下的LDA主题模型分析

完整代码:


import numpy as np
import re
import pandas as pd
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation

df1 = pd.read_csv('小红书评论.csv')  # 读取同目录下csv文件
# df1 = df1.drop_duplicates(subset=['用户id'])  # 获取一个id只评论一次的数据
pattern = u'[\\s\\d,.<>/?:;\'\"[\\]{}()\\|~!\t"@#$%^&*\\-_=+a-zA-Z,。\n《》、?:;“”‘’{}【】()…¥!—┄-]+'
df1['cut'] = df1['内容'].apply(lambda x: str(x))
df1['cut'] = df1['cut'].apply(lambda x: re.sub(pattern, ' ', x))  #对评论内容作清洗,只保留中文汉字,生成新的cut行
df1['cut'] = df1['cut'].apply(lambda x: " ".join(jieba.lcut(x)))  #对评论内容作分词和拼接
print(df1['cut'])
print(type(df1['cut']))


# 1.构造TF-IDF
tf_idf_vectorizer = TfidfVectorizer()
tf_idf = tf_idf_vectorizer.fit_transform(df1['cut'])
# 2.特征词列表
feature_names = tf_idf_vectorizer.get_feature_names_out()
# 3.将特征矩阵转变为pandas DataFrame
matrix = tf_idf.toarray()
feature_names_df = pd.DataFrame(matrix,columns=feature_names)
print(feature_names_df)
# 所有的特征词组成列,所有的评论组成行,矩阵中的元素表示这个特征词在该评论中所占的重要性,即tf-idf值,0表示该句评论中没有该词。

n_topics = 5
# 定义LDA对象
lda = LatentDirichletAllocation(
    n_components=n_topics,max_iter=50,
    learning_method='online',
    learning_offset=50.,
    random_state=0
)
# 核心,将TF-IDF矩阵放入LDA模型中
lda.fit(tf_idf)

#第1部分
# 要输出的每个主题的前 n_top_words 个主题词数
n_top_words = 50
def top_words_data_frame(model: LatentDirichletAllocation,
                         tf_idf_vectorizer: TfidfVectorizer,
                         n_top_words: int) -> pd.DataFrame:
    rows = []
    feature_names = tf_idf_vectorizer.get_feature_names_out()
    for topic in model.components_:
        top_words = [feature_names[i]
                     for i in topic.argsort()[:-n_top_words - 1:-1]]
        rows.append(top_words)
    columns = [f'topic {i + 1}' for i in range(n_top_words)]
    df = pd.DataFrame(rows, columns=columns)
    return df

#2
def predict_to_data_frame(model: LatentDirichletAllocation, X: np.ndarray) -> pd.DataFrame:
    matrix = model.transform(X)
    columns = [f'P(topic {i + 1})' for i in range(len(model.components_))]
    df = pd.DataFrame(matrix, columns=columns)
    return df


# 要输出的每个主题的前 n_top_words 个主题词数


# 计算 n_top_words 个主题词
top_words_df = top_words_data_frame(lda, tf_idf_vectorizer, n_top_words)

# 获取五个主题的前五十个特征词
print(top_words_df)

# 转 tf_idf 为数组,以便后面使用它来对文本主题概率分布进行计算
X = tf_idf.toarray()

# 计算完毕主题概率分布情况
predict_df = predict_to_data_frame(lda, X)

# 获取五个主题,对于每个评论,分别属于这五个主题的概率
print(predict_df)
import pyLDAvis
import pyLDAvis.sklearn

panel = pyLDAvis.sklearn.prepare(lda, tf_idf, tf_idf_vectorizer)
pyLDAvis.save_html(panel, 'lda_visualization.html')
pyLDAvis.display(panel)

一、数据清洗

 

代码逐行讲解:

df1 = pd.read_csv('小红书评论.csv')  # 读取同目录下csv文件
# df1 = df1.drop_duplicates(subset=['用户id'])  # 获取一个id只评论一次的数据
pattern = u'[\\s\\d,.<>/?:;\'\"[\\]{}()\\|~!\t"@#$%^&*\\-_=+a-zA-Z,。\n《》、?:;“”‘’{}【】()…¥!—┄-]+'
df1['cut'] = df1['内容'].apply(lambda x: str(x))
df1['cut'] = df1['cut'].apply(lambda x: re.sub(pattern, ' ', x))  #对评论内容作清洗,只保留中文汉字,生成新的cut行
df1['cut'] = df1['cut'].apply(lambda x: " ".join(jieba.lcut(x)))  #对评论内容作分词和拼接
print(df1['cut'])
print(type(df1['cut']))

读取同目录下的文件,df1是数据框格式

提取评论内容,并对评论内容做清洗,采用正则表达式,去除标点和英文。

用jieba对每一行的数据作分词处理,最后得到的数据展现以及数据类型。

cc395ce2626d4e26abfbe27aaf023067.png 

二、模型构建 

tf_idf_vectorizer = TfidfVectorizer()
tf_idf = tf_idf_vectorizer.fit_transform(df1['cut'])
# 2.特征词列表
feature_names = tf_idf_vectorizer.get_feature_names_out()
# 3.将特征矩阵转变为pandas DataFrame
matrix = tf_idf.toarray()
feature_names_df = pd.DataFrame(matrix,columns=feature_names)
print(feature_names_df)
# 所有的特征词组成列,所有的评论组成行,矩阵中的元素表示这个特征词在该评论中所占的重要性,即tf-idf值,0表示该句评论中没有该词。

# 定义LDA对象
n_topics = 5
lda = LatentDirichletAllocation(
    n_components=n_topics, max_iter=50,
    learning_method='online',
    learning_offset=50.,
    random_state=0
)
# 核心,将TF-IDF矩阵放入LDA模型中
lda.fit(tf_idf)
  1. tf_idf_vectorizer = TfidfVectorizer()

    • 这行代码创建了一个 TfidfVectorizer 对象,这是 scikit-learn 库中的一个文本向量化工具。它将文本数据转换为TF-IDF特征矩阵,这是一种常用的文本表示形式,能够反映出文本中单词的重要性。
  2. tf_idf = tf_idf_vectorizer.fit_transform(df1['cut'])

    • 这行代码执行了两个操作:
      • fit: 根据提供的文本数据(df1['cut'])来学习词汇表和计算IDF(逆文档频率)。
      • transform: 使用学习到的词汇表和IDF来转换文本数据为TF-IDF矩阵。结果 tf_idf 是一个稀疏矩阵,其中每一行代表一个文档,每一列代表一个单词,矩阵中的值表示该单词在文档中的重要性(TF-IDF权重)。
  3. # 定义LDA对象

    • 这是一个注释行,说明接下来的代码将定义一个LDA(隐狄利克雷分配)模型对象。
  4. n_topics = 5

    • 这行代码设置了一个变量 n_topics,其值为5,表示LDA模型中的主题数量。
  5. lda = LatentDirichletAllocation( ...)

    • 这行代码创建了一个 LatentDirichletAllocation 对象,即LDA模型,用于主题建模。它接受多个参数:
      • n_components=n_topics: 设置模型中的主题数量,这里与之前定义的 n_topics 变量相等。
      • max_iter=50: 设置模型训练的最大迭代次数。
      • learning_method='online': 指定学习算法,这里使用在线学习算法。
      • learning_offset=50.: 在线学习算法中的学习偏移量。
      • random_state=0: 设置随机状态,以确保结果的可重复性。
  6. lda.fit(tf_idf)

    • 这行代码将之前转换得到的TF-IDF矩阵 tf_idf 用于训练LDA模型。fit 方法将根据文档-词项矩阵和设置的主题数量来学习文档的主题分布以及词项在各个主题下的分布。

总的来说,这段代码的目的是使用LDA模型来发现文档集合中的潜在主题。首先,它通过TF-IDF向量化器将文本数据转换为数值矩阵,然后使用这个矩阵来训练LDA模型,最后可以通过模型来分析文档的主题分布。

打印出来的结果为:

f3c8644da9304920ae8f2e2331ad532a.png 

三、结果展现 

#第1部分
# 要输出的每个主题的前 n_top_words 个主题词数
n_top_words = 50
def top_words_data_frame(model: LatentDirichletAllocation,
                         tf_idf_vectorizer: TfidfVectorizer,
                         n_top_words: int) -> pd.DataFrame:
    rows = []
    feature_names = tf_idf_vectorizer.get_feature_names_out()
    for topic in model.components_:
        top_words = [feature_names[i]
                     for i in topic.argsort()[:-n_top_words - 1:-1]]
        rows.append(top_words)
    columns = [f'topic {i + 1}' for i in range(n_top_words)]
    df = pd.DataFrame(rows, columns=columns)
    return df

#2
def predict_to_data_frame(model: LatentDirichletAllocation, X: np.ndarray) -> pd.DataFrame:
    matrix = model.transform(X)
    columns = [f'P(topic {i + 1})' for i in range(len(model.components_))]
    df = pd.DataFrame(matrix, columns=columns)
    return df


# 要输出的每个主题的前 n_top_words 个主题词数


# 计算 n_top_words 个主题词
top_words_df = top_words_data_frame(lda, tf_idf_vectorizer, n_top_words)

# 获取五个主题的前五十个特征词
print(top_words_df)

# 转 tf_idf 为数组,以便后面使用它来对文本主题概率分布进行计算
X = tf_idf.toarray()

# 计算完毕主题概率分布情况
predict_df = predict_to_data_frame(lda, X)

# 获取五个主题,对于每个评论,分别属于这五个主题的概率
print(predict_df)

这段代码是用于分析和可视化LDA(Latent Dirichlet Allocation,隐狄利克雷分配)模型的输出结果的。以下是对代码的逐行解释:

 

这部分代码定义了两个函数,用于处理和展示LDA模型的结果。

  1. n_top_words = 50

    • 设置变量 n_top_words 为50,表示每个主题中要提取的前50个最重要的词。
  2. def top_words_data_frame(...) -> pd.DataFrame:

    • 定义了一个名为 top_words_data_frame 的函数,它接受一个LDA模型、一个TF-IDF向量化器和一个整数 n_top_words 作为参数,并返回一个包含每个主题的前 n_top_words 个词的DataFrame。
  3. rows = []

    • 初始化一个空列表 rows,用于存储每个主题的顶级词汇。
  4. feature_names = tf_idf_vectorizer.get_feature_names_out()

    • 从TF-IDF向量化器中获取词汇表,以便知道每个特征索引对应的词。
  5. for topic in model.components_:

    • 遍历LDA模型的每个主题。
  6. top_words = [feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1])

    • 对每个主题,获取其权重数组的排序索引,然后选择前 n_top_words 个索引对应的词。
  7. rows.append(top_words)

    • 将每个主题的顶级词汇列表添加到 rows 列表中。
  8. columns = [f'topic {i + 1}' for i in range(n_top_words)]

    • 创建DataFrame的列名,表示每个主题的顶级词汇。
  9. df = pd.DataFrame(rows, columns=columns)

    • 使用 rows 数据和 columns 列名创建一个DataFrame。
  10. return df

    • 返回包含每个主题顶级词汇的DataFrame。

 

这部分代码使用LDA模型对文档进行主题预测,并展示结果。

  1. def predict_to_data_frame(model: LatentDirichletAllocation, X: np.ndarray) -> pd.DataFrame:

    • 定义了一个名为 predict_to_data_frame 的函数,它接受一个LDA模型和一个NumPy数组 X 作为参数,并返回一个包含文档主题概率分布的DataFrame。
  2. matrix = model.transform(X)

    • 使用LDA模型的 transform 方法将文档集 X 转换为每个文档的主题概率分布矩阵。
  3. columns = [f'P(topic {i + 1})' for i in range(len(model.components_))]

    • 创建列名,表示每个文档属于每个主题的概率。
  4. df = pd.DataFrame(matrix, columns=columns)

    • 使用转换得到的主题概率矩阵和列名创建一个DataFrame。
  5. return df

    • 返回包含文档主题概率分布的DataFrame。

 

这部分代码执行了上述定义的函数,并打印了结果。

  1. top_words_df = top_words_data_frame(lda, tf_idf_vectorizer, n_top_words)

    • 调用 top_words_data_frame 函数,获取LDA模型的每个主题的前50个词。
  2. print(top_words_df)

    • 打印每个主题的前50个词。
  3. X = tf_idf.toarray()

    • 将TF-IDF矩阵转换为一个NumPy数组,以便用于主题预测。
  4. predict_df = predict_to_data_frame(lda, X)

    • 调用 predict_to_data_frame 函数,获取文档的主题概率分布。
  5. print(predict_df)

    • 打印每个文档属于每个主题的概率。

这段代码的目的是分析LDA模型的结果,展示每个主题的代表性词汇以及文档的主题概率分布,从而帮助理解文档集合中的潜在主题结构。

88f21d2d865741a38f4aadc86b88b949.png

 

四、可视化分析

# 获取五个主题,对于每个评论,分别属于这五个主题的概率
print(predict_df)
import pyLDAvis
import pyLDAvis.sklearn

panel = pyLDAvis.sklearn.prepare(lda, tf_idf, tf_idf_vectorizer)
pyLDAvis.save_html(panel, 'lda_visualization.html')
pyLDAvis.display(panel)

结果展现:

24d632f02fc644db9fb9eee781e2cc46.png 

五、词云图分析

另写代码,加入停用词后,对数据内容作词云图分析:

import numpy as np
import re
import pandas as pd
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation
from wordcloud import WordCloud  # 导入 WordCloud 类
import matplotlib.pyplot as plt

# 读取小红书评论数据
df1 = pd.read_csv('小红书评论.csv')
pattern = u'[\\s\\d,.<>/?:;\'\"[\\]{}()\\|~!\t"@#$%^&*\\-_=+a-zA-Z,。\n《》、?:;“”‘’{}【】()…¥!—┄-]+'
df1['cut'] = df1['内容'].apply(lambda x: str(x))
df1['cut'] = df1['cut'].apply(lambda x: re.sub(pattern, ' ', x))

# 定义停用词列表,将你、了、的、我、你等常见词加入其中
stop_words = set(['你', '了', '的', '我', '你', '他', '她', '它','是','有','哭','都','吗','也','啊'])

# 分词并过滤停用词
df1['cut'] = df1['cut'].apply(lambda x: " ".join([word for word in jieba.lcut(x) if word not in stop_words]))


# 生成小红书评论的词云图
def generate_wordcloud(text):
    wordcloud = WordCloud(background_color='white', font_path='msyh.ttc').generate(text)
    plt.figure()
    plt.imshow(wordcloud, interpolation="bilinear")
    plt.title("小红书评论词云")
    plt.axis("off")
    plt.show()

# 获取小红书评论的文本
all_comments_text = ' '.join(df1['cut'])

# 生成词云图
generate_wordcloud(all_comments_text)

结果展现:e5fc30176bda4be4bba7d3af2eecfa49.png 

数据我在上方绑定了,需要可自取。 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/707276.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最短路径Bellman-Ford算法和SPFA算法详解

目录 Bellman-Ford算法介绍 Bellman-Ford算法证明 Bellman-Ford算法实现 SPFA算法详解 Bellman-Ford算法介绍 Dijkstra算法可以很好的解决无负权图的最短路径问题&#xff0c;但是如果出现了负权边&#xff0c;Dijkstra算法就会失效。为了更好地求解有负权边的最短路径问…

redis 06 集群

1.节点&#xff0c;这里是把节点加到集群中的操作&#xff0c;跟主从结构不同 这里是在服务端使用命令&#xff1a; 例子&#xff1a; 2.启动节点 节点服务器 首先&#xff0c;先是服务器节点自身有一个属性来判断是不是可以使用节点功能 一般加入集群中的节点还是用r…

常见的 EVM 版本以及它们的区别

EVM&#xff08;以太坊虚拟机&#xff09;版本的演进是为了引入新的特性和改进以太坊平台的安全性、效率和功能性。每个版本通常伴随着以太坊网络的硬分叉&#xff0c;这是以太坊协议的重大升级。以下是一些常见的EVM版本及其主要区别&#xff1a; Homestead (2016年3月)&…

用h()给渲染的组件传递参数

项目的一个下载悬浮提示框是使用antv的notification组件结合自定义的进度条实现的。 效果&#xff1a; 由于进度条需要完整显示&#xff0c;所以取消了组件自带的自动关闭效果。 查看官方文档&#xff0c;可以通过notification.close(key)来关闭提示框窗口。其中key是notifica…

【odoo】odoo常用的ORM方法

概要 在Odoo中&#xff0c;ORM&#xff08;对象关系映射&#xff0c;Object-Relational Mapping&#xff09;方法是一种将Python对象映射到数据库表的方法。Odoo的ORM系统使开发者能够使用高级的Python代码而不是复杂的SQL语句来操作数据库。Odoo的ORM方法主要用于创建、读取、…

驱动开发(二):创建字符设备驱动

往期文章&#xff1a; 驱动开发&#xff08;一&#xff09;&#xff1a;驱动代码的基本框架 驱动开发&#xff08;二&#xff09;&#xff1a;创建字符设备驱动 ←本文 目录 字符驱动设备的作用 函数 字符驱动设备注册和注销 注册 注销 自动创建设备节点 创建class类…

LogicFlow 学习笔记—7. LogicFlow 基础 背景 Background

背景 Background 提供可以修改画布背景的方法&#xff0c;包括背景颜色或背景图片&#xff0c;背景层位于画布的最底层。 info 创建画布时&#xff0c;通过 background 选项来设置画布的背景层样式&#xff0c;支持透传任何样式属性到背景层。默认值为 false 表示没有背景。 …

DETR实现目标检测(二)-利用自己训练的模型进行预测

1、图片预测&#xff08;CPU&#xff09; 关于DETR模型训练自己的数据集参考上篇文章&#xff1a; DETR实现目标检测(一)-训练自己的数据集-CSDN博客 训练完成后的模型文件保存位置如下&#xff1a; 准备好要预测的图片&#xff1a; 然后直接调用模型进行预测&#xff0c;并设…

图像生成新篇章:Stable Diffusion 3 Medium开源评析

摘要 在数字艺术与人工智能的交汇点上&#xff0c;Stable Diffusion 3&#xff08;SD3&#xff09;的开源无疑是一场技术革新的盛宴。就在3月份&#xff0c;我撰写了一篇博文&#xff0c;深入探讨了SD3的技术报告内容与介绍&#xff0c;文章发表在CSDN博客上&#xff0c;https:…

docker拉取镜像失败超时的解决方法,docker配置国内镜像源

更换国内源 创建或修改 /etc/docker/daemon.json 文件 安装docker后一般只有 /etc/docker 这个目录 下面并没有 daemon.json 文件 我们直接创建 &#xff1a; vim /etc/docker/daemon.json {"registry-mirrors" : ["https://registry.docker-cn.com"…

leetcode240 搜索二维矩阵II

题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18…

热门开源项目OpenHarmony

目录 1.概述 1.1.开源项目的意义 1.2.开源项目对软件行业的促进作用 1.3.小结 2.OpenHarmony 2.1.技术架构 2.2.分布式软总线 2.2.1.架构 2.2.2.代码介绍 2.2.2.1.代码目录 2.2.2.2.说明 2.2.2.3.发现组网和传输 2.2.2.3.1.发现 2.2.2.3.2.组网 2.2.2.3.3.传输…

H5漂流瓶交友源码|社交漂流瓶H5源码 附安装教程

H5漂流瓶交友源码|社交漂流瓶H5源码 附安装教程 搭建教程 环境&#xff1a;Nginx 1.20.1-MySQL 5.6.50-PHP-7.3 上传源码至网站根目录&#xff0c;创建并导入数据库 数据库信息修改&#xff1a;/config/database.php 网站运行目录/public 配置文件加入&#xff08;从24行…

2. 音视频H264

视频软件基本流程 1.什么是H264 H.264是由ITU-T视频编码专家组&#xff08;VCEG&#xff09;和ISO/IEC动态图像专家组&#xff08;MPEG&#xff09;联合组成的联合视频组&#xff08;JVT&#xff0c;Joint Video Team&#xff09;提出的高度压缩数字视频编解码器标准 H265又名高…

数据预处理之基于预测的(线性,ARIMA)异常值检测#matlab

基于密度的LOF异常值检测可见上篇文章。以下介绍基于预测的异常值检测&#xff1a; 1.基于预测的异常值检测方法 基于预测的异常值检测方法&#xff0c;特别是结合线性回归和ARIMA&#xff08;自回归积分滑动平均模型&#xff09;模型&#xff0c;是数据分析中常用的技术。这…

期末复习5---PTA

以下是提交正确的代码&#xff1a; int max_len( char *s[], int n ) {int i;int max0;for(i1;i<n;i){if(strlen(s[i])>strlen(s[max]))maxi;}return strlen(s[max]); } 以下是我自己写的代码&#xff1a; 出现的问题是 &#xff1a;括号加的不对&#xff0c;需要细心…

Vue31-生命周期的简介

一、需求&#xff1a;文字的透明度递减 示例&#xff1a; 对象的简写形式 new vue({ key:value, key:value, 。。。。。。 }) 二、代码的实现 注意&#xff1a;JS不擅长小数的计算&#xff01;&#xff01;&#xff01; 此写法不好&#xff01;&#xff01;&#xff01;追求…

【抽代复习笔记】19-群(十三):奇偶置换、循环置换的几个定理及例题

定义&#xff1a; ①在Sn中&#xff0c;能够表示为奇数多个对换乘积的置换称为“奇置换”&#xff0c;能够表示为偶数多个对换乘积的置换称为“偶置换”&#xff1b; ②所有偶置换的集合记为An。 例1&#xff1a;&#xff08;1&#xff09;计算S1和S2中奇、偶置换的数目&…

QT基础-简介,安装(6.7.1编译)

目录 QT简介 一.QT编译 国内镜像网站 1. For windows a.下载:qt-everywhere-src-6.7.1.zip b.下载Cmake c.下载python d.查看readme.md e. x64 native Tools cd 到 源码目录 f.输入 g. 然后输入 ​编辑 h.最后输入 1.2. qt-creator 1.3. 配置编译 2. For Ubu…

数据结构(DS)学习笔记(4):线性表

2.1线性表的类型定义 线性表是最常用且最简单的一种数据结构&#xff0c;是一种典型的线性结构&#xff0c;一个线性表是n个数据元素的有限序列。 线性表&#xff1a;&#xff0c; ——是数据元素&#xff0c;是线性起点&#xff08;起始结点&#xff09;&#xff0c;是线性…