金融科技之情感分析:股民情绪指数与股市价格的相关性分析

您所在的位置:网站首页 对数据分析预测用什么技术进行 金融科技之情感分析:股民情绪指数与股市价格的相关性分析

金融科技之情感分析:股民情绪指数与股市价格的相关性分析

2024-07-10 02:40:19| 来源: 网络整理| 查看: 265

金融科技之情感分析(一):股民情绪指数与股市价格的相关性分析 源代码获取前言文本数据源介绍评论数据爬取数据存储和查询计算情绪指数股票历史价格数据的获取相关性分析和可视化

源代码获取

2020年11月11日: 源代码可在点赞、评论该博文后,在下面百度网盘中自行下载。 复制这段内容后打开百度网盘App,操作更方便哦。 链接:https://pan.baidu.com/s/1Tzg-gdC6_-hvm1_b189aeA 提取码:9wx6

前言

本文是我在一家金融机构实习时做的第一个项目的整理。蒟蒻一枚,是金融科技和人工智能的初学者,写下本篇博文意在记录自己的足迹并与和我一样想要从事金融科技行业的小伙伴分享我遇到的问题和解决方案。如果本文有错误的地方,请大佬们指正。

在投资者社区中有许多文本型数据,我们可以对这些文本型数据进行处理,挖掘出有价值的信息。比如,东方财富股吧中有很多用户的发言、评论,我们可以借助自然语言处理中的情感分析技术,挖掘出市场的情绪指数,并研究情绪指数与金融市场的相关性。这个项目做的就是这个工作。

主要涉及爬虫、自然语言处理和相关性分析以及有限的MySQL的技术。

文本数据源介绍

首先我们打开http://guba.eastmoney.com/list,zssh000001,f.html,进入上证指数吧。进入后的界面如下图所示,同时我们选择排序方式为“发帖时间”。 在这里插入图片描述 可以看到,在股吧的界面中,有财经评论、东方财富网、股吧访谈等官方发布的内容,也有普通用户发表的评论。在这里,我们只研究普通用户发表的评论。 接着我们点击鼠标右键,选择网页源代码,可以看到该页面的html代码如下图。 在这里插入图片描述 我们发现在页面上看到的用户评论信息都被写在了HTML页面中,这为我们后面的爬虫提供了方便。进一步观察该源代码,我们发现源代码还同时包含了评论详细信息的网址、评论作者页面的网址。如果点击打开评论详细信息的网址,并打开其网页源代码,可以发现,我们可以在源代码中找到该条评论的**“发表时间”、”点赞数“**等数据。同样的,我们可以在评论作者的用户页面的源代码中找到该用户的”粉丝数“等数据。这些数据在我们后面情绪指数计算时都会用到。

评论数据爬取

我们通过分析数据源——股吧,发现我们所需要的数据基本上都被包含在了相关页面的HTML源代码中。那下一步便可以设计我们的爬虫了。我们这里只使用requests和BeautifulSoup两个库便可以完成数据爬取的任务了。 首先,引入这两个库。若还未安装这两个库,只需通过pip安装即可。

import requests from bs4 import BeautifulSoup

首先把requests进一步封装成根据url获取HTML的函数

def getHtml(url):#下载网页源代码 header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; LCTE; rv:11.0) like Gecko'} try: r=requests.get(url,headers=header) r.encoding='utf-8' #print(r.status_code) r.raise_for_status() return r.text except: getHtml(url)

现在我们可以根据url地址获取对应网页的HTML源代码。下一面要做的便是解析HTML的结果,定位我们需要的数据的位置。 通过分析股吧页面的HTML源代码我们发现,每条评论、公告、新闻等数据都存储在一个div标签下,且该div标签的class属性为articleh。 在这里插入图片描述 而对于每一个div标签,其又有5个span子标签,分别存储阅读量、评论数、标题、作者和发表时间。在第三个span子标签,即class属性值为”l3 a3“的span标签中,有一个a标签,a标签存在两个属性,其中href属性是该条评论详细页面的地址,title属性是该条评论的标题。我们可以发现多数散户的评论标题和正文的内容是一致的,所以这里保存title的值作为用户的评论文本。 分析完网页源代码后,我们便可以使用BeautifulSoup来获取对应的数据了。主要代码如下:(关于BeautifulSoup的用法,读者只需知道其可以通过标签类型和标签属性、属性值查询到相应的标签即可,具体的用法可自行在网络中查询。)

html=getHtml(url) soup = BeautifulSoup(html, "html.parser") contain = soup.find_all("div", {"class": "articleh"})#获取存有数据的div标签,存在contain中,因为一个页面有多条评论,所以contain是一个列表。 for i in contain:#遍历contain content = i.find("span", {"class": "l3 a3"}).find("a")#获取一个div便签中第三个span标签下的a标签,其有href和title两个属性 contentUrl="http://guba.eastmoney.com"+content["href"]#content["href"]是该评论的详细界面网址,因为其是相对地址,所以需要在前添加网址的前缀,得到完整的界面网址 commentId=content["href"][-14:-5]#我们观察content["href"]属性的值,发现其是具有规则的字符串,从该字符串的倒数第14个位置到倒数第5个位置是该条评论的id text=content.attrs["title"]#获取评论文本(标题) userUrl = i.find("span", {"class": "l4 a4"}).find("a").attrs["href"]#用同样的方法获取用户主页链接 userId=userUrl[23:]#获取用户ID

通过上面的代码段,我们已经从股票的评论列表页面中获取了我们需要的数据。下面我们将根据我们获取的conteUrl和userUrl获取其他我们需要的信息,方法和上面类似。

commentHtml=getHtml(contentUrl)#获取评论详细信息源代码 soup = BeautifulSoup(commentHtml, "html.parser") date = soup.find("div", {"class": "zwfbtime"}).text[4:14]#获取评论发表时间 likeCount=int(soup.find("div", {"data-like_count": True}))#获取评论点赞数,并转换成整数类型。(因为从html中获取会认为是字符串类型) userHtml=getHtml(userUrl)#获取用户主页源代码 soup = BeautifulSoup(userHtml, "html.parser") fans=int(soup.find("a", {"id": "tafansa"}).find("span").text)#获取用户粉丝数

至此,我们已经能够获取我们所需要的数据了。但目前我们只是从评论列表的第一页获取数据,如果获取其他页的数据呢?很简单,当我们在网页上点击第二页时,可以发现浏览器的地址栏变成了 http://guba.eastmoney.com/list,zssh000001,f_2.html。所有我们只需要改变该地址字符串的”f_2”和“.html“之间的数字即可。 不过,上述代码只是简化后的结果。没有考虑如果该条”评论“是新闻、讨论、问答等的情况。事实上,这些情况经常出现,且因为不同类型的数据其html得到标签结构往往不同,所有可能导致程序异常终止。一个简单粗暴的方法便是在程序段外面,在循环语句下加上try-except异常处理,若出现异常,则执行continue语句,跳过这一层循环,即跳过该条”评论“。

html=getHtml(url) soup = BeautifulSoup(html, "html.parser") contain = soup.find_all("div", {"class": "articleh"}) for i in contain: try: content=i.find("span", {"class": "l3 a3"}).find("a") contentUrl="http://guba.eastmoney.com"+content["href"] commentId=content["href"][-14:-5] text=content.attrs["title"] userUrl=i.find("span", {"class": "l4 a4"}).find("a").attrs["href"] userId=userUrl[23:] commentHtml=getHtml(contentUrl) soup=BeautifulSoup(commentHtml, "html.parser") date=soup.find("div", {"class": "zwfbtime"}).text[4:14] likeCount=int(soup.find("div", {"data-like_count": True}) userHtml=getHtml(userUrl) soup=BeautifulSoup(userHtml, "html.parser") fans=int(soup.find("a", {"id": "tafansa"}).find("span").text) except: continue

这样可以解决大多数情况的问题,但也并非万无一失。可能有的”评论“标签(这里指新闻讨等类型的数据)执行try语句下的代码并没有出现异常,但存储的数据并非我们想要的内容。这需要我们在实践的过程中不断总结、寻找规律、判断并排除这类情况。 至此,获取数据我们已经介绍完了。

数据存储和查询

在利用爬虫技术获取到我们需要的数据后,便需要将数据存储以待后续处理。数据存储有很多方法,在这里,我们将其存储到数据库中。 这里使用的是MySQL数据库和DataGrip数据库图形界面操作工具。读者可参考网络上的MySQL安装教材进行安装。若读者无法使用DataGrip(收费软件,在校大学生和教师可申请免费使用)也无妨,我只是使用该软件方面查看数据库的内容。

成功安装数据库,并输入密码登录后。便可以创建数据库和数据表了。 首先我们创建数据库。注:windows操作系统下不区分大小写

create database dfcf;

其中,dfcf是自定义的数据库名。dfcf即东方财富。 接着,我们在dfcf数据库中创建数据表。

use dfcf; create table tb_comment ( id int auto_increment primary key, comment_id varchar(20) null, content varchar(300) null, like_count int null, date date null, user_id varchar(20) null, share_code varchar(15) null, ); create table tb_user ( id char(18) not null primary key, fans int null );

通过上面的代码,我们便在dfcf数据库中创建了两个表。一个存储评论的相关信息,另一个存储用户的相关信息。在tb_comment表中,id字段为从1开始递增的整数,用来方便查看存储的数据总数。share_code字段存储的是该条评论所针对的股票,在这里,因为我们研究的是上证指数吧,所以share_code为zssh000001.

现在我们已经打建好了数据库。下一个问题便是如何向数据库中存储和从数据库中查询数据了。只需要简单的了解一下SQL语句即可。对数据库的操作基本上可以归为增删改查四大块。每一块常用的语句很少也很简单,读者自行在网络上了解即可,后面我也会给出用到的SQL语句。 关于数据存储和查询的最后一个问题便是:如何使用Python对数据库进行操作。 事实上,我们只需要安装pymysql库,再按照一定格式调用即可。下面给出例子:

import pymysql def storeCommentInf(comment):#存储评论 db = pymysql.connect("localhost", "root", "你的登录密码", "dfcf") cur=db.cursor() sql = "INSERT INTO TB_COMMENT(comment_id,content,like_count,date ,user_id,share_code) values (%(comment_id)s,%(content)s,%(like_count)s,%(date)s,%(user_id)s,%(share_code)s)" sql1 = "SELECT * FROM TB_COMMENT where COMMENT_ID=%s" if cur.execute(sql1,(comment["comment_id"])):#去重 cur.close() print("评论已经存在") db.close() else: cur.execute(sql, (comment)) db.commit() cur.close() db.close() print("插入评论成功")

在上面的代码中,我们首先导入了pymysql库,并定义了一个函数。函数中有一个参数comment,为字典类型,存储的是一条评论的有关数据。上述代码段的第3行,我们连接了dfcf数据库。第4行,我们引入了一个会话指针,这是固定写法,读者不必深究。随后,我们定义个两个字符串sql和sql1来定义要执行的数据库操作。sql用来插入comment,其values()内定义的%(xxx)s中的”xxx"是参数comment中的键,执行该语句可以将参数comment对应键的值存入数据库对应字段中。sql1用来根据comment_id来查询数据,避免同一条评论被重复插入。cur.execute()便是用来执行设置好的sql语句。 下面给出全部的用到的关于数据库操作的函数:

import pymysql def storeCommentInf(comment):#存储评论 db = pymysql.connect("localhost", "root", "你的登录密码", "dfcf") cur=db.cursor() sql = "INSERT INTO TB_COMMENT(comment_id,content,like_count,date ,user_id,share_code) values (%(comment_id)s,%(content)s,%(like_count)s,%(date)s,%(user_id)s,%(share_code)s)" sql1 = "SELECT * FROM TB_COMMENT where COMMENT_ID=%s" if cur.execute(sql1,(comment["comment_id"])):#去重 cur.close() print("评论已经存在") db.close() else: cur.execute(sql, (comment)) db.commit() cur.close() db.close() print("插入评论成功") def storeUserInf(user):#储存用户数据 db = pymysql.connect("localhost", "root", "你的登录密码 ", "dfcf") cur = db.cursor() sql = "INSERT INTO TB_USER(id,fans) values (%(id)s,%(fans)s)" sql1="SELECT * FROM TB_USER where ID=%s" if cur.execute(sql1,(user["id"])):#去重 cur.close() db.close() print("用户已经存在") else: cur.execute(sql, (user)) db.commit() cur.close() db.close() print("插入用户成功") def selectCommentOrderByDate(share_code,method):#查询评论信息 db = pymysql.connect("localhost", "root", "你的登录密码", "dfcf") cur = db.cursor() if method==0:#按照日期升序 sql = "SELECT * FROM TB_COMMENT WHERE SHARE_CODE=%s ORDER BY DATE" else:#按照日期降序 sql="SELECT * FROM TB_COMMENT WHERE SHARE_CODE=%s ORDER BY DATE DESC " cur.execute(sql,(share_code)) db.commit() cur.close() return cur.fetchall() def selectFansByUserId(userId):#查询用户粉丝数 db = pymysql.connect("localhost", "root", "你的登录密码", "dfcf") cur = db.cursor() sql = "SELECT FANS FROM TB_USER where ID=%s" cur.execute(sql,userId) db.commit() cur.close() return cur.fetchall()

至此,我们已经解决了获取数据和存储、查询数据的问题了。

计算情绪指数

现在,我们便可以计算投资者的情绪指数了。我们需要借助自然语言处理中的情感分类技术。按照正常的处理流程,我们需要搭建模型、准备语料库、训练模型、测试模型然后得到一个情感分类的模型。但这里,我们直接使用现有的模型。snownlp是一个中文的开源的自然语言处理的Python库,可以进行分词、情感分类等。但snownlp库有一个缺陷,便是其模型的训练语料是商品购物评论语料,用来做金融领域的情感分类效果一般,但目前还并没有关于金融领域的中文自然语言处理的开源库、语料库。所以这里我们暂时使用snownlp库来完成我们的实验。若想进一步提高准确率,还需自己搭建语料库进行模型训练。 下面介绍用snownlp进行情感分析的方法: 首先,需要安装snownlp库,直接用pip安装即可。安装完毕之后,按照下列方法调用。

from snownlp import SnowNLP text="大牛市来啦,发财啦" nlp=SnowNLP(text) print(nlp.sentiments)

运行上述代码,我们可以得到一个浮点数0.7343040563996935。nlp.sentiments是一个在【0,1】之间的浮点数,这个数越接近1,代表该文本表达的积极情绪越强,反之,则代表该文本表达的消极情绪越强。 现在我们已经可以计算一个评论文本的情感得分了,下一步便是量化出某一日市场投资者的整体情绪。量化的方法有许多种,可以将某一日所有的评论情绪得分得分相加再求评价,也可以求某一日情绪得分大于0.5的评论所占的比例。

本蒟蒻采用的方法是:

①将情绪得分>0.6的评论当作积极评论,小于0.4的评论当作消极评论。

②设置变量neg和pos,存储某一日市场的积极情绪因子和消极情绪因子。关于neg和pos的计算方法,以neg为例: 初始化为0 若某一日的某一评论comment的情绪得分0.6): fans=SQL.selectFansByUserId(comment['user_id']) pos+=1+math.log(comment['like_count']+fans[0][0]+1,2) if(sentimentScore



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭