如何将多个时间序列数据呈现给R中的SVM(ksvm)(或者,如何将二维输入数据呈现给SVM)

17
我该如何使ksvm模型知道数据集中前100个数字都是来自一个传感器的时间序列数据,而接下来的100个数字都是来自另一个传感器的时间序列数据,以此类推,总共有6个不同的时间序列传感器输入?或者更一般地说,如何向SVM呈现二维输入数据?
我需要一个二元的是/否预测模型,用于处理六个非周期时间序列输入,采样频率相同。数据收集开始于某个事件触发后,在一段预定时间后需要进行是/否预测(最好包括正确性概率输出)。虽然不知道哪些时间序列输入应该产生“是”或“否”,但已知每个输入时间序列数据和最终结果之间应该存在某种相关性。所有输入都存在显著的噪声。有意义的信息以及噪声都会呈现为短暂的突发事件(对于给定的输入源,有意义的突发事件总是在大致相同的时间出现),但确定哪些突发事件是有意义的,哪些是噪声却很困难;即使某个输入在“正确”的时间发生了突发事件,也不一定表示输出应该是“是”,它可能只是噪声。为了知道预测是否应该是“是”,模型需要以某种方式结合所有六个时间序列输入的信息。我有一组先前的数据,其中约有900个“否”结果和100个“是”结果。

我对R和SVM都比较新,但我想使用SVM模型 (kernlab的ksvm)。我在如何向它呈现输入数据方面遇到了困难。我也不确定如何告诉ksvm数据是时间序列数据,或者这是否相关。我尝试使用Rattle GUI前端来自csv文件导入我的数据,但我无法弄清如何将所有六个输入的时间序列数据呈现给ksvm模型。作为csv文件输入,似乎唯一的导入所有1000个样本数据的方法是组织输入数据,使所有样本数据(对于所有六个时间序列输入)都在csv文件的一行上,每行csv文件上都有一个单独的已知结果文件的数据呈现。但这样做,第1、2、3等数字是每个传感器的时间序列数据的一部分,在翻译中丢失了,以及第101、102、103等数字是每个第二个传感器的时间序列数据的一部分,依此类推;对于ksvm模型,每个数据样本只被视为与其相邻的孤立数字。我该如何将这些数据呈现给ksvm作为六个单独但相互关联的时间序列数组?或者我该如何向ksvm呈现二维数据数组?


更新:

好的,我尝试了两种基本策略,但效果都很差(虽然生成的模型比盲猜要好一些,但还是不够好)。

首先,由于不熟悉R语言,我使用了Rattle GUI前端来操作R。我有一种感觉,这样做可能会限制我的选择。但无论如何,以下是我所做的……

示例已知结果文件(仅显示4个传感器而非6个,以及仅有7个时间样本而非100个):

training168_yes.csv

Seconds Since 1/1/2000,sensor1,sensor2,sensor3,sensor4
454768042.4,           0,      0,      0,      0
454768042.6,           51,     60,     0,      172
454768043.3,           0,      0,      0,      0
454768043.7,           300,    0,      0,      37
454768044.0,           0,      0,      1518,   0
454768044.3,           0,      0,      0,      0
454768044.7,           335,    0,      0,      4273

training169_no.csv

Seconds Since 1/1/2000,sensor1,sensor2,sensor3,sensor4
454767904.5,           0,      0,      0,      0
454767904.8,           51,     0,      498,    0
454767905.0,           633,    0,      204,    55
454767905.3,           0,      0,      0,      512
454767905.6,           202,    655,    739,    656
454767905.8,           0,      0,      0,      0
454767906.0,           0,      934,    0,      7814

我唯一知道的将所有训练样本数据导入R/Rattle的方法是将所有结果文件组合成一个单独的.csv文件,每行一个样本结果。我只能想到两种方法来实现这一点,所以我尝试了这两种方法(我知道这样做会隐藏潜在重要信息,这也是这个SO问题的关键): 试验 #1:对于每个结果文件,将每个传感器的样本添加到一个数字中,摧毁所有时间信息:
result,sensor1,sensor2,sensor3,sensor4
no,    886,    1589,   1441,   9037
yes,   686,    60,     1518,   4482
no,    632,    1289,   1173,   9152
yes,   411,    67,     988,    5030
no,    772,    1703,   1351,   9008
yes,   490,    70,     1348,   4909

当我使用Rattle生成SVM后,Rattle的日志选项卡会给出以下脚本,可用于在RGui中生成和训练SVM:

library(rattle)
building <- TRUE
scoring  <- ! building
library(colorspace)
crv$seed <- 42 
crs$dataset <- read.csv("file:///C:/Users/mminich/Desktop/stackoverflow/trainingSummary1.csv", na.strings=c(".", "NA", "", "?"), strip.white=TRUE, encoding="UTF-8")
set.seed(crv$seed) 
crs$nobs <- nrow(crs$dataset) # 6 observations 
crs$sample <- crs$train <- sample(nrow(crs$dataset), 0.67*crs$nobs) # 4 observations
crs$validate <- NULL
crs$test <- setdiff(setdiff(seq_len(nrow(crs$dataset)), crs$train), crs$validate) # 2 observations
# The following variable selections have been noted.
crs$input <- c("sensor1", "sensor2", "sensor3", "sensor4")
crs$numeric <- c("sensor1", "sensor2", "sensor3", "sensor4")
crs$categoric <- NULL
crs$target  <- "result"
crs$risk    <- NULL
crs$ident   <- NULL
crs$ignore  <- NULL
crs$weights <- NULL
require(kernlab, quietly=TRUE)
set.seed(crv$seed)
crs$ksvm <- ksvm(as.factor(result) ~ .,
      data=crs$dataset[,c(crs$input, crs$target)],
      kernel="polydot",
      kpar=list("degree"=1),
      prob.model=TRUE)

试验 #2:对于每个结果文件,将每个时间点所有传感器的样本值相加,并将其转化为单个数字,消除有关各个传感器的信息:

result,time1, time2, time3, time4, time5, time6, time7
no,    0,     549,   892,   512,   2252,  0,     8748
yes,   0,     283,   0,     337,   1518,  0,     4608
no,    0,     555,   753,   518,   2501,  0,     8984
yes,   0,     278,   12,    349,   1438,  3,     4441
no,    0,     602,   901,   499,   2391,  0,     7989
yes,   0,     271,   3,     364,   1474,  1,     4599

我再次使用Rattle来生成SVM,Rattle的日志选项卡给我以下脚本:

library(rattle)
building <- TRUE
scoring  <- ! building
library(colorspace)
crv$seed <- 42 
crs$dataset <- read.csv("file:///C:/Users/mminich/Desktop/stackoverflow/trainingSummary2.csv", na.strings=c(".", "NA", "", "?"), strip.white=TRUE, encoding="UTF-8")
set.seed(crv$seed) 
crs$nobs <- nrow(crs$dataset) # 6 observations 
crs$sample <- crs$train <- sample(nrow(crs$dataset), 0.67*crs$nobs) # 4 observations
crs$validate <- NULL
crs$test <- setdiff(setdiff(seq_len(nrow(crs$dataset)), crs$train), crs$validate) # 2 observations
# The following variable selections have been noted.
crs$input <- c("time1", "time2", "time3", "time4", "time5", "time6", "time7")
crs$numeric <- c("time1", "time2", "time3", "time4", "time5", "time6", "time7")
crs$categoric <- NULL
crs$target  <- "result"
crs$risk    <- NULL
crs$ident   <- NULL
crs$ignore  <- NULL
crs$weights <- NULL
require(kernlab, quietly=TRUE)
set.seed(crv$seed)
crs$ksvm <- ksvm(as.factor(result) ~ .,
      data=crs$dataset[,c(crs$input, crs$target)],
      kernel="polydot",
      kpar=list("degree"=1),
      prob.model=TRUE)

很不幸,即使有近1000个训练数据集,两个生成的模型给出的结果仅比随机猜测略好一些。我相信如果有办法避免消除时间数据或不同传感器之间的区别,结果会更好。我该怎么做呢?顺便说一句,我不知道这是否重要,但所有传感器的读数几乎在同一时间被获取,但从一个运行到下一个(即“训练”文件之间)的时间差通常会变化10%到20%左右,并且我无法控制。我认为这可能是可以忽略的(即我认为可以安全地将读数按顺序编号,如1,2,3等)。

3
当我开始发布R语言问题时,有人要求我"制作可重现的例子"。这些提示帮助我提出更好的R语言问题,甚至回答了我自己的R语言问题。简而言之,如果您在问题中提供示例数据以及您认为应该工作的代码(或者是最接近使其工作的代码),并提供期望的输出,那么我们都可以很好地开始帮助您找到答案。 - Christopher Bottoms
@BenjyKessler - 我不确定卡尔曼滤波器是否适用于我的情况?维基百科关于卡尔曼滤波器的文章谈到了“固定滞后平滑器”,但在我的情况下,一个传感器与其他传感器之间的滞后时间是未知的,但已知存在(可能)。我希望SVM模型可以自动调整自己以检测滞后时间,如果它们是显著的。而且滞后时间也会随着时间而改变;我希望每次过程发生变化时,我都可以使用新的训练数据重新训练SVM。如果我不知道滞后时间,卡尔曼滤波器仍然有用吗?此外,如果我有6个输入而不是2个,它能帮助吗? - phonetagger
@ChristopherBottoms - 谢谢您的建议。我正在努力组织一个小例子,展示我已经尝试过但结果不佳的内容。 - phonetagger
@ChristopherBottoms,希望我的更新足以作为一个可重现的示例? - phonetagger
他们应该将其作为要求,如果一个人想要对一个问题进行负评,他们必须留下评论说明为什么他们对其进行了负评(如果他们选择匿名),如果评论没有意义,任何人都可以标记它以便撤销。 - phonetagger
显示剩余2条评论
1个回答

1
SVM将特征向量用于构建分类器。您的特征向量可以来自不同来源和时间的每个6维,并作为第七维。每个信号时间点都会产生另一个向量。创建大小为7的t向量Vt,并将其用您的数据填充,然后传递给ksvm。通过将t添加为特征向量的另一个特征,您既可以使同一特定时间发生的所有数据相互关联,也可以帮助SVM学习值的变化。您可以选择Vt的子集作为训练集。您需要手动为这些向量打上正确分类的标签。

你在R中手动创建过ksvm对象吗(而不是使用Rattle)?我在弄清如何创建你所说的“特征向量”方面遇到了麻烦。我可以从它的.csv文件中加载单个“观察”,这会产生一个typeof()为“list”的表格,尽管当我打印它时,它看起来像是一个矩阵(二维数组)。我是否只需创建这些二维对象的列表,并将其作为“数据”输入到ksvm中即可?顺便说一下,我现在正在将时间戳从2000年以来的秒数转换为从开始以来的秒数,因此第一行的时间戳为0.000,依此类推。 - phonetagger
嗯,实际上我以前从来没有用过R :) 如果我理解正确的话,你需要构建一个二维矩阵,其中每一行都是一个特征向量。 - Benjy Kessler
哇,R在SO上可能不是很受欢迎。人们纷纷涌出来回答C和C++的问题。 - phonetagger
有一个名为Cross Validated的堆栈交换网站专门用于此类问题。 - Benjy Kessler
1
不是这样的,但如果你这样做可能会得到更好的答案。 - Benjy Kessler
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接