自研“因子挖掘流水线”——语法树的实现(附python代码)

原创文章第624篇,专注“AI量化投资、世界运行的规律、个人成长与财富自由"。

由于因子挖掘对于量化投资非常重要,因此本周开始,自研“因子挖掘流水线”。

1、拆解deap和gplearn代码,自研因子挖掘框架。

2、写因子挖掘的专栏系列教程。

图片

我们需要一种符合因子表达式语法的树:

先看下效果:

随机生成一些因子:

图片

代码并不复杂:

这里对于“堆栈”的理解要比较深刻——核心逻辑,先“压栈”一个表达式,而后根据它的参数列表,比如log(EXPR),有一个参数是EXRP,再把EXPR压栈,当表达式达到预定高度时,只选择叶子节点(open,high)这种没有参数,也就是树不再生长了;还有一种情况就是常数的情况,目前就是INT,也是没有参数,自然也不再生长了。

一个while循环搞定因子生成——当然这里是随机生成。

stack = [ExprType.EXPR]
        expr = []
        while len(stack) > 0:
            type_ = stack.pop()

            if len(expr) > self.depth and type_ == ExprType.EXPR:
                node = random.choice(leafs[type_])
            else:
                node = random.choice(expr_sets[type_])
            expr.append(node)
            for arg in reversed(node.args):
                stack.append(arg)
        return expr

也就是数据结构里用数组来实现二叉树——完整代码如下:(更完整的在星球更新:AI量化实验室——2024量化投资的星辰大海

 

import random

from alpha_miner.expression import *

from alpha_miner.expression import ExprType


def _random_int_():
return random.choice([1, 3, 5, 10, 20, 40, 60])


class Tree:
def __init__(self, min_: int, max_: int):
self.depth = random.randint(min_, max_)

def build(self):
stack = [ExprType.EXPR]
expr = []
while len(stack) > 0:
type_ = stack.pop()

if len(expr) > self.depth and type_ == ExprType.EXPR:
node = random.choice(leafs[type_])
else:
node = random.choice(expr_sets[type_])
expr.append(node)
for arg in reversed(node.args):
stack.append(arg)
return expr

def expr_to_string(self, nodes: list):
string = ""
stack = []
for node in nodes:
stack.append((node, [])) # node和节点压进去
while len(stack[-1][1]) == stack[-1][0].arity: # 当前节点的元数
node, args = stack.pop()
if len(args):
string = '{}({})'.format(node.name, ','.join(args))
else:
if node.type_ == ExprType.INT:
string = str(_random_int_())
else:
string = node.name

if len(stack) == 0:
break # If stack is empty, all nodes should have been seen
stack[-1][1].append(string)
return string


if __name__ == '__main__':
tree = Tree(3, 8)
for i in range(5):
expr = tree.build()
show_name = [n.name for n in expr]
print(show_name, '>>', tree.expr_to_string(expr))

第二部分的代码,是把node列表,生成一个符合咱们阅读习惯,且可以被eval的python字符串表达式:

也是类似的原理,依次入栈,当前节点的args与堆栈中一致时,出栈。

比如log(open), log先入栈,遇到open时,参数是零,直接生成字符串‘open’入log节点的栈,这时满足log节点的出栈标准,生成字符串log(open),依次类推。

这个代码还是非常有意思,非常精炼的。

下一步,我们来实现遗传算法的——复制、交叉、变异

复制最简单——就是直接复制。

# 复制就是直接复制
def reproduce(self):
    return copy(self.nodes)

历史文章:

“因子流水线”的构建逻辑

整合deap和gplearn的代码,打造自研的因子流水线

AI量化实验室——2024量化投资的星辰大海

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI量化投资实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值