文章目录
前言
2020年11月作为汇丰科技innovation team的一员在深圳参加了AWS举办的云图谱大赛,在五天时间内与团队其他成员一起完成了基于知识图谱的负面新闻对基金股票风险影响识别产品,我在其中主要负责构建图数据库和图算法应用。
一、产品概述
1.1 功能概述
- 系统功能:负面新闻影响股票基金预测系统主要功能包括,使用爬虫收集新闻数据,将新闻数据抽离出公司、人物等实体,对实体的情感分析,将负面情感新闻的实体放进图数据库中进行匹配,找到此条负面新闻所影响的所有股票基金实体。
- 应用场景:某基金经理日常关注新闻,但是新闻太多他不能有效识别这些新闻会影响到哪些基金,这个时候他可以选择使用我们的产品,将多条新闻导入产品页面/或者自动爬取新闻到产品页面,然后系统找到其中负面情感新闻,将该新闻中的实体在数据库中进行匹配,将新闻作为一个节点导入到数据库中,并与匹配上的公司股票基金等实体关联起来,可以向基金经理返回这些新闻里面关联的风险实体。
1.2 数据来源与处理
- 获取新闻数据的渠道:爬虫系统(各大财经网站)、海知(第三方公司)提供、通联(第三方公司)提供。
- 获取股票数据的渠道:通联(第三方公司)提供。
- 分析系统对新闻数据进行NLP分析,比如对新闻数据进行情感分析,分析出负面新闻。
- 图数据库Neptune导入数据(格式CSV),公司数据、股票数据、基金数据;
- 通联提供的新闻数据属性较为齐全,但是由于时间紧促,我们对于整体产品的设想进一步精简,负面新闻中的实体在图数据库中进行匹配公司、人物、股票、基金类别的实体,暂时没有将历史新闻数据运用到其中
1.3 项目架构图
这是初期设想,实际上没有对历史新闻进行和股票基金涨跌的预测模型训练
1.4 项目部署
系统上线时预计部署9台物理机, 1台API Gateway, 2台Cache,1台LoadBanlance Server, 2台LambdaServer,3台Neptune 图数据库。
1.5 知识图谱架构
我们采用的是aws的neptune图数据库,然后从s3以csv的格式向neptune中导入,比从本地导入快很多,查询语句使用的是Gremlin
1.6 数据展示时序图
后端使用的是AWS的Lambda服务,主要是使用gremlin语言将从新闻中提取出的实体在neptune中进行匹配
二、图数据库neptune
1.图数据库介绍
这里使用aws的ppt解释一下图和图数据库
2.neptune导入
2.1 neptune导入格式
- 图数据库中的数据分为两种类型,一种是节点,一种是节点之间的关系,节点一般包含节点的id和各种属性,而关系则包含关系两边的节点和关系的属性,一般会对两种数据类型有不同的格式要求,在导入时这两种情况要分开处理。
- 导入数据一般有两种形式,直接导入csv文件或者使用cypher语句一条一条数据导入,下面分别举例说明
2.1.1 使用gremlin导入
- 以下为gremlin语言中构建图用到的一些元素
Schema:Schema是一种描述语言,这里就是指所有属性和类型的集合,包括边和点的属性,边和点的Label等;
属性类型(PropertyKey ):只边和点可以使用的属性类型;
顶点类型(VertexLabel):顶点的类型,比如User,Car等;
边类型(EdgeLabel):边的类型,比如know,use等;
顶点(Vertex):代表图中的一个节点;
边(Edge):连接两个节点,分为有向边和无向边;
创建属性类型:(用于点和边)
graph.schema().propertyKey("name").asText().ifNotExist().create();
graph.schema().propertyKey("age").asInt().ifNotExist().create();
graph.schema().propertyKey("sex").asText().ifNotExist().create();
graph.schema().propertyKey("TV").asText().ifNotExist().create();
创建顶点类型:人物(以姓名为主键,有三个属性)
person = graph.schema().vertexLabel("person").properties("name", "age", "sex").primaryKeys("name").ifNotExist().create();
创建边类型:合作演出(此边的两端都是人物,即描述谁和谁共同演出过,属性为电视剧,即此边描述两个人物在某部电视剧中合作演出过)
co-star = graph.schema().edgeLabel("co-star").sourceLabel("person").targetLabel("person").properties("TV").ifNotExist().create();
创建点和边:(创建点和边的时候要同时赋予其属性)
Liu = graph.addVertex(T.label, "person",