暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python | 如何从大量的公司公告中查找政策影响的痕迹?

数据化审计 2021-07-03
1198

点蓝字关注  设为星标 ☆ 优先赏阅
数据化审计:问题导向、应用至上、解决痛点

内容导读重大决策部署、重大政策最终都要落到每个经济实体头上,也必然会影响到每个经济实体的行为,年报作为行为的载体,也会流露出蛛丝马迹。

问题背景

“如何从公司公告中分析相关政策的影响?”

这个问题源自一位做公司财务方向研究的网友,也启发了一个看问题的视角:重大决策部署、重大政策最终都要落到每个经济实体头上,也必然会影响到每个经济实体的行为。

行为的结果自然也会在经营管理成果中有所映射,在上市的年度报告中,往往会披露各类政策对公司经营管理的影响。

此外,该问题对研究非结构化数据的应用也有借鉴意义。

本文重点是如何在多个文本文件中批量查找,关于如何在多个word文档中查找关键词,参见文章《如何批量在多个word文档中查找关键词?

图源:WW

实现思路

要分析这种影响,首先需要查找相关政策关键字在公告中的位置,然后读取关键字的上下文,再对这些文字进行分词、共词分析等处理、展现。

实现步骤如下:

  1. 文本内容获取,文本清洗,编码格式判断。这一步涉及从PDF文档中抽取文本的处理,还有文本内容的规范化处理。在python的PDF处理库pdfminer中,文字版本的PDF文件中的文本内容一般为位于LTTextBox中,可以使用get_text()函数提取。本文不赘述。公告PDF文件转为文本文件后,存放在代码所在目录的txt子目录下,每个公告一个文本文件(*.txt)。

  2. 循环读取文件,根据指定的关键词,查找关键词所在的上下文。本例中,查找“产业政策|货币政策|环保政策”三个关键词。为便后续溯源和分析,查找结果存入Excel文件,包括六个字段:文件名、行数、关键字、上下文、前一段、后一段。

  3. 对关键词所在的文本内容进行分词和词频统计,分析政策相关的共词。在使用jieba库进行分词过程中,需要根据文本的实际内容,增加自定义词组、停用词等处理。

代码运行环境

主环境为python 3.8 。Python 3.8.5 (default, Sep  3 2020, 21:29:08) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32。

核心外部库:

  • pandas==1.1.3
  • jieba==0.42.1

实现代码

"""
Python 3 环境
"""

import glob
import pandas as pd
import re # 内置的正则表达式处理库
import codecs
import jieba

# 建立一个空白的pandas数据框 df,用于存放查找的结果
# 并考虑提取关键字所在的前后段落作为参考
df = pd.DataFrame(columns=[u'文件名',u'行数',u'关键字',u'上下文',u'前一段',u'后一段'])

# 确定查询关键词 多个关键词间用英文的 | 隔开,并放在英文括弧中 ()
kw = u'(产业政策|货币政策|环保政策)'

# 建立一个正则表达式规则字符串,匹配关键词前后的所有中文
# 关键词前后各取30个字作为上下文摘要,可以调整数值
regstr = u'([\w\W\u4e00-\u9fff]{0,30}'+kw+u'[\w\W\u4e00-\u9fff]{0,30})'
pattern = re.compile(regstr) 

# 循环读取指定目录下的文本文件 进行检索
for f in glob.glob('txt/*.txt'):
    # 逐个读取文本文件 并将文本文件内容逐行存入list
    with codecs.open(f,mode='r',encoding='utf-8'as fp:
        fcontentlist = fp.readlines()

    # 对每行文本进行循环查找
    for index,p in enumerate(fcontentlist):
        results =  pattern.findall(p)
        # 查找的结果是个list变量,可以理解为存储多个值的表
        # 循环查找结果的list 提取每个查找结果
        for result in results:
            ## 显示下查询结果
            print(u'【{}】-第【{}】段包含关键字【{}】\r\n上下文内容【{}】'.format(f,index,result[1],result[0]))
            # 创建一个空的list 用于存储6个字段的内容
            # strip函数删除结尾的换行字符
            row = []
            row.extend([f,index+1,result[1],result[0].strip('\r\n'),fcontentlist[index-1].strip('\r\n'),fcontentlist[index+1].strip('\r\n')])
            # 在数据框中添加一行记录,包括6个字段的数据
            df.loc[len(df)] = row

## 将数据框中的查询结果保存为中文格式的Excel文件
df.to_excel(u'查询结果.xlsx',encoding='gbk')


保存后的数据如下图所示:

# 对检索结果进行分词梳理,找到检索关键词的关系词
# 增加一个自定义词汇
jieba.add_word('环保政策')
# 根据实际情况 增加一些停用词
stopwords = ['我国','如果','主要','相关','一是','二是','三是']
segments = []
for idx,row in df.iterrows():
    ls = row['前一段'] + row['上下文'] + row['后一段']
    segs = jieba.cut(ls.replace(' ',''))
    #print(list(segs))
    for seg in segs:
        if len(seg)>1 and seg not in stopwords:
            segments.append({'word':seg,'count':1});

# 转换为dataframe 后续好计算
df_seg = pd.DataFrame(segments)
# 统计词频
df_wordcount = df_seg.groupby('word')['count'].sum().reset_index()
# 按照词频倒序排列
df_wordcount.sort_values(["count"],ascending=False,inplace=True)
# 列出前20个词
df_wordcount.head(20)

和“产业政策|货币政策|环保政策”相关高频出现的20个词语如下:

延伸应用

可以根据共词理论,对每个句子中的关键词进行抽取,建立共词矩阵,进行聚类等分析,找出这些文本聚焦的共同话题。

还可以将每个句子分词的结果当成一个“购物篮”数据,对相关词语出现的情况进行预测分析。

另外,由于微信公众号推送机制的调整,大家可以点下“赞”和“在看”,这样每次文章推送后,就会第一时间出现在您的订阅号列表中。


文章转载自数据化审计,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论