# eda(数据描述)&baseline
- target 服从泊松分布(或卡方)
- MSE 的分布前提假设数据满足高斯分布
- 分类问题的评估函数多用 f1 score
F1 分数是精确率(P,预测结果对了多少)和召回率(R,对实际结果我覆盖了多少)的调和平均数
-
encoding 技巧:对面板数据,按类别 groupby,然后聚合操作
-
按时间聚合时,可以考虑 tsfresh 包
-
聚合时,考虑到越新的数据,对未来影响越大,可以考虑从后往前选特定长度
-
伪标签思想:用初始学到的模型给无标签数据集打标签,取确信度大的结果加入 train set,用于后续训练(要防止确认偏见 )
-
stacking 思想:
把不同模型看作不同的专家,用一个主席模型缝合到一起。
在训练主席模型时,为了防止数据泄露,会使用 K-fold 生成临时专家小模型,小专家的输出作为主席训练用的元特征。
这样的好处是整个原始训练集中的每一条数据,都恰好被当过一次 “验证集”,并由一个从未见过它的模型做出了预测
最后在 test dataset 上,再用整个训练集跑出专家模型,输出结果给主席模型缝合。
bagging 思想:有放回抽样 train data,并行训练多个同类型模型,预测时投票 or 均值(随机森林在此基础上会对特征列的随机抽样 )
boosting 思想:则对上一个弱模型的误差重点关注,最后所有子模型合并
- 分类问题,训练时缩放权重,预测时对子模型按权重加和投票
- 拟合问题,训练时拟合残差,预测时加和结果(按学习率,这个训练时就有)
- MSE 会优先拟合值较大的结果,它过分关注标签比较大的样本。所以用反比的 weight 中和
# feature 因子工程
# 订单簿基处理(横向扩展)
book_wap1和book_wap2
- 含义:加权平均价格(Weighted Average Price),基于每一档位的买卖盘数据计算
注意:此处量价交叉相乘,为了体现力量趋势
买盘量大,则价格向卖方价前进。反之同理
-
book_wap_mean- 含义:加权平均价格的平均值
-
book_wap_diff- 含义:相邻档加权平均价格的差值
-
book_price_spread- 含义:买卖价差的相对值(归一化处理)
此处分母可以是买一和卖一之和,也即 2 倍中间位均值
-
book_bid_spread- 含义:买盘的价格差
-
book_ask_spread- 含义:卖盘的价格差
-
book_total_volume- 含义:买卖盘的总数量
-
book_volume_imbalance
- 含义:买卖盘数量的不平衡程度(总卖减总买)
# agg 特征(纵向聚合)
基于同股票同时间段聚合,得到:
- 订单簿:求每一列的
对数变动率的标准差(平方和的平方根) - trade:基于
price、size、order_count(成交订单数)、seconds_in_bucket(10min 时间桶内第几秒成交的 trade) 四列,对每一列求简单聚合(sum、mean、std、max、min)
# 伪 K 线特征
由于每个 trade 只有一个成交价格数据,太单薄
所以考虑重采样
波动率和成交量关系密切
对每个 10min 时间桶,重采样为 10s 一根 K,构建开高低收,计算:
-
MACD,KDJ 等基础指标,TA-lib
-
量价 corr 等回归指标
-
AD 指标(Accumulation/Distribution)(价格给成交量权重)
核心思想是:
- 如果收盘价接近最高价,并且成交量较大,就说明市场有 “资金流入”(吸筹、买入)。
- 如果收盘价接近最低价,并且成交量较大,就说明市场有 “资金流出”(派发、卖出)。
公式分两步:
- 计算 CLV(Close Location Value,收盘位置值):
CLV 取值范围在 -1 到 1 之间,越接近 1 表示收盘越靠近最高,越接近 -1 表示收盘越靠近最低。
- 计算 AD 值:
AD 指标的走势可以帮助判断价格走势背后的资金动向。如果股价在涨,但 AD 没有同步上涨,可能暗示上涨缺乏资金支撑,有背离风险。
- OBV 能量潮 **(切割)**
简单说就是今日价格上涨,咱累加 vol;下跌,就减。
- Klinger 成交量摆动指标 **(切割)**
同 OBV,只是切割指标不用 close 了,用
-
ATR**(前面都是量,这里开始是价)**
-
乖离率 **(收盘价和均线偏离程度)**
-
相对波动率 RVI**(切割)**
核心思想是:把近期的波动 “活跃度” 和整体波动做对比,用来判断市场是平稳还是波动剧烈。
计算步骤大致如下(常见做法):
-
划分 & 计算
一般用标准差、TR 或者绝对收益(| 今日收盘 − 昨日收盘 |)作为每日波动指标。-
UpVol:如果当天价格上涨,用当日波动值;否则为 0
-
DownVol:如果当天价格下跌,用当日波动值;否则为 0
-
-
平滑处理
用 N 日移动平均或者指数加权平均:
- 计算 RVI
RVI 的值在 0~100 之间:
- RVI 接近 100 → 上涨波动占主导,波动活跃
- RVI 接近 0 → 下跌波动占主导
- 中间区域 → 市场波动平稳
barra 对流动性的定义就是不同周期内的换手率
流动性可以用
买卖不平衡性,买卖压力衡量
- 深度差 & 高度差
每档买卖量的相对差
对每档价格求差分,对差分求买卖相对差
- 价格加权的买卖量压力
核心思想:离买一卖一的中间价(midprice)越近,权重越大;
- Amihud
核心思想:单位成交量带来的价格波动越大,说明流动性越差。
分子可以用最短价格路径来改进
# boosting 树模型
# 基础
- sigmoid 函数
- softmax
要对一个 feature 进行 分类,用该 feature 喂进 model 出一个 长度的 output,其每个元素为。然后 softmax,就是算指数比例,将 output 值映射到 ,且
- 逻辑回归
逻辑回归就是一个线性回归 + sigmoid 激活,损失函数取交叉熵,反向传播优化
-
在逻辑回归和分类问题里:
交叉熵损失 = 负对数似然损失 -
交叉熵损失:
多分类,分 k 类时,对一个样本
其中:
- 是 one-hot 编码(真实类别),如果真实类别是 ,那么 ,其他 。
- 是预测概率,来自 Softmax
当,代入:
得到二分类交叉熵(对每个样本):
# cart 树
可分类可回归
用 “基尼指数” 衡量纯度,分裂时选基尼指数最小的特征。
严格的二叉树
# GBDT
-
所有树都是 cart 回归树(无论分类任务还是回归任务)
-
串行训练,第 1 棵树学完后,第 2 棵树专门修正第 1 棵的伪残差
-
残差怎么算,由损失函数反向传播决定。分类常用交叉熵,回归常用 MSE
-
每棵树的分裂层数由超参数确定,怎么分裂选取 loss 下降最多(即 gain 最大的方式)。在分裂时,分类任务计算 loss 用泰勒展开近似,用一阶导 g 和二阶导 h 计算,回归(损失函数 MSE)直接算;叶子节点的值,分类任务也是用泰勒近似的,基于一阶导 g 和二阶导 h 计算;回归(MSE)任务取均值
-
迭代数量为 时,二分类每次迭代训练 1 棵树,总共有 棵树;多分类(k 类)每次迭代训练 棵树,总共有 棵树;
# XGBoost
GBDT 改进版
- 加入正则项,防止过拟合
- 利用二阶导数,优化更快
- 支持并行、缺失值处理、剪枝等
# LightGBM
XGBoost 高速大容量版
-
使用直方图加速特征分裂
-
采用 “叶子优先” 生长策略(而非层优先)
-
支持大规模数据、类别特征原生处理
更快、更省内存;精度也很高,特别适合海量数据
# 树模型的缺陷
# KNN 最邻近模型
思想:对要分类点 x ,看 x 附近最近的 K 的点,这些点大多属于哪个类,x 就是哪类
要点:交叉验证确定超参 K,还有使用二叉树思想构建训练数据,用于更快查点
# K 近邻与树模型的异同
相同:本质上都是在特征空间内划分成小区间。每个小区间用一个值来表示
区分:
- K 近邻在划分时可斜着、曲线切;树模型的划分线只能平行于某个 feature
- K 近邻算法在进行特征空间划分时候,其实并没有用到训练数据的标签信息;树模型使用 label 划分
多树模型只是划分区间更细,那这里有一个关键问题:
** 这种模型只适用于区间内预测。 ** 对于区间外的样本标签,它没有办法进行一个良好的预测。
# 解决方法
把直接预测改为相对预测,比如对 label 做差分:
- 利用过去一段时间的平均值(特定模型)和未来的标签的差生成相对标签。
- 利用另一个趋势模型的预测值(某个模型)和未来的标签的差生成相对标签。
标准差考虑其非负性,可以相对预测下一时刻与当前的比值。
# 超参数搜索
超参数指模型无法靠机器学习优化的参数,人为设置的。大致方法有:
- 网格搜索
- 随机搜索
- 贝叶斯搜索
- 强化学习搜索
前两者的不同参数集之间没有联系;后两者基于历史的搜索路径,指导和启发我们以后的搜索路径
# 高斯过程
在拟合模型时,假设有一个拟合函数库(先验,由均值 & 核函数决定),我们有一系列真实观测数据,那么对于观测到的每组(x, y),就会从函数库里筛函数。最后筛出来的函数们,对于输入,就会输出不同的 y,看作模型 的概率分布。
高斯过程定义:对任意有限多个输入点,对应的函数值向量 都服从一个多元高斯分布。
写成公式:
意思是:
- 均值函数 m (x) m (x) m (x) 给出在每个输入点的期望值;
- 协方差函数 k (x,x′) k (x,x') k (x,x′) 给出不同输入点之间的相关性。
高斯过程通过规定任意有限点的函数值的联合高斯分布,间接地定义了整个函数库的概率分布,而不必直接给每条函数一个概率。
贝叶斯搜索会假设我们搜索的超参数的点、以及它的验证集的评估指标符合的是一个高斯过程。
搜了一些点 —> 高斯过程拟合 —> 拟合结果告诉你超参数取哪些值评估结果比较好 —> 以这些点采样超参数,循环
# alpha 的寻找
- 截取片段
- 聚合
- 分类(比如 kmeans、按某一 feature 的大小排序)
在每一个股票上,我们这里可以根据 “买卖方向”“成交额大小” 对每一行 feature 进行分类
跨股票维度上,我们可以对近似类别的股票聚合求新 feature
也考虑特殊回归的 feature—— 弹性系数
# 加速
# python 内生加速技巧
- del 引用,释放内存
- 列表推导式快于 for 循环
- 调用局部变量比全局变量快
- from import 比 import 快
# 多进程
python 由于 GIL 锁,每个时刻,同一进程下,只有一个线程能在运行代码块(处理 list,dict 等数据结构的缺陷,python 早期就加了这个锁),这导致:
- IO 操作,python 多线程没问题
- CPU 密集操作,需要 python 多进程
于是我们使用 multiprocessing 实现多进程
pool 中,先 close 声明:“不给子进程池加新任务了”,然后 join 堵塞等人齐。可用 with 自动管理资源
| 类型 | 定义 |
|---|---|
| 阻塞 | 主进程会卡在当前这一行代码,等任务完成后才继续往下执行 |
| 非阻塞 | 主进程不会卡住,调用后立即继续执行下一行代码,任务在后台运行 |
map 加任务的函数基本返回都是有序结果,除非你特殊 unordered
# numba
可搜索参考:numba 自动并行化
# 多集群
就是用多个计算机,经典的有 mapreduce (分治 + 聚合) 思想
# 量化简述
# 基于 base feature 的深度挖掘
基本就是遗传规划 & 深度学习