特征工程:文本数据与其他另类数据

在这一章节,我们介绍股票分析中的另类数据特征。与上一章节的技术指标和基本面指标不同,另类数据指的是那些并不直接反应市场变化或者公司基本经营状况的数据。我们首先会通过举例的方式介绍另类数据的主要类别以及一些成功的应用案例。然后我们会主要以文本数据为例,分析如何提取其中的情绪因子。

1. 另类数据介绍

另类数据可以被大致分为如下几类:个人活动产生的数据、商业活动产生的数据和高科技监测获取的数据。

1.1 个人活动产生的数据

包括社交媒体、新闻稿和评论、搜索引擎数据、网络搜索量和点击率等。个人活动产生的数据既包括广大普通投资者通过社交网络表达的股票投资观点,也包括重要人物通过社交网络发布的重大消息,典型的代表就是美国的川普总统和他的推文。早在2010年,美国印第安纳大学的团队已开始研究Twitter的信息是否对道琼斯指数有持续的预测作用。研究团队分析每日的Twitter内容,划分为六种情绪状态,用时间序列方法,发现Twitter情绪能有效预测市场指数的升降,准确率高达87.6%。许多其他的渠道,包括新闻媒体、网络搜索、专业论坛等,也源源不断产生大量个人活动数据,这些数据也可以用于判断股价的走势。

这类数据也是相对而言比较获取的另类数据,通过网络爬虫等技术可以通过比较低的成本获取这类数据。

1.2 商业活动产生的数据

包括交易记录、信用记录、政府收集的数据等。这里商业活动产生的交易记录并不是指股票市场的交易。许多数据公司会与金融机构达成合作,获取匿名的交易数据和信用记录。比如一家另类数据提供商Eagle Alpha通过搜集和分析信用卡账户和电子邮件收据显示的交易信息,纠正样本偏差后,能有效预测零售业和餐饮业公司的收入情况,在正式财报公布之前抢占交易的先机。美国一家公司Thasos会根据特斯拉在加州弗里蒙特的工厂里员工的手机信号,监测员工加班的情况,来判断特斯拉的量产能力,从而提前预判特斯拉的股价。

商业活动产生的数据具有很高的商业价值,除了用于股价的分析,也是公司本身的商业机密,反应了公司的经营状况。获取这类数据往往需要比较高的成本和比较高的保密等级。监管机构也会担忧这些商业活动产生的数据,特别是跟个人身份、信用、消费等相关的记录,如果没有进行足够的匿名处理,可能泄露部分个人信息并带来潜在的危害,如电信诈骗等。

1.3 高科技监测获取的数据

卫星监测图像、地理定位和气候变化数据等。获取特定地点的卫星监测图像,可以推测一家企业的经营状况,例如根据卫星监控的油盖阴影判断原油的产量,根据停车场的停车数量推测大型超市的销量等。

高科技监测获取的数据获取的成本非常高,而且很有可能会出现带来的股票交易收益不能涵盖获取数据成本的情况。

2. 基于文本数据的情绪分析

2.1 原始数据获取

尽管新浪微博、Twitter等社交网络提供了应用程序接口API,然而目前还没有接口能够直接获取某一只股票或上市公司相关的推文信息。一种获取方式是首先通过应用程序接口获取大量推文之后,再从中筛选与股票相关的内容。另一种获取方式是编写爬虫,通过关键词判断的方式直接抓取相关的内容。然而目前这些社交网络也在不断改进它们的反爬虫技术,使得通过爬虫技术获取文本数据并提取特征的方式并不是那么可靠,更无法应用到交易相关的实际生产环境中。

另一个获取股票相关文本数据的来源是各类财经网站,包括门户网站、论坛等。这些网站的文章和帖子与股票更加相关,反爬虫的技术应用得相对较少,而且很多财经类论坛也会主动出售匿名后的文本数据,可以作为更加可靠的文本数据来源。

这里我们会用到网上两个现成的文本数据集:

  • 东财股吧的上证指数股评文本:约50万条,时间跨度为17年4月到18年5月。可以点这里(提取码: kib3)下载
  • 东财股吧的平安银行股评文本:约6万5千条,时间跨度为14年1月到15年12月。可以点这里(提取码: ykf3)下载。

这一章节下载的数据文件都统一放到当前工作目录下的data文件夹中。我们首先读取上证指数股评文本:

import pandas as pd
df_sh = pd.read_csv('./data/sh000001_comments.csv')
df_sh.dropna(inplace=True)
df_sh.reset_index(drop=True, inplace=True)
df_sh['created_time'] = pd.to_datetime(df_sh['created_time'], format='%Y-%m-%d %H:%M:%S')
print(df_sh.head())

输出为:

         created_time                             title
0 2017-03-30 09:29:02                         股市解散,都回家吧
1 2017-03-30 09:29:09                         外围股市都是收涨的
2 2017-03-30 09:29:12  全球都在涨...悲催的中国股市...关门吧..坑死人的东西..!
3 2017-03-30 09:29:16               让我一次跌个狗
4 2017-03-30 09:29:16                           那什么去祭祖!

然后我们读取平安银行股评文本:

df_pa = pd.read_csv('./data/sz000001_comments.csv', names=['id', 'user_id', 'title', 'comments', 'view', 'created_time', 'content'])
df_pa.dropna(inplace=True)
df_pa.reset_index(drop=True, inplace=True)
df_pa['created_time'] = pd.to_datetime(df_pa['created_time'], format='%Y-%m-%d %H:%M:%S')
print(df_pa.head())

输出为:

         id                user_id         title  comments  view  \
0  96913800  [u'4492113794958718']       将来的投资方向         2  1875   
1  96919995  [u'1794013234124438']       马年看“三马”         1  2425   
2  96918819  [u'9556613541531060']  分析利率市场化对银行影响         1  1940   
3  96922938  [u'2664113168461378']    涨幅大,回调很正常。         0  1081   
4  96923252  [u'5175013741202704']           继续跌         1  1343   

         created_time                                            content  
0 2014-01-04 14:05:04  从新年交易情况来看 主板阴跌不止 而创业板和中小板长势不断 主板属于将抛弃的 主力基金全部转...  
1 2014-01-04 17:03:03  中国平安最新战略是互联网金融核心平台 就是即将上线的一个移动社交金融服务平台。此款产品必会与...  
2 2014-01-04 16:32:14  利率市场化挤压小贷公司 利好银行银行可以放***了 当然 同时 存款利率也提高了。但是 现在...  
3 2014-01-04 18:25:26  平安银行1849点最低8.97到最高14.49涨幅达60% 融资购买者多了去了 回调很正常。...  
4 2014-01-04 18:42:55  这么好业绩 都没把股价拉起来 股民蜂拥而入 不惜借债买入 银行股是股指期货最好的做空标的 做...  

对于两个数据集,我们都会使用标题作为接下来要进行分析的文本数据。

texts_sh = df_sh['title']
texts_pa = df_pa['title']

2.2 分词

从上面的输出中,我们可以看出目前的标题都是连贯的句子。分词要做的就是将连贯的语句按照一定的规范重新组合成词序列。我们会用到结巴(jieba)这个强大的分词工具,可以通过pip安装jieba:pip install jieba

我们首先通过一个例子来看一下分词具体在做什么:

import jieba
print('|'.join(jieba.cut(texts_sh[0])))

输出为:

'股市|解散|,|都|回家吧'

可以看到原本一句话已经被分成了单词的组合,然而在结果中有一些我们不想要留下的单词,例如标点符号、停用词(没有意义的常用词)。因此我们需要使用一个停用词表来过滤掉这些不想要的单词。这里我用到的停用词列表可以在这里(提取码: e6sf)下载。

我们首先读取停用词列表:

stop_f = open('./data/stop_words.txt',"r",encoding='utf-8')
stop_words = list()
for line in stop_f.readlines():
    line = line.strip()
    if not len(line):
        continue

    stop_words.append(line)
stop_f.close()
print(len(stop_words))

输出为:

1895

这表示我们使用的停用词列表包含1895个词语。然后我们在分词结果中过滤掉这些词语:

seg_list = jieba.cut(texts_sh[0])
seg_list_new = list()
for word in seg_list:  
    if word not in stop_words:  
        if word != '\t':  
            seg_list_new.append(word.strip())
print('|'.join(seg_list_new))

输出为:

股市|解散|回家吧

可以看到标点符号和常用词已经被过滤掉了。

接下来我们把分词的过程封装为一个函数并且应用到每一个标题上:

def word_seg(input_str):
    seg_list = jieba.cut(input_str)
    seg_list_new = list()
   

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

<p> 在这个专刊中,我们会学习Python在金融中的应用: ·掌握Python进行数据分析和处理的方法; ·了解Python在量化投资中的应用; ·转行到金融数据分析和量化交易领域的基础等内容。 这个专刊适合: ·想要学习Python编程的在校学生; ·想要转行到金融领域的在职人士; ·想要利用业余时间进行量化投资的在职人士等。 本专刊购买后即可解锁所有章节,故不可以退换哦~ </p>

全部评论
uft-8读平安论坛评论会报错,请问怎么解决呢
点赞 回复 分享
发布于 2022-11-18 15:05 上海

相关推荐

03-31 16:42
已编辑
郑州西亚斯学院 后端
Java抽象带篮子:你简历少了几个模块看上去就感觉信息很少,简历怎么写可以看看我发的帖子
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务