3

この例は、scikit-learn を使用して分類器の画像を作成するために残しました。

各画像は単一のカテゴリに属していますが、すべてが機能しますが、各画像はいくつかのカテゴリに属している可能性があります: 昼間の犬の写真、夜の猫の写真、夜の猫と犬の写真など...

target=[[0,1],[0,2],[1,2],[0,2,3]]
target = MultiLabelBinarizer().fit_transform(target)

classifier = svm.SVC(gamma=0.001)
classifier.fit(data, target)

しかし、私はこのエラーが発生します:

Traceback (most recent call last):
  File "test.py", line 49, in <module>
    classifier.fit(data, target)
  File "/home/mezzo/.local/lib/python2.7/site-packages/sklearn/svm/base.py", line 151, in fit
    y = self._validate_targets(y)
  File "/home/mezzo/.local/lib/python2.7/site-packages/sklearn/svm/base.py", line 514, in _validate_targets
    y_ = column_or_1d(y, warn=True)
  File "/home/mezzo/.local/lib/python2.7/site-packages/sklearn/utils/validation.py", line 551, in column_or_1d
    raise ValueError("bad input shape {0}".format(shape))
ValueError: bad input shape (4, 4)

完全なコード

import numpy as np
import PIL
from PIL import Image
import matplotlib.image as mpimg

# The digits dataset
digits = datasets.load_digits()

def normalize(old_im):
    base = 400

    if (old_im.size[0] > old_im.size[1]):
        wpercent = (base/float(old_im.size[0]))
        hsize = int((float(old_im.size[1])*float(wpercent)))
        old_im = old_im.resize((base,hsize), PIL.Image.ANTIALIAS)
    else:
        wpercent = (base/float(old_im.size[1]))
        wsize = int((float(old_im.size[0])*float(wpercent)))
        old_im = old_im.resize((wsize, base), PIL.Image.ANTIALIAS)

    old_size = old_im.size

    new_size = (base, base)
    new_im = Image.new("RGB", new_size)
    new_im.paste(old_im, ((new_size[0]-old_size[0])/2,
                          (new_size[1]-old_size[1])/2))

    #new_im.show()
    new_im.save('prov.jpg')
    return mpimg.imread('prov.jpg')

# To apply a classifier on this data, we need to flatten the image, to
# turn the data in a (samples, feature) matrix:
imgs = np.array([normalize(Image.open('/home/mezzo/Immagini/1.jpg')),normalize(Image.open('/home/mezzo/Immagini/2.jpg')),normalize(Image.open('/home/mezzo/Immagini/3.jpg')),normalize(Image.open('/home/mezzo/Immagini/4.jpg'))])
n_samples = len(imgs)
data = imgs.reshape((n_samples, -1))

target=[[0,1],[0,2],[1,2],[0,2,3]]
target = MultiLabelBinarizer().fit_transform(target)

# Create a classifier: a support vector classifier
classifier = svm.SVC(gamma=0.001)

# We learn the digits on the first half of the digits
classifier.fit(data, target)

# Now predict the value of the digit on the second half:
predicted = classifier.predict(data)

print("Classification report for classifier %s:\n%s\n"
      % (classifier, metrics.classification_report(target, predicted)))
print("Confusion matrix:\n%s" % metrics.confusion_matrix(target, predicted))
4

2 に答える 2

1

Scikit-learn の SVM 実装は、マルチラベル分類をネイティブにサポートしていませんが、他にもさまざまな分類子があります


ラベルの一意の組み合わせを個別のクラスとして扱うことにより、SVM でマルチラベル分類を行うこともできます。マトリックス内の一意の各行をtarget単一の整数ラベルに単純に置き換えることができます。これは、次を使用して効率的に行うことができますnp.unique

d = np.dtype((np.void, target.dtype.itemsize * target.shape[1]))
_, ulabels = np.unique(np.ascontiguousarray(target).view(d), return_inverse=True)

次に、単一ラベルの分類問題の場合と同じように SVM をトレーニングできます。

clf = svm.SVC()
clf.fit(data, ulabels)

考えられる注意事項の 1 つは、多数のトレーニング サンプルがない場合、まれなラベルの組み合わせで分類子のパフォーマンスが低下する可能性があることです。

于 2016-02-23T21:14:18.850 に答える
0

これは、ターゲットが次の場合に発生します。

array([[1, 1, 0, 0],
       [1, 0, 1, 0],
       [0, 1, 1, 0],
       [1, 0, 1, 1]])

ターゲットの形状は (m,) である必要があります。ここで、m は例の数です。これに対処する 1 つの方法は、次のようにバイナリ配列をラベルに変換することです。

for item in target:
    print(sum(1<<i for i, b in enumerate(item) if b))

これの出力は次のようになります。

3
5
6
13

[3,5,6,13]これで、ターゲットとして使用できます。

于 2016-02-23T21:21:43.210 に答える