使用Neo4j对共同基金进行分析

栏目: 编程工具 · 发布时间: 5年前

内容简介:就在前几天,我和一位投资风险经理谈了他的团队正在研究的一个数据问题,他想知道为了简单起见,假设我们只想追踪一个度量,这个度量是$r^2$。当我们比较共同基金和基准的价值变化时,变化轨迹有多近?$r^2$总是在0和1之间。0值意味着基准与共同基金无关,而1值意味着有关。那么我们怎么来建立模型呢?

就在前几天,我和一位投资风险经理谈了他的团队正在研究的一个数据问题,他想知道 Neo4j 是否能提供帮助。假设你有大约20,000个共同基金和ETFs,你想要追踪他们是如何衡量基准的,例如标准普尔500指数的回报率。比如说,2000个不同的基准,你想要跟踪它五年内的每一天的情况。这就有$20000 5 252 * 2000$ 共500亿数据点。如果我们使用关系数据库的话,这是一个很大的连接表。我们如何使用 neo4j 建立一个有效模型?

为了简单起见,假设我们只想追踪一个度量,这个度量是$r^2$。当我们比较共同基金和基准的价值变化时,变化轨迹有多近?$r^2$总是在0和1之间。0值意味着基准与共同基金无关,而1值意味着有关。那么我们怎么来建立模型呢?

使用Neo4j对共同基金进行分析

我们的第一个选项是将该基金作为一个节点建模,基准作为一个节点,并通过他们对应的日期进行关系连接,其中日期和$r^2$作为关系的属性,如上所示。我们将有20,000个基金节点,2000个基准节点,以及500亿条关系。这是一个非常稠密的图。

首先我们尝试一个查询,看看我们的模型是怎么做的。我想知道在2017年10月31日(万圣节)X基金和基准Y的$r^2$情况。

MATCH (f:Fund {name: $fund_name})-[r:HAS_DATA]->(b:Benchmark {name: $benchmark_name})
WHERE r.date = $date
RETURN r.r_squared

首先对 :Fund(name) 建立索引,这样可以直接快速的定位到我们所需要查询的 Found ,但是这个模型在性能上很糟糕,主要是我必须遍历$2000 5年 252天= 250万$个关系,以找到我想要的。

让我们试试另一种方法,使用日期关系类型:

使用Neo4j对共同基金进行分析

为了找到基金和基准之间的$r^2$,可以这样写查询语句:

MATCH (f:Fund {name: $fund_name})-[r:ON_2017_10_31]->(b:Benchmark {name: $benchmark_name})
RETURN r.r_squared

现在,我只需要遍历2000个关系,而不是遍历250万个关系,这要快得多。另一个好处是,如果我想在指定的一个日期内得到所有基金的基准,这很容易得到:

MATCH (f:Fund {name: $fund_name})-[r:ON_2017_10_31]->(b:Benchmark)
RETURN b.name, r.r_squared

但是让我们尝试另一个查询。比方说,我们想看看自今年初以来,一个基金与一个基准的$r^2$是如何变化的。

MATCH (f:Fund {name: $fund_name})-[r]->(b:Benchmark {name: $benchmark_name})
WHERE TYPE(r) STARTS WITH "ON_2017"
RETURN TYPE(r) AS day, r.r_squared

首先,我们可以快速地从索引中一次遍历找到指定的基金节点,然后我们再遍历250万的关系来找到我们想要的。现在,遍历2-4百万的关系并不是极限。Neo4j可以在大约一秒钟内做到这一点。但我们可以做得更好。让我们尝试将基准名称移动到关系中。

使用Neo4j对共同基金进行分析

使用这个模型,我们将从我们的基金节点开始,遍历5年* 252天= 1,260个关系,并检查日期属性满足条件得到想要的结果。

MATCH (f:Fund {name: $fund_name})-[r:FOR_BENCHMARK_X]->(b:Benchmark {name: $benchmark_name})
WHERE r.date > $date
RETURN r.date, r.r_squared

好吧…如果想要得到一个基金与所有基准之间的$r^2$?

MATCH (f:Fund {name: $fund_name})-[r]->(b:Benchmark)
WHERE r.date = $date
RETURN b.name, r.r_squared

从上面查询语句看我们又要遍历$5年 252天 2000$个基准或250万个关系。我们不能同时使用日期和基准名称作为关系类型。 Neo4j 只能处理大约32k的关系类型,而不是我们需要的250万。那么我们能做什么呢?

使用Neo4j对共同基金进行分析

这是正确的。我们可以创建一个新类型的节点- FundDay ,所以有20,000个基金 5年 252天大约是2500万个节点。然后我们将这些节点与我们的基金和基准联系起来。我们的查询是想得到所有的$r^2$值,:

MATCH (f:Fund {name: $fund_name})-[:ON_2017_10_31]->()-[r]->(b:Benchmark)
RETURN b.name, r.r_squared

我们从基金节点开始,首先遍历 FundDay (我们将忽略它),然后再遍历这个 FundDay 关联的所有基准。因此,我们的查询将遍历一段关系,再加上2000个基准。遍历2,001个关系要比遍历250万个关系快得多。

还有一个小问题。我们现在的图是有20000年基金节点,2000年基准节点,和250万 FundDay 节点组成.但我们仍然有25 m FundDay 节点和2000年基准之间的关系,大约500亿条关系。我们可以削减这个数据库的大小吗?我们记住Neo4j可以处理像整数、字符串、浮点数等标量值,以及它们的数组。因此,如果我们将$r^2$存储在数组中,而不是分别存储每个$r^2$,如何存储在一个列表中?

使用Neo4j对共同基金进行分析

我们现在存储了一个5年* 252天$r^2$值的数组,而不是在$r^2$属性中存储一个值。2017年万圣节这天的$r^2$位于列表中的1218位。

MATCH (f:Fund {name: $fund_name})-[r:FOR_BENCHMARK_X]->(b:Benchmark {name: $benchmark_name})
RETURN r.r_squared[1218]

从2017年第一个交易日到万圣节这天,所有的$r^2$值,首先我们计算开始的index:4年* 252 = 1008,在加上2017年时间段,所以我们现在的查询是:

MATCH (f:Fund {name: $fund_name})-[r:FOR_BENCHMARK_X]->(b:Benchmark {name: $benchmark_name})
RETURN r.r_squared[1009..1218]

首先从基金节点开始,遍历一次关系,并将$r^2$属性数组的一部分作为值。那么对于许多基准测试呢?

MATCH (f:Fund {name: $fund_name})-[r]->(b:Benchmark)
RETURN b.name, r.r_squared[1009..1218]

上面的查询成本只需遍历2000个关系(每个基准测试一个)和2000个属性查找,而且我们降低数据库的大小,只有20000个基金节点,2000个基准节点和4000万(一个为每个组合)个关系。

还有一个小问题:默认情况下,Neo4j将数组属性存储在120字节的块中。8-10字节的开销会留下112字节的存储空间。由于每个$r^2$值是一个需要8个字节的浮点数,每个块每次只需要使用14个$r^2$值,这相当于需要从一个block跳转到另外一个block,会降低一点查询速度。

但是,由于我们提前知道了要存储的数量,我们可以将这个参数(array_block_size)更改为10080(5年* 252天(8个字节)的值。Neo4j将使用这个值加上8-10字节的开销。每一页有8192个字节,所以我们可以预留一页半(12878)或两页(16,374),留下10个字节的开销。我们的数据库大小约为700 GB,所以我们需要使用x1.16xlarge或x1e。8xlarge每月预付一笔3年的预付费用,每月约1,365美元。另一种选择是,我们可以花2万美元买一个大的RAM服务器,然后自己托管它。

记住,在图数据库中没有“第三范式”来建模数据。这是一个疯狂的前沿。使用你所拥有的数据和你想要回答的问题作为指南,但一定要让你的想象力和创造力帮助你前进。

来源: https://dzone.com/articles/mutual-fund-benchmarks-with-neo4j


以上所述就是小编给大家介绍的《使用Neo4j对共同基金进行分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java语言精粹

Java语言精粹

Jim Waldo / 王江平 / 电子工业出版社 / 2011-6 / 39.00元

这是一本几乎只讲java优点的书。 Jim Waldo先生是原sun微系统公司实验室的杰出工程师,他亲历并参与了java从技术萌生、发展到崛起的整个过程。在这《java语言精粹》里,jim总结了他所认为的java语言及其环境的诸多精良部分,包括:类型系统、异常处理、包机制、垃圾回收、java虚拟机、javadoc、集合、远程方法调用和并发机制。另外,他还从开发者的角度分析了在java技术周围......一起来看看 《Java语言精粹》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具