Keras. Определяем погибших на Титанике

Добавлено: 11/02/2020 14:55 |  Обновлено: 11/02/2020 15:42 |  Добавил: nick |  Просмотры: 3998 Комментарии: 1
Вводная часть
В данном материале привожу пример реализации нейронной сети на языке Python для определения погибших на Титанике. Используем библиотеку Keras и сопутствующие приблуды (pandas, sklearn, matplotlib).
Пример с Титаником вы можете найти на сайте соревнований по машинному обучению - kaggle.com (https://www.kaggle.com/c/titanic). Датасеты тоже можно скачать там же, но для этого нужно быть зарегистрированными. Если вы не зарегистрированы, то можно скачать с моего сайта. Но советую зарегистрироваться, так как там можно “залить” результат работы своей сети и посмотреть какое место вы заняли среди других участников. На данный момент их там 15 923.

Несколько слов о скачанных файлах.

train.csv - файл с данными, по которым вы будете обучать свою сеть.
test.csv - файл с данными, по которым ваша сеть должна сделать предсказания.
gender_submission.csv - файл, куда нужно добавить результат своих предсказаний. Понадобится, если захотите поучаствовать в соревновании на сайте kaggle.com.

Предсказание делается на основе следующих показателей:

pclass - класс билета (билет 1 класса, 2, 3)
name - имя пассажира
sex - пол
age - возраст
sibsp - количество братьев/сестер или есть ли супруг/супруга
parch - количество родителей / детей на борту
ticket - номер билета
fare - стоимость билета
cabin - номер каюты
embarked - место посадки

Если мы посмотрим на файл train.csv, то можно увидеть там 2 проблемы. 1 проблема - есть разные данные (числовые и текстовые).
2 проблема - есть пустые поля.

В других реализациях авторы решают первую проблему просто избавлением от текстовых полей. Не знаю, насколько это эффективно, но в данном примере мы не будем избавляться от этих полей. Поступим по другому, и приведем все поля к одному типу - текстовому. Кусок кода, который отвечает за это:
X = X.astype(str)
Xt = Xt.astype(str)
Где X - это показатели из файла train.csv, а Xt - это показатели из файла test.csv.

Вторую проблему решим просто добавлением нуля в пустые поля. Кусок кода, который отвечает за это:
data = read_csv('train.csv', header=0)
data2 = read_csv('test.csv', header=0)
data = data.fillna(0);
data2 = data2.fillna(0);
Здесь в переменные data и data2 мы получаем данные из csv-файлов. Тут же указываем, что в csv-файлах есть заголовки в первой строке (header=0).

Перейдем к практике. Создайте новый py-файл в папке с датасетами и добавьте в него следующее содержимое:
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
from keras.models import Sequential
from keras.layers import Dense
import matplotlib.pyplot as plt
# загружаем датасет
data = read_csv('train.csv', header=0)
data2 = read_csv('test.csv', header=0)
data = data.fillna(0);
data2 = data2.fillna(0);
# разделяем 1-й файл на X и y
dataset = data.values
dataset2 = data2.values
X = dataset[:,2:]
y = dataset[:,1:2]
Xt = dataset2[:,1:]

# приводим все поля к строковому типу
X = X.astype(str)
Xt = Xt.astype(str)

# подготавливаем входные данные
def prepare_inputs(X_train, X_test):
    ohe = OneHotEncoder(handle_unknown='ignore')
    ohe.fit(X_train)
    X_train_enc = ohe.transform(X_train)
    X_test_enc = ohe.transform(X_test)
    return X_train_enc, X_test_enc
 
# подготавливаем входные данные
X, Xt_prep = prepare_inputs(X, Xt)

# определяем модель
model = Sequential()
model.add(Dense(24, input_dim=X.shape[1], activation='relu'))
model.add(Dense(12, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# компилируем модель
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# обучаем модель на датасете
history = model.fit(X, y, epochs=150, batch_size=10)
# делаем предсказания по тестовым данным
predictions = model.predict_classes(Xt_prep)
# выводим предсказания
for i in range(0, Xt_prep.shape[0]):
    print('%s => %d' % (Xt[i].tolist(), predictions[i]))
# рисуем красивый график зависимости функции потерь от количества эпох
history_dict = history.history
print(history_dict.keys())
loss_values = history_dict['loss']
acc_values = history_dict['accuracy']
epochs = range(1, len(acc_values) + 1)
plt.plot(epochs, loss_values, 'bo', label='Training loss')
plt.title('Training loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
Если вы его запустите, то в идеале должны увидеть следующие бегущие строки: После чего вы должны увидеть результат вывода тестовых данных и соответствующих предсказаний: И в отдельном окне график зависимости функции потерь от количества эпох: Результативность работы нейронной сети получилась в районе 70%. В принципе не так уж и хорошо. Если у кого-то будут варианты получше, пишите в комментариях.

Оставьте свой комментарий

Комментарии