如何使用两个特征向量训练 svm?

Posted

技术标签:

【中文标题】如何使用两个特征向量训练 svm?【英文标题】:How to train svm with using two feature vectors? 【发布时间】:2018-02-25 02:00:36 【问题描述】:

我有两个 numpy 数组(功能)。 numpy 数组的维度是:

audio=(360,13) ---> 从音频文件中提取特征

image=(360,5)--> 从这些音频文件的频谱图中提取特征。

我想一起使用这两个数组来训练 svm 分类器。但我知道 svm train 只得到一个数组。 (svm.train(特征,标签))。我在找有没有类似 svm.train(audio,image,label) 的东西

我也尝试连接这两个数组,但尺寸不同。我该如何解决这种情况?

【问题讨论】:

【参考方案1】:

也许我看错了,但是尺寸有什么问题吗?

每个数组中有 360 个样本,一个有 13 个维度,另一个有 5 个。将其转换为 18 个维度的 360 个样本的单个数组。

您可能需要对值进行规范化,但串联应该只是:

new_data = np.concatenate((audio,image), axis=1)

您可以通过将数据值设为零均值、单位方差来标准化数据值(求每个维度的均值和方差,从每个样本中减去均值,然后除以方差)。

means = np.mean(new_data, axis=0)
vars = np.var(new_data, axis=0)
norm_data = (new_data - means) / vars

编辑:您可能仍然以这种方式正常化,但我会使用@lejlot 的解决方案。多内核方法很有意义,并且比这种方法更灵活。

【讨论】:

好的。谢谢你。但我关心我应该进行标准化吗?如果我不正常化,会发生什么? 它经常但不总是与梯度下降的速度有关。以下是有关动机的更多信息:en.wikipedia.org/wiki/Feature_scaling【参考方案2】:

虽然@Saedeas 提供了一个简单的解决方案,但我建议采用稍微不同的方式。

连接有利于同质特征,当数据来自完全不同的模式(如音频+视频)时,它就不能很好地工作。但是,可以使用核函数(SVM 的基础)的简单属性来处理,即两个核之和是一个核,因此我们可以定义:

K_audio x video(x,y) = a K_video(x_video, y_video) + 
                         (1-a) K_audio(x_audio,y_audio)

因此分别给定每个模态的内核,我们在其之上定义一个联合内核,其中 a 是要调整的超参数 a e [0,1]。

在代码方面,它可能会以类似于已经建议的方式完成:

# First concat, but only for easier handling
new_data = np.concatenate((audio,image), axis=1)
y = ...

def video_kernel(X, Y):
  ...

def audio_kernel(X, Y):
  ...

# now new kernel
def new_kernel(X, Y, a=0.5):
  return a*audio_kernel(X[:, :13], Y[:, :13]) + (1-a)*video_kernel(X[:, 13:], Y[:, 13:])

svm = SVC(kernel=new_kernel)
svm.fit(new_data, y)

【讨论】:

【参考方案3】:

您可以连接它们。例如:http://scikit-learn.org/stable/modules/pipeline.html#feature-union,或者您可以训练两个 SVM 并使用预测结果。示例:http://scikit-learn.org/stable/modules/ensemble.html#voting-classifier。

【讨论】:

以上是关于如何使用两个特征向量训练 svm?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SVM 的权重向量和逻辑回归进行特征重要性?

如何使 HOG 特征向量适应线性 svm 输入

使用多个特征的支持向量机 (SVM) 训练

如何在 Opencv for android 中训练 SVM?

如何缩放 SVM 分类的输入特征?

如何使用线性支持向量机 (SVM) 分类器确定最重要/信息量最大的特征