Научный руководитель: Вильданов Алмаз Нафкатович
к.ф.-м.н., Уфимский университет науки и технологий, Нефтекамский филиал
Введение
В современном мире методы машинного обучения и искусственного интеллекта находят широкое применение в самых различных областях, включая медицину, финансы, транспорт и многие другие. Одной из классических задач, используемых для обучения и отработки навыков работы с алгоритмами машинного обучения, является задача предсказания выживаемости пассажиров Титаника. Данная задача представляет собой бинарную классификацию, где необходимо на основе набора признаков о пассажире определить, выжил он или нет.
Инструментарий
В качестве инструментария для решения поставленной задачи была выбрана библиотека TensorFlow с высокоуровневым фреймворком Keras, которые предоставляют удобные средства для создания и обучения нейронных сетей различной архитектуры. Для работы с табличными данными используется библиотека Pandas, для математических операций и работы с массивами – NumPy, для визуализации результатов – Matplotlib.
Загрузка данных
Поскольку работа выполнялась в среде Google Colab, потребовалось подключение Google Drive для доступа к файлам датасета:
from google.colab import drive
drive.mount(‘/content/drive/’)
Путь к данным задается через переменную PATH, после чего загружаются тренировочный и тестовый наборы данных, а также файл с примером формата ответов sample_submission.csv:
DIR = “Titanic”
PATH = ‘/content/drive/My Drive/’+ DIR + ‘/’
train = pd.read_csv(PATH + ‘train.csv’)
test = pd.read_csv(PATH + ‘test.csv’)
sample_submission = pd.read_csv(PATH + ‘sample_submission.csv’, index_col=’PassengerId’)
Предобработка данных
Одной из важнейших задач при работе с реальными данными является их предобработка. Исходные данные содержат как числовые, так и категориальные признаки, которые необходимо преобразовать в формат, пригодный для обучения нейронной сети.
Замена категориальных признаков
В первую очередь производится замена текстовых значений пола на числовые:
train = train.replace(‘male’, 1).replace(‘female’, 0)
test = test.replace(‘male’, 1).replace(‘female’, 0)
Создание дамми-переменных
Далее создаются дамми-переменные для категориальных признаков Embarked (порт посадки) и Pclass (класс билета), что позволяет представить эти признаки в виде бинарных векторов:
train = pd.concat([train, pd.get_dummies(train.Embarked, prefix="Emb")], axis=1)
train = pd.concat([train, pd.get_dummies(train.Pclass, prefix="Pclass")], axis=1)
test = pd.concat([test, pd.get_dummies(test.Embarked, prefix="Emb")], axis=1)
test = pd.concat([test, pd.get_dummies(test.Pclass, prefix="Pclass")], axis=1)
Создание новых признаков
Важным этапом инженерного анализа данных является создание новых признаков, которые могут нести дополнительную информацию для модели. На основе имеющихся признаков Parch (количество родителей и детей) и SibSp (количество братьев, сестер, супругов) был создан новый бинарный признак “наличие более одного родственника”, принимающий значение 1, если у пассажира было более одного родственника на борту, и 0 в противном случае.
train['more than one relative'] = train.Parch + train.SibSp > 1
train = train.replace(True, 1).replace(False, 0)
test['more than one relative'] = test.Parch + test.SibSp > 1
test = test.replace(True, 1).replace(False, 0)
Анализ пропущенных значений
Производится анализ пропущенных значений с помощью методов isnull().sum():
train.isnull().sum()
Для визуализации используется тепловая карта библиотеки Seaborn, что позволяет наглядно увидеть, в каких колонках присутствуют пропуски:
import seaborn as sns
sns.heatmap(train.isnull(), cbar = False).set_title(“Карта пропущенных значений”)
Заполнение пропусков
На основе анализа принимается решение о заполнении пропущенных значений. Для числовых колонок Age и Fare пропуски заменяются средними значениями:
numeric_cols = ['Age', 'Fare']
train[numeric_cols] = train[numeric_cols].fillna(train[numeric_cols].mean())
test[numeric_cols] = test[numeric_cols].fillna(train[numeric_cols].mean())
При этом важно отметить, что для заполнения пропусков в тестовом наборе используются средние значения, вычисленные на тренировочном наборе, чтобы избежать утечки данных.
Формирование признакового пространства
После завершения предобработки формируется список признаков features и целевая переменная target:
features = ['Pclass_1', 'Pclass_2', 'Pclass_3', 'Age', 'Sex', 'Fare', 'more than one relative', 'Emb_C', 'Emb_Q', 'Emb_S']
target = ‘Survived’
Данные преобразуются в массивы NumPy для подачи в нейронную сеть:
X_train = train[features].values
Y_train = train[target].values
X_test = test[features].values
Нормализация данных
Важным этапом подготовки данных является нормализация, которая позволяет привести все признаки к единому масштабу и ускорить процесс обучения нейронной сети. Нормализация производится путем вычитания среднего значения и деления на стандартное отклонение:
mean = X_train.mean(axis=0)
std = X_train.std(axis=0)
X_train = X_train – mean
X_train /= std
X_test = X_test – mean
X_test /= std
Построение модели нейронной сети
Для построения модели используется последовательная архитектура Sequential с импортом необходимых слоев:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
Модель состоит из трех полносвязных слоев. Первый слой содержит 200 нейронов с функцией активации ReLU и принимает на вход данные размерности, соответствующей количеству признаков. Второй скрытый слой содержит 20 нейронов также с функцией активации ReLU. Выходной слой содержит один нейрон с сигмоидной функцией активации, что позволяет получать на выходе вероятность принадлежности к классу 1 (выживший) в диапазоне от 0 до 1.
Для предотвращения переобучения после каждого скрытого слоя добавляется слой Dropout с вероятностью отключения нейронов 0.1:
model = Sequential()
model.add(Dense(200, activation=’relu’, input_shape=(X_train.shape[1],)))
model.add(Dropout(0.1))
model.add(Dense(20, activation=’relu’))
model.add(Dropout(0.1))
model.add(Dense(1, activation=’sigmoid’))
После создания модели выводится ее краткое описание:
print(model.summary())
Компиляция модели
Компиляция модели производится с использованием оптимизатора Adam. В качестве функции потерь используется binary_crossentropy, подходящая для бинарной классификации. Метрикой качества выбрана accuracy – доля правильных ответов:
model.compile(optimizer=’adam’, loss=’binary_crossentropy’, metrics=['accuracy'])
Обучение модели
Обучение модели производится на тренировочных данных с валидационным разделением 10% от обучающей выборки. Количество эпох обучения установлено равным 2, размер пакета batch_size равен 1:
history = model.fit(X_train, Y_train,
epochs=2,
batch_size=1,
validation_split=0.1,
verbose=2)
Визуализация процесса обучения
Для визуализации процесса обучения строится график изменения точности на обучающем и проверочном наборах данных:
plt.plot(history.history['accuracy'], label=’Точность на обучающем наборе’)
plt.plot(history.history['val_accuracy'], label=’Точность на проверочном наборе’)
plt.xlabel(‘Эпоха обучения’)
plt.ylabel(‘Точность’)
plt.legend()
plt.show()
График позволяет оценить, насколько хорошо модель обучается, и демонстрирует рост точности в процессе обучения.
Предсказание на тестовых данных
После завершения обучения производится предсказание на тестовых данных:
predictions = model.predict(X_test)
Полученные предсказания представляют собой вероятности принадлежности к классу 1. Для преобразования вероятностей в бинарные метки используется пороговое значение 0.5:
sample_submission[target] = [0 if pred < 0.5 else 1 for pred in predictions]
Экспорт результатов
Полученные предсказания записываются в файл-образец и сохраняются в файл titanic_submission.csv:
sample_submission.to_csv(‘titanic_submission.csv’)
Поскольку работа велась в Google Colab, для загрузки файла на локальный компьютер используется модуль files:
from google.colab import files
files.download(‘titanic_submission.csv’)
Заключение
В результате выполненной работы была построена нейросетевая модель, способная с высокой точностью предсказывать выживаемость пассажиров Титаника на основе предоставленных характеристик. В процессе решения были отработаны ключевые этапы построения модели машинного обучения: загрузка и анализ данных, предобработка и создание новых признаков, заполнение пропусков, нормализация, построение архитектуры нейронной сети с регуляризацией, обучение и оценка качества, формирование предсказаний и экспорт результатов.
Полученный опыт может быть использован для решения других задач классификации и регрессии, а также служить основой для изучения более сложных архитектур нейронных сетей и методов глубокого обучения.
