И можно было бы закончить на этом, ведь мы только что пришли к выводу, позволяющему сделать вполне логичные прогнозы. Но мы можем больше, так что продолжим. Есть ли какие-либо факторы, с помощью которых мы могли бы уточнить наш прогноз? Ведь кроме данных выживших у нас есть информация о классе пассажиров, имена, пол, возраст, данные о родственниках и членах семьи на борту, стоимость их билетов, номера кают и города отправления.
Pclass – лакмусовая бумажка, отражающая социоэкономический статус пассажира, подходит в качестве прогностической характеристики. Можно догадаться, что пассажиры первого класса оказались в спасательных шлюпках раньше пассажиров 3-го класса. Пол также является важным предиктором, ведь нам известно, что во время кораблекрушений работает принцип «женщин и детей спасать в первую очередь». Он восходит к 1852 г., когда транспортно-десантный корабль Британских ВМС сел на мель у побережья Южной Африки. Этот принцип работает не всегда, но часто, поэтому для социального анализа мы учитываем его.
Теперь проведем несколько сравнений и посмотрим, сможем ли мы обнаружить другие переменные, в потенциале обладающие предсказательной силой:
# Выжившие и погибшие пассажиры
print (train [ «Survived»].value_counts ())
0 549
1 342
Name: Survived, dtype: int64
# В пропорции
print (train [ «Survived»].value_counts (normalize = True))
0 0.616162
1 0.383838
Name: Survived, dtype: float64
# Мужчины выжившие и погибшие
print (train [ «Survived»] [train [ «Sex»] = ‘male’].value_counts ())
0 468
1 109
Name: Survived, dtype: int64
# Женщины выжившие и погибшие
print (train [ «Survived»] [train [ «Sex»] = ‘female’].value_counts ())
1 233
0 81
Name: Survived, dtype: int64
# Усредненное выживание мужчин
print (train [ «Survived»] [train [ «Sex»] = ‘male’].value_counts (normalize=True))
0 0.811092
1 0.188908
Name: Survived, dtype: float64
# Усредненное выживание женщин
print (train [ «Survived»] [train [ «Sex»] = ‘female’].value_counts (normalize=True))
1 0.742038
0 0.257962
Name: Survived, dtype: float64
Мы видим, что 74 % женщин и 18 % мужчин выжили. Так мы можем еще более точно определить нашу гипотезу, предположив, что, вероятнее всего, в катастрофе выжила бы женщина, а не мужчина.
Помните, что изначально нашей целью было создать колонку данных о выживших? Так вот, на основе новой информации мы можем создать ее и поставить «1» (значит «да, пассажир выжил») напротив тех 74 % женщин и «0» (то есть «нет, пассажир не выжил») у оставшихся женщин. Мы также могли бы поставить «1» у 18 % и «0» у 81 % мужчин.
Однако мы не будем так делать, поскольку это означало бы, что мы совершаем поверхностные предположения на основе только лишь пола. Известно, что в данных можно обнаружить факторы, существенно влияющие на результаты. (Если же вам действительно интересна внутренняя кухня этих процессов, я советую найти это упражнение на DataCamp либо что-то подобное в интернете.) А как насчет женщин, путешествующих третьим классом? Или первым классом? Женщин с детьми? И вот уже ручной подсчет кажется весьма трудоемким, потому давайте научим нашу модель, опираясь на известные факторы, угадывать за нас.
Для этого нам понадобится алгоритм decision tree. Помните, в машинном обучении существуют весьма полезные базовые алгоритмы? У них есть названия, такие как «дерево решений» (decision tree), «случайный лес» (random forest), «искусственная нейронная сеть» (artificial neural network), «наивный байесовский классификатор» (naive Bayes), «метод k ближайших соседей» (k-nearest neighbor) или «глубокое обучение» (deep learning). Список алгоритмов машинного обучения, представленный в Википедии, достаточно полный.
Алгоритмы поставляются пользователям в пакетах вроде того, что мы уже использовали, – pandas. На самом деле немногие самостоятельно пишут алгоритмы, гораздо проще воспользоваться уже существующими. Процесс написания алгоритма похож на изобретение нового языка программирования. Это действительно очень важно, кроме того, требует много времени. «Математика, – скажу я и всплесну руками, – это лучшее объяснение того, что задействовано во время разработки алгоритма». Извините. Если хотите знать больше, я советую почитать об этом. Это, конечно, очень интересно, но написание алгоритма не относится к нашим актуальным задачам.
Итак, теперь обучим модель на тренировочном пакете данных. По итогам небольшого исследования нам стало известно, что необходимо учитывать факторы класса и пола. Теперь нам предстоит выстроить догадки о выживших. Пускай модель попробует угадать, а мы затем сравним результаты с реальностью. Независимо от итогового процента мы получим величину точности модели.
Открою вам секрет из мира больших данных: все данные – «грязные». Абсолютно все. Они собраны людьми, подсчитывающими все вокруг, либо посредством сенсоров – тоже созданных людьми. В каждой, казалось бы, упорядоченной колонке чисел присутствует шум, искажения. Это беспорядок. Это незавершенность. Это жизнь. Проблема заключается в том, что некорректные данные не следует учитывать. Больше того, иногда для того, чтобы алгоритмы заработали как надо, нам приходится подправлять данные.
Еще не страшно? Мне было страшно, когда я поняла это. Как журналист я не склонна подправлять что-либо. Мне необходимо проверить каждую строчку и представить подтверждения для проверяющего, редактора, или читателей – однако в машинном обучении приходится частенько делать так, чтобы все сходилось.
К физике это тоже применимо. Например, если нужно измерить температуру в конкретной точке А закрытого контейнера, необходимо измерить температуру в двух равноудаленных точках (В и С) и предположить, что температура в точке А примерно соответствует средней температуре между В и С. В статистике… ну, так это и происходит, а недостаток данных способствует неуверенности в подсчетах. Мы все пользуемся функцией fillna, чтобы заполнить пустующие значения:
train [“Age”] = train [“Age”].fillna (train [“Age”].median ())
Алгоритм не работает при отсутствующих значениях. Поэтому придется исправить ситуацию. Создатели упражнения на DataCamp советуют воспользоваться медианой.