简介
本文重点介绍机器学习模型中输入变量(预测因子)的选择,预处理以及评估的相关细节。所有的计算和实验将用R语言来实现。
我们将采用11个指标(振荡器),在输入设置中不设优先级。我们将从某些指标中抽取多个变量。然后我们将写一个函数形成17个变量的输入集。
最近4000个 TF = M30 / EURUSD 柱形的报价将被采用。
In <- function(p = 16){
require(TTR)
require(dplyr)
require(magrittr)
adx <- ADX(price, n = p) %>% as.data.frame %>%
mutate(.,oscDX = DIp -DIn) %>%
transmute(.,DX, ADX, oscDX) %>% as.matrix()
ar <- aroon(price[ ,c('High', 'Low')], n = p)%>%
extract(,3)
atr <- ATR(price, n = p, maType = "EMA") %>%
extract(,1:2)
cci <- CCI(price[ ,2:4], n = p)
chv <- chaikinVolatility(price[ ,2:4], n = p)
cmo <- CMO(price[ ,'Med'], n = p)
macd <- MACD(price[ ,'Med'], 12, 26, 9) %>%
as.data.frame() %>%
mutate(., vsig = signal %>%
diff %>% c(NA,.) %>% multiply_by(10)) %>%
transmute(., sign = signal, vsig) %>%
as.matrix()
rsi <- RSI(price[ ,'Med'], n = p)
stoh <- stoch(price[ ,2:4], nFastK = p, nFastD =3, nSlowD = 3, maType = "EMA")%>%
as.data.frame() %>% mutate(., oscK = fastK - fastD)%>%
transmute(.,slowD, oscK)%>% as.matrix()
smi <- SMI(price[ ,2:4],n = p, nFast = 2, nSlow = 25, nSig = 9)
vol <- volatility(price[ ,1:4], n = p, calc = "yang.zhang", N = 144)
In <- cbind(adx, ar, atr, cci, chv, cmo, macd, rsi, stoh, smi, vol)
return(In)
}
作为目标变量,我们将使用ZigZag信号。下面就是计算zigzag和其信号的公式:
ZZ <- function(pr = price, ch = ch , mode="m") {
require(TTR)
if(ch > 1) ch <- ch/(10 ^ (Dig - 1))
if(mode == "m"){pr <- pr[ ,'Med']}
if(mode == "hl") {pr <- pr[ ,c("High", "Low")]}
if(mode == "cl") {pr <- pr[ ,c("Close")]}
zz <- ZigZag(pr, change = ch, percent = F, retrace = F, lastExtreme = T)
n <- 1:length(zz)
for(i in n) { if(is.na(zz[i])) zz[i] = zz[i-1]}
dz <- zz %>% diff %>% c(0,.)
sig <- sign(dz)
return(cbind(zz, sig))
}
函数参数:
折线最小长度 25/75 p 的Zigzags
接下来我们将使用第一个ZZ并采用更短的leg。我们打算将输入和目标变量组合到一般数据帧中,移除condition = "0"的未定义数据并且从目标变量中移除“0”类型。
查看目标的类型分布:
> table(data$Class)
-1 1 1980 1985
从中可见,分类数量很均衡。既然我们已经准备好了输入和输出数据集,我们就能开始评估预测因子的重要性了。
首先我们检查输入数据的相关性:
> descCor <- cor(data[ ,-ncol(data)])
> summary(descCor[upper.tri(descCor)])
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.20170 0.03803 0.26310 0.31750 0.57240 0.95730
那两个输入变量的相关性超过了90%?
> highCor <- caret::findCorrelation(descCor, cutoff = .90)
> highCor
[1] 12 15
答案是 — rsi 和 SMI。我们将这连个排除后形成一个而数据集并观察剩余因子的相关性。
> data.f <- data[ ,-highCor]
> descCor <- cor(data.f[ ,-ncol(data.f)])
> summary(descCor[upper.tri(descCor)])
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.20170 0.03219 0.21610 0.27060 0.47820 0.89880
我们将按2:3的比例,把数据集data.f[]分成训练集和测试集,并且将数据规范化到-1:1范围内同时进行模型测试。我们使用rminer::holdout() 函数进行数据分组,将数据集一分为二。使用caret::preProcess() 函数和method = c("spatialSign")做数据规范化。当进行模型训练时,使用"doParallel"包将在可用的处理器内核间自动采用并行计算模式。你可以使用threads" 选项来指定要用于计算的特定内核数量"。
我们将简单解释下这些内容的含义:
让我们看下训练误差图表:
现在我们考察预测因子的全局重要度。
> summary(ruf)全局变量重要度:
注意:最具预测性的特征根据'score'排序并绘制。
通过查看 'class'以及'class.frequency',也必须把把最具判别能力的变量 考虑在内。
variables score class class.frequency percent1 cci 2568 1 0.50 100.002 signal 2438 1 0.51 94.923 slowD 2437 1 0.51 94.904 oscK 2410 1 0.50 93.855 ADX 2400 -1 0.51 93.446 vol 2395 1 0.51 93.247 atr 2392 -1 0.51 93.158 sign 2388 1 0.50 92.979 vsig 2383 1 0.50 92.8110 ar 2363 -1 0.51 92.0111 chv 2327 -1 0.50 90.6212 cmo 2318 -1 0.51 90.2813 DX 2314 1 0.50 90.1014 oscDX 2302 -1 0.51 89.6415 tr 2217 1 0.52 86.31 percent.importance1 72 73 74 75 76 77 78 79 710 711 712 713 614 615 6Average tree size (number of nodes) summary:
Min. 1st Qu. Median Mean 3rd Qu. Max.
3 1044 1313 1213 1524 1861 Average Leaf nodes (number of terminal nodes) summary:
Min. 1st Qu. Median Mean 3rd Qu. Max.
2 522 657 607 762 931 Leaf nodes size (number of observations per leaf node) summary:
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 1.000 2.000 4.355 3.000 2632.000 Average tree depth : 10 Theoretical (balanced) tree depth : 11
可见所有的输入参数都是显著并重要的。也就是说在那个分类中变量出现的最频繁。
更多的一些统计特征:
> pr.ruf <- predict(ruf, x.test, type = "response");
> ms.ruf <- model.stats(pr.ruf, y.test)Test set
Error rate: 19.97%Confusion matrix:
Reference
Prediction -1 1 class.error
-1 540 144 0.2105 1 120 518 0.1881Area Under ROC Curve: 0.8003Area Under Precision-Recall Curve: 0.7991F1-score: 0.7969Geometric mean: 0.8001
局部重要度
> imp.ruf <- importance(ruf, Xtest = x.test, maxInteractions = 3)1 - 全局变量重要度 (15个基于信息增益的最重要变量):
注意:最具预测性的特征根据'score'排序并绘制。
通过查看 'class'以及'class.frequency',也必须把把最具判别能力的变量 考虑在内。
Class -1 Class 1cci 0.16 0.23cmo 0.20 0.18slowD 0.09 0.10oscK 0.09 0.07signal 0.05 0.07tr 0.02 0.07ADX 0.06 0.03chv 0.06 0.04atr 0.05 0.06ar 0.05 0.03
由此可见,基于相互影响的变量的重要度的前10名同全局重要度并不相符。最终,用于分类的变量重要度是考虑它们的贡献和影响在内的。请注意变量tr,基于全局重要度的话应该位于最后一位,理论上它应该被丢弃,但却因为强相互影响性使其排名升至第六位。
因此,前十位变量为:
> best <- Cs(cci, cmo, slowD, oscK, signal, tr, ADX. chv, atr, ar)
让我们来验证下模型的质量是如何被最重要的预测因子改善的。
模型质量显然得到了改善。测试集的预测误差为17.55%,比上限28.18%低,因此没有必要重新训练。模型还有很多其他参数,改变它们可能会进一步提升模型的质量,然而这不是本文当前的目标。
我们将继续探讨输入变量的最优数据集。
如我们所见,全局变量重要度几乎已经趋于稳定,但是分类变量的重要度 排名有所不同。tr 变量位于第三位。
预测因子的部分依赖
那些重要度最高的变量的部分依赖将被考虑。
上图显示了预测椅子cci的部分依赖性。分类之间的预测数据分割除了覆盖范围外,相对来说还不错。
上图中的预测因子signal的部分依赖性图形完全不同 。两个分类的几乎所有数据都在考察范围内。
预测因子tr的部分依赖性显示了分类的合理分割,并且仍旧具有相当的覆盖性。
chv预测因子的部分依赖性很差。观察分类的完整数据。
用这种方式我们能够直观的确定预测因子数据是如何同分类联系起来以及如何将它们分隔开的。
分类的变量重要度
在分类上的“变量重要度”提供了一个局部视角:分类是固定的,意味着首先考虑重要的并且作为常量的变量来确定固定分类,最终,考虑针对每一分类的重要变量。因此,如果没有其他分类,则每一个变量都有重要度。
此处我们对能够选择确定分类的变量并不感兴趣,我们感兴趣的是当在做出选择时,在确定分类中有重要作用的变量。不考虑分类重要度,根据它们在每个分类中的排位,变量的顺序给出了其自由排名。
这个图表说明了些什么?tr预测因子对于类型“1”比类型“-1”重要很多。相反,预测因子oscK对于类型“-1”来说比类型“1”重要很多。<预测因子在不同的分类中的重要度也不同。
基于相互影响的变量重要度
下图显示了每个变量的显示方式与任何其它变量的联合的相互作用。重要的一点提醒是:第一个变量并不一定是最重要的,而是对其他变量产生最大影响的。
观察值上的变量互相影响情况
上图显示了所有预测因子的一阶和二阶相互影响,相互作用的概念如我们之前的定义。它的面积为1。如果仅在考虑一个变量的基础上做出判定,一阶表示变量(降序排列)是最重要的。二阶表示,如果一个位置变量已经选择为第一顺序了,那么第二重要的变量就是那些在第二位的变量。
为了清晰起见,互相作用给出一个顺序特征表。首先给出最重要的变量。其次给出次重要的变量。从所有互相影响组合中给出一对变量之间的相互影响。请注意这取决于模型和数据两者。因此,模型的质量直接取决于预测的质量。我们也可以一个称为“other signs”的变量元,这样我们就可以让算法显示相对不重要的变量的默认试图。
部分重要度
你可以看看基于x.tst观测值的分类“-1”上的部分 重要度。
如我们所见,对应分类“-1”的五个最重要的预测因子如上图显示。
对于分类“+1”也同样
我们看到,预测因子在结构和排位方面都不同。
让我们看看预测因子 cci and atr, 的部分依赖性,它们是预测因子互相作用中最重要的一阶和二阶重要度。
> par.dep.1 <- partialDependenceBetweenPredictors(Xtest = x.tst,
+ imp.ruf.opt,
+ features = Cs(atr, cci),
+ whichOrder = "all",
+ perspective = T)
Level of interactions between atr and cci at first order: 0.1748(99.97% of the feature(s) with maximum level)
Level of interactions between atr and cci at second order: 0.1526(87.28% of the feature(s) with maximum level)分类分布:对于一对中的一个变量,显示概率分布
被考察的变量有同样的class。
如果同样的class为 TRUE,那么这个变量很可能在预测时对其他变量
有影响(对于当前的分类或者值)。依赖性:对于变量对,显示它们的
依赖关系,以及在 预测同一个class时针对定义依赖性的值
的评估协议。对于分类变量,
使用交叉制表。热力图 : 针对变量对,显示哪里的相关性
是最强的。
颜色越暗,相关性也越强。在变量中,其决定作用的最可能是那个
最具判断能力的(查看'全局变量重要度')
并/或那个具有高阶相互作用性的(查看
'基于互相作用的变量重要度')。
全局变量重要度用于确定哪个全局变量对于减小预测误差的作用最大。
局部变量重要度描述从变量相互影响角度来看,什么使得一个变量具有影响力。
这就产生了部分重要度的概念,它表示了何时一个变量更重要。分析变量重要度的最后一步是获得局部依赖性,设置一个变量是何时 以及/或者 如何同响应相关的。
总结:Random Uniform Forests中一个变量的重要度从最高到最低级别依次展开。首先,我们找出那些变量是重要的,学习每个分类的细微的差别。然后考虑到它们之间的相互作用,我们找到是什么使它们相互影响,并将所有的分类作为一个考虑后先选择一个变量。下一步 — 我们要知道当每种分类圈定的情况下它们的影响力从何而来。最后,通过观察“部分依赖性”,我们获知变量是何时以及如何被确认重要的。所有的步骤,除了"全局变量重要度",都在任意训练或者测试集上进行操作。
已提出的多层次预测因子评估,通过显著降低数据维度和提升预测质量,来选择最重要的预测因子以及创建最优数据集。
你不仅可以评估和选择预测因子,还能够选择最具信息丰度的观测项。
让我们看看另一个有意思的包 — "RoughSet"。
Brief 描述到:这个包主要由两部分构成:Rough Set Theory (RST) 和 Fuzzy Rough Set Theory (FRST))。RST由 Z. Pawlak (1982, 1991)提出,它提供了一套复杂的数学工具用于建模和分析涵盖异质性和不确定性的信息系统。使用RST对象间不可分辨的关系不需要额外的参数来解析信息。
FRST理论,RST的扩展,由 D. Dubois 和 H. Prade (1990)提出,它将RST和由L.A.Zadeh (1965)在模糊理论中提出的不确定性和不可分辨性概念结合起来。这个概念使得你可以分析连续分布(变量)而无需预先将数据离散化。基于上述概念提出了许多方法并且已经应用到多个不同的领域中去了。为了解决问题,这个方法使用模糊关系和上下限的概念。
让我们继续。所有在这个包中提供的方法被如下划分:
我们仅研究此列表中的两项 — 预测因子的选择以及样本的选择。
让我们形成输入数据集和输出数据。我们将使用和之前获得的数据一样的数据,但将其转换到包所使用的“DecisionTable”类中。
> library(RoughSets)
加载所需的包: Rcpp
> require(magrittr)
> data.tr <- SF.asDecisionTable(data.f[idx$tr, ],
+ decision.attr = 16,
+ indx.nominal = 16)
> data.tst <- SF.asDecisionTable(data.f[idx$ts, ],
+ decision.attr = 16,
+ indx.nominal = 16+ )
> true.class <- data.tst[ ,ncol(data.tst)]
如前所述,RST使用标定数据。既然我们有的是连续的数值数据,我们将使用一个包中提供的特殊的离散化函数,来将其转换为标定数据。
> cut.values <- D.global.discernibility.heuristic.RST(data.tr)
> data.tr.d <- SF.applyDecTable(data.tr, cut.values)
让我们来看看结果(部分):
> summary(data.tr.d)
DX
(12.5,20.7]: 588
(20.7, Inf]:1106
[-Inf,12.5]: 948
我们看到预测因子被离散化成不同的值。像变量slowD, sign 完全没有被分离。变量signal, vsig, cci, oscDX被简单的分为两个区域。其他变量被分为3和6个分类。
我们选择重要的变量:
> reduct1 <- FS.quickreduct.RST(data.tr.d, control = list())
> best1 <- reduct1$reduct
> best1
DX ADX oscDX ar tr atr cci
1 2 3 4 5 6 7 chv cmo vsig oscK signal vol
8 9 11 13 14 15
没有被分离的数据 (slowD, sign) 从数据集中被移除。我们将执行测试集的离散化并且根据缩减执行情况进行变换。
> data.tst.d <- SF.applyDecTable(data.tst, cut.values)
> new.data.tr <- SF.applyDecTable(data.tr.d, reduct1)
> new.data.tst <- SF.applyDecTable(data.tst.d, reduct1)
现在,使用名为“induction rules”的包,我们将得到一系列绑定预测因子和目标的规则。下面的选项之一将被使用:
> rules <- RI.AQRules.RST(new.data.tr, confidence = 0.9, timesCovered = 3)
我们将在测试集上效验这些规则是如何用于预测的:
> pred.vals <- predict(rules, new.data.tst)
> table(pred.vals)
pred.vals
-1 1 655 667
矩阵:
> caret::confusionMatrix(true.class, pred.vals[ ,1])
模糊矩阵及其统计数据
Reference
Prediction -1 1
-1 497 163
1 158 504
大约300个样本被标记为无足轻重且可丢弃的。我们将从这个集从解析一系列规则,并将之与之前集的预测质量进行对比。
> rules <- RI.AQRules.RST(new.data.tr, confidence = 0.9,
timesCovered = 3)
> pred.vals <- predict(rules, new.data.tst)
> table(pred.vals)
pred.vals
-1 1
638 684
> caret::confusionMatrix(true.class, pred.vals[ ,1])
模糊矩阵及其统计数据