一、文献阅读推荐
(一)组织制度分析:基于主题建模的研究述评与展望
文献来源:组织制度分析:基于主题建模的研究述评与展望
介绍:本文以国内外重要文献为语料库,通过主题建模提出了该流 派沿革的过程模型,据此阐明了组织制度分析的发展脉络与细分流派。本文以主题建模为工具,对组织制度分析的历史脉络和阶段划分进行梳理。
(1)方法认知
主题模型在管理研究领域具有广阔的研究前景。2019年,Hannigan等人[6]更是将主题模型概念化为“一个呈现的过程”,是从文本数据中呈现(Rendering)构念与主题关系的过程。该过程包括三步骤:(1)呈现语料库(Rendering Corpora),即选择和清理要分析的语料库。(2)呈现主题(Rendering Topics),通过算法将语料库编码为多组具有实质意义的类别,即“主题”。(3)呈现理论框架,将主题归纳为构念、因果联系或机制(见 Hannigan 等人 2019 提出的“主题模型在理论构建空间中的呈现” 。据此进一步表明,主题建模的机器学习算法并不是简单地将文本分析转化为机械过程,而是通过最小限度的人工干预来挖掘文本实质的可解释性潜在深层意义。
(2)数据来源及处理
同样的,中文语料库检索自中国知网 CSSCI 管理期刊中,以“制度理论” 或“制度分析”为关键词,获得共计 165 篇文献,其时间跨度为 1999 年至 2020 年。数据处理与英文文献大致相同。为确定应该生成多少主题, 本文采用 Mallet 相关度模型(Mallet Model Coherence),中英文语料库分别在 4 个主题模型和 15 个主题模型中显示出了很好的拟合度。
(二)Research trends of sustainability and marketing research, 2010–2020: Topic modeling analysis
文献来源:Research trends of sustainability and marketing research, 2010–2020: Topic modeling analysis
介绍:本研究通过应用基于潜在狄利克雷分配(LDA)模型的主题建模,仅调查了2010年至2020年间在SSCI或SCIE索引期刊上发表的2147篇文章的标题、摘要和关键词。结果指出了研究趋势的相关转变。
(1)方法介绍
主题建模是用于大型非结构化文本数据中潜在变量的流行统计工具。每个文档都有属于某个主题的概率,每个主题都由单词的概率分布来标识。在本研究中,使用了主题建模中使用最广泛的算法——潜在狄利克雷分配(LDA)。文档是根据主题的单词distribution以及主题在文档中的混合方式生成的。图1显示了LDA的文档生成过程。图中的每个节点1表示一个随机变量,α和β是狄利克雷分布φk和θd的超参数。φk是属于第k个主题的单词的分布,θd对应于属于dth文档的单词的分配。每个单词所属的主题z由θd决定。w是基于θd和z(d,n)生成的单词。对于包括在M个文档中的N个单词,迭代地执行该生成过程。
主题建模是一种已被证明的趋势分析分析方法。分析方法通过文献收集、预处理和主题建模进行标准化。图2显示了我们模型中主题建模的数据收集和预处理。
(2)数据处理
在LDA分析之前,对文本语料库进行预处理。首先,语料库中的所有文本都转换为小写。去除特殊字符后,通过应用单词标记化来标记文本。通过验证每个表征的词性,只提取名词,并通过提取词条来减少表征的数量。最后,将学术文献摘要中频繁出现且无意义的单词,如研究、论文和研究,定义为停止词,并删除相应的标记。对于从预处理中获得的数据的LDA分析,我们确定了主题的数量,α和β,它们是狄利克雷分布的超参数。在通过将主题的数量改变为5、10、15和20来进行LDA分析之后,通过检查每个主题的单词分布来确定主题的数量为15;α和β分别设置为0.1和0.01,
二、python实现主题建模的步骤
(一)python爬取知网文献实现lda
(1)功能描述
本设计具体功能如下:1.Selenium 爬取知网“Python”主题、类别为“核心期刊”论文,下载到 Excel 文件。2. LDA 模型分别对 5 个时间区间的文献进行分析,对比分析得出 Python 论文主题(应用领域)趋势,预测未来发文热点。由于知网 PC 端有很强的反爬虫机制,选择爬取手机端。
关键技术:(1.Python+Selenium库的使用。2. Python 处理 Excel 数据。3. jieba,gensim, pyLDAvis 等库的使用。)
(2)核心代码
1. Selenium_Reptile.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
import xlwt#写入excel的扩展工具
#驱动所在路径
chrome_driver = 'C:\Program Files\Google\Chrome\Application\chromedriver.exe'
browser = webdriver.Chrome(executable_path=chrome_driver)
browser.get('http://wap.cnki.net/touch/web/guide')#打开指定页面
time.sleep(0.3)#强制暂停0.3s便于看清爬虫步骤
# 搜索主题
topic = "Python"
browser.find_element_by_id('btnSearch').click()
browser.find_element_by_id('keyword_ordinary').send_keys(topic)
browser.find_element_by_class_name('btn-search').click()
time.sleep(0.3)
# 筛选类型
browser.find_element_by_id("articletype_a").click()
time.sleep(0.3)
browser.find_element_by_css_selector("a[data-value=\"11\"]").click()
# 获取论文数量
num = browser.find_element_by_class_name('search-number').text
num = int(num[:-1])#从位置0到位置-1的个数即所有数量
# 加载所有页面,若加载5页,改为for i in range(5):
for i in range(int(num/10)):#num/10根据文献数量锁定所有页面的数量
browser.find_element_by_class_name('c-company__body-item-more').click()
time.sleep(0.3)
# 获取文献信息
title = browser.find_elements_by_class_name('c-company__body-title')#标题
author = browser.find_elements_by_class_name('c-company__body-author')#作者
content = browser.find_elements_by_class_name('c-company__body-content')#摘要
source = browser.find_elements_by_class_name('color-green')#来源
cite = browser.find_elements_by_class_name('c-company__body-info')#引用
# 保存为xls文件
worksheet = xlwt.Workbook()#定义workbook
sheet = worksheet.add_sheet(topic)#添加sheet,以之前搜索的主题命名
head = ['标题', '作者', '摘要', '来源', '引用']#标题
for h in range(len(head)):
sheet.write(0, h, head[h])#把表头写到Excel里面去
i = 1#定义Excel表格的行数,从第二行开始写入,第一行已经写了标题
#依次写入每行记录
for n in range(len(title)):#文章标题的数量表示文献
sheet.write(i, 0, title[n].text)
sheet.write(i, 1, author[n].text)
sheet.write(i, 2, content[n].text)
sheet.write(i, 3, source[n].text)
sheet.write(i, 4, cite[n].text)
i += 1
worksheet.save('C:/Users/86184/Desktop/知网Python主题核心期刊论文.xls')#保存到桌面
# 关闭浏览器
browser.quit()
2.对导入表格的数据整理,txtAnalysis.py,在该过程中要运用stopwords.txt作停用词处理,构造词典,进一步运用LDA找到每个主题(词袋)下对应的多个词语。
import xlrd
import re
import jieba
import jieba.posseg as jp
import pyLDAvis.gensim_models
from gensim.models.coherencemodel import CoherenceModel
from gensim.models.ldamodel import LdaModel
from gensim.corpora.dictionary import Dictionary
class txtAnalysis:
def __init__(self,sheet_id,name_id):
self.sheet_id=sheet_id#表号
self.name_id=name_id#名称
def txthandle(self):
#读取表,行
table=xl.sheets()[self.sheet_id]
texts=[]
for i in range(1,table.nrows):
row=table.row_values(i)
txt=f"{row}"
#去除标点,字母,数字
txt=re.sub('[\W_]+','',txt)
txt=re.sub('[a-zA-Z]','',txt)
txt=re.sub('[\d]','',txt)
texts.append(txt)
#分词,构造词典
flags = ('n')#挖掘主题,限定词性为名词
stopwords = open("stopwords.txt","r",encoding='utf-8').read()# 停用词表
words_lst = []
for txt in texts:
# jieba分词,词性识别,去停用词
words = [i.word for i in jp.cut(txt) if i.flag in flags and i.word not in stopwords]
words_lst.append(words)
dictionary = Dictionary(words_lst)
corpus = [dictionary.doc2bow(words) for words in words_lst]
# lda模型计算
#设置主题个数为5,训练10次,种子数200,迭代100次
lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=5,passes=10,random_state=200,iterations=100)
# U_Mass Coherence可通过指标得合理主题数
ldaCM = CoherenceModel(model=lda, corpus=corpus, dictionary=dictionary, coherence='u_mass')
# 打印主题,每个主题显示8个词
for topic in lda.print_topics(num_words=8):
print("{0}".format(self.name_id),topic)
# LDA可视化
plot =pyLDAvis.gensim_models.prepare(lda,corpus,dictionary)
# 保存到本地html
pyLDAvis.save_html(plot, 'Python{0}论文LDA可视化结果.html'.format(self.name_id))
if __name__=='__main__':
#读取表格文件
xl= xlrd.open_workbook("处理.xlsx")
txtAnalysis1=txtAnalysis(1,"2019-2021")
txtAnalysis1.txthandle()
txtAnalysis2=txtAnalysis(2,"2016-2018")
txtAnalysis2.txthandle()
txtAnalysis3=txtAnalysis(3,"2013-2015")
txtAnalysis3.txthandle()
txtAnalysis4=txtAnalysis(4,"2010-2012")
txtAnalysis4.txthandle()
txtAnalysis5=txtAnalysis(5,"2010以前")
txtAnalysis5.txthandle()
(二)python实现LDA步骤
(1)文本预处理
import jieba
import re
import csv
# 创建停用词列表
def stopwordslist():
stopwords = [line.strip() for line in open('E:/Chinese_stop_words.txt',encoding='UTF-8').readlines()]
return stopwords
def processing(text):
"""
数据清洗, 可以根据自己的需求进行重载
"""
text = re.sub("@.+?( |$)", "", text) # 去除 @xxx (用户名)
text = re.sub("【.+?】", "", text) # 去除 【xx】 (里面的内容通常都不是用户自己写的)
text = re.sub(".*?:", "", text) #去除微博用户的名字
text = re.sub("#.*#", "", text) #去除话题引用
text = re.sub("\n","",text)
return text
# 对句子进行中文分词
def seg_depart(sentence):
jieba.load_userdict('E:/保留词.txt')
sentence_depart = jieba.cut(sentence.strip())
print(sentence_depart)
stopwords = stopwordslist() # 创建一个停用词列表
outstr = '' # 输出结果为outstr
for word in sentence_depart: # 去停用词
if word not in stopwords:
if word != '\t':
outstr += word
outstr += " "
return outstr
# 给出文档路径
filename = "E:/data/input.csv" #原文档路径
outputs = open("E:/data/output.csv", 'w', encoding='UTF-8') #输出文档路径
with open(filename, 'r', encoding='utf-8-sig') as csvfile:
reader = csv.reader(csvfile,delimiter=',',quotechar='"',doublequote=False)
for line in reader:
print(line[0]) #微博在文档的第一列
line = processing(line[0])
line_seg = seg_depart(line)
outputs.write(line_seg + '\n')
outputs.close()
print("分词成功!!!")
当爬取完所需微博保存在一个csv文件中后,可用如下代码对其进行分词、保留所需词、去除停用词操作,并将分词结果放在新的文档中。停用词和保留词网上都能搜到,可对其进行增减或保留词表中加入专业词汇。
(2)导入算法包
import gensim
from gensim import corpora
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import warnings
warnings.filterwarnings('ignore') # To ignore all warnings that arise here to enhance clarity
from gensim.models.coherencemodel import CoherenceModel
from gensim.models.ldamodel import LdaModel
(3)加载数据
先将文档转化为一个二元列表,其中每个子列表代表一条微博:
PATH = "E:/data/output.csv"
file_object2=open(PATH,encoding = 'utf-8',errors = 'ignore').read().split('\n') #一行行的读取内容
data_set=[] #建立存储分词的列表
for i in range(len(file_object2)):
result=[]
seg_list = file_object2[i].split()
for w in seg_list : #读取每一行分词
result.append(w)
data_set.append(result)
print(data_set)
构建词典,语料向量化表示:
dictionary = corpora.Dictionary(data_set) # 构建词典
corpus = [dictionary.doc2bow(text) for text in data_set] #表示为第几个单词出现了几次
(4)构建LDA模型
ldamodel = LdaModel(corpus, num_topics=10, id2word = dictionary, passes=30,random_state = 1) #分为10个主题
print(ldamodel.print_topics(num_topics=num_topics, num_words=15)) #每个主题输出15个单词
这是确定主题数时LDA模型的构建方法,一般我们可以用指标来评估模型好坏,也可以用这些指标来确定最优主题数。一般用来评价LDA主题模型的指标有困惑度(perplexity)和主题一致性(coherence),困惑度越低或者一致性越高说明模型越好。一些研究表明perplexity并不是一个好的指标,所以一般我用coherence来评价模型并选择最优主题,但下面代码两种方法我都用了。
#计算困惑度
def perplexity(num_topics):
ldamodel = LdaModel(corpus, num_topics=num_topics, id2word = dictionary, passes=30)
print(ldamodel.print_topics(num_topics=num_topics, num_words=15))
print(ldamodel.log_perplexity(corpus))
return ldamodel.log_perplexity(corpus)
#计算coherence
def coherence(num_topics):
ldamodel = LdaModel(corpus, num_topics=num_topics, id2word = dictionary, passes=30,random_state = 1)
print(ldamodel.print_topics(num_topics=num_topics, num_words=10))
ldacm = CoherenceModel(model=ldamodel, texts=data_set, dictionary=dictionary, coherence='c_v')
print(ldacm.get_coherence())
return ldacm.get_coherence()
(5)判断最佳主题数
绘制主题-coherence曲线,选择最佳主题数
x = range(1,15)
# z = [perplexity(i) for i in x] #如果想用困惑度就选这个
y = [coherence(i) for i in x]
plt.plot(x, y)
plt.xlabel('主题数目')
plt.ylabel('coherence大小')
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
plt.title('主题-coherence变化情况')
plt.show()
(6)结果输出与可视化
通过上述主题评估,我们发现可以选择5作为主题个数,接下来我们可以再跑一次模型,设定主题数为5,并输出每个文档最有可能对应的主题.
from gensim.models import LdaModel
import pandas as pd
from gensim.corpora import Dictionary
from gensim import corpora, models
import csv
# 准备数据
PATH = "E:/data/output1.csv"
file_object2=open(PATH,encoding = 'utf-8',errors = 'ignore').read().split('\n') #一行行的读取内容
data_set=[] #建立存储分词的列表
for i in range(len(file_object2)):
result=[]
seg_list = file_object2[i].split()
for w in seg_list :#读取每一行分词
result.append(w)
data_set.append(result)
dictionary = corpora.Dictionary(data_set) # 构建词典
corpus = [dictionary.doc2bow(text) for text in data_set]
lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=5, passes = 30,random_state=1)
topic_list=lda.print_topics()
print(topic_list)
for i in lda.get_document_topics(corpus)[:]:
listj=[]
for j in i:
listj.append(j[1])
bz=listj.index(max(listj))
print(i[bz][0])
同时我们可以用pyLDAvis对LDA模型结果进行可视化:
import pyLDAvis.gensim
pyLDAvis.enable_notebook()
data = pyLDAvis.gensim.prepare(lda, corpus, dictionary)
pyLDAvis.save_html(data, 'E:/data/3topic.html')
三、他山之石
「1」LDA主题模型简介及Python实现_(强推)-CSDN博客