В моей предыдущей публикации я объяснил процедуры, которые я проделал для классификации цветов ириса с помощью контролируемых методов обучения K-ближайшего соседа и Наивного Байеса.



Привет ML - Классификация Ирис Флауэрс
Набор данных Ирис считается« Привет, мир
машинного обучения. Итак, студент, изучающий компьютерную инженерию, начинающий ML… medium.com »



Недавно я столкнулся с другим эксцентричным набором данных, который представляет собой набор данных Pokemon на Kaggle от Alberto Barradas. Следующим шагом в изучении машинного обучения будет этот набор данных с использованием PyCharm.

Данные

Набор данных содержит 13 атрибутов с 800 образцами, и моей целью будет выяснить, является ли данный покемон легендарным или нет.

Атрибуты есть;

  1. Индексный номер PokeDex
  2. Имя
  3. Тип 1 - Тип покемона
  4. Тип 2 - Вторичный тип покемонов
  5. HP - Здоровье
  6. Атака - точка атаки
  7. Защита - точка защиты
  8. Sp. Атк - Специальная точка атаки
  9. Sp. Защита - Особая точка защиты
  10. Скорость
  11. Итого - Сумма атаки, Sp. Атк, Защита, Sp. Защита, Скорость и HP
  12. Поколение
  13. Легендарный - легендарен ли покемон или нет

В предыдущей публикации отсутствующих значений не было, но в этом наборе данных есть отсутствующие значения.

Предварительная обработка

Прежде всего, файл CSV должен быть прочитан и классифицирован с помощью библиотеки pandas. На этот раз я использовал структуру данных панд Dataframe.

pokemon_csv = pd.read_csv('Pokemon.csv')

df = pd.DataFrame(pokemon_csv, columns = ['Name', 'Type 1', 'Type 2', 'Total', 'HP','Attack','Defense','Sp. Atk','Sp. Def','Speed','Generation','Legendary'])

Выявить недостающие значения;

print(df.apply(lambda x: x.count()))

Лямбда-функция показывает, что все 12 атрибутов не имеют пропущенных значений, но атрибут «Тип 2» имеет всего 414 значений. В этом случае может быть два подхода;

  • Заполнение пропущенных значений
  • Удаление столбца "Тип 2"

Поскольку пропущено 386 значений, я предпочитаю отбросить весь столбец.

Кроме того, в столбце «Имя» нет уникальных имен. Так что он тоже будет отброшен.

df = df.drop(['Name','Type 2'],axis=1)

Во-вторых, столбец типа 1 содержит 18 различных строковых значений, которые необходимо преобразовать в числовые значения. Чтобы правильно пронумеровать переменные, создайте словарь с именем «uniqueItem» и добавьте каждое уникальное слово в столбец с уникальными номерами.

i = 0
uniqueItem = dict()
for item in df['Type 1']:
    if item not in uniqueItem:
        uniqueItem[str(item)] = i
        i+=1

Вот 18 различных типов;

uniqueItem = {'Grass': 0, 'Fire': 1, 'Water': 2, 'Bug': 3, 
              'Normal': 4, 'Poison': 5, 'Electric': 6, 
              'Ground': 7, 'Fairy': 8, 'Fighting': 9, 
              'Psychic': 10, 'Rock': 11, 'Ghost': 12, 
              'Ice': 13, 'Dragon': 14, 'Dark': 15, 
              'Steel': 16, 'Flying': 17}

В словарь uniqueItem был введен в dataFrame;

for type in df['Type 1']:
    df = df.replace({type:uniqueItem.get(type)})

Наконец, данные нужно будет разделить пополам в качестве данных для тестирования и обучения позже;

X = np.array(df.iloc[:,0:-1])
Y = np.array([[df['Legendary']]])

Форма массивов X и Y создала проблему, поэтому пришлось изменить форму массива Y;

Y = Y.reshape(800)
Before reshaping Y :  (1, 1, 800)
After reshaping  Y :  (800,)

Создание гауссовской наивной байесовской модели

После этого массивы X и Y разделены на тестовую и обучающую секции, необходимо создать модель и подогнать данные;

X_train, X_test, y_train, y_test = train_test_split(
X, Y, test_size = 0.2, random_state = 10)

model = GaussianNB()
model.fit(X_train, y_train)

Затем можно отобразить точность;

y_pred = model.predict(X_test)
print("Accuracy score of NaiveBayes:",accuracy_score(y_test,y_pred))
Accuracy score of Naive Bayes:  0.95625

Создание модели классификатора ЦУР

По схеме на sci-kit, решил попробовать классификатор ЦУР;

clf = linear_model.SGDClassifier()
clf.fit(X, Y)

y_pred = clf.predict(X_test)
print("Accuracy score of SDG: ",accuracy_score(y_test,y_pred))
Accuracy score of SDG:  0.91875

Заключение

В качестве второго набора данных я попытался реализовать методы машинного обучения, этот набор данных многому меня научил. Особенно в части предварительной обработки пришлось погрузиться в особенности pandas. Благодаря схеме на сайте sci-kit я реализовал новый классификатор.

Как результат,

  • Оценка точности наивного Байеса: 0,95625
  • Оценка точности SDG: 0,9125

Наконец, репозиторий GitHub можно найти здесь.

Редактировать 27.09.2018:

Один из моих профессоров посоветовал вместо удаления всего столбца «Тип 2» удалить строки, не содержащие значения «Тип 2». В некоторых случаях плотность набора данных может быть увеличена при удалении большого количества строк, чтобы не потерять весь столбец.

Для удаления строк без Типа 2 значение кода изменено;

df = df.drop(['Name'],axis=1)
df = df.dropna(subset=['Type 2'])

Тот же код выполняется для нумерации записей в столбце;

for item in df['Type 2']:
    if item not in uniqueItem2:
        uniqueItem2[str(item)] = i
        i+=1

for type in df['Type 2']:
    if type in uniqueItem2:
        df = df.replace({type:uniqueItem2.get(type)})

К сожалению, результат был снижен для обоих методов;

  • Оценка точности наивного Байеса: 0,903614457831
  • Оценка точности SDG: 0,819277108434