内核svm

时间:2019-01-25 20:17:32

标签: python arrays scikit-learn classification svm

我很难将一系列图像转换为正确的格式以馈入sklearn.svm.SVC。

这是我的第一个图像识别项目,所以我有点痛苦。

我有一个循环,可以将一堆base64 RGB图像(大小不同)引入数据帧

imageData = mpimg.imread(io.BytesIO(base64.b64decode(value)),format='JPG')

然后我将RGB图像转换为灰度图像并进行平坦化

data_images = rgb2gray(imageData).ravel()

其中rgb2gray:

def rgb2gray(rgb):
    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
    return gray

如果我看一下尺寸差异

df_raw.sample(10)

enter image description here

我们可以看到样本之间的图片像素长度不同。我在这里对如何进行有点困惑。由于缺乏更好的主意,我决定根据尺寸最大的图片添加填充

df_raw.picLen.max()

然后在每个1D图片数组的末尾附加多个零。

def padPic(x,numb,maxN):
    N = maxN-len(x)
    out = np.pad(x,(numb,N),'constant')
    return out

通话

df_raw['picNew'] = df_raw.apply(lambda row: padPic(row['pic'],0,df_raw.picLen.max()), axis=1)
df_raw['picNewLen']  = df_raw.apply(lambda row: len(row['picNew']), axis=1)

我现在有所有相同大小的数组 enter image description here

在这里,我尝试使用图片数据作为X和一组标签作为y来拟合模型以支持矢量算法。

from sklearn.svm import SVC
X_train, X_test, y_train, y_test = train_test_split(df_raw.picNew, df_raw.name, test_size = 0.2, random_state=42)

检查尺寸:

print('Training data and target sizes: \n{}, {}'.format(X_train.shape,y_train.shape))
print('Test data and target sizes: \n{}, {}'.format(X_test.shape,y_test.shape))
  

训练数据和目标大小:(198,),(198,)测试数据和目标   大小:(50,),(50,)

在我说服自己一切都准备好之后,然后尝试拟合模型

svm = SVC()
svm.fit(X_train, y_train)

这会引发错误,我无法弄清原因:

  

/opt/wakari/anaconda/envs/ulabenv_2018-11-13_10.15.00/lib/python3.5/site-packages/numpy/core/numeric.py asarray(a,dtype,order)       499       500“”“   -> 501返回数组(a,dtype,copy = False,order = order)       502       503

     

ValueError:设置具有序列的数组元素。

我认为这必须与数组大小有关,但我无法弄清楚。 :-/

除了错误之外,更一般而言,我对我的方法总体上还有疑问。特别是,我认为我的“填充”可能不正确,并且可能需要进行一些调整。 我感谢对我的方法提出的任何反馈。谢谢

2 个答案:

答案 0 :(得分:1)

我很确定这是由于使用功能列中的列表和字符串作为目标值。对于后者,您需要根据fit()的要求使用LabelEncoder类将它们转换为归一化的类标签。

在此处查看说明: https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html

这需要在训练/测试拆分之前完成,以确保您拥有LabelEncoder看到的所有名称。

对于前者,您可能需要搜索MNIST教程,该教程将提供大量适用于图像分类问题的算法。

此外,在展平前调整大小比填充要好。

答案 1 :(得分:0)

我已经解决了问题。

感谢Artem抓住了我明显的不编码类的问题,但这最终不是我的问题。

结果显示了我的图片数组的表示方式不正确。 原始数组为df_raw['picNew'].shape,其结果为

  

(248,)

我需要的是2D表示

np.stack(df_raw['picNew'] , axis=1).shape
  

(830435,248)

现在一切都好。

我仍然不确定将图像调整为相同长度的最“正确”方法。在数组长度上加上0似乎有点复杂……所以,如果有人有想法:)