特定事件追踪
基于给定事件关键词,采集事件资讯,对事件进行挖掘和分析。
架构:
------------------------------------------------------------------------------
1.基于话题关键词的话题历时语料库采集
基于scrapy爬虫框架:
一.Scrapy 简介:
Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,Scrapy 使用了 Twisted['twɪstɪd](其主要对手是Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求。
二.Scrapy框架
1.框架图
绿色线是数据流向
2.框架图讲解:
功能讲解:
Scrapy Engine(引擎): 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。
Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。
Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,
Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),
Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.
Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。
Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)
------------------------------------------------------------------------------
------------------------------------------------------------------------------
2.关于热点事件的情感分析
基于句法依存的情感分析+情感词扩展
https://www.cnblogs.com/bbn0111/p/6677517.html
https://blog.csdn.net/SpringRolls/article/details/80228349
https://blog.csdn.net/MrZhangZZ/article/details/60342343
https://www.cnblogs.com/CheeseZH/p/5768389.html
传入一篇文章,先做分句处理:依据文章中的句号,把文章分成若干句,装入list;情感句过滤:通过步骤1的linst,分词并且过滤出含有情感词的句子;计算情感句中每个分词的情感得分并累加,结果作为情感句的情感得分;最终求一篇文章的所有情感句的得分加和求平均,得到一篇文章的情感得分;通过双曲正切函数tanh把最后得分映射到(-1,1)区间作为最终得分。整个过程中用到jieba分词,ltp词性标注,依存句法格式化等ltp功能。
# 总结
1)基于情感词库的篇章级情感分析领域相关性很强,针对不同的领域,需要构建领域相关的情感词表,用于解决领域迁移性
2)本项目以情感词为核心,借助依存句法的情感计算方式还有改进空间
过程中学习:SentimentWordExpansion 基于SOPIM算法的情感词表扩展项目
SO-PMI情感倾向点互信息算法
https://www.jianshu.com/p/d9b6ed70abd9
输入:
1、5W个文档,每个文档为一行,保存在'./data/train.txt'中
2、种子情感词:正负情感词各50个,共100个,格式为 ‘词\t极性’,保存在'./data/sentiment_words.txt'中
1)输出:
1、格式:复杂,29.47870186147108,neg,2,a (词语,pmi值,情感极性,词长,词性)
2、正向扩充情感候选词,保存在'./data/candi_pos.txt'中
3、负向扩充情感候选词,保存在'./data/candi_neg.txt'中
2)参数:
window_size: 默认为5, 左右窗口为5,作为词共现窗口
结果:
以本项目5M语料,100个情感种子词作为语料进行训练得到的结果,可参考2)输出
以65M语料, 2700个情感种子词作为语料进行训练,按照sopmi进行从大到小排序,分别取Pos Top20, Neg Top20;
备注:
1、本算法效果受训练语料影响,语料越大,效果越好
2、本算法效率受训练语料影响,语料越大,训练越耗时100个种子词,5M的数据, 大约耗时62.679秒
3、候选词的选择,可根据PMI值,词长,词性设定规则,进行筛选
------------------------------------------------------------------------------
------------------------------------------------------------------------------
3.关于热点事件的搜索趋势
百度指数采集项目
BaiduIndexSpyder:https://github.com/liuhuanyong/BaiduIndexSpyder
微博指数采集项目
WeiboIndexSpyder:https://github.com/liuhuanyong/WeiboIndexSpyder
------------------------------------------------------------------------------
------------------------------------------------------------------------------
4.关于热点事件的话题分析
LDA,Kmeans模型进行话题分析
知识点:lda,lsi,svd,pca,hash_trick,plsa
https://www.cnblogs.com/zy230530/p/7029025.html
https://www.jianshu.com/p/bb7bce40a15a
https://blog.csdn.net/july_2/article/details/12710147
https://blog.csdn.net/qq_22238533/article/details/79451141
https://blog.csdn.net/qq_22238533/article/details/79460711
精读:
https://www.cnblogs.com/pinard/p/6805861.html
----------------------------------------------------------------------------------------------
K-means
步骤:
用到以下模块:
from sklearn.cluster import KMeans
from sklearn.feature_extraction.text import TfidfTransformer # Tfidf高频无用词过滤
from sklearn.feature_extraction.text import CountVectorizer #文本特征提取方法
----------------------------------------------------------------------------------------------
文本数据预处理:
sklearn 中 CountVectorizer、TfidfTransformer 和 TfidfVectorizer
https://blog.csdn.net/m0_37324740/article/details/79411651
当Kmeans聚类的K没有指定时,可以通过肘部法来估计聚类数量
https://blog.csdn.net/xiligey1/article/details/82457271
----------------------------------------------------------------------------------------------
corpus_train = "./corpus_train.txt" #训练集,[文章id,paper]
cluster_docs = "./cluster_result_document.txt" #输出聚类主题文章[文章id,主题id]
cluster_keywords = "./cluster_result_keyword.txt" #输出主题关键词[主题id,关键词]
num_clusters = 7 #聚类簇个数,超参
tfidf_train,word_dict=tfidf_vector(corpus_train) #预处理训练语料、构建词典得到[(文档矩阵索引对) 得分]、[词典索引对]
----------------------------------------------------------------------------------------------
关于得分构成,
count_v1= CountVectorizer(max_df=0.4,min_df=0.01)#向量化
counts_train = count_v1.fit_transform(corpus_train) #预处理,把文档内容处理成[(文档矩阵索引对) 词频]
tfidftransformer = TfidfTransformer()
tfidf_train = tfidftransformer.fit(counts_train).transform(counts_train) #将上面文档词频矩阵拟合归一化[(文档矩阵索引对) 得分]
----------------------------------------------------------------------------------------------
best_kmeans(tfidf_train,word_dict) #输入[(文档矩阵索引对) 得分]、[词典索引对],寻找最佳聚类个数,此处用的肘部法
----------------------------------------------------------------------------------------------
关于肘部法寻找最佳参数:
def best_kmeans(tfidf_matrix,word_dict):
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
import numpy as np
K = range(1, 10)
meandistortions = []
for k in K:
print (k,'****'*5)
kmeans = KMeans(n_clusters=k)
kmeans.fit(tfidf_matrix)
meandistortions.append(sum(np.min(cdist(tfidf_matrix.toarray(), kmeans.cluster_centers_, 'euclidean'), axis=1)) / tfidf_matrix.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.grid(True)
plt.xlabel('Number of clusters')
plt.ylabel('Average within-cluster sum of squares')
plt.title('Elbow for Kmeans clustering')
plt.show()
----------------------------------------------------------------------------------------------
start=time.time()
cluster_kmeans(tfidf_train,word_dict,cluster_docs,cluster_keywords,num_clusters)
----------------------------------------------------------------------------------------------
关于聚类:
km = KMeans(n_clusters=num_clusters)#根据超参聚类
order_centroids = km.cluster_centers_.argsort()[:, ::-1] # 按离质心的距离排列聚类中心,由近到远
后续选择出靠近每个主题最近的前50个特征
----------------------------------------------------------------------------------------------
end=time.time()
print("Time--->" + str(end-start))
----------------------------------------------------------------------------------------------
LDA
用到以下模块:
from gensim.models import LdaModel,TfidfModel,LsiModel
from gensim import corpora
if __name__=="__main__":
corpus_path = "./corpus_train.txt"
cluster_keyword_lda = './cluster_keywords_lda.txt'
cluster_keyword_lsi = './cluster_keywords_lsi.txt'
sentence_dict,dictionary,corpus,corpus_tfidf=create_data(corpus_path)
----------------------------------------------------------------------------------------------
关于create_data():
sentence_dict[count]=line[1] #保存文档内容
sentences.append(line[1].split(' ')) #构建语料
#对文本进行处理,得到文本集合中的词表
dictionary = corpora.Dictionary(sentences) #构造词典,变成[词,id]
#利用词表,对文本进行bow词袋模型表示
corpus = [dictionary.doc2bow(text) for text in sentences]
#利用bow,对文本进行tfidf表示
tfidf=TfidfModel(corpus)
corpus_tfidf=tfidf[corpus]#用tfidf过滤出高频无用词
return sentence_dict,dictionary,corpus,corpus_tfidf
----------------------------------------------------------------------------------------------
lsi_model(sentence_dict,dictionary,corpus,corpus_tfidf,cluster_keyword_lsi)
----------------------------------------------------------------------------------------------
关于lsi聚类:
lsi = LsiModel(corpus=corpus_tfidf, id2word=dictionary, num_topics=11) #设置主题个数参数,调包然后存储
----------------------------------------------------------------------------------------------
lda_model(sentence_dict, dictionary, corpus, corpus_tfidf,cluster_keyword_lda)
----------------------------------------------------------------------------------------------
关于lda聚类:
lda = LdaModel(corpus=corpus_tfidf, id2word=dictionary, num_topics=11)#调包训练,存储
#利用lsi模型,对文本进行向量表示,这相当于与tfidf文档向量表示进行了降维,维度大小是设定的主题数目
#这里选择53维,把所有语料都降维到53维,把稀疏的高级矩阵变成一个计算起来会比较轻松的小矩阵
#也把一些没有用的燥音给过滤掉了
------------------------------------------------------------------------------
------------------------------------------------------------------------------
5.关于热点事件的代表性文本分析
PageRank、TextRank
这个要从搜索引擎的发展讲起。最早的搜索引擎采用的是 分类目录的方法,即通过人工进行网页分类并整理出高质量的网站。那时 Yahoo 和国内的 hao123 就是使用的这种方法。
后来网页越来越多,人工分类已经不现实了。搜索引擎进入了 文本检索 的时代,即计算用户查询关键词与网页内容的相关程度来返回搜索结果。这种方法突破了数量的限制,但是搜索结果不是很好。因为总有某些网页来回地倒腾某些关键词使自己的搜索排名靠前。于是我们的主角要登场了。PageRank的核心思想就诞生了:
文本重要性计算:
知识点:pagerank textrank TF-IDF
针对某一事件话题下的新闻报道集合,通过使用docrank算法,对新闻报道进行重要性识别,并通过新闻报道时间挑选出时间线上重要新闻。
目前,网络上针对某一特定热门事件会产生大量的报道,这些报道会随着该事件的发展而发生内容上的变化,这个具体表现在时间轴上对应新闻的差异性。因此,这就产生了关于特定事件报道的三个问题:
1、同质的新闻报道有很多,如何对浩如烟海的新闻报道进行代表性新闻抽取
2、如何检测这种内容上的变化,如何表示这种内容,这个涉及到内容的表示问题
3、如何对这种变化的内容进行有效组织和表示
https://www.cnblogs.com/rubinorth/p/5799848.html
https://blog.csdn.net/qq_41664845/article/details/82869596
https://blog.csdn.net/laobai1015/article/details/77747702
https://blog.csdn.net/reigns_/article/details/80983031
https://blog.csdn.net/mmc2015/article/details/42581737
总结:
实验6) TextGrapher,包含textrank算法,用图谱形式展示了textrank算法构造的图结构而已
textrank TF-IDF进行关键词提取排序
textrank 基于句子的节点排序,引申docrank基于文章的节点排序
------------------------------------------------------------------------------
------------------------------------------------------------------------------
6.关于热点事件新闻文本的图谱化展示
输入一篇文档,将文档进行关键信息提取,进行结构化,并最终组织成图谱组织形式,形成对文章语义信息的图谱化展示。
如何用图谱和结构化的方式,即以简洁的方式对输入的文本内容进行最佳的语义表示是个难题。 本实验将对这一问题进行尝试,采用的方法为:输入一篇文档,将文档进行关键信息提取,并进行结构化,并最终组织成图谱组织形式,形成对文章语义信息的图谱化展示。
总结:
1)如何用图谱和结构化的方式,即以简洁的方式对输入的文本内容进行最佳的语义表示是个难题。
2)本项目采用了高频词,关键词,命名实体识别,主谓宾短语识别等抽取方式,并尝试将三类信息进行图谱组织表示,这种表 示方式是一种尝试。
3)命名实体识别以及关键信息抽取受限于NLP的性能,在算法和方式上还存在多处不足。
------------------------------------------------------------------------------
对文章进行去噪处理
对文章进行长句切分处理
对文章进行短句切分处理
words_list存储整篇文章的词频信息
ner_sents保存具有命名实体的句子
ners保存命名实体
triples保存主谓宾短语
存储文章事件
获取文章关键词, 并图谱组织
对三元组进行event构建
取文章词频信息话,并图谱组织
获取全文命名实体(基于CRF命名实体识别)
获取全文命名实体共现信息,构建事件共现网络(三元组)
将关键词与实体进行关系抽取(基于textrank关键词抽取,基于ltp依存句法分析进行实体关系抽取)
事件网络进行图谱化展示