blackcat1402

t-SNE降维短线情绪可视化

SSE:000016   上证50指数
最近有人在TradingView社区私信我说:“怎么好意思把发布几个技术指标就称之为量化?”。 我对于这种倾向于冒犯的留言并没有生气,因为我也确实认同技术指标不等于量化。只不过我提示了他怎么知道我只会写技术指标的呢?

借这个这个有趣的事情就引出一个不那么“传统”的量化分析方法: t-SNE, 分析股票短线市场情绪的一些自己简介。首先,t-SNE的标准发音是“踢死你”。作为目前公认最好的降维可视化技术,t-SNE没有踢死你我,却踢到了PCA的软肋上。至于这个梗,感兴趣的各位可以自行上网学习。

短线市场的情绪好比游泳下水前要知道水温一样。短线交易者常说顺风局和逆风局,顺风局买啥啥涨停,买错的能赚,逆风局买到涨停,就炸板或次日核按钮,同样的技术策略有时吃肉有时吃面究竟是什么原因? 情绪啊。 归根结底还是市场氛围和情绪不同。情绪是择时交易的依据。常听人说:“站在风口上猪都能飞起来”,很多人更专注猪:“哇,猪飞起来耶”,然而重要的是风而不是猪,只要风够大,不要说是猪,就是房子都会飞起来的。同理,交易里我们不能只见猪(个股),却忽视了风的作用(情绪)。交易过程中包括猪、风,我。但实际上只需要控制两个方面,第一是我,我能控制的就是风险(亏损)控制和选那头猪骑上去;第二个就是风,风决定利润的多少。感知风要么凭借触觉经验,要么就通过量化把它可视化。

可视化只有三个选项:1D就是点,2D就是面,3D就是体。对于更高的维度(>= 4D)我们是没有办法进行可视化的。对于市场情绪的量化来说,涉及的维度会超过3,这时候要想可视化表现情绪就需要用到高维数据降维技术。而我们今天要讨论的t-SNE和PCA都是降维技术。

降维技术在人工智能(AI),尤其是训练机器 学习模型时会经常用到,其可以降低计算的复杂度,从而可以简化机器学习算法从输入数据集合到完成学习的过程。PCA(Principal Component Analysis) 作为降维技术的主要算法由皮尔逊(Pearson)在1901年开发。它的主要缺点时无法维护数据集合局部结构,而t-SNE就可以有效的解决这个问题。举个例子,在人工智能中让机器学习分辨不同种类的物种特征,PCA降维往往会出现无法分辨的情况,而t-SNE在这方面的性能就高一筹。

t-SNE出现比较晚,是2008年由Laurens van der Maatens和Geoffrey Hinton开发的,它能更高地将N维数据映射到1~3D,于此同时比较号地维持原始数据地相似性。t-SNE的基本工作原理是随机选择一个数据点(标点)并计算与数据集合中其它点的欧几里德距离并创建概率分布。标点附近的点具有更高的相似度,反之相似度低。然后根据相似度给数据集合中每个点都创建一个相似度矩阵。t-SNE根据正态分布计算出相似距离并转换为联合概率,这样可以将所有数据点随机排列在低维度上。接着,t-SNE有一次对高维数据点和随机排列的低维数据进行相同的计算,根据t分布分配概率。因为t分布可以减少拥挤问题,所以其分类效果要好于PCA。


回到正题,对于短线市场情绪,我手头收集了一个13维的数据集,从今日回溯700个交易日的时间序列数据,包括首板数量、2连板数量、3连板数量、高度板数量、连板数量、跌停数量、涨停数量、连板高度、曾跌停数量、炸板数量、一字板数量、换手板数量和老版本的情绪指标,如图所示。接下来,我将使用t-SNE对这个数据集合降维处理,目的是实现13维数据的可视化、解决降维后样本分布拥挤问题、解决老版本短线情绪指标边界不明显的问题。

13维数据集合表征短线情绪

首先,要使用t-SNE,需要安装python的sklearn库,并且通过国内pip镜像可以提高下载安装速度:
pip install scikit-learn -i pypi.tuna.tsinghua.edu.cn/simple

除此之外,对于数据处理还用到Python的numpy 和 pandas库。另外一个值得注意的问题是需要保证13个子集在方向上是一致的。所以,我取数值越大表示上涨方向。这样,其中的3个子集数据需要进行反向处理,包括:跌停、曾涨停、炸板。处理后的结果保证当这些数量变大时,表示市场情绪好转的方向。只有这样,才能和其它10个子集在情绪表达方向上是一致的。然后,对13个子集数据进行归一化处理,以保证每个子集的幅度在0~1之间。这些数据操作建议通过pandas的dataframe进行处理,最终结果存储在df1中。

13维数据归一化结果

接下来就是t-SNE处理部分,具体代码如下:
from sklearn import manifold,datasets
import numpy as np
import pandas as pd

#归一化函数
max_min_scaler = lambda x: (x - np.min(x)) / (np.max(x) - np.min(x))

X = np.array(df1)
tsne = manifold.TSNE(n_components=1, init='pca', random_state=501)
X_tsne = tsne.fit_transform(X)

值得注意的是,t-SNE输入数据需要是一个2维的numpy数组,需要提前将df1转换维2维数组或者说矩阵格式。降维处理的结果X_tsne,但这并不是最终的结果,而是市场情绪的权重系数。这个系数体现了13维数据在单日市场情绪的综合结果。所以,我还需要再对X_tsne进行一次归一化处理:
df2 = pd.DataFrame(X_tsne)
for column in df2:
df2 = df2[].apply(max_min_scaler)

生成13维数据降维后的情绪系数,存储在df2中。最终的新短线市场情绪的计算公式为:
新短线市场情绪 = 老短线市场情绪 X 降维后的情绪系数

新老情绪量化对比图

最终效果如图:当13维子集趋势高度一致的时候,新情绪值会和老的情绪值重合;反之,则按照降维后的结果修改老的情绪值。例如:最近A股短线非常难做,从上周比较差的情绪对应老情绪指标可能并不能体现出每一天都亏钱效应十足,但是降维计算后的新情绪则更贴近实际创下近期情绪的最低值。


上证指数行情来自TradingView

如上图所示,t-SNE降维的新情绪下探到了白色冰点区域,老情绪在蓝色区域。新情绪会产生情绪底背离,老情绪指标没有情绪底背离。


综上所述,t-SNE降维是更好量化短线市场情绪的一次尝试,至于其长期效果有待观察。本人抛砖引玉,对这项技术感兴趣的朋友可以考虑将t-SNE用于其它降维量化场景。至于t-SNE算法复杂度远远大于PCA,可能导致计算时间较长的担心,我这里(13*700数据量)并没有观察到,基本都是秒出的。本人也不确定当数据集合变得庞大后t-SNE算法时间会有长的延时。

Avoid losing contact!Don't miss out! The first and most important thing to do is to join my Discord chat now! Click here to start your adventure: discord.com/invite/ZTGpQJq 防止失联,请立即行动,加入本猫聊天群: discord.com/invite/ZTGpQJq
免责声明

这些信息和出版物并不意味着也不构成TradingView提供或认可的金融、投资、交易或其它类型的建议或背书。请在使用条款阅读更多信息。