59、支持向量机与人工神经网络:原理、应用与性能分析

支持向量机与人工神经网络:原理、应用与性能分析

一、单类支持向量分类器(One - class SVC)的异常检测

单类支持向量分类器(One - class SVC)是对二元支持向量分类器(Binary SVC)的扩展。其主要区别在于,单类包含了大部分的基线(或正常)观测值,而另一类则由一个被称为SVC原点的参考点所取代。异常(或异常值)观测值位于单类的支持向量之外。

异常观测值的标签值为 -1,而其余训练集的标签为 +1。为了创建一个相关测试,我们添加了四家大幅削减股息的公司(股票代码为WLT、RGS、MDC、NOK和GM)。数据集包含了股息削减前记录的股票价格和财务指标。

该测试用例的实现与二元SVC驱动代码非常相似,但有以下不同:
- 分类器使用Nu - SVM公式,即OneSVFormulation。
- 标记数据是通过将消除股息的公司标记为 -1,其他所有公司标记为 +1 来生成的。

测试针对数据集 resources/data/chap8/dividends2.csv 执行。首先,我们需要定义单类支持向量机的公式:

class OneSVCFormulation(nu: Double) extends SVMFormulation {
  override def update(param: svm_parameter): Unit = {
     param.svm_type = svm_parameter.ONE_CLASS
     param.nu = nu
  }
}

测试代码与二元SVC的执行代码类似,唯一的区别是输出标签的定义:消除股息的公司为 -1,其他公司为 +1。

val NU = 0.2; val GAMMA = 0.5; val NFOLDS = 2
val path = "resources/data/chap8/dividends2.csv"
val xs = DataSource(path, true, false, 1) |> extractor
val config = SVMConfig(new OneSVCFormulation(NU),
                           RbfKernel(GAMMA), 
                           SVMExecution(EPS, NFOLDS))
val features = XTSeries.transpose(xs.dropRight(1))
val svc = SVM[Double](config, features, xs.last.map( filter (_)))
svc.accuracy match {
  case Some(acc) => Display.show("Accuracy: $acc", logger)
  case None => { … }
}

测试使用以下特征执行:relPriceChange、debtToEquity、dividendCoverage、cashPerShareToPrice和epsTrend。模型生成的准确率为0.821。这个准确率水平并不令人惊讶,因为异常值(完全消除股息的公司)被添加到了原始股息.csv文件中。这些异常值与原始输入文件中的基线观测值(减少、维持或增加股息的公司)有显著差异。

在有标记观测值的情况下,单类支持向量机是聚类技术的一个很好的替代方案。不过,单类支持向量分类器生成的结果在很大程度上取决于对异常值的主观定义。该测试用例假设消除股息的公司具有独特的特征,使其与其他公司区分开来,但这种假设并不总是有效的。

二、支持向量回归(SVR)

大多数使用支持向量机的应用都与分类有关,但同样的技术也可以应用于回归问题。幸运的是,与分类一样,LIBSVM支持两种支持向量回归的公式:
- ε - VR(有时称为C - SVR)
- υ - SVR

为了与前两种情况保持一致,以下测试使用支持向量回归的ε(或C)公式。

SVR引入了误差不敏感区域和不敏感误差ε的概念。不敏感区域定义了围绕预测值y(x)的一个值范围。惩罚组件C不会影响属于不敏感区域的数据点{xi, yi}。

对于非线性模型,最大化边际会引入一对松弛变量。而C - 支持向量分类器使用单个松弛变量。ε SVR的最小化公式如下:
[
\begin{align }
&\min_{w,\xi,\xi^
}\frac{1}{2}w^Tw + C\sum_{i = 1}^{n}(\xi_i+\xi_i^ )\
&\text{s.t. }w^T\phi(x_i)+b - y_i\leqslant\varepsilon+\xi_i\
&y_i - w^T\phi(x_i)-b\leqslant\varepsilon+\xi_i^
\
&\xi_i,\xi_i^ \geqslant0, i = 1,\cdots,n
\end{align
}
]
其中,ε是不敏感误差函数。ε - SVR回归方程为:
[
\hat{y}(x)=\sum_{i = 0}^{n - 1}\hat{\alpha}_iK(x,x_i)+w_0
]

我们可以复用SVM类来评估SVR与线性回归的能力。该测试包括复用单变量线性回归的示例,目的是比较线性回归和SVR在预测股票价格或指数值方面的输出。我们选择了标准普尔500交易型开放式指数基金(SPY),它是标准普尔500指数的代理。

模型包括以下内容:
- 一个标记输出:SPY调整后的每日收盘价。
- 一个单变量特征集:交易会话的索引(或SPY值的索引)。

实现步骤如下:
1. 定义SVR的配置参数(C成本/惩罚函数、RBF核的GAMMA系数、收敛标准的EPS和回归不敏感误差的EPSILON)。
2. 从数据源(DataSource)中提取标记数据(SPY价格),该数据源是雅虎财经的CSV格式数据文件。
3. 创建线性回归SingleLinearRegression,以交易会话的索引作为单变量特征,SPY调整后的收盘价作为标记输出。
4. 创建观测值作为索引的时间序列xt。
5. 实例化SVR,以交易会话的索引作为特征,SPY调整后的收盘价作为标记输出。
6. 运行SVR和线性回归的预测方法,并比较结果。

val path = "resources/data/chap8/SPY.csv"
val C = 1; val GAMMA = 0.8; val EPS = 1e - 3; val EPSILON = 0.1 //1
val price = DataSource(path, false, true, 1) |> adjClose //2
val priceIdx = price.zipWithIndex
                    .map(x => (x._1.toDouble, x._2.toDouble))
val linRg = SingleLinearRegression(priceIdx) //3
val config = SVMConfig(new SVRFormulation(C, EPSILON), 
RbfKernel(GAMMA)) //3
val labels = price.toArray
val xt = XTSeries[DblVector](
              Array.tabulate(labels.size)(Array[Double](_))) //4
val svr = SVM[Double](config, xt, labels) //5
collect(svr, linRg, price) //6

def collect(svr: SVM_Double, 
            lin: SingleLinearRegression[Double], 
            price: DblVector): Array[XYTSeries] = {
  val collector = Array.fill(3)(new ArrayBuffer[XY])
  Range(1, price.size - 2).foldLeft(collector)( (xs, n) => {
      xs(0).append((n, (svr |> n.toDouble).get)) //7
      xs(1).append((n, (lin |> n).get)) //8
      xs(2).append((n, price(n))) //9
      xs
  }).map( _.toArray)
}

支持向量回归比线性回归模型提供了更准确的预测。此外,SVR的L2正则化项会对与价格均值有较大偏差的数据点(SPY价格)进行惩罚。较低的C值会增加L2范数惩罚因子,因为λ = 1/C。

三、支持向量机的性能考虑

训练大型数据集上的支持向量回归模型是耗时的。支持向量机的性能取决于训练期间选择的优化器类型(例如,序列最小优化)。
- 线性模型(无核的SVM)训练N个标记观测值的渐近时间复杂度为O(N)。
- 非线性模型依赖于核方法,其被表述为一个二次规划问题,渐近时间复杂度为O(N³)。
- 使用序列最小优化技术(如索引缓存或消除空值,如LIBSVM中)的算法,渐近时间复杂度为O(N²),最坏情况下(二次优化)为O(N³)。
- 对于非常大的训练集(N > 10000)的稀疏问题,渐近时间复杂度也为O(N²)。

核化支持向量机的时间和空间复杂度一直受到广泛关注。

四、人工神经网络简介

神经网络在90年代变得非常流行,被视为解决众多问题的万能方法。从本质上讲,神经网络是一种非线性统计模型,它利用逻辑回归来创建非线性分布式模型。人工神经网络的概念源于生物学,旨在模拟大脑的关键功能,并在神经元、激活和突触的层面上复制其结构。

五、前馈神经网络(FFNN)

5.1 生物学背景

在生物学中,神经网络由通过突触相互连接的神经元组组成。神经科学家一直对理解大脑中数十亿个神经元如何相互作用以提供人类并行处理能力特别感兴趣。60年代出现了一个新的研究领域——连接主义,它将认知心理学、人工智能和神经科学结合起来,目标是创建心理现象的模型。虽然连接主义有多种形式,但神经网络模型已成为最流行和最常教授的连接主义模型。

生物神经元通过称为刺激的电荷进行通信,这种神经元网络可以用简单的示意图表示。生物神经网络和人工神经网络有对应的术语:
| 生物神经网络 | 人工神经网络 |
| ---- | ---- |
| 轴突 | 连接 |
| 树突 | 连接 |
| 突触 | 权重 |
| 电位 | 加权和 |
| 阈值 | 偏置权重 |
| 信号、刺激 | 激活 |
| 神经元组 | 神经元层 |

在生物世界中,刺激在神经元之间没有特定的传播方向。而数据科学家最常用的人工神经网络有一个预定义的方向:从输入层到输出层,这些神经网络被称为FFNN。

5.2 数学背景

支持向量机能够将模型的训练表述为一个非线性优化问题,其目标函数是凸的,实现起来相对简单。但SVM的核化可能会导致大量的基函数(或模型维度)。一种解决方案是通过参数化减少基函数的数量,使这些函数能够适应不同的训练集,这种方法可以建模为FFNN,即多层感知器(MLP)。

线性回归可以可视化为一个使用神经元和突触的简单连接模型。对于一组输入变量x = {xi}₀ⁿ和权重w = {wi}₁ⁿ,感知器的输出y计算如下:
[
y=\sigma(w^Tx + w_0)=\frac{1}{1 + e^{-(w^Tx + w_0)}}
]
FFNN可以看作是一系列逻辑回归层,输出层为线性回归。每个隐藏层的变量值计算为连接权重和前一层输出的点积的Sigmoid函数。

5.3 多层感知器(MLP)

感知器是一个基本的处理元素,通过将标量或向量映射到二进制(或异或)值{true, false}或{-1, +1}来执行二进制分类。原始的感知器算法被定义为单层神经元,特征向量的每个值xi并行处理并生成单个输出y。后来感知器扩展到包含激活函数的概念。

单层感知器只能处理权重和输入值的单个线性组合。科学家发现,在输入层和输出层之间添加中间层可以解决更复杂的分类问题,这些中间层被称为隐藏层,因为它们只与其他感知器交互,隐藏节点只能通过输入层访问。

我们使用三层感知器来研究和说明神经网络的特性。三层感知器需要两组权重:wij用于处理从输入层到隐藏层的输出,vij用于处理从隐藏层到输出层的输出。在神经网络的可视化中,线性和逻辑回归中的截距值w₀用 +1 表示。

没有隐藏层的FFNN类似于线性统计模型,输入层和输出层之间的唯一转换或连接实际上是线性回归,因此线性回归是没有隐藏层的FFNN的更有效替代方案。

MLP组件的描述和实现依赖于以下阶段:
1. 软件设计概述。
2. MLP模型组件的描述。
3. 四步训练周期的实现。
4. 训练策略的定义和实现以及由此产生的分类器。

5.4 激活函数

感知器表示为权重wi和输入值xi的线性组合,由输出单元激活函数h处理:
[
y = h\left(\sum_{i = 0}^{n}w_ix_i\right)=h(w^Tx + w_0)
]
输出激活函数h必须在权重的一定范围内连续且可微,它根据要解决的问题采用不同的形式:
- 对于二元分类或回归问题的输出层,使用恒等函数。
- 对于隐藏层,使用Sigmoid函数σ。
- 对于多项分类,使用Softmax函数。
- 对于使用零均值的分类,使用双曲正切函数tanh。

5.5 网络架构

输出层和隐藏层具有计算能力(权重、输入和激活函数的点积),输入层不转换数据。n层神经网络是具有n个计算层的网络,其架构由以下组件组成:
- 1个输入层
- (n - 1)个隐藏层
- 1个输出层

全连接神经网络的所有输入节点都连接到隐藏层神经元。如果一个或多个输入变量未被处理,则网络被称为部分连接神经网络。部分连接网络可以通过将全连接网络的一些权重设置为零来生成。

输出层的结构高度依赖于要解决的问题类型(回归或分类),问题类型决定了输出节点的数量:
- 单变量回归有一个输出节点,其值为实数[0, 1]。
- 具有n个变量的多变量回归有n个实数输出节点。
- 二元分类有一个二进制输出节点{0, 1}或{-1, +1}。
- 多项或K类分类有K个二进制输出节点。

综上所述,支持向量机和人工神经网络在数据处理和建模方面都有各自的优势和应用场景。支持向量机在分类和回归问题中表现出色,而人工神经网络则在处理复杂的非线性问题时具有强大的能力。在实际应用中,需要根据具体问题选择合适的模型,并合理调整参数以获得最佳性能。

支持向量机与人工神经网络:原理、应用与性能分析

六、多层感知器(MLP)的详细分析
6.1 MLP的训练过程

MLP的训练通常采用误差反向传播算法(Backpropagation)。这是一种基于梯度下降的优化算法,其核心思想是通过计算输出误差相对于网络中每个权重的梯度,然后沿着梯度的反方向更新权重,以最小化误差。训练过程可以简单概括为以下几个步骤:
1. 前向传播 :输入数据从输入层开始,经过隐藏层,最终到达输出层,计算出网络的输出。
2. 计算误差 :将网络的输出与真实标签进行比较,计算出误差。
3. 反向传播 :从输出层开始,将误差反向传播到隐藏层和输入层,计算每个权重的梯度。
4. 更新权重 :根据计算得到的梯度,更新网络中的权重。

这个过程会重复多次,直到误差达到一个可接受的水平或者达到最大迭代次数。

6.2 MLP配置参数的评估和调整

MLP的性能很大程度上取决于其配置参数,如隐藏层的数量、每个隐藏层的神经元数量、学习率等。以下是一些常见参数的影响和调整建议:
- 隐藏层数量 :增加隐藏层数量可以提高模型的复杂度,使其能够学习更复杂的模式。但过多的隐藏层可能会导致过拟合,即模型在训练数据上表现很好,但在测试数据上表现不佳。一般来说,对于简单的问题,1 - 2个隐藏层可能就足够了;对于复杂的问题,可以尝试增加隐藏层数量。
- 神经元数量 :每个隐藏层的神经元数量也会影响模型的性能。增加神经元数量可以提高模型的表示能力,但同样可能导致过拟合。可以通过交叉验证的方法来选择合适的神经元数量。
- 学习率 :学习率控制了每次权重更新的步长。如果学习率过大,模型可能会跳过最优解;如果学习率过小,模型的收敛速度会很慢。可以尝试不同的学习率,观察模型的训练过程和性能,选择一个合适的值。

6.3 MLP的Scala实现

下面是一个简单的Scala实现示例,展示了如何构建一个基本的MLP分类器:

// 定义MLP类
class MLP(inputSize: Int, hiddenSize: Int, outputSize: Int) {
  // 初始化权重
  val weightsInputHidden = Array.ofDim[Double](inputSize, hiddenSize)
  val weightsHiddenOutput = Array.ofDim[Double](hiddenSize, outputSize)

  // 初始化偏置
  val biasHidden = Array.ofDim[Double](hiddenSize)
  val biasOutput = Array.ofDim[Double](outputSize)

  // 激活函数(这里使用Sigmoid)
  def sigmoid(x: Double): Double = {
    1.0 / (1.0 + math.exp(-x))
  }

  // 前向传播
  def forward(input: Array[Double]): Array[Double] = {
    val hidden = Array.ofDim[Double](hiddenSize)
    for (j <- 0 until hiddenSize) {
      var sum = biasHidden(j)
      for (i <- 0 until inputSize) {
        sum += input(i) * weightsInputHidden(i)(j)
      }
      hidden(j) = sigmoid(sum)
    }

    val output = Array.ofDim[Double](outputSize)
    for (k <- 0 until outputSize) {
      var sum = biasOutput(k)
      for (j <- 0 until hiddenSize) {
        sum += hidden(j) * weightsHiddenOutput(j)(k)
      }
      output(k) = sigmoid(sum)
    }
    output
  }
}

// 使用示例
val inputSize = 3
val hiddenSize = 4
val outputSize = 2
val mlp = new MLP(inputSize, hiddenSize, outputSize)
val input = Array(1.0, 2.0, 3.0)
val output = mlp.forward(input)
println(output.mkString(", "))
七、MLP在货币汇率相关模型提取中的应用

MLP可以用于提取货币汇率的相关模型。货币汇率受到多种因素的影响,如经济数据、政治事件、市场情绪等,这些因素之间的关系往往是非线性的,因此MLP是一个合适的选择。以下是使用MLP进行货币汇率预测的一般步骤:
1. 数据收集 :收集与货币汇率相关的数据,如利率、通货膨胀率、GDP等。
2. 数据预处理 :对收集到的数据进行清洗、归一化等处理,以提高模型的训练效果。
3. 模型构建 :根据数据的特点和问题的要求,构建合适的MLP模型,包括确定隐藏层数量、神经元数量等参数。
4. 模型训练 :使用预处理后的数据对MLP模型进行训练,调整模型的权重和偏置。
5. 模型评估 :使用测试数据对训练好的模型进行评估,计算模型的准确率、均方误差等指标。
6. 预测应用 :使用训练好的模型对未来的货币汇率进行预测。

八、支持向量机与人工神经网络的比较
比较项 支持向量机(SVM) 人工神经网络(ANN)
模型复杂度 相对较低,通过核函数控制复杂度 可以非常复杂,取决于隐藏层和神经元数量
训练速度 对于小数据集较快,大数据集较慢 训练时间通常较长,尤其是深度神经网络
可解释性 相对较好,支持向量有明确的物理意义 较差,网络内部的权重和神经元难以解释
处理非线性问题 通过核函数可以处理非线性问题 天然适合处理非线性问题
数据要求 对数据的规模和分布有一定要求 可以处理大规模和复杂的数据
九、总结与展望

支持向量机和人工神经网络都是强大的机器学习工具,在不同的领域和问题中都有广泛的应用。支持向量机在处理小规模数据和线性可分问题时表现出色,而人工神经网络在处理大规模数据和复杂非线性问题时具有优势。

在实际应用中,我们需要根据具体的问题和数据特点选择合适的模型。同时,合理调整模型的参数也是提高模型性能的关键。未来,随着数据量的不断增加和计算能力的不断提升,支持向量机和人工神经网络都将不断发展和完善,为解决更多复杂的问题提供有力的支持。

以下是一个简单的mermaid流程图,展示了使用MLP进行货币汇率预测的主要步骤:

graph LR
    A[数据收集] --> B[数据预处理]
    B --> C[模型构建]
    C --> D[模型训练]
    D --> E[模型评估]
    E --> F{评估结果是否满意?}
    F -- 是 --> G[预测应用]
    F -- 否 --> C

通过对支持向量机和人工神经网络的深入了解,我们可以更好地利用这些工具来解决实际问题,推动机器学习技术的发展和应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值