31.5月9日 临时使用jieba版
本项目预期结果:

步骤一:导入评论数据
在5月6日课程中,我们已经获取了B站视频的前200条热门评论。
我们利用之前课程结果“B站评论.json”。
我们首先实现读取json文件内容:
import json
with open('B站评论.json', 'r', encoding='utf-8') as json_file:
str_json = json.load(json_file)
print(str_json)
能看到,获取到了一个列表,每一项为一条评论内容。
步骤二:对每一条评论进行分词
构建一个循环,读出每一条评论内容
import jieba
import json
with open('B站评论.json', 'r', encoding='utf-8') as json_file:
str_json = json.load(json_file)
for item in str_json:
tokens = list(jieba.cut(item, cut_all=False))
print(tokens)
可见,每次分词后得到一个列表,列表内容为分词结果。
但是!这样的结果是没有办法进行词频统计的。
多个列表没法很好的进行后续的词频统计,我们需要将结果整合到一个列表中
# ....
words_list = []
for item in str_json:
tokens = list(jieba.cut(item, cut_all=False))
# 结合成一个列表
words_list.extend(tokens)
print(words_list)
words_list.extend() 和words_list.append()区别!重要!
我们之前都是使用append(),但是此处需要使用extend(),我们来做个辨析:
在Python中,extend和 append都是用于向列表中添加元素的方法,但它们的作用和使用场景有所不同:
append
append方法用于在列表末尾添加一个元素。- 如果提供的参数是一个可迭代对象(如列表、元组、字符串等),
append会将这个可迭代对象作为单个元素添加到列表中。
例如(只做展示,不用于此项目):
words_list = ['hello', 'world']
tokens = ['I', 'am', 'dl']
words_list.append(tokens) # 将tokens作为一个元素添加到words_list中
print(words_list) # 输出: ['hello', 'world', ['I', 'am', 'dl']]
extend
extend方法用于将一个可迭代对象的所有元素添加到列表末尾。- 与
append不同,extend会将可迭代对象中的每个元素分别添加到列表中,而不是作为一个整体。
例如(只做展示,不用于此项目):
words_list = ['hello', 'world']
tokens = ['I', 'am', 'dl']
words_list.extend(tokens) # 将tokens中的每个元素分别添加到words_list中
print(words_list) # 输出: ['hello', 'world', 'I', 'am', 'dl']
结论
本项目中,由于每次分词结果都是一个列表。我们是希望将每个列表中的每个元素加入到新列表中,而不是将每个列表加入新列表!
所以此处使用 extend
步骤三:词频统计
词频统计(Word Frequency Count)是自然语言处理(NLP)和文本分析中的一项基本任务,它涉及计算文档或语料库中每个单词出现的次数。词频统计对于多种应用场景非常重要,包括但不限于:
- 文本摘要:通过识别出现频率高的单词,可以推断出文档中的关键主题或概念。
- 情感分析:某些词语的出现频率可能与文本的情感倾向有关。
- 关键词提取:高频率的单词可能是文档的关键词。
- 文本分类:词频可以作为文本分类器的特征之一。
- 语言模型:在构建语言模型时,词频统计有助于了解语言的使用模式。
- 信息检索:搜索引擎优化(SEO)和信息检索系统会利用词频数据来评估文档的相关性。
词频统计的步骤通常包括:
- 预处理:对文本进行清洗,包括去除标点符号、转换为小写(如果区分大小写的语言)、去除停用词(stop words,即在文本分析中通常不携带有用信息的常见词)等。
- 分词:将文本分割成单词或词汇单元。
- 计数:对每个单词出现的次数进行计数。这通常通过创建一个字典(或哈希表)来完成,其中键是单词,值是该单词出现的次数。
- 排序:根据计数结果对单词进行排序,以识别最常见的单词。
- 可视化:有时,词频统计的结果会通过条形图、饼图等形式进行可视化展示。
collections库
我们进行词频统计需要用到collections 库
Counter是一个非常实用的类,用于快速进行词频统计。提供了丰富的方法来处理计数数据,是Python中处理计数问题的一个非常有用的工具。
示例代码(只做展示,不用于此项目):
from collections import Counter
# 假设我们有以下文本
text = "hello world hello universe"
# 分词
words = text.split()
# 使用Counter进行词频统计
word_counts = Counter(words)
# 输出词频统计结果
print(word_counts)
输出将是:
Counter({'hello': 2, 'world': 1, 'universe': 1})
这表明在给定的文本中,“hello”出现了两次,“world”和“universe”各出现了一次。
collections库的使用
在原先代码的基础上:
# ...
# 使用Counter进行词频统计
word_counts = Counter(words_list)
# 输出词频统计结果
print(word_counts)

可见,结果是Counter 对象,属于一种特殊的字典。
Counter 对象的一些特性包括:
- 元素的计数是整数值:每个键对应的值都是一个非负整数,表示该元素出现的次数。
- 无序性:Counter 是一个无序的集合
由图可知,当前结果存在几个重要的问题:
- 统计了标点符号,这本没有任何意义
- 统计许多“停用词”,这也没有意义
这就牵扯到词频分析的“预处理”了
步骤四:数据预处理,去除停用词
在自然语言处理(NLP)中,停用词(Stop Words)是指在文本处理时通常会被忽略的词汇,因为它们对于文本分析和理解通常贡献不大。这些词包括但不限于:
- 常见虚词:如“的”、“和”、“是”等,在中文中这些词非常常见,但在理解句子的主要意思时通常不是关键。
- 介词:如“在”、“对”、“关于”等,它们用于构建句子结构,但往往不携带关键信息。
- 连词:如“和”、“或”、“但是”等,它们用于连接句子或子句,但本身不包含具体内容。
- 助词:如“了”、“的”、“地”、“得”等,用于辅助句子的语气或时态,但通常不作为信息的载体。
- 冠词:如英文中的“a”、“an”、“the”等,在中文中没有冠词,但概念相似。
- 代词:如“我”、“你”、“他”等,虽然它们在某些情况下可以携带重要信息,但在进行词频统计或某些文本分析时,可能会被考虑作为停用词。
- 量词:如“个”、“只”、“件”等,它们用于计数,但在分析文本的主题时可能不是关键。
- 感叹词:如“哦”、“啊”、“嗯”等,通常用于表达情感,但在文本分析中可能不被视为重要。
- 填充词:如“呃”、“嗯”等,这些词在口语中常用,但在书面文本分析中通常没有太大价值。
- 各种符号:如,.,。等
在进行文本挖掘、搜索引擎优化、文本分类、情感分析等任务时,去除停用词可以减少噪声,提高处理效率和准确性。然而,是否将某些词视为停用词,以及停用词的具体列表,往往取决于具体的应用场景和分析目标。
使用现有的停用词列表(网上找的,还是很全的)
在现实项目中可以根据情况进行自定义添加或删除。
创建并导入停用词列表
stopwords_path = 'stopwords.txt'
stopwords = set()
with open('stopwords.txt', 'r', encoding='utf-8') as file_stopwords:
for line in file_stopwords:
stopwords.add(line.strip())
print(stopwords)
这段代码是用来创建一个停用词集合(stopwords),它将包含从指定文件中读取的停用词。下面是代码的逐行解释:
stopwords_path = 'stopwords.txt':这行代码定义了一个变量stopwords_path,它的值是一个字符串'stopwords.txt',这个字符串是包含停用词的文本文件的名称。这个文件应该位于与你的Python脚本相同的目录中,或者你需要提供文件的完整路径。stopwords = set():这里初始化了一个空的集合(set),用来存储后续读取的停用词。集合是一个无序的不重复元素集,适合用来存储唯一性重要的数据,如停用词。with open('stopwords.txt', 'r', encoding='utf-8') as file_stopwords::这行代码以只读模式('r')打开名为'stopwords.txt'的文件,并指定文件编码为'utf-8',这对于处理包含中文或其他非ASCII字符的文件是必要的。with语句是一个上下文管理器,它确保文件在使用后会被正确关闭,即使在读取文件过程中发生异常也是如此。for line in file_stopwords::这个for循环遍历文件file_stopwords中的每一行。在Python中,文件默认以读取模式打开时,for line in file会自动逐行读取文件,其中line是包括换行符的字符串。stopwords.add(line.strip()):在循环体内,这行代码使用strip()方法移除每一行字符串两端的空白字符(包括空格、制表符、换行符等),然后将处理后的单词添加到stopwords集合中。由于集合不允许有重复的元素,即使文件中的停用词有重复,它们在集合中也只会存储一次。
最终,stopwords集合包含了文件'stopwords.txt'中定义的所有停用词,每个停用词都是唯一的,并且没有前后的空白字符。这个集合可以用于后续的文本处理,例如在进行词频统计之前移除文本中的停用词。
在词频分析前对停用词进行过滤
对之前的代码进行更改:
words_list = []
for item in str_json:
# 分词
tokens = list(jieba.cut(item, cut_all=False))
# tokens结果是 ['您好', ',', '我', '是', '衡水二中', '的', '一', '名', '学生']
filtered_tokens = []
for token in tokens:
# token在 '您好' ',' ...中循环。
if token not in stopwords:
# 将不在停用词表中的添加如过滤后列表
filtered_tokens.append(token)
# 将过滤后的分词结果添加到words_list
words_list.extend(filtered_tokens)
结果为:

可见结果基本符合预期。
步骤五:利用词云将结果可视化
纯数据的词频结果,既不直观也不好看。一般我们使用词云进行数据的可视化。
要创建一个词云,您需要使用一个可以生成词云的库,比如 wordcloud
wordcloud 是一个流行的Python库,用于生成词云,即根据文本数据中的词频以不同大小显示单词的视觉表现形式。词云通过图形化的方式展示文本中各个单词的重要性,通常词频越高的单词在词云中显示得越大,位置也越显著。
以下是 wordcloud 库的一些关键特性:
- 多种布局形状:允许用户自定义词云的形状,如矩形、圆形,甚至可以使用自己的图片作为模板。
- 颜色和背景:支持设置词云的颜色方案和背景颜色。
- 字体选择:可以指定字体文件,对于生成中文词云等非拉丁字符的词云尤为重要。
- 词频统计:可以直接从词频统计(如
Counter对象)或原始文本生成词云。 - 停用词过滤:允许排除一些不需要显示在词云中的单词。
- 可定制性:提供多种参数调整,如最大词数、字体大小、词云尺寸等。
- 易于使用:具有简单的API,可以快速生成词云。
- 可视化:生成的词云可以保存为图片或直接在Jupyter Notebook中展示。
- 兼容性:与常见的Python可视化库如
matplotlib兼容,方便集成和展示。
安装wordcloud库通常可以通过pip进行:
pip install wordcloud
引入库
from wordcloud import WordCloud
import matplotlib.pyplot as plt
设置WordCloud类
wordcloud = WordCloud(
font_path='C:\\Windows\\Fonts\\HGWT_CNKI.TTF',
width=1200,
height=800,
background_color='white'
)
注意!WordCloud库,不带中文字体!!必须手动指定!
font_path: 这个参数指定了生成词云时使用的字体文件的路径。对于中文词云来说,需要使用支持中文字符的字体文件。这里指定的是 Windows 系统中常见的HGWT_CNKI.TTF字体,位于C:\Windows\Fonts目录下。如果您在其他操作系统上生成词云,需要选择一个合适的支持中文的字体文件。width和height: 这两个参数分别定义了生成词云图片的宽度和高度,单位是像素。这里设置的宽度为 1200 像素,高度为 800 像素。较大的尺寸可以使得词云更加清晰,但同时也会增加计算和渲染的时间。background_color: 这个参数定义了词云的背景颜色。这里设置为'white',即白色背景。您也可以选择其他颜色,如'black'(黑色)等,这会影响词云的整体视觉效果。
显示图片
这里我们又用到了“老朋友”matplotlib
# 绘制词云图
plt.figure(figsize=(12, 8))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off') # 去除坐标轴
plt.savefig('ciyun.png')
其中interpolation=‘bilinear’ 是 imshow() 函数的一个参数,它定义了图像插值的方法。插值是在图像放大或缩小时用来计算像素值的一种算法。‘bilinear’ 表示双线性插值,它在放大图像时可以提供平滑的边缘,减少锯齿效应。这对于词云图像尤其重要,因为词云中的文字边缘通常很细,使用适当的插值方法可以避免文字边缘出现不美观的锯齿。
结果如下:

存在以下问题:
- 评论中高频出现“罗老师”,“罗翔”,但是分词的时候会将其拆分成“罗”,“老师”
- 结果中“读”,“非”,“弹幕”,“太”等等。这些词其实是没有必要的。
步骤六: 优化结果
固定特有词
jieba.load_userdict('userdict.txt')
临时加入停用词
可以直接更改停用词文件,但有时候,只是需要在这个项目中临时加入一些停用词如:“弹幕”
这时候建议使用以下办法:
stopwords.add('\n')
结果
import jieba
import json
from collections import Counter
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# 加载自定义词典
jieba.load_userdict('userdict.txt')
# 读取JSON文件
with open('B站评论—胖猫-另1.json', 'r', encoding='utf-8') as json_file:
str_json = json.load(json_file)
stopwords_path = 'stopwords.txt'
stopwords = set()
with open(stopwords_path, 'r', encoding='utf-8') as file_stopwords:
for line in file_stopwords:
stopwords.add(line.strip())
stopwords.add(' ')
stopwords.add('\n')
words_list = []
for item in str_json:
# 使用jieba进行分词
tokens = list(jieba.cut(item, cut_all=False))
filtered_tokens = []
for token in tokens:
if token not in stopwords:
filtered_tokens.append(token)
words_list.extend(filtered_tokens)
# print(words_list)
word_counts = Counter(words_list)
print(word_counts)
wordcloud = WordCloud(
font_path='C:\\Windows\\Fonts\\HGWT_CNKI.TTF',
width=1200,
height=800,
background_color='white'
)
wordcloud.generate_from_frequencies(word_counts)
# 绘制词云图
plt.figure(figsize=(12, 8))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off') # 去除坐标轴
plt.savefig('B站-ciyun-pangmao-另1.png')

后续

