Вступление

Kaggle - это удивительное сообщество для начинающих специалистов по обработке данных и практиков машинного обучения, которые собираются вместе для решения проблем, связанных с наукой о данных, в условиях конкуренции. Многие статистики и специалисты по обработке данных соревнуются в дружественном сообществе с целью создания лучших моделей для прогнозирования и анализа наборов данных. Любая компания, у которой есть набор данных и проблема, которую необходимо решить, может извлечь выгоду из Kagglers. Kaggle не только предоставил профессиональную среду для проектов в области науки о данных, но и создал среду, в которой новички могут изучать и практиковать науку о данных и навыки машинного обучения.

Этот блог будет служить введением в платформу Kaggle и даст краткое описание процесса присоединения к соревнованиям, участия в обсуждениях, создания ядер и продвижения по ранжированию.

Система прогресса Kaggle

У Kaggle есть система ранжирования, которая помогает специалистам по данным отслеживать их прогресс и эффективность. Медали награждаются за определенные действия, которые выполнены. Когда Кагглер зарабатывает достаточно медалей, чтобы подняться на уровень в системе прогресса, он повышается в рейтинге!

Рейтинг Kaggle может быть получен по трем различным «категориям опыта»: Соревнования, Ядра и Обсуждение.

Каждая из трех категорий имеет пять разрядов: Новичок, Участник, Эксперт, Мастер и Грандмастер. . Большинство пользователей Kaggle считаются «новичками», что по сути означает, что они не взаимодействовали с сообществом, не запускали никаких скриптов и не подавали заявки на участие в конкурсе. Каждый пользователь выше уровня новичка отправлял материалы и использовал наборы данных для прогнозов и анализа.

Слово мудрым: учитесь у всех на Kaggle, особенно у высокопоставленных лиц! Одной из причин большого успеха Kaggle является его дружественная к обучению среда и легкость обучения новым навыкам. Просмотр видеоуроков по методам науки о данных - отличное начало, но нет ничего более ценного, чем прочитать ядро ​​и объяснения опытного специалиста по данным, а затем использовать навыки, полученные в ваших собственных моделях.

Доска обсуждений

Доска обсуждений - отличное место, чтобы задавать вопросы, отвечать на вопросы и общаться с сообществом. Всегда есть люди, которые публикуют ответы на важные вопросы, из которых мы все можем извлечь уроки. Существует также форум «Приступая к работе» для новых Kagglers, которые хотят изучить основы платформы Kaggle. Kaggle предоставляет шесть уникальных форумов на доске обсуждений, каждый из которых имеет свою цель.

Наборы данных

Вам нужны данные для любого научного проекта данных. Kaggle предоставляет огромное количество доступных наборов данных на вкладке «Наборы данных». На момент написания этого блога насчитывалось более 17 730 общедоступных наборов данных. Наборы данных можно сортировать с помощью нескольких фильтров, чтобы найти именно то, что вы ищете. Как только вы найдете нужный набор данных, вы можете просто щелкнуть по нему и нажать «Загрузить», чтобы загрузить данные на свой компьютер.

Старт вашего первого соревнования!

На вкладке «Соревнование» Kaggle есть много конкурсов, в которых вы можете принять участие. Это похоже на вкладку «Наборы данных», где вы можете щелкнуть по конкурсу и загрузить данные для своих моделей. Есть несколько соревнований, которые предназначены для начинающих, чтобы принять участие и изучить основы Kaggle и Data Science. Одним из соревнований для начинающих является знаменитый набор данных MNSIT, в котором мы создадим модель, которая будет классифицировать рукописные цифры и делать прогнозы на основе тестовых данных. В этом сообщении в блоге будет использоваться набор данных MNIST, а также будут представлены прогнозы для участников конкурса. Первое, что нам нужно сделать, это посмотреть на наши данные и начать думать о построении нашей модели. Для начала мы можем запустить новое ядро ​​.

Ядро

Согласно документации Kaggle, ядра - это облачные вычислительные среды, которые обеспечивают воспроизводимый и совместный анализ. Ядра позволяют Kaggler создавать и запускать код из браузера без необходимости загружать Python и пакеты на свой компьютер. Один из типов ядра, которое предоставляет Kaggle, - это блокнот. Если вы знакомы с Jupyter Notebooks, значит, вы знакомы с блокнотами Kaggle, потому что это одно и то же!

Нам нужно будет создать ядро, для этого мы можем нажать «Создать ядро» и выбрать опцию «Блокнот», чтобы провести анализ в Jupyter Notebook. Как только записная книжка откроется, вы заметите заранее написанный код, известный как «стартовый код». Начальный код импортирует некоторые общие библиотеки и распечатает каталоги в папке данных. Для этого блога мы удалим стартовый код и напишем наш импорт самостоятельно. В первой ячейке записной книжки мы напишем весь необходимый импорт для нашего проекта и распечатаем все, что находится в папке «digit_data», которую мы загрузили.

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
import os
print(os.listdir('digit_data'))

Выход:

['test.csv', 'train.csv', 'sample_submission.csv']

Следующий шаг включает загрузку наших данных в записную книжку. Обратите внимание, что наша папка данных предоставляет нам обучающий и тестовый файл. Мы можем использовать pandas, библиотеку Python для анализа данных, для чтения файлов CSV в наши обучающие и тестовые фреймы данных.

train = pd.read_csv('digit_data/train.csv')
test = pd.read_csv('digit_data/test.csv')

После того, как мы загрузили наши данные, нам нужно понять, что это за данные. Чтобы получить краткий обзор того, что находится в нашем наборе данных, мы можем использовать метод panda .head() для распечатки заголовка или вершины нашего набора данных. Мы можем установить количество отображаемых строк равным 5.

train.head(5)

Первое, что нам нужно сделать с нашими обучающими данными, - это разделить их на входы, или X (функции), и выходы (y). Глядя на наши данные, мы видим, что результат (y) - это столбец «метка». Это означает, что нашими данными X будет каждый столбец, кроме столбца «метка», а данными y будет только столбец «метка». Чтобы разделить их, мы можем использовать .drop() метод pandas и указать имя столбца, который мы хотим удалить. Чтобы дать пандам понять, что мы хотим удалить столбец, мы установим «ось» на 1.

После разделения наших обучающих данных мы можем распечатать формы всего, что у нас есть на данный момент. После печати фигур мы также можем распечатать образцы как в тестовых, так и в обучающих данных. Форма обучающих данных будет (42000, 784). Это означает, что имеется 42000 строк с 784 столбцами. Каждая строка представляет собой отдельную цифру в данных. Каждый столбец представляет значение одного пикселя для изображения. Наши изображения в наборе данных MNIST должны иметь форму 28x28 (28 x 28 = 784). Каждое изображение выровнено в одну строку.

x_train = train.drop('label', axis=1)
y_train = train['label'].astype('int32')
print('x_train shape: ', x_train.shape)
print('y_train shape: ', y_train.shape)
print('test shape: ', test.shape)
print('\nsamples in test: ', test.shape[0])
print('samples in train: ', x_train.shape[0])

Выход:

x_train shape:  (42000, 784)
y_train shape:  (42000,)
test shape:  (28000, 784)
samples in test:  28000
samples in train:  42000

Давайте выясним, сколько у нас образцов каждой цифры. Насколько нам известно, наши данные могут быть несбалансированными, и некоторые цифры могут быть представлены больше, чем другие. Это может помешать нашему обучению! Чтобы проверить, сколько образцов каждой цифры мы обучаем, мы снова можем использовать панды и метод value_counts() на обучающем наборе y.

print('Number of Examples Per Digit:\n', y_train.value_counts())

Выход:

Number of Examples Per Digit:
1    4684
7    4401
3    4351
9    4188
2    4177
6    4137
0    4132
4    4072
8    4063
5    3795
Name: label, dtype: int64

Еще одна удивительная библиотека Python высокого уровня, которая часто используется в науке о данных для визуализации, - это Seaborn. Seaborn - это библиотека визуализации данных, которая в значительной степени основана на matplotlib, но, как известно, делает более привлекательную графику. Поскольку нам нравится привлекательность, мы будем работать с Seaborn, чтобы визуализировать, сколько образцов каждой цифры имеется в нашем обучающем наборе. После визуализации баланса в данных и использования панд для просмотра точного количества выборок мы можем с уверенностью сказать, что наши данные очень хорошо сбалансированы и что никакие цифры не представлены чрезмерно.

sns.countplot(y_train)

Каждая рукописная цифра в наборе данных MNIST имеет пиксели со значением RGB от 0 до 255. Чтобы нормализовать этот диапазон значений, мы можем разделить каждое значение пикселя на 255. Это сблизит значения каждого пикселя (в диапазоне от 0 до 1) и упростит обучение нашей нейронной сети. Например, значение RGB 56 тогда станет 0,219, а значение RGB 230 станет 0,901.

Затем мы можем изменить значения как в x_train, так и в тестовом наборе. Мы захотим изменить их форму так, чтобы сначала было количество образцов, а затем, как упоминалось ранее, каждая цифра имела размеры (28x28x1) или 28 строк, 28 столбцов и 1 цветовой канал, потому что изображения не окрашены.

x_train /= 255.0
test /= 255.0
x_train = x_train.values.reshape(x_train.shape[0], 28, 28, 1)
test = test.values.reshape(test.shape[0], 28, 28, 1)

Теперь мы можем распечатать окончательную форму данных обучения и тестирования.

print('x_train shape: ', x_train.shape)
print('y_train shape: ', y_train.shape)
print('test shape: ', test.shape)

Выход:

x_train shape:  (42000, 28, 28, 1)
y_train shape:  (42000,)
test shape:  (28000, 28, 28, 1)

Чтобы просмотреть, что содержит набор данных MNIST, мы можем использовать pyplot из matplotlib и показать восемь изображений. Изображения будут поступать из обучающего набора (x_train), и над каждым изображением мы можем установить заголовок подзаголовка как соответствующий результат (y_train).

plt.figure(figsize=(12,10))
for img in range(10):
    plt.subplot(5, 5, img+1)
    plt.imshow(x_train[img].reshape((28, 28)), cmap='binary_r')
    plt.axis('off')
    plt.title('Label: ' + y_train[img].astype('str'))
plt.show()

Теперь мы можем приступить к созданию нашей модели. Для классификации каждой цифры мы будем использовать сверточную нейронную сеть. К счастью, Keras, библиотека нейронной сети Python высокого уровня, предоставляет простой и быстрый ресурс для создания моделей глубокого обучения. Нам нужно будет импортировать Keras, последовательную модель и необходимые слои для использования в нашей CNN.

import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split

Мы можем использовать функцию Keras to_categorical() для преобразования нашего вектора класса в двоичную матрицу классов. Наши классы в y_train помечены как 1,2,3,4 и т. Д. to_categorical() создаст матрицу с таким количеством столбцов, сколько классов, где 1 означает да, а 0 означает нет. Документация Кераса дает наглядный пример этого. Вы можете просмотреть документы Кераса здесь или посмотреть пример ниже:

# Consider an array of 5 labels out of a set of 3 classes {0, 1, 2}:
> labels
array([0, 2, 1, 2, 0])
# `to_categorical` converts this into a matrix with as many
# columns as there are classes. The number of rows
# stays the same.
> to_categorical(labels)
array([[ 1.,  0.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.]], dtype=float32)

Как только это будет сделано, наши данные готовы к обучению! Мы можем разделить данные на наборы для обучения и тестирования, а затем приступить к обучению нашей модели.

y_train = to_categorical(y_train, 10)
x_train, x_test, y_train, y_test = train_test_split(x_train, y_train, test_size = 0.1, random_state=1)

Теперь мы можем создать нашу модель CNN, что, благодаря Керасу, очень просто. Нам нужно будет использовать двумерные сверточные слои, слои с максимальным объединением и плотные слои, которые являются полностью связанными слоями. Мы также будем использовать dropout и flatten. Сглаживание наших данных берет результирующую матрицу из сверточного и объединяющего слоев и «сглаживает» ее в один длинный вектор входных данных (столбец). Наш выходной слой будет использовать функцию активации softmax с 10 выходными узлами (количество классов в наших данных).

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28,28,1)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

Прежде чем обучать модель, мы должны сначала определить функцию потерь, оптимизатор и метрики, по которым мы будем оценивать нашу модель.

model.compile(loss='categorical_crossentropy', optimizer='Adadelta', metrics=['accuracy'])

Теперь мы наконец можем обучить нашу модель! Мы передадим функции .fit() наши обучающие данные и запустим ее в течение 12 эпох или итераций.

model.fit(x_train, y_train, batch_size=128, epochs=12, verbose=1,
          validation_data=(x_test, y_test))

Выход:

Train on 37800 samples, validate on 4200 samples
Epoch 1/12
37800/37800 [==============================] - 144s 4ms/step - loss: 0.3357 - acc: 0.8946 - val_loss: 0.1302 - val_acc: 0.9610
Epoch 2/12
37800/37800 [==============================] - 154s 4ms/step - loss: 0.0894 - acc: 0.9738 - val_loss: 0.0518 - val_acc: 0.9848
Epoch 3/12
37800/37800 [==============================] - 145s 4ms/step - loss: 0.0623 - acc: 0.9818 - val_loss: 0.0398 - val_acc: 0.9879
Epoch 4/12
37800/37800 [==============================] - 142s 4ms/step - loss: 0.0481 - acc: 0.9858 - val_loss: 0.0426 - val_acc: 0.9860
Epoch 5/12
37800/37800 [==============================] - 145s 4ms/step - loss: 0.0398 - acc: 0.9872 - val_loss: 0.0358 - val_acc: 0.9898
Epoch 6/12
37800/37800 [==============================] - 134s 4ms/step - loss: 0.0350 - acc: 0.9891 - val_loss: 0.0305 - val_acc: 0.9907
Epoch 7/12
37800/37800 [==============================] - 144s 4ms/step - loss: 0.0302 - acc: 0.9911 - val_loss: 0.0275 - val_acc: 0.9917
Epoch 8/12
37800/37800 [==============================] - 133s 4ms/step - loss: 0.0269 - acc: 0.9918 - val_loss: 0.0292 - val_acc: 0.9910
Epoch 9/12
37800/37800 [==============================] - 140s 4ms/step - loss: 0.0225 - acc: 0.9929 - val_loss: 0.0400 - val_acc: 0.9886
Epoch 10/12
37800/37800 [==============================] - 132s 3ms/step - loss: 0.0215 - acc: 0.9933 - val_loss: 0.0330 - val_acc: 0.9914
Epoch 11/12
37800/37800 [==============================] - 133s 4ms/step - loss: 0.0191 - acc: 0.9938 - val_loss: 0.0304 - val_acc: 0.9910
Epoch 12/12
37800/37800 [==============================] - 155s 4ms/step - loss: 0.0183 - acc: 0.9943 - val_loss: 0.0314 - val_acc: 0.9921
<keras.callbacks.History at 0x1a30906ac8>

Похоже, наша модель достойно поработала! Мы можем оценить модель и получить ее потери и точность как для обучающей, так и для тестовой выборки. Как только мы получим данные о потерях и точности, мы можем распечатать их и округлить для простоты.

loss, accuracy = model.evaluate(x_test, y_test, verbose=0)
train_stat = model.evaluate(x_train, y_train, verbose=0)
print('Train Loss:     ', round(train_stat[0], 5))
print('Train Accuracy: ', round(train_stat[1]*100, 4), '%')
print('Test Loss:      ', round(loss, 5))
print('Test Accuracy:  ', round(accuracy*100, 4), '%')

Выход:

Train Loss:      0.00551
Train Accuracy:  99.8413 %
Test Loss:       0.03136
Test Accuracy:   99.2143 %

Поскольку наша модель обучена и оказалась довольно точной, мы можем начать делать прогнозы. Мы будем использовать .predict() метод Кераса для прогнозирования выходных значений каждой цифры в данных x_test.

predictions = model.predict(x_test)

Поскольку мы создаем ядро ​​в Kaggle для соревнований, нам нужно будет создать новый файл CSV, содержащий наши прогнозы. Этот файл будет нашей подачей на конкурс, и как только он будет создан, мы закончим конкурс!

results = np.argmax(predictions, axis = 1)
results = pd.Series(results, name="Label")
submission = pd.concat([pd.Series(range(1,28001),name = "ImageId"),results],axis = 1)
submission.to_csv("submission.csv", index=False)

Kaggler предоставляет отличную платформу для изучения и применения полученных вами знаний и навыков в реальных соревнованиях и наборах данных. Существует множество наборов данных на выбор, и в каждом соревновании участвует очень дружелюбное сообщество, которое готово вам помочь. Я бы порекомендовал зарегистрироваться на Kaggle и попробовать!