如何使用两个特征向量训练 svm?
How to train svm with using two feature vectors?
我有两个 numpy 数组(特征)。 numpy 数组的维度是:
audio=(360,13) ---> 从音频文件中提取特征
image=(360,5)--> 从这些音频文件的频谱图中提取特征。
我想同时使用这两个数组来训练 svm 分类器。但我知道 svm train 只得到一个数组。 (svm.train(特征,标签))。我正在寻找是否有类似 svm.train(audio,image,label)
我也试过连接这两个数组,但尺寸不同。我该如何解决这种情况?
也许我看错了,但是尺寸是个问题吗?
每个数组中有 360 个样本,一个有 13 个维度,另一个有 5 个维度。将它变成一个包含 360 个样本的 18 维数组。
您可能需要规范化这些值,但串联应该只是:
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 的解决方案。多内核方法很有意义,并且比这种方法更灵活。
您可以将它们串联起来。例如:http://scikit-learn.org/stable/modules/pipeline.html#feature-union , or you can train two SVM and work with prediction results. Example: http://scikit-learn.org/stable/modules/ensemble.html#voting-classifier .
虽然@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)
我有两个 numpy 数组(特征)。 numpy 数组的维度是:
audio=(360,13) ---> 从音频文件中提取特征
image=(360,5)--> 从这些音频文件的频谱图中提取特征。
我想同时使用这两个数组来训练 svm 分类器。但我知道 svm train 只得到一个数组。 (svm.train(特征,标签))。我正在寻找是否有类似 svm.train(audio,image,label)
我也试过连接这两个数组,但尺寸不同。我该如何解决这种情况?
也许我看错了,但是尺寸是个问题吗?
每个数组中有 360 个样本,一个有 13 个维度,另一个有 5 个维度。将它变成一个包含 360 个样本的 18 维数组。
您可能需要规范化这些值,但串联应该只是:
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 的解决方案。多内核方法很有意义,并且比这种方法更灵活。
您可以将它们串联起来。例如:http://scikit-learn.org/stable/modules/pipeline.html#feature-union , or you can train two SVM and work with prediction results. Example: http://scikit-learn.org/stable/modules/ensemble.html#voting-classifier .
虽然@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)