R語言主題模型LDA評估公司面臨的風險領(lǐng)域與可視化
原文鏈接:http://tecdat.cn/?p=17996
原文出處:拓端數(shù)據(jù)部落公眾號
?
介紹
隨著越來越多的數(shù)據(jù)被數(shù)字化,獲取信息變得越來越困難。我們在本文中重點關(guān)注的一個示例是評估公司面臨的不同風險領(lǐng)域。
為此,我們參考公司提交給證券交易委員會的年度報告,其中提供了公司財務(wù)業(yè)績的全面摘要[1],包括公司歷史,組織結(jié)構(gòu),高管薪酬,股權(quán),子公司和經(jīng)審計的財務(wù)報表等信息,以及其他信息。
目的
除了通常的信息(例如股票的波動性,季節(jié)性方面)之外,公司還會發(fā)布諸如
“我們的前15名客戶約占我們凈銷售額的80%”
“已經(jīng)對我們提起產(chǎn)品責任訴訟”
這些作為潛在投資者對公司狀況的警告[3]。目的是對公司面臨的風險進行分類,這可以作為對警告投資者和潛在投資者的充分建議。
分析的意義
其中大多數(shù)是標準的東西–例如,庫存波動很大,有些企業(yè)是季節(jié)性的。我們尋找異常的信息,例如“我們的前15名客戶約占我們凈銷售額的80%”或“對我們提起了許多產(chǎn)品責任訴訟” – 非處方藥制造商?;蚩紤]演唱會的發(fā)起人提出:“我們承擔大量債務(wù)和租賃義務(wù),這可能會限制我們的運營并損害我們的財務(wù)狀況?!?/p>
?
分析
根據(jù)David Blei的說法,主題模型是一種算法,用于發(fā)現(xiàn)大量,非結(jié)構(gòu)化文檔集合的主要主題。主題模型可以根據(jù)發(fā)現(xiàn)的主題來組織集合[2]
主題模型是探索或理解任何語料庫集合的一種巧妙方法。首先,清理工作空間并加載所需的程序包,如下所示:
rm(list=ls()) # 清理工作空間
library("tm")
library("wordcloud")
library(lda)
為了簡便起見,我們下載了數(shù)據(jù),并從中提取了公司的風險部分。
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) ? ? ? ? ? ? ? ? ? ? ? ? ?#文本數(shù)據(jù)
{
x ?= ?gsub("<.*?>", "", x) ? ? ? ? ? ? ? ? ?# 用于刪除HTML標簽的正則表達式
x ?= ?gsub("[^[:alnum:]///' ]", " ", x) ? ? # 僅保留字母數(shù)字
x ?= ?iconv(x, "latin1", "ASCII", sub="") ? # 僅保留ASCII字符
x ?= ?tolower(x) ? ? ? ? ? ? ? ? ? ? ? ? ?# 轉(zhuǎn)換為小寫字符
x ?= ?removePunctuation(x) ? ? ? ? ? ? ? ?# 刪除標點符號
x ?= ?removeNumbers(x) ? ? ? ? ? ? ? ? ? ?# 刪除數(shù)字
x ?= ?stripWhitespace(x) ? ? ? ? ? ? ? ? ?# 刪除空格
x ?= ?gsub("^\\s+|\\s+$", "", x) ? ? ? ? ?# 刪除開頭和結(jié)尾的空格
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中出現(xiàn)的次數(shù)[7],而?逆文檔頻率?估計整個文檔集合中詞的稀有性。(如果在集合的所有文檔中都出現(xiàn)一個詞,則其IDF為零。)
#tokenize以列表形式輸出:
doc.list <- strsplit(companyRDF$RF, "[[:space:
# 計算詞表:
term.table <- table(unlist(doc.list))
對于我們的分析,我們使用?tf-idf,?通過較小的權(quán)重來規(guī)范出現(xiàn)在所有文檔中的關(guān)鍵詞的影響。
########################################################
# ? ? ? ? ? ?創(chuàng)建文檔矩陣 ? ? ? ? ? #
########################################################
x1 = Corpus(VectorSource(companyRDF$RF)) ? ? ? ? ?# 創(chuàng)建語料庫
#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)]
我們記錄與數(shù)據(jù)集相關(guān)的統(tǒng)計信息。
D <- length(documents) ? ? ?#文件數(shù) (85)
W <- length(vocab) ? ? ? ? # 詞匯中的詞數(shù) (6662)
doc.length <- sapply(documents, function(x) sum(x[2, ])) ?# 每個文檔的數(shù)量
N <- sum(doc.length) ?#數(shù)據(jù)總數(shù)
?語料庫中有?D = 85個文檔?和?W = 6662個關(guān)鍵詞標記。并且我們必須確定K個主題。
Topic模型為我們提供了兩個主要輸出:
一個是關(guān)鍵詞概率的θ矩陣-告訴我們每個關(guān)鍵詞屬于每個主題的概率是多少。
二是ω文檔矩陣-它是文檔中主題比例的概率分布。
現(xiàn)在,我們建立了一個包含6個主題的主題模型。主題比例(α)和主題多項式的Dirichlet超參數(shù)的值分別為0.02和0.02。
lda.cgibbs(documents = documents, K = K
,num.iterations = G, alpha = alpha
,eta = eta, initial = NU
使用LDAvis可視化擬合模型
我們已經(jīng)計算了每個文檔的數(shù)量以及整個語料庫中關(guān)鍵詞的出現(xiàn)頻率。我們將它們連同θ,ω和vocab一起保存在列表中,作為數(shù)據(jù)對象?Risk,包含在LDAvis包中。
現(xiàn)在,我們準備調(diào)用?CreateJSON()?函數(shù)?LDAvis。此函數(shù)將返回一個字符串,該字符串表示用于填充可視化效果的JSON對象。createJSON()函數(shù)計算主題頻率,主題間距離,并將主題投影到二維平面上以表示它們彼此之間的相似性。
json <- createJSON(phi = RiskAnalysis$pta,
doc.length = RiskAnalysis$doc.length,
serVis()函數(shù)可以采用json并以多種方式提供結(jié)果。我們評論了以下代碼,因為這是一個交互式代碼。
?#serVis(json)
這是我們選擇的6個主題的可視化
總體

主題一

主題二

主題三

主題四

主題五

主題六

我們可以看到?Topic-2?和?Topic-3?彼此重疊,這從它們中的關(guān)鍵詞也可以看出。但是,如果我們仔細觀察一下,?主題3?則更多地涉及?制造業(yè)?,其中涉及供應(yīng)管理,需求和供應(yīng)等。?主題2?則更多地涉及軟件產(chǎn)品,運營,收入和服務(wù)。
我們選擇一個值K = 6
K = 6 # 選擇模型中的主題數(shù)
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
我們來看一下項概率矩陣θ,以總項概率的降序?qū)@個矩陣進行排序:
## ? ? ? ? ? ?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
另外,我們看到了與主題相關(guān)的文檔關(guān)聯(lián)概率的ω矩陣。
## ? ? ? ? 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上的權(quán)重很大,而文檔7在主題5上的權(quán)重很大。文檔2是主題1和主題4的混合。
一些關(guān)鍵詞具有高頻,另一些具有低頻。我們要確保詞頻不會過度影響主題權(quán)重。因此,我們使用稱為“提升”的量度對關(guān)鍵詞頻率進行歸一化。
關(guān)鍵詞的提升是通過關(guān)鍵詞的出現(xiàn)概率歸一化的主題成員概率。如果某個主題的關(guān)鍵詞提升很高,那么可以說,該關(guān)鍵詞對于構(gòu)建該主題很有用。
由于主題函數(shù)不會返回關(guān)鍵詞的提升矩陣,因此我們可以編寫一個簡單的函數(shù)來計算每個關(guān)鍵詞的提升。
ptermtopic = theta[i, j] ? ? # 關(guān)鍵詞i是主題j成員的概率
pterm = sum(dtm1[,i])/sum1 ? # 關(guān)鍵詞i在語料庫中出現(xiàn)的邊際概率
lift[i, j] = ptermtopic/pterm ? # 因此,lift是通過出現(xiàn)概率歸一化的主題隸屬概率
}
}
我們?yōu)橐韵逻x擇的六個主題生成一個詞云
for (i in 1:K){ ? ? ? # 每個主題
a0 = which(lift[,i] > 1) # 主題i的提升大于1的項
freq = theta[a0,i] # 大于1的項的Theta
freq = sort(freq,decreasing = T) # 主題i具有較高概率的關(guān)鍵詞
# 自動更正提升度高于1的主題詞
n = ifelse(length(freq) >= 100, 100, length(freq))
# 繪制詞云圖
wordcloud(rownames(top_word), top_word, ?scal






研究共現(xiàn)矩陣可視化圖進一步了解
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))
# 現(xiàn)在獲取前30個單詞,讓我們找到文檔矩陣
mat ?= dtm1[,match(row.names(top_word),colnames(dtm1))]
# 將連接數(shù)限制為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矩陣中的位置
以下是根據(jù)我們選擇的主題對公司進行的分類。
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] "--------------------------"
結(jié)論
潛在主題1
主要講與產(chǎn)品制造及其需求-供應(yīng)鏈有關(guān)的風險?。
潛在主題2
主要講在線和移動廣告相關(guān)的主題 。
潛在主題3
該潛在主題講以與股息和養(yǎng)老金相關(guān)成本相關(guān)的風險。此外,我們還可以看到與寬帶和有線電視運營商相關(guān)的風險。
潛在主題4
該潛在主題講與太陽能行業(yè)財務(wù)/合并相關(guān)的風險。
潛在主題5
該潛在主題是衛(wèi)生部門,并討論與實施政府法規(guī)有關(guān)的風險。
參考資料
[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_chuang13
[4]??http://www.kiplinger.com/article/investing/T052-C000-S002-our-10-k-cheat-sheet-how-to-speed-read-a-company-s.html#KAR6M3qFkMeVI1Zo .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/measures.pdf
[8]??http://leitang.net/presentation/LDA-Gibbs.pdf

最受歡迎的見解
1.探析大數(shù)據(jù)期刊文章研究熱點
2.618網(wǎng)購數(shù)據(jù)盤點-剁手族在關(guān)注什么
3.r語言文本挖掘tf-idf主題建模,情感分析n-gram建模研究
4.python主題建??梢暬痩da和t-sne交互式可視化
5.r語言文本挖掘nasa數(shù)據(jù)網(wǎng)絡(luò)分析,tf-idf和主題建模
6.python主題lda建模和t-sne可視化
7.r語言中對文本數(shù)據(jù)進行主題模型topic-modeling分析
8.r語言對nasa元數(shù)據(jù)進行文本挖掘的主題建模分析
9.python爬蟲進行web抓取lda主題語義數(shù)據(jù)分析