关于数据挖掘:R语言主题模型LDA文本挖掘评估公司面临的风险领域与可视化附代码数据

38次阅读

共计 9711 个字符,预计需要花费 25 分钟才能阅读完成。

原文链接:http://tecdat.cn/?p=17996

最近咱们被客户要求撰写对于主题模型 LDA 的钻研报告,包含一些图形和统计输入。

随着越来越多的数据被数字化,获取信息变得越来越艰难。咱们在本文中重点关注的一个示例是评估公司面临的不同危险畛域

介绍

为此,咱们参考公司提交给证券交易委员会的年度报告,其中提供了公司财务业绩的全面摘要[1],包含公司历史,组织构造,高管薪酬,股权,子公司和经审计的财务报表等信息,以及其余信息。

目标

除了通常的信息(例如股票的波动性,季节性方面)之外,公司还会公布诸如

  • “咱们的前 15 名客户约占咱们净销售额的 80%”
  • “曾经对咱们提起产品责任诉讼”

这些作为潜在投资者对公司情况的正告[3]。目标是对公司面临的危险进行分类,这能够作为对正告投资者和潜在投资者的充沛倡议。

剖析的意义

其中大多数是规范的货色–例如,库存稳定很大,有些企业是季节性的。咱们寻找异样的信息,例如“咱们的前 15 名客户约占咱们净销售额的 80%”或“对咱们提起了许多产品责任诉讼”– 非处方药制造商。或思考演唱会的发起人提出:“咱们承当大量债权和租赁任务,这可能会限度咱们的经营并侵害咱们的财务状况。”

 

剖析

依据 David Blei 的说法,主题模型是一种算法,用于发现大量,非结构化文档汇合的次要主题。主题模型能够依据发现的主题来组织汇合[2]

主题模型是摸索或了解任何语料库汇合的一种奇妙办法。首先,清理工作空间并加载所需的程序包,如下所示:

rm(list=ls()) # 清理工作空间

library("tm")
library("wordcloud")
library(lda)

为了简便起见,咱们下载了数据,并从中提取了公司的危险局部。

textdata = readRDS("data.Rds")

咱们计算 词频 (term frequency,TF) 和逆文档频率(IDF inverse document frequency)进行评估

stpw = c("item.","1a","risk","factors","may","and","our","the","that","for","are","also","u","able","use","will","can","s")      # 抉择 stopwords.txt 文件
stopwords('english')         # tm 软件包停用词列表
comn  = unique(c(stpw, stpw1))       # 两个列表的并集
stopwords = unique(c(gsub("'","",comn),comn)) # 删除标点符号后的最终停用词 lsit

#############################################################
#                       文本清理                     #
#############################################################

text.clean = function(x)                          #文本数据
{x  =  gsub("<.*?>", "", x)                  # 用于删除 HTML 标签的正则表达式
  x  =  gsub("[^[:alnum:]///' ]"," ", x)     # 仅保留字母数字
  x  =  iconv(x, "latin1", "ASCII", sub="")   # 仅保留 ASCII 字符
  x  =  tolower(x)                          # 转换为小写字符
  x  =  removePunctuation(x)                # 删除标点符号
  x  =  removeNumbers(x)                    # 删除数字
  x  =  stripWhitespace(x)                  # 删除空格
  x  =  gsub("^\s+|\s+$", "", x)          # 删除结尾和结尾的空格
  x  =  gsub("'","", x)                    # 删除撇号
  x  =  gsub("[[:cntrl:]]", " ", x)         # 用空格替换控制字符
  x  =  gsub("^[[:space:]]+", "", x)        # 删除文档结尾的空白
  x  =  gsub("[[:space:]]+$", "", x)        # 删除文档开端的空白


###########################################################
# 定义文档矩阵
###########################################################
custom.dtm  = function(x1,                               # 文本语料库
                scheme)                           # tf 或 tfidf
{
  

#删除空白文档(即总和为零的列)for (i1 in 1:ncol(tdm.new)){if (sum(tdm.new[, i1]) == 0) {a0 = c(a0, i1)} }
length(a0)    # 语料库中的空文档
if (length(a0) >0) {tdm.new1 = tdm.new[, -a0]} else {tdm.new1 = tdm.new};

dim(tdm.new1)    # 缩小 tdm

}

词频 (term frequency,TF) 定义为词 t 在文档 d 中呈现的次数[7],而 逆文档频率 预计整个文档汇合中词的稀有性。(如果在汇合的所有文档中都呈现一个词,则其 IDF 为零。)

#tokenize 以列表模式输入:doc.list <- strsplit(companyRDF$RF, "[[:space:

  # 计算词表:
  term.table <- table(unlist(doc.list))

对于咱们的剖析,咱们应用 tf-idf, 通过较小的权重来标准呈现在所有文档中的关键词的影响。

########################################################
#            创立文档矩阵           #
########################################################

x1 = Corpus(VectorSource(companyRDF$RF))          # 创立语料库
#x1 = n.gram(x1,"bi",2)                   # 将至多 2 频率的 Bi-gram 编码为 uni-gram

dtm1 = custom.dtm(x1,"tf")               # 文档频率
dtm2 = custom.dtm(x1,"tfidf")            # 逆文档频率
freq1 = (sort(apply(dtm1,2,sum), decreasing =T)) # 计算词频

 (sort(apply(su,2,sum), decreasing =T)) # 计算词频

咱们将首先在语料库中建设惟一的词汇表,而后再映射到每个公司


get.terms <- function(x) {index <- match(x, vocab)
    index <- index[!is.na(index)]

咱们记录与数据集相干的统计信息。

 D <- length(documents)      #文件数 (85)
  W <- length(vocab)         # 词汇中的词数 (6662)
  doc.length <- sapply(documents, function(x) sum(x[2,]))  # 每个文档的数量
  N <- sum(doc.length)  #数据总数

 语料库中有 D = 85 个文档 和 W = 6662 个关键词标记。并且咱们必须确定 K 个主题。

Topic 模型为咱们提供了两个次要输入:

一个是关键词概率的 θ 矩阵 - 通知咱们每个关键词属于每个主题的概率是多少。

二是 ω 文档矩阵 - 它是文档中主题比例的概率分布。

当初,咱们建设了一个蕴含 6 个主题的主题模型。主题比例(α)和主题多项式的 Dirichlet 超参数的值别离为 0.02 和 0.02。


lda.cgibbs(documents = documents, K = K
                                     ,num.iterations = G, alpha = alpha
                                     ,eta = eta, initial = NU

应用 LDAvis 可视化拟合模型

咱们曾经计算了每个文档的数量以及整个语料库中关键词的呈现频率。咱们将它们连同 θ,ω 和 vocab 一起保留在列表中,作为数据对象 Risk,蕴含在 LDAvis 包中。

当初,咱们筹备调用 CreateJSON()函数 LDAvis。此函数将返回一个字符串,该字符串示意用于填充可视化成果的 JSON 对象。createJSON()函数计算主题频率,主题间间隔,并将主题投影到二维立体上以示意它们彼此之间的相似性。

  json <- createJSON(phi = RiskAnalysis$pta, 
                     doc.length = RiskAnalysis$doc.length, 

serVis()函数能够采纳 json 并以多种形式提供后果。咱们评论了以下代码,因为这是一个交互式代码。

  #serVis(json)

这是咱们抉择的 6 个主题的可视化

总体

主题一

主题二

主题三

主题四

主题五

主题六

咱们能够看到 Topic-2 和 Topic-3 彼此重叠,这从它们中的关键词也能够看出。然而,如果咱们仔细观察一下,主题 3 则更多地波及 制造业,其中波及供给治理,需要和供给等。主题 2 则更多地波及软件产品,经营,支出和服务。


点击题目查阅往期内容

NLP 自然语言解决—主题模型 LDA 案例:开掘人民网留言板文本数据

左右滑动查看更多

01

02

03

04

咱们抉择一个值 K = 6

  
K = 6 # 抉择模型中的主题数
opics(dtm2,  K = K, verb = 2) # 拟合 K 主题模型
## 
## Top 12 phrases by topic-over-null term lift (and usage %):
## 
## [1] 'bull', 'corning', 'rsquo', 'glass', 'teledyne', 'middot', 'vpg', 'ndash', 'vishay', 'dalsa', 'dow', 'lecroy' (17) 
## [2] 'aol', 'advertisers', 'yahoo', 'ads', 'advertising', 'tapp', 'reit', 'apps', 'engagement', 'zuckerberg', 'ibx', 'titles' (16.9) 
## [3] 'frontier', 'households', 'mbps', 'switched', 'escrow', 'unserved', 'windstream', 'rural', 'collective', 'territories', 'bargaining', 'tower' (16.8) 
## [4] 'flash', 'nand', 'captive', 'ssd', 'solar', 'modules', 'memory', 'bics', 'reram', 'module', 'applied', 'wafers' (16.8) 
## [5] 'merchant', 'groupons', 'companys', 'peo', 'nhs', 'clients', 'iaccn', 'motivated', 'ibms', 'client', 'csc', 'lorenzo' (16.8) 
## [6] 'leap', 'cricket', 'preservation', 'blurred', 'dated', 'deploys', 'mvno', 'subsidized', 'waiting', 'rollout', 'leaps', 'dividing' (15.8) 
## 
## Dispersion = -0.01

咱们来看一下项概率矩阵 θ,以总项概率的降序对这个矩阵进行排序:

##            topic
## phrase                 1            2            3            4            5            6
##   tds       2.648959e-06 2.586869e-06 2.805227e-06 2.680430e-06 2.702986e-06 3.510401e-02
##   brocades  2.842265e-06 2.669269e-06 2.823106e-06 2.920408e-06 2.799614e-06 2.506861e-02
##   clients   3.646912e-06 3.546243e-06 3.928365e-06 3.578786e-06 1.898607e-02 3.969126e-06
##   companys  3.492683e-06 3.201781e-06 3.634969e-06 3.471822e-06 1.816372e-02 3.747852e-06
##   sprints   2.549403e-06 2.484293e-06 2.629347e-06 2.561769e-06 2.579702e-06 1.698829e-02
##   brocade   2.856517e-06 2.680381e-06 2.839519e-06 2.936274e-06 2.811306e-06 1.651110e-02
##   solar     3.302091e-06 3.124243e-06 3.361212e-06 1.292429e-02 3.270826e-06 3.614037e-06
##   sprint    2.578740e-06 2.513213e-06 2.669652e-06 2.595447e-06 2.609471e-06 1.278997e-02
##   reit      3.553825e-06 1.196685e-02 3.855616e-06 3.501886e-06 3.483736e-06 3.886507e-06
##   clearwire 2.549970e-06 2.484945e-06 2.630211e-06 2.562457e-06 2.580352e-06 1.193481e-02

另外,咱们看到了与主题相干的文档关联概率的 ω 矩阵。

##         topic
## document          1          2         3          4         5         6
##       1  0.13290480 0.13105774 0.1318767 0.35729726 0.1209075 0.1259561
##       2  0.23640159 0.13706762 0.1484124 0.21041974 0.1342693 0.1334293
##       3  0.13676833 0.12301388 0.1227510 0.37290276 0.1251001 0.1194639
##       4  0.09920569 0.09944122 0.1006772 0.09860462 0.5015284 0.1005428
##       5  0.13465553 0.14035768 0.2964859 0.13016315 0.1426592 0.1556786
##       6  0.09969202 0.10480960 0.4542832 0.10026436 0.1099848 0.1309660
##       7  0.11668769 0.10861933 0.1301019 0.11348415 0.4139718 0.1171352
##       8  0.38743792 0.12338647 0.1222238 0.12780836 0.1241574 0.1149860
##       9  0.19793670 0.13959183 0.2197639 0.13766412 0.1675246 0.1375189
##       10 0.18527824 0.14644241 0.2087677 0.17083618 0.1542025 0.1344730

咱们能够说文档 1 和文档 3 在主题 4 上的权重很大,而文档 7 在主题 5 上的权重很大。文档 2 是主题 1 和主题 4 的混合。

一些关键词具备高频,另一些具备低频。咱们要确保词频不会适度影响主题权重。因而,咱们应用称为“晋升”的量度对关键词频率进行归一化。

关键词的晋升是通过关键词的呈现概率归一化的主题成员概率。如果某个主题的关键词晋升很高,那么能够说,该关键词对于构建该主题很有用。

因为主题函数不会返回关键词的晋升矩阵,因而咱们能够编写一个简略的函数来计算每个关键词的晋升。


    ptermtopic = theta[i, j]     # 关键词 i 是主题 j 成员的概率
    pterm = sum(dtm1[,i])/sum1   # 关键词 i 在语料库中呈现的边际概率
    lift[i, j] = ptermtopic/pterm   # 因而,lift 是通过呈现概率归一化的主题附属概率
      }
}

咱们为以下抉择的六个主题生成一个词云


for (i in 1:K){       # 每个主题
a0 = which(lift[,i] > 1) # 主题 i 的晋升大于 1 的项
freq = theta[a0,i] # 大于 1 的项的 Theta
freq = sort(freq,decreasing = T) # 主题 i 具备较高概率的关键词

# 主动更正晋升度高于 1 的主题词
n = ifelse(length(freq) >= 100, 100, length(freq))


# 绘制词云图
wordcloud(rownames(top_word), top_word,  scal 

钻研共现矩阵可视化图进一步理解

for (i in 1:K){       # 每个主题
a0 = which(lift[,i] > 1) # 主题 i 的晋升力大于 1 的项
freq = theta[a0,i] # 大于 1 的项的 Theta
freq = sort(freq,decreasing = T) # 主题 i 具备较高能力的词

# 主动更正大于 20 的词
n = ifelse(length(freq) >= 20, 20, length(freq))
 
# 当初获取前 30 个单词,让咱们找到文档矩阵
mat  = dtm1[,match(row.names(top_word),colnames(dtm1))]

# 将连接数限度为 2
for (p in 1:nrow(cmat)){
  vec = cmat[p, 

plot(graph,         #要绘制的图形
 layout=layout.fruchterman.reingold,    #布局办法 
 vertex.frame.color='blue',         #点边界的色彩
 vertex.label.color='black',        #名称标签的色彩
 vertex.label.font=1,           #名称标签的字体
 vertex.size = .00001,   # 点大小

eta = function(mat, dtm) {rownames(a12) = rownam 
    a13[1:15];  length(a13)
    a14a = match(a13, terms1);      # 匹配项在 mat1 矩阵中的地位
  

以下是依据咱们抉择的主题对公司进行的分类。

eta.file
    read_doc = mat[order(mat[,i], decreasing= T),]  # 对文档概率矩阵(twc)进行排序
    read_names = row.names(read_doc[1:n,])          # 前 n 个文档的文档索引
    s[[i]] = calib[as.numeric(read_names),1]     # 将前 n 个公司名称存储在列表中
## [1] "Companies loading heavily on topic 1 are"
## [1] "TELEDYNE TECHNOLOGIES INC"  "CORNING INC"                "VISHAY INTERTECHNOLOGY INC" "BENCHMARK ELECTRONICS INC"  "WESTERN DIGITAL CORP"      
## [1] "--------------------------"
## [1] "Companies loading heavily on topic 2 are"
## [1] "FACEBOOK INC"  "ECHOSTAR CORP" "YAHOO INC"     "AOL INC"       "GOOGLE INC"   
## [1] "--------------------------"
## [1] "Companies loading heavily on topic 3 are"
## [1] "FRONTIER COMMUNICATIONS CORP" "WINDSTREAM HOLDINGS INC"      "LEVEL 3 COMMUNICATIONS INC"   "MANTECH INTL CORP"            "CENTURYLINK INC"             
## [1] "--------------------------"
## [1] "Companies loading heavily on topic 4 are"
## [1] "FIRST SOLAR INC"        "SANDISK CORP"           "SUNPOWER CORP"          "APPLIED MATERIALS INC"  "ADVANCED MICRO DEVICES"
## [1] "--------------------------"
## [1] "Companies loading heavily on topic 5 are"
## [1] "AUTOMATIC DATA PROCESSING"   "DST SYSTEMS INC"             "COMPUTER SCIENCES CORP"      "CERNER CORP"                 "INTL BUSINESS MACHINES CORP"
## [1] "--------------------------"
## [1] "Companies loading heavily on topic 6 are"
## [1] "SPRINT CORP"                  "TELEPHONE & DATA SYSTEMS INC" "INTL GAME TECHNOLOGY"         "BROCADE COMMUNICATIONS SYS"   "LEAP WIRELESS INTL INC"      
## [1] "--------------------------"

论断

潜在主题 1

次要讲与产品制作及其需要 - 供应链无关的危险。

潜在主题 2

次要讲在线和挪动广告相干的主题。

潜在主题 3

该潜在主题讲以与股息和养老金相干老本相干的危险。此外,咱们还能够看到与宽带和有线电视运营商相干的危险。

潜在主题 4

该潜在主题讲与太阳能行业财务 / 合并相干的危险。

潜在主题 5

该潜在主题是卫生部门,并探讨与施行政府法规无关的危险。

参考资料

  • [1]  https://zh.wikipedia.org/wiki/Form_10-K
  • [2]  http://www.cs.columbia.edu/~blei/topicmodeling.html
  • [3]  http://machinelearning.wustl.edu/mlpapers/papers/icml2013_chu…
  • [4]  http://www.kiplinger.com/article/investing/T052-C000-S002-our… .99
  • [5]  http://www.uq.edu.au/student-services/learning/topic-analysis
  • [6]  http://cpsievert.github.io/LDAvis/reviews/reviews.html
  • [7]  http://disi.unitn.it/~bernardi/Courses/DL/Slides_11_12/measur…
  • [8]  http://leitang.net/presentation/LDA-Gibbs.pdf
    • *

点击文末 “浏览原文”

获取全文残缺代码数据资料。

本文选自《R 语言主题模型 LDA 文本开掘评估公司面临的危险畛域与可视化》。

点击题目查阅往期内容

Python 主题建模 LDA 模型、t-SNE 降维聚类、词云可视化文本开掘新闻组数据集
自然语言解决 NLP:主题 LDA、情感剖析疫情下的新闻文本数据
R 语言对 NASA 元数据进行文本开掘的主题建模剖析
R 语言文本开掘、情感剖析和可视化哈利波特小说文本数据
Python、R 对小说进行文本开掘和档次聚类可视化剖析案例
用于 NLP 的 Python:应用 Keras 进行深度学习文本生成
长短期记忆网络 LSTM 在工夫序列预测和文本分类中的利用
用 Rapidminer 做文本开掘的利用:情感剖析
R 语言文本开掘 tf-idf, 主题建模,情感剖析,n-gram 建模钻研
R 语言对推特 twitter 数据进行文本情感剖析
Python 应用神经网络进行简略文本分类
用于 NLP 的 Python:应用 Keras 的多标签文本 LSTM 神经网络分类
R 语言文本开掘应用 tf-idf 剖析 NASA 元数据的关键字
R 语言 NLP 案例:LDA 主题文本开掘优惠券举荐网站数据
Python 应用神经网络进行简略文本分类
R 语言自然语言解决(NLP):情感剖析新闻文本数据
Python、R 对小说进行文本开掘和档次聚类可视化剖析案例
R 语言对推特 twitter 数据进行文本情感剖析
R 语言中的 LDA 模型:对文本数据进行主题模型 topic modeling 剖析
R 语言文本主题模型之潜在语义剖析(LDA:Latent Dirichlet Allocation)

正文完
 0