量化软件下载:赫兹量化中支持向量机如何应用于交易
更高维度上文展示的二维空间的情形让我们得以将支持向量机的处理过程可视化,然而它只能使用两个输入数据来对数据点分类。如果要使用更多的输入数据呢?庆幸的是,支持向量机算法可以让我们在更高维度做同样的事情,尽管在概念上更难解释一些。 思考一下:你希望创建获取 20 个输入数据并且能够使用这些输入把任何数据点划分为类型 1 或类型 2。要做到这一点,支持向量机要将数据在 20 维空间建模,同时要用一个回归算法找到一个将数据点区分为两类的 19 维超平面。要对上述情形进行可视化是极其困难的,因为我们很难理解三维以上空间。不管怎样,您只需知道它的工作原理与二维空间完全相同。
支持向量机的工作原理示例:这是 Schnick 吗?
想象一个场景,您是一个研究人员,正在调查一种稀有的动物叫做 Schnicks,该动物只在北极深处出没。由于这研究对象罕见,只有很少一部分被发现过(假设是 5000 只左右)。作为一个研究人员,您被这样一个问题所困惑:我怎么去认定这是一个 Schnick 呢?
您手头上只有一些见过该动物的其他研究员发表的论文。而这些研究论文中,作者对他们发现的 Schnicks 的某些特征进行了描述,包括身高、体重、肢体数量等等。不过每一篇论文的特征描述都各不相同,而且没有明显的模式……
我们如何用这些数据来确定一只新的动物是 schnick 呢?
支持向量机就有可能成为解决该问题的方案之一。利用支持向量机区分数据的模式,创建一个框架模型以区分动物是 Schnick 还是非 Schnick。第一步就是创建一系列的数据,用于训练你的支持向量机分辨 schnick。训练数据是一系列的输入参数,为支持向量机匹配输出结果,以分析并从中提取模式。
因此,我们必须决定哪些输入参数要用到,以及其数量。理论上说,我们可以获取所希望数量的输入参数,然而这将经常减缓训练的速度(参数越多,支持向量机提取模式的时间越长)。同时,你希望选取在所有 schnick 中较为一致的输入值。比如,动物的身高或体重将是一个很好的输入选择,因为您期望所有的 schnick 都在这些数值上保持相对一致。然而,平均年龄将不是个好选择,因为您知道,所辨认的动物年龄可能差距非常大。
因此,以下的输入参数是我们选择的:
身高
体重
肢体数量
眼睛数量
前肢长度
平均奔跑速度
交配鸣叫频率
选择了以上的输入参数,我们开始编译熟练数据。有效的训练数据对于支持向量机来说必须满足以下特定条件:
数据必须包含 schnick 这一动物的案例
数据必须包含非 schnick 动物的案例
在这个案例中,我们获得了科学家的研究论文,这些论文已经成功地辨认出 schnick 并列出了它的相关属性。因此我们可以阅读研究论文并提取每一输入的数据,然后对每一案例分配真或假的输出结果。本例中的训练数据可能与下表类似。
训练采样
身高 [mm]
体重 [kg]
N_legs
N_eyes
L_arm [mm]
av_speed [m/s]
f_call [Hz]
Schnick (true/false)
示例 1
1030
45
8
3
420
2.1
14000
TRUE
示例 2
1010
42
8
3
450
2.2
14000
TRUE
示例 3
900
40
7
6
600
6
13000
FALSE
示例 4
1050
43
9
4
400
2.4
12000
TRUE
示例 5
700
35
2
8
320
21
13500
FALSE
示例 6
1070
42
8
3
430
2.4
12000
TRUE
示例 7
1100
40
8
3
430
2.1
11000
TRUE
示例 N
...
...
...
...
...
...
...
...
表 1. schnick 数据例表
一旦我们收集了所有的训练输入和输出数据,我们就可以用它训练我们的支持向量机。在训练过程中,支持向量机会创建一个七维模型,用以将各种训练示例分类为 ture 或 false。支持向量机会不断创建,直到获得精确表示训练数据(在指定误差容许范围之内)的模型。一旦这项训练结束,该模型就可以用来处理新的数据点,按照 true 或 false 归类。
支持向量机到底工作了吗?
借助 Schnick 案例,我写了一个脚本,测试支持向量机实际上是如何很好地处理新的 schnick 的。为了完成这个测试,我使用了“支持向量机学习工具”函数库(可以在“应用市场”中下载)。
为了针对这个案例有效建模,我们首先决定哪些是 Schnick 的实际属性。我假定的这些属性已经列在了下表中。如果一只动物满足以下所有标准,那么它就是 Schnick……
参数
下限
上限
身高 [mm]
1000
1100
体重 [kg]
40
50
N_legs
8
10
N_eyes
3
4
L_arm [mm]
400
450
av_speed [m/s]
2
2.5
f_call [Hz]
11000
15000
表 2. 定义 schnick 的参数汇总
现在我们定义了 Schnick,我们可以用这种定义来试验支持向量机。第一步是创建一个函数:能获取指定动物的 7 个输入,然后返回是否为 schnick 的动物实际分类结果。这个函数将用来生成支持向量机的训练数据,同时在结束的时候评估支持向量机的性能。可以用以下的函数完成:
//+------------------------------------------------------------------+ //| This function takes the observation properties of the observed //| animal and based on the criteria we have chosen, returns true/false whether it is a schnick //+------------------------------------------------------------------+ bool isItASchnick(double height,double weight,double N_legs,double N_eyes,double L_arm,double av_speed,double f_call) { if(height < 1000 || height > 1100) return(false); // If the height is outside the parameters > return(false) if(weight < 40 || weight > 50) return(false); // If the weight is outside the parameters > return(false) if(N_legs < 8 || N_legs > 10) return(false); // If the N_Legs is outside the parameters > return(false) if(N_eyes < 3 || N_eyes > 4) return(false); // If the N_eyes is outside the parameters > return(false) if(L_arm < 400 || L_arm > 450) return(false); // If the L_arm is outside the parameters > return(false) if(av_speed < 2 || av_speed > 2.5) return(false); // If the av_speed is outside the parameters > return(false) if(f_call < 11000 || f_call > 15000) return(false); // If the f_call is outside the parameters > return(false) return(true); // Otherwise > return(true) }
下一步就是创建一个可生成训练输入和输出的函数。本例中的输入,将通过在 7 个输入值的各自设置范围内创建随机数字的方式生成。然后针对每组随机生成的输入,再使用上面的 isItASchnick() 函数生成希望的输出结果。这在下述函数中完成:
//+------------------------------------------------------------------+ //| This function takes an empty double array and an empty boolean array, //| and generates the inputs/outputs to be used for training the SVM //+------------------------------------------------------------------+ void genTrainingData(double &inputs[],bool &outputs[],int N) { double in[]; // Creates an empty double array to be used for temporarily storing the inputs generated ArrayResize(in,N_Inputs); // Resize the in[] array to N_Inputs ArrayResize(inputs,N*N_Inputs); // Resize the inputs[] array to have a size of N*N_Inputs ArrayResize(outputs,N); // Resize the outputs[] array to have a size of N for(int i=0;i<N;i++) { in[0]= randBetween(980,1120); // Random input generated for height in[1]= randBetween(38,52); // Random input generated for weight in[2]= randBetween(7,11); // Random input generated for N_legs in[3]= randBetween(3,4.2); // Random input generated for N_eyes in[4]= randBetween(380,450); // Random input generated for L_arms in[5]= randBetween(2,2.6); // Random input generated for av_speed in[6]= randBetween(10500,15500); // Random input generated for f_call ArrayCopy(inputs,in,i*N_Inputs,0,N_Inputs); // Copy the new random inputs generated into the training input array outputs[i]=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]); // Assess the random inputs and determine if it is a schnick } } //+------------------------------------------------------------------+ //| This function is used to create a random value between t1 and t2 //+------------------------------------------------------------------+ double randBetween(double t1,double t2) { return((t2-t1)*((double)MathRand()/(double)32767)+t1); }
我们现在有了一系列的输入和输出参数,现在到了利用“应用市场”的“支持向量机学习工具”创建支持向量机的时候了。只要新的支持向量机创建好,就必须要将训练输入输出参数传递给它,并执行训练。
void OnStart() { double inputs[]; // Empty double array to be used for creating training inputs bool outputs[]; // Empty bool array to be used for creating training inputs int N_TrainingPoints=5000; // Defines the number of training samples to be generated int N_TestPoints=5000; // Defines the number of samples to be used when testing genTrainingData(inputs,outputs,N_TrainingPoints); //Generates the inputs and outputs to be used for training the SVM int handle1=initSVMachine(); // Initializes a new support vector machine and returns a handle setInputs(handle1,inputs,7); // Passes the inputs (without errors) to the support vector machine setOutputs(handle1,outputs); // Passes the outputs (without errors) to the support vector machine setParameter(handle1,OP_TOLERANCE,0.05); // Sets the error tolerance parameter to <5% training(handle1); // Trains the support vector machine using the inputs/outputs passed }
现在,我们有了一个支持向量机并完成了良好的训练,它可以成功分辨 Schnick 了。为了确认这一点,我们可以测试最终支持向量机,让它对新的数据点进行分类。首先可以生成随机输入,然后使用 isItASchnick() 函数来判断这些输入是否对应实际的 Schnick,然后使用支持向量机去划分输入,并判断所预测的结果是否与实际结果相符。这在下述函数中完成: