RMS Titanic — британский пассажирский лайнер, эксплуатируемый известной британской судоходной компанией White Star Line. Он считался одним из самых роскошных и технологичных кораблей своего времени. Титаник был построен, чтобы обеспечить роскошь и комфорт пассажирам, путешествующим через Атлантический океан из Саутгемптона, Англия, в Нью-Йорк, США.

Однако трагическое столкновение с айсбергом 14 апреля 1912 года прервало его путешествие, что привело к затоплению корабля и гибели более 1500 человек.

История Титаника будоражит публику уже более века. Значительный объем исследований, исследований, фильмов, музыки и документальных фильмов доказывает неугасающий интерес общества к этой теме.

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

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

Основные вопросы, на которые мы хотим ответить:
1) Сколько стоил проезд среди социальных классов?
2) Каковы были социальные титулы пассажиров?
3) Каково гендерное распределение? на корабле?
4) Каково возрастное распределение на корабле?
5) Какова выживаемость среди пассажиров?
6) Были ли у женщин больше шансов выжить, чем у мужчин, или наоборот? наоборот?
7) Определяет ли возраст или социальный класс шансы на выживание
8) Влияет ли порт посадки на сумму проезда?
9) Может ли порт посадки подразумевать социальный статус?

Набор данных

def summary(df):
    col = []
    d_type = []
    n_uniq = []
    uniq = []

    for c in df.columns:
        col.append(c)
        d_type.append(df[c].dtypes)
        n_uniq.append(df[c].nunique())
        uniq.append(df[c].unique()[:5]) 
    aniu = pd.DataFrame({'Column': col, 'd_type': d_type, 'n_uniques':n_uniq, 'unique': uniq})
    return aniu

В наборе данных 12 столбцов. Мы уточним некоторые столбцы, чтобы лучше понять предоставленную информацию. Имеется 891 идентификатор пассажира, представляющий 891 пассажира. Pclass означает пассажирский класс. Pclass 1 — самый высокий класс на корабле, за ним следует Pclass 2 и Pclass 3 — самый низкий класс. SibSp представляет собой количество братьев, сестер или супругов пассажиров на борту. Парч представляет собой количество родителей или детей пассажиров на борту. Столбец тарифа содержит различные суммы тарифов. Столбцы «На борту» содержат инициалы каждого порта посадки: Саутгемптон (S), Шербур (C) и Квинстаун (Q).

1) Сколько стоил проезд для представителей социальных слоев?

df.groupby('Pclass')['Fare'].describe()

Здесь показано количество пассажиров в каждом классе и различных ценовых категориях.

  • Pкласс 1: 216 пассажиров. Средняя стоимость проезда: 84 доллара. Стандартный тариф: 78 долларов. Максимальный тариф: 512 долларов.
  • Pкласс 2: 184 пассажира. Средняя стоимость проезда: 21 доллар. Стандартный тариф: 13 долларов. Максимальный тариф: 73 доллара.
  • Pкласс 3: 491 пассажир. Средняя стоимость проезда: 14 долларов. Стандартный тариф: 12 долларов. Максимальный тариф: 69 долларов.

Самый низкий тариф во всех трех классах составляет 0 долларов, что указывает на то, что некоторым пассажирам был предоставлен бесплатный проезд. Различные суммы тарифов в каждом классе отражают социальный статус пассажиров. Pclass 1 представляет высший социальный класс, тогда как Pclass 2 и Pclass 3 имеют одинаковые диапазоны тарифов и могут быть связаны с более низкими социальными классами.

2) Каковы были социальные титулы пассажиров?

def get_titles(data):
    #extract titles from name and count
    title = [i.split(',')[1].split('.')[0].strip() for i in data['Name']] 
    data['title'] = pd.Series(title)
    count_titles = data['title'].value_counts() 
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))
    #count titles table
    to_count = [[title, count] for title, count in count_titles.items()]
    ax1.table(cellText=to_count, colLabels=['Title', 'Count'], cellLoc='center', loc='center')
    ax1.axis('off') #get rid of the background grid and extra boxes on top and bottom
    ax1.set_title('Value Counts')
    #combine similar titles
    data["title"] = data["title"].replace(['Don', 'Dr', 'Major', 'Rev','Lady', 'the Countess', 'Countess', 'Capt', 'Col', 'Sir', 'Jonkheer'], 'Others')
    data['title'] = data['title'].replace(['Miss', 'Ms', 'Mme', 'Mlle', 'Mrs'], 'Miss/Ms/Mme/Mlle/Mrs')
    #bar chart
    sns.set_theme(style="darkgrid")
    my_palette = ["#ED917D","#CBB4D9", "#875A74", "#8793AB"]
    data['title'].value_counts().plot(kind='bar',color = my_palette, width=0.5)
    plt.title('Distribution According to Title')
    plt.xticks(rotation=0)
    plt.xlabel('')
    plt.ylabel('Count')
    plt.show()
    return

В левой таблице приведены общие данные по каждому социальному званию пассажиров на борту «Титаника». Судя по гистограмме, мы объединили похожие заголовки с меньшим количеством повторений в категорию «Другие». Число пассажиров-мужчин больше, чем пассажиров-женщин. Было подсчитано около 577 пассажиров-мужчин, как показано в «Мистер» (517), «Мастер» (40) и «Другие» (около 20). Число пассажиров-женщин чуть больше 300, как показано на фиолетовой полосе и в разделе «Другие».

3) Каково гендерное распределение на корабле?

Pclass_gender = df.groupby(['Pclass','Sex'])['PassengerId'].count().reset_index() #reset_index() to turn turn the index of Pclass and Sex into regular column for sns to make plot 
#print(Pclass_gender)
sns.set(style = 'darkgrid')
plt.figure(figsize = (6,4))
sns.barplot(data=Pclass_gender, x='Pclass', y='PassengerId', hue = 'Sex')
plt.xlabel('Pclass')
plt.ylabel('Count')
plt.title('Gender Distribution in each Pclass')
plt.show()

Согласно гистограмме, синие столбцы обозначают женщин, а коричневые столбцы обозначают мужчин.

  • Pclass 1: в этом классе около 100 пассажиров-женщин и менее 150 пассажиров-мужчин. Мы наблюдаем относительно сбалансированное количество мужчин и женщин, что позволяет предположить, что эти женщины являются супругами или членами семей мужчин, находящихся на борту. Альтернативно, эта разница может отражать женщин-профессионалов или людей, путешествующих в одиночку.
  • Pclass 2: количество пассажиров-женщин составляет около 80, а количество пассажиров-мужчин – около 100. Оба показателя в этом классе немного меньше, чем в Pclass 1.
  • Pкласс 3: этот класс показывает самые высокие показатели как для мужчин, так и для женщин. В частности, в этом классе находятся около 150 пассажиров женского пола и около 350 мужчин. Быть низшим классом здесь может включать в себя сочетание рабочего класса, иммигрантов и семей, ищущих доступный проезд.

4) Каково возрастное распределение на корабле?

sns.set(style = 'whitegrid')
plt.figure(figsize = (10,5))
sns.histplot(data = df, x='Age', bins = 26, kde=True, color='purple') #change num bins will slightly change the bar graph
plt.xlabel('Age')
plt.ylabel('Number of Passengers')
plt.title('Age Distribution on the Titanic')
plt.show()

Ось X представляет разные возрасты: от 0 до 80 лет. По оси Y указано количество пассажиров каждой возрастной группы. График показывает, что большинству пассажиров «Титаника» было от 20 до 30 лет. С возрастом количество пассажиров постепенно уменьшается, что позволяет предположить, что на борту корабля было относительно молодое население.

Распределение по возрасту в каждом классе P:

#get age distribution ffrom each class
class_1_age = df[df['Pclass']==1]['Age']
# plt.figure(figsize = (6,5))
# sns.histplot(data = class_1_age, kde=True, label = "Pclass 1", color = 'skyblue')
class_2_age = df[df['Pclass']==2]['Age']

class_3_age = df[df['Pclass']==3]['Age']

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize = (15,5))
sns.histplot(data = class_1_age,kde=True, ax=ax1,  color = 'green')
ax1.set_xlabel('Age')
ax1.set_ylabel('Num of Passengers')
ax1.set_title('Pclass 1')

sns.histplot(data = class_2_age, kde=True, ax=ax2, color = 'brown')
ax2.set_xlabel('Age')
ax2.set_ylabel('Num of Passengers')
ax2.set_title('Pclass 2')

sns.histplot(data = class_3_age,kde=True,ax=ax3, color = 'orange')
ax3.set_xlabel('Age')
ax3.set_ylabel('Num of Passengers')
ax3.set_title('Pclass 3')

plt.tight_layout()
plt.show()

5) Какова выживаемость пассажиров?

Pclass_survived = df['Survived'].mean()*100
sns.set(style = 'darkgrid')
plt.figure(figsize=(5,5))
sns.countplot(x='Survived', data=df, palette='Set2')
plt.title('Total Count for Survival')
survival_rate = df['Survived'].mean()*100
plt.legend(title='Survival Rate: {:.2f}%'.format(survival_rate))
plt.xticks([0,1],['No','Yes'])
plt.show()

Эти данные дают четкое представление об общем количестве выживших и не выживших в ту роковую ночь. 38% из 891 пассажира (примерно 300) посчастливилось выжить. По данным многих источников, после отбытия всех спасательных лодок оставшимся пассажирам пришлось пережить мучительное двухчасовое ожидание на корабле, поскольку он постепенно накренился и затонул. После того, как Титаник был полностью разрушен, те, кого не удалось спасти, оказались в ледяной воде, цепляясь за обломки или спасательные пояса, чтобы оставаться на плаву, пока их тела не поддались ледяному холоду Северной Атлантического океана.

6) Были ли у женщин больше шансов выжить, чем у мужчин, или наоборот?

#find survival rate for each gener
w = df.loc[df.Sex == 'female']['Survived']
rate_w = sum(w)/len(w)*100
m = df.loc[df.Sex == 'male']['Survived']
rate_m = sum(m)/len(m)*100
survival_rate = [rate_m, rate_w]
labels = ['Male', 'Female']
#find gender rate
male_pass = df[df['Sex']== 'male'].shape[0]
female_pass = df[df['Sex']=='female'].shape[0]
passengers = [male_pass, female_pass]

fig, (ax1, ax2) = plt.subplots(1,2, figsize=(15,5))
#Gender rate pie chart
ax1.pie(passengers,labels = labels, autopct='%1.1f%%', startangle=260, colors=['skyblue', 'lightcoral'])
ax1.set_title('Gender Rates aboard the Titanic')
ax1.axis('equal')
#Survival rate pie chart
ax2.pie(survival_rate, labels=labels, autopct='%1.1f%%', startangle=140, colors=['skyblue', 'lightcoral'])
ax2.set_title('Survival Rates by Gender')
ax2.axis('equal')

plt.tight_layout()
plt.show()

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

7) Определяет ли возраст или социальный класс шанс на выживание

sns.catplot(df, x = 'Survived', y = 'Age', 
            hue = 'Pclass', kind = 'swarm',height = 6, palette = 'Set2')
plt.xticks([0,1],['No','Yes'])
plt.show()

Диаграмма рассеяния иллюстрирует возрастное распределение выживших и не выживших на основе двух категорий «Да» (выжил) и «Нет» (не выжил) на оси X, а ось Y представляет возрастной диапазон от 0 до 80 лет. лет.

Как мы видим, в области «Нет» точек больше, чем в области «Да»; это означает, что число невыживших превышает число выживших.

Значительная часть фиолетовых точек в зоне «Нет», означающая, что большинство умерших относились к классу P 3, за ним следовал класс P 2 и, наконец, класс P 1.

В возрасте от 0 до 20 лет, учитывая политику «женщины и дети прежде всего», во всех трех пассажирских классах были спасены самые разные женщины и дети/подростки. Однако, учитывая район Но, там обнаруживается значительное количество детей и подростков, которые не выжили.

В возрастном диапазоне 20–40 лет наблюдается сбалансированное распределение, однако большая концентрация зеленых точек указывает на то, что выжило больше взрослых из высшего класса, чем из низшего.

В возрастном диапазоне 40–60 лет проявляется отчетливая тенденция: в этой группе видно больше выживших из Pкласса 1 по сравнению с Pклассом 2 и Pклассом 3. Особенно в возрастном диапазоне от 30 до 60 лет она в основном состоит из зеленых точек, обозначающих большее количество пассажиров. из высшего класса, которые выжили, чем мужчины этого возраста из низших классов.

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

8) Повлиял ли порт посадки на стоимость проезда?

sns.boxplot(data = df, x = 'Embarked', y='Fare')
plt.xlabel('Embarked')
plt.ylabel('Fare')
plt.title('The Relationship between Embarkation and Fare')
plt.show()

Есть три порта посадки пассажиров: Саутгемптон, Шербур и Квинстаун. Этот график поясняет, что в разных портах был разный ценовой диапазон.

  • Саутгемптон: пассажиры платят от 0 до примерно 50 долларов. Многие выбросы платили от 50 до почти 300 долларов за проезд. Это указывает на то, что эти выбросы относятся к пассажирам Pкласса 1.
  • Шербур: пассажиры платили от 0 до почти 100 долларов. Некоторые выбросы заплатили около 200–300 долларов, а один значительный пассажир заплатил более 500 долларов. Напомним, из первого анализа тарифов и социальных классов максимальная стоимость проезда составляла 512 долларов. Этот пассажир, должно быть, прибыл отсюда.
  • Куинстаун: пассажиры платили очень небольшую сумму, от 0 до менее 25 долларов. Но есть и исключения — пассажиры, заплатившие до 100 долларов за проезд.

9) Может ли социальный статус зависеть от порта посадки?

sns.set(style = 'whitegrid')
embarked_ports = df['Embarked'].unique()

fig, axes = plt.subplots(1,len(embarked_ports), figsize = (25,5))
for i,port in enumerate(embarked_ports):
    ax = axes[i] #num of graphs = num of embarkation
    port_data = df[df['Embarked'] == port]['Fare'] #get the fare data at each port
    sns.histplot(data = port_data, bins = 30, ax=ax)
    ax.set_xlabel('Fare')
    ax.set_ylabel('Num of passengers')
    ax.set_title(f'Embarked at {port}')
    
plt.tight_layout()
plt.show()

Мы наблюдали диапазон оплаты проезда от 0 до 100 долларов во всех портах посадки. Примечательно, что пассажиры, оплатившие проезд стоимостью от 100 до 500 долларов, преимущественно встречались в Саутгемптоне и Шербуре. Это предполагает вероятность того, что значительная часть пассажиров Pкласса 1 села на борт из этих двух портов. И наоборот, пассажиры, вылетающие из Квинстауна, обычно платили более низкие тарифы, что подразумевает потенциал пассажиров P-класса 2 или P-класса 3.

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

Раскрытие связи между Pclass и портом посадки

sns.histplot(data=df,x='Embarked',hue='Pclass',bins=8,multiple='stack', palette='Set1')

Хотя предыдущий анализ фактически намекал на пассажиров Pclass 1, прибывших из портов Саутгемптона и Шербура, он не обеспечил точного подсчета каждого социального класса в каждом порту. Вот точная разбивка по социальным классам для каждого порта:

  • Что касается Pкласса 1, мы заметили, что около 100 пассажиров поднялись на борт из Саутгемптона и Шербура.
  • В классе P 2 большинство пассажиров вылетели из Саутгемптона (около 150), еще около 10 пассажиров - из Шербура и, возможно, только 1 из Квинстауна.
  • Наконец, пассажиры P-класса 3 поднялись на борт из всех трех портов: примерно 350 из Саутгемптона, почти 100 из Шербура и такое же количество из Квинстауна.

Через призму анализа данных мы отправились в путешествие, чтобы раскрыть тонкости путешествия «Титаника». Наше исследование выявило связь между классом пассажиров, социальным статусом, полом и выживанием. Он выявил закономерности, подчеркнул влияние социальных норм и пролил свет на некоторые скрытые аспекты, о которых часто забывают из-за других известных тем, связанных с этой знаковой историей.

Наследие «Титаника» — это не только печаль, но и любопытство и стремление к знаниям. В этой статье мы хотим предположить, что анализ данных предназначен не только для технических обзоров или исследований; это также может быть нетрадиционный способ рассказывать истории.

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