使用 R 语言处理港股年报计算数字赋能指数(繁体文本的文本分析)

最近有小伙伴问到了如何计算港股公司的数字赋能指数问题,在计算过程中我发现在处理繁体文本的时候不仅仅需要考虑繁体与简体的转换,还需要考虑繁体和简体的不同用词习惯。

在今天的课程中我们将会以「阿里巴巴」公司的年报分析为例进行讲解。

下载年报文件

港股上市公司的年报可以在披露易网站下载: https://sc.hkexnews.hk/TuniS/www.hkexnews.hk/index_c.htm

我下载了阿里巴巴公司 2020~2023 年的年报存放在了附件的 pdf 文件夹中。

读取和处理 pdf 文本

在之前的文本分析课程中我们讲解过 pdf 文件的文本提取和处理:

library(tidyverse)
library(jiebaR)

# 读取 pdf 文本
fs::dir_ls("pdf") %>%
lapply(function(x){
tibble(file = x,
text = paste0(pdftools::pdf_text(x), collapse = ""))
}) %>%
bind_rows() -> dfall

# 去除空格、换行符和制表符
dfall %>%
mutate(text = str_remove_all(text, "[\\s\\n\\t]")) -> dfall

dfall

下面我们将根据这一文本数据计算阿里巴巴的数字赋能指数,计算方法参考的是吴非(2021),附件中也提供了该文献的 pdf 文件。

企业数字化转型包含下面这些词汇:

我们下面要做的就是从年报文本中统计这些词汇的词频。然后加总起来就是企业的数字化转型指标了。

附件中的 dictionary.txt 文件存放的就是这些词汇,也就是后面分词使用的用户词典。

由于 dfall 里面的文本是繁体,而 dictionary.txt 中的词汇是简体,所以我们需要进行繁体-简体的转换。之前的课程中我们介绍过调用百度翻译接口进行语言转换的方法:

使用 R 语言调用百度翻译接口:https://rstata.duanshu.com/#/brief/course/87d85f8605dc4c5cb608a54341bf1725

不过对于这种超长文本,这个方法并不好用。所以这里我们可以使用中文繁简体字符对照表.txt文件进行字对字的转换。

繁体-简体转换

在 R 语言中,pinyi 包(https://github.com/pzhaonet/pinyin)可以实现把文字转换成拼音的功能,也可以自定义词典把某些字符批量替换成另外一些字符。

# 安装 pinyi
install.packages("pinyin")

该包的帮助文档给出了一个自定义词典的案例:

library('pinyin')
mypy <- pydic() # 载入默认字典
py("春眠不觉晓,处处闻啼鸟", dic = mypy) # 转换

dic_sj <- 'sijiao.txt' #自定义字典链接
mysj <- load_dic(dic_file = dic_sj) # 载入自定义字典
py("春眠不觉晓,处处闻啼鸟", sep = '_', dic = mysj) # 转换

我们这里就可以仿照 sijiao.txt 文件构建一个我们的繁简体转换词典:

# 构造中文繁简体字符对照表
write_delim(x = tibble("# format = 2\n"),
file = "简繁体对照表.txt", delim = " ",
quote = "none", col_names = F)

read_table('中文繁简体字符对照表.txt', col_names = F) %>%
separate(X1, into = c("繁体", "简体"), sep = "\\(") %>%
mutate(简体 = str_remove_all(简体, "\\)")) %>%
select(简体, 繁体) %>%
mutate(简体 = paste0(简体, "&&", row_number(), "&&")) %>%
mutate(繁体 = paste0(繁体, "\n")) %>%
write_delim("简繁体对照表.txt", delim = " ",
quote = "none", col_names = F, append = T)

然后就可以把繁体的年报转换成简体的了:

library(pinyin)
# 载入自定义字典
mysj <- load_dic(dic_file = "简繁体对照表.txt")
py("弔冊", sep = '_', dic = mysj)

dfall %>%
mutate(text = map_chr(text, py, dic = mysj, sep = "")) -> dfall2

# 去除特征符号
dfall2 %>%
mutate(text = str_remove_all(text, "&&\\d+&&")) -> dfall2

dfall2

繁体与简体的表达差异

按照我们最开始说的,在繁体文本的分析中,我们不仅仅需要进行繁体简体的转换,还需要注意不同文本的用词差异,例如简体文本中的“人工智能”,在繁体文本中通常使用“人工智慧”来表达。因此这里我们不能单纯把繁体转换成简体之后就立即进行文本分析,而是应该再处理下用户词典,尽可能包含同一词汇的各种表达方式。

所以下面我们把数字转型关键词再使用百度翻译接口翻译成繁体的表达方式:

# 词典翻译为繁体
read_csv("dictionary.txt", col_names = F) -> word

在之前的课程「使用 R 语言调用百度翻译接口」https://rstata.duanshu.com/#/brief/course/87d85f8605dc4c5cb608a54341bf1725 中我们介绍了百度翻译接口的使用,这里我们就可以使用该接口把简体文本翻译成繁体(注意这个就不是直接的字对字翻译了,例如它会把“人工智能”翻译成“人工智慧”):

library(tidyverse)
library(jsonlite)
appid = "20171205000102469"
key = "8PHPDzkGMr_kWd5rIhRc"
rand = round(runif(1, 1000000000, 9999999999), 0)
query = "人工智能"
paste0("http://api.fanyi.baidu.com/api/trans/vip/translate?q=", query, "&from=zh&to=cht&appid=", appid, "&salt=", rand, "&sign=", cli::hash_md5(paste0(appid, query, rand, key))) %>%
URLencode() %>%
fromJSON() -> lst
lst$trans_result$dst

然后就可以翻译所有的了:

word %>%
mutate(X2 = map_chr(X1, function(x){
rand = round(runif(1, 1000000000, 9999999999), 0)
paste0("http://api.fanyi.baidu.com/api/trans/vip/translate?q=", x, "&from=zh&to=cht&appid=", appid, "&salt=", rand, "&sign=", cli::hash_md5(paste0(appid, x, rand, key))) %>%
URLencode() %>%
fromJSON() -> lst
lst$trans_result$dst
})) -> word1

word1

合并两部分得到新的用户词典:

word1 %>%
mutate(X2 = map_chr(X2, py, dic = mysj, sep = "")) %>%
mutate(X2 = str_remove_all(X2, "&&\\d+&&")) %>%
mutate(id = row_number()) %>%
gather(X1, X2, key = "key", value = "value") %>%
distinct(value) -> word1a

word1a$value

word1a %>%
write.table("dictionary2.txt", col.names = F, row.names = F, quote = F)

根据新的用户词典进行分词与词频统计

engine_s2 <- worker(stop_word = "stopwords.txt", user = "dictionary2.txt")

dfall2 %>%
mutate(res = map(text, function(x){
jiebaR::segment(x, jiebar = engine_s2) %>%
dplyr::as_tibble() %>%
dplyr::count(value, sort = T)
})) -> dfall3

dfall3

最后再简单处理下就得到了数字赋能指数计算结果:

dfall3 %>%
select(-text) %>%
mutate(file = str_extract(file, "\\d+")) %>%
rename(年份 = file) %>%
mutate(年份 = as.numeric(年份)) %>%
unnest(res) %>%
filter(value %in% word$X1) %>%
spread(value, n, fill = 0) %>%
rowwise() %>%
mutate(数字赋能指数 = sum(c_across(大数据:C2C)))

点击这里跳转到 RStata 短书平台获取附件:使用 R 语言处理港股年报计算数字赋能指数(繁体文本的文本分析)

评论