NLP-基于bertopic工具的新闻文本分析与挖掘
一,前言
最近简单接触了一些NLP的内容,练一下如何结合ChatGPT进行学习。
二,具体过程
(1)预处理文本,记录处理过程。
在使用Bertopic进行主题建模之前,需要对文本进行预处理。下面是如何使用Bertopic预处理文本的具体处理过程
1.安装Bertopic库:
在Python环境中安装Bertopic库。你可以使用pip命令来安装Bertopic库:
pip install bertopic
2.加载数据集:
数据下载地址:
链接:https://pan.baidu.com/s/1e7u\_7M3k19NMO8qwUlaTxA?pwd=eqqs
提取码:eqqs
将数据下载下来,存放位置如下
使用以下代码将训练集加载到一个列表中:
dirPath=r'E:\AIStudy\WordSystem\new2016zh'
validPath=os.path.join(dirPath,'news2016zh_valid.json')
datas=[]
with open(trainPath, 'r',encoding='utf-8') as f:
lines=f.readlines()
for line in lines:
data = json.loads(line)
datas.append(data)
3.预处理数据
在使用Bertopic进行主题建模之前,需要对数据进行预处理。Bertopic使用spacy库进行预处理,因此你需要安装spacy库并下载相应的模型。
可以使用以下命令来安装spacy和en_core_web_sm模型:
pip install spacy
python -m spacy download en_core_web_sm
具体对数据进行预处理程序如下:
print('#2.预处理数据')
nlp = spacy.load('en_core_web_sm')
texts = [doc['title'] for doc in datas]
processed_texts = []
qtar=tqdm(total=len(texts))
for text in texts:
qtar.update(1)
doc = nlp(text)
processed_texts.append(' '.join([token.lemma_ for token in doc if not token.is_stop and not token.is_punct]))
qtar.close()
print(len(processed_texts))
预处理运行中:
(2)使用文本聚类工具对新闻集合进行聚类处理,记录处理过程和结果。
我使用文本聚类工具Bertopic对新闻集合进行聚类处理,下面是处理的过程
4.记录处理过程
在进行文本预处理时,可以记录处理过程,以便以后查看
import logging
logging.basicConfig(filename='preprocessing.log', level=logging.INFO)
for doc in data:
text = doc['content']
doc = nlp(text)
processed_text = ' '.join([token.lemma_ for token in doc if not token.is_stop and not token.is_punct])
processed_texts.append(processed_text)
logging.info(f'Processed document {doc["id"]}: {text} -> {processed_text}')
5.使用Bertopic建立主题模型并训练
print('3.训练模型')
model = BERTopic(language='english', calculate_probabilities=True)
topics, probabilities = model.fit_transform(processed_texts)
6.评估模型
你可以使用sklearn.metrics提供的评估工具来评估模型的性能。
from sklearn.metrics import silhouette_score
silhouette_avg = silhouette_score(probabilities, topics)
print("Silhouette Score:", silhouette_avg)
7.分类新闻标题
最后,使用训练好的模型来对新闻标题进行分类。假设你有一个新的新闻标题,可以使用以下代码将其分类到一个主题:
new_title = '如何选择儿童摄影机构给宝宝拍照?'
new_processed_text = ' '.join([token.lemma_ for token in nlp(new_title) if not token.is_stop and not token.is_punct])
new_topic, new_prob = model.transform([new_processed_text])
处理结果如下:
(3)人工观察聚类结果进行简单调优,记录调优过程和结果。
基于以下对聚类结果进行简单调优的基本准则
1.检查聚类质量:首先,需要检查聚类结果的质量。可以使用Silhouette Score、Calinski-Harabasz Index等指标来评估聚类结果的质量。如果聚类质量不佳,可以尝试调整聚类参数或者增加数据量来提升聚类效果。
2.根据聚类结果进行分类:将聚类结果根据主题进行分类,可以发现相似主题下的文章,有助于进一步对聚类结果进行理解和分析。
3.调整聚类粒度:根据聚类结果,可以对聚类粒度进行调整。如果聚类结果过于粗糙,可以尝试增加主题数或者调整聚类参数;如果聚类结果过于细致,可以尝试减少主题数或者调整聚类参数。
4.检查聚类标签:检查聚类标签是否能够准确地描述聚类结果。如果聚类标签不够准确,可以考虑手动修改聚类标签或者使用自动化标签生成技术来生成更准确的聚类标签。
5.进一步分析聚类结果:对聚类结果进行进一步的分析,可以发现主题之间的关联性和区别性,有助于进一步理解文本数据的内在结构。可以使用可视化技术将聚类结果可视化,或者使用文本挖掘技术进行主题词提取和文本关系分析等。
我们对以上的结果进行一下分析。
1.提高数据量,为了方便查看效果,我只使用了5000词条,数据较小。
2.调整聚类参: calculate_probabilities=True, top_n_words=5, nr_topics=3。语言改为简体中文
可以看到聚类效果,提升了6倍多
3.根据聚类结果与标签进行分类
calculate_similarity:用于指定是否计算主题之间的相似度,默认为 False。
similarity_threshold:用于指定主题之间的相似度阈值,当两个主题的相似度高于此阈值时,这两个主题将被合并为一个主题,默认为 0.75。
三、实验分析和总结
1学习文本处理的基本概念和术语,包括文本信息抽取、文本聚类和文本摘要等。
(2)掌握文本处理中常用的指标,如准确率、召回率、F1值等,可以帮助你衡量算法性能。
(3)熟悉常用的文本处理工具和算法,如TextRank算法、Summarization算法、BERTopic算法等。
(4)掌握文本聚类的基本过程和方法,包括文本预处理、聚类模型训练、聚类结果评估和聚类结果可视化等。
(5)了解如何从文本中提取关键词和摘要句,并将它们用于生成新闻专题的概要。
对于初学者来说是一份很好学习资料,可以快速入门并掌握文本处理的基本技术和工具。同时,涉及到了一些常用的文本处理算法和工具,这些内容也对于进一步深入学习和应用文本处理技术来说非常有帮助。
同时也学习了一些常见调优方法,可以让我可以更好地理解和优化聚类结果
四、思考题
(1)针对父子事件的定义,上述过程中所采用的方法聚类的粒度是过粗还是过细,思考优化方式。
1.上述过程中所采用的方法聚类的粒度是过粗
针对父子事件的定义,使用文本聚类工具Bertopic对新闻池进行聚类时,聚类的粒度可能会受到影响。如果聚类过粗,则可能会将不同的子事件聚合到同一个父事件中,导致无法区分不同的子事件;如果聚类过细,则可能会将同一个父事件分成多个子事件,导致聚类结果过于细致。
为了解决这个问题,我们在检索了一些资料之后发现可以,采取以下优化方式:
调整主题数:Bertopic的聚类粒度取决于主题数,因此我们可以通过调整主题数来控制聚类的粒度。如果聚类过粗,可以尝试增加主题数;如果聚类过细,可以尝试减少主题数。需要注意的是,主题数不应该设置得太小或太大,否则可能会导致聚类效果变差。
调整聚类参数:Bertopic提供了一些参数可以用来调整聚类的粒度,例如词频阈值、主题相似度阈值等。通过调整这些参数,可以控制聚类的粒度。需要注意的是,不同的参数取值可能会对聚类结果产生不同的影响,因此需要进行实验来确定最佳的参数取值。
使用层次聚类:Bertopic使用的是基于密度的聚类方法,可能会导致聚类结果过于粗糙。可以考虑使用层次聚类方法,将聚类结果分层,从而得到更为细致的聚类结果。层次聚类方法可以使用scikit-learn库中的AgglomerativeClustering类来实现。
结合手动标注:如果聚类结果过于粗糙或过于细致,可以考虑结合手动标注来进行优化。可以选择一部分代表性文本进行手动标注,然后将手动标注的结果反馈到聚类模型中,从而优化聚类结果。手动标注可以采用人工标注、半自动标注或众包标注等方式。
五,整合代码
全部代码整合如下
import json
import spacy
import os
from tqdm import tqdm
from bertopic import BERTopic
from sklearn.metrics import silhouette_score
# 1.加载数据集
print('# 1.加载数据集')
dirPath=r'E:\AIStudy\WordSystem\new2016zh'
validPath=os.path.join(dirPath,'news2016zh_valid.json')
datas=[]
with open(validPath, 'r',encoding='utf-8') as f:
lines=f.readlines()
for i in range(len(lines)):
line=lines[i]
data = json.loads(line)
datas.append(data)
if i>2000:
break
#2.预处理数据
print('#2.预处理数据')
nlp = spacy.load('en_core_web_sm')
texts = [doc['title'] for doc in datas]
processed_texts = []
qtar=tqdm(total=len(texts))
for text in texts:
qtar.update(1)
doc = nlp(text)
processed_texts.append(' '.join([token.lemma_ for token in doc if not token.is_stop and not token.is_punct]))
qtar.close()
print(len(processed_texts))
#3训练模型
print('3.训练模型')
model = BERTopic(language='chinese (simplified)', calculate_probabilities=True, top_n_words=5, nr_topics=3)
topics, probabilities = model.fit_transform(processed_texts)
#4评估模型
silhouette_avg = silhouette_score(probabilities, topics)
print("Silhouette Score:", silhouette_avg)
#实际分类
new_title = '如何选择儿童摄影机构给宝宝拍照?'
new_processed_text = ' '.join([token.lemma_ for token in nlp(new_title) if not token.is_stop and not token.is_punct])
new_topic, new_prob = model.transform([new_processed_text])
print(new_processed_text,new_topic, new_prob)