Должен ли ярлык y быть определенного типа для работы SVM? - PullRequest
0 голосов
/ 26 марта 2019

Я борюсь с классификатором SVM, чтобы классифицировать изображения домино в соответствии с их классом, например, 1x3.

У меня есть 2.000+ изображений 28 различных классов домино (можно скачать здесь ).

Я запускаю следующий скрипт, используя scikit-learn и SVM в качестве алгоритма:

import matplotlib.pyplot as plt
from sklearn import svm, metrics
from sklearn.model_selection import train_test_split
import numpy as np
import os # Working with files and folders
from PIL import Image # Image processing

rootdir = os.getcwd()

image_file = 'images.npy'
key_file = 'keys.npy'

if (os.path.exists(image_file) and os.path.exists(key_file)):
  print "Loading existing numpy's"
  pixel_arr = np.load(image_file)
  key = np.load(key_file)
else:
  print "Creating new numpy's"  
  key_array = []
  pixel_arr = np.empty((0,10000), "uint8")

  for subdir, dirs, files in os.walk('data'):
    dir_name = subdir.split("/")[-1]    
    if "x" in dir_name:
      for file in files:
        if ".DS_Store" not in file:
          im = Image.open(os.path.join(subdir, file))
          if im.size == (100,100):            
            key_array.append(dir_name)          
            numpied_image = np.array(im.convert('L')).reshape(1,-1)
            #Image.fromarray(np.reshape(numpied_image,(-1,100)), 'L').show()
            pixel_arr = np.append(pixel_arr, numpied_image, axis=0)
          im.close()

  key = np.array(key_array)
  np.save(image_file, pixel_arr)
  np.save(key_file, key)


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

X_train, X_test, y_train, y_test = train_test_split(pixel_arr, key, test_size=0.1,random_state=33)

# We learn the digits on the first half of the digits
print "Fitting classifier"
classifier.fit(X_train, y_train)

# Now predict the value of the digit on the second half:
expected = y_test

print "Predicting"
predicted = classifier.predict(X_test)

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

, что дает следующее:

Classification report for classifier SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False):
             precision    recall  f1-score   support

        0x0       0.00      0.00      0.00         9
        1x0       0.00      0.00      0.00         9
        1x1       0.00      0.00      0.00        12
        2x0       0.00      0.00      0.00        12
        2x1       0.00      0.00      0.00        10
        2x2       0.00      0.00      0.00         7
        3x0       0.00      0.00      0.00         7
        3x1       0.00      0.00      0.00         8
        3x2       0.00      0.00      0.00         8
        3x3       0.01      1.00      0.02         3
        4x0       0.00      0.00      0.00        11
        4x1       0.00      0.00      0.00        10
        4x2       0.00      0.00      0.00         8
        4x3       0.00      0.00      0.00        15
        4x4       0.00      0.00      0.00         8
        5x0       0.00      0.00      0.00        12
        5x1       0.00      0.00      0.00         7
        5x2       0.00      0.00      0.00        11
        5x3       0.00      0.00      0.00         7
        5x4       0.00      0.00      0.00         9
        5x5       0.00      0.00      0.00        14
        6x0       0.00      0.00      0.00        11
        6x1       0.00      0.00      0.00        12
        6x2       0.00      0.00      0.00        11
        6x3       0.00      0.00      0.00         9
        6x4       0.00      0.00      0.00         9
        6x5       0.00      0.00      0.00        18
        6x6       0.00      0.00      0.00        13

avg / total       0.00      0.01      0.00       280


>>> print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted))
Confusion matrix:
[[ 0  0  0  0  0  0  0  0  0  9  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  9  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 12  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 12  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 10  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  7  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  7  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  8  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  8  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  3  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 11  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 10  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  8  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 15  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  8  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 12  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  7  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 11  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  7  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  9  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 14  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 11  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 12  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 11  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  9  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  9  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 18  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0 13  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0]]

Очевидно, что-то очень неправильно. Даже если классификатор будет угадывать свободно, он получит более высокую точность Я подозреваю, что я не смог подтвердить, что способ создания метки ключа / y не подходит. Тем не менее скрипт выполняется без ошибок, но не может ничего предсказать.

Одна вещь, которая заставляет меня думать, что с ключом что-то не так, это то, что матрица смешения не имеет никаких меток.

В чем может быть ошибка, когда вы получаете такие результаты?

Редактировать: я пытался использовать LabelEncoder на key, но результаты были такими же.

Edit2: я также пробовал разные лямбды, и лямбда, настроенная вручную на 0,00001, что-то дало, что оценка классификатора составила 0,05 (что было улучшением по сравнению с вышеупомянутым). Я не ожидаю, что классификатор будет идеальным на этих данных, но я бы по крайней мере ожидал что-то в области 60-70%, а не 5%.

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Хотя я не смог заставить его работать со сценарием, я использовал набор рукописных изображений и применил этот сценарий, и он дал те же результаты.Однако в итоге он работал лучше с другими значениями гаммы .Т.е. сначала все результаты были посередине, но с изменением гаммы я получил рукописный скрипт для получения точных результатов.Я могу только предположить, что это та же самая проблема здесь, хотя я не смог найти гамма-значение, которое дает что-то лучше, чем точность 5%.

Но относительно того, почему это происходит, я совершенно уверенчто значение гаммы (или, возможно, любой другой параметр SVC) отключено.

0 голосов
/ 26 марта 2019

Для задачи классификации вы должны сначала преобразовать целевой вектор (ключ) в числовой тип вместо непосредственного использования названий категорий / меток. Как в следующем примере:

In [21]: iris=datasets.load_iris()

In [22]: X=iris.data

In [23]: y=iris.target

In [24]: y
Out[24]: 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

In [25]: iris.target_names
Out[25]: array(['setosa', 'versicolor', 'virginica'], dtype='<U10')

Попробуйте следующий код, используя упомянутый LabelEncoder:

from sklearn import preprocessing
le=preprocessing.LabelEncoder()
le.fit(key)
le.transform(key)
Out[36]: array([0, 1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...