{ "cells": [ { "metadata": {}, "cell_type": "markdown", "source": [ "# Анализ данных пассажиров Титаника\n", "\n", "**Источник данных:** Kaggle - Titanic: Machine Learning from Disaster\n", "**Цель анализа:** Изучить факторы, влияющие на выживаемость пассажиров\n", "\n", "**Дата анализа:** 07.05.2026" ], "id": "849d0fe9d43b3ad2" }, { "metadata": {}, "cell_type": "markdown", "source": [ "# Импорт библиотек (изменен стиль импорта)\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from tqdm import tqdm\n", "import warnings\n", "warnings.filterwarnings('ignore')\n", "\n", "# Настройка отображения\n", "%matplotlib inline\n", "plt.rcParams['figure.figsize'] = (12, 6)\n", "plt.style.use('seaborn-v0_8-darkgrid')\n", "sns.set_palette(\"husl\")\n", "\n", "print(\"✅ Библиотеки загружены\")\n", "\n", "# Загрузка встроенного датасета Titanic\n", "df = sns.load_dataset('titanic')\n", "print(f\"✅ Загружено {len(df)} записей о пассажирах\")\n", "df.head(10) # Вывод в последней строке ячейки" ], "id": "7b68a95f07cd5093" }, { "metadata": {}, "cell_type": "markdown", "source": [ "print(\"📊 ПЕРВИЧНЫЙ АНАЛИЗ ДАННЫХ\")\n", "print(\"=\" * 50)\n", "\n", "print(\"\\n1. Информация о данных (df.info()):\")\n", "print(df.info())\n", "\n", "print(\"\\n2. Статистическое описание (df.describe()):\")\n", "print(df.describe())\n", "\n", "# Дополнительный анализ\n", "print(\"\\n3. Анализ выживаемости по полу (изменено от примера):\")\n", "print(pd.crosstab(df['sex'], df['alive'], normalize='index') * 100)" ], "id": "82fb50b6dfcb725a" }, { "metadata": {}, "cell_type": "markdown", "source": [ "# Анализ пропущенных значений\n", "missing_data = df.isnull().sum()\n", "missing_percent = (missing_data / len(df)) * 100\n", "\n", "missing_df = pd.DataFrame({\n", " 'Кол-во пропусков': missing_data,\n", " 'Процент': missing_percent\n", "}).sort_values('Кол-во пропусков', ascending=False)\n", "\n", "print(\"📊 АНАЛИЗ ПРОПУЩЕННЫХ ДАННЫХ\")\n", "print(\"=\" * 40)\n", "print(missing_df[missing_df['Кол-во пропусков'] > 0])\n", "\n", "# Заполнение пропусков\n", "df['age'].fillna(df['age'].median(), inplace=True)\n", "df['embarked'].fillna(df['embarked'].mode()[0], inplace=True)\n", "df.drop('deck', axis=1, inplace=True)\n", "\n", "print(f\"\\n✅ Пропуски заполнены. Размер данных: {df.shape}\")" ], "id": "8624dc43d9bf124d" }, { "metadata": {}, "cell_type": "markdown", "source": [ "# Гистограмма распределения возрастов\n", "plt.figure(figsize=(12, 6))\n", "\n", "# Разделение по выжившим/погибшим\n", "survived = df[df['survived'] == 1]['age']\n", "died = df[df['survived'] == 0]['age']\n", "\n", "plt.hist(survived, bins=20, alpha=0.7, label='Выжившие', color='green', edgecolor='black')\n", "plt.hist(died, bins=20, alpha=0.7, label='Погибшие', color='red', edgecolor='black')\n", "\n", "plt.xlabel('Возраст', fontsize=12)\n", "plt.ylabel('Количество пассажиров', fontsize=12)\n", "plt.title('Распределение возрастов пассажиров: Выжившие vs Погибшие', fontsize=14)\n", "plt.axvline(survived.mean(), color='darkgreen', linestyle='--',\n", " label=f'Ср. возраст выживших: {survived.mean():.1f}', alpha=0.8)\n", "plt.axvline(died.mean(), color='darkred', linestyle='--',\n", " label=f'Ср. возраст погибших: {died.mean():.1f}', alpha=0.8)\n", "plt.legend()\n", "plt.grid(alpha=0.3)\n", "plt.show()\n", "\n", "print(f\"\\n📊 Вывод: Средний возраст выживших ({survived.mean():.1f}) выше, чем погибших ({died.mean():.1f})\")" ], "id": "ecea1247c0fbb76f" }, { "metadata": {}, "cell_type": "markdown", "source": [ "# Scatterplot: возраст vs стоимость билета\n", "plt.figure(figsize=(12, 6))\n", "\n", "# Разные цвета для выживших и погибших\n", "colors = df['survived'].map({0: 'red', 1: 'green'})\n", "plt.scatter(df['age'], df['fare'], c=colors, alpha=0.6, s=50)\n", "\n", "plt.xlabel('Возраст (лет)', fontsize=12)\n", "plt.ylabel('Стоимость билета ($)', fontsize=12)\n", "plt.title('Зависимость стоимости билета от возраста пассажира', fontsize=14)\n", "\n", "# Добавление регрессионной линии для общего тренда\n", "z = np.polyfit(df['age'].dropna(), df['fare'].dropna(), 1)\n", "p = np.poly1d(z)\n", "plt.plot(df['age'].dropna().sort_values(), p(df['age'].dropna().sort_values()),\n", " 'b--', alpha=0.8, label='Тренд')\n", "\n", "# Легенда\n", "from matplotlib.patches import Patch\n", "legend_elements = [Patch(facecolor='green', alpha=0.6, label='Выжившие'),\n", " Patch(facecolor='red', alpha=0.6, label='Погибшие')]\n", "plt.legend(handles=legend_elements)\n", "plt.grid(alpha=0.3)\n", "plt.show()\n", "\n", "print(f\"\\n📊 Корреляция между возрастом и стоимостью билета: {df['age'].corr(df['fare']):.3f}\")" ], "id": "a2e54f37810622bd" }, { "metadata": {}, "cell_type": "markdown", "source": [ "# Boxplot: класс билета vs возраст\n", "plt.figure(figsize=(10, 6))\n", "\n", "# Изменен порядок классов и добавлены цвета\n", "order = [1, 2, 3]\n", "sns.boxplot(x='class', y='age', data=df, order=order, palette='Set2')\n", "\n", "plt.xlabel('Класс билета (1 - лучший, 3 - худший)', fontsize=12)\n", "plt.ylabel('Возраст пассажира', fontsize=12)\n", "plt.title('Распределение возрастов по классам билетов', fontsize=14)\n", "\n", "# Добавление средних значений\n", "for i, class_val in enumerate([1, 2, 3]):\n", " mean_age = df[df['pclass'] == class_val]['age'].mean()\n", " plt.text(i, mean_age + 1, f'Ср.: {mean_age:.1f}', ha='center', fontsize=10)\n", "\n", "plt.grid(axis='y', alpha=0.3)\n", "plt.show()\n", "\n", "print(\"\\n📊 Статистика по классам:\")\n", "print(df.groupby('pclass')['age'].agg(['mean', 'median', 'std']).round(1))" ], "id": "85009f4a16158b88" }, { "metadata": {}, "cell_type": "markdown", "source": [ "from tqdm import tqdm\n", "import time\n", "\n", "# Симуляция обработки данных с прогресс-баром\n", "print(\"🔄 Анализ данных пассажиров с прогресс-баром...\")\n", "\n", "# Группировка пассажиров и анализ\n", "results = []\n", "for ticket_class in tqdm(df['pclass'].unique(), desc=\"Анализ классов\", unit=\"класс\", colour='green'):\n", " class_data = df[df['pclass'] == ticket_class]\n", " time.sleep(0.1) # Симуляция вычислений\n", "\n", " results.append({\n", " 'класс': ticket_class,\n", " 'кол-во_пассажиров': len(class_data),\n", " 'выживаемость_%': (class_data['survived'].sum() / len(class_data)) * 100,\n", " 'средний_возраст': class_data['age'].mean(),\n", " 'средняя_цена_билета': class_data['fare'].mean()\n", " })\n", "\n", "result_df = pd.DataFrame(results)\n", "print(\"\\n✅ Анализ завершен!\")\n", "result_df" ], "id": "ea8315adea678f3d" }, { "metadata": {}, "cell_type": "markdown", "source": [ "# Тепловая карта корреляций\n", "plt.figure(figsize=(10, 8))\n", "\n", "# Выбираем числовые колонки\n", "numeric_cols = ['survived', 'pclass', 'age', 'sibsp', 'parch', 'fare']\n", "corr_matrix = df[numeric_cols].corr()\n", "\n", "sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0,\n", " square=True, linewidths=2, fmt='.3f',\n", " cbar_kws={'label': 'Коэффициент корреляции'})\n", "plt.title('Матрица корреляции параметров выживаемости', fontsize=14)\n", "plt.show()\n", "\n", "print(\"\\n📈 Ключевые корреляции с выживаемостью:\")\n", "print(f\" Класс билета: {corr_matrix.loc['survived', 'pclass']:.3f} (отрицательная = лучше класс = выше шанс)\")\n", "print(f\" Цена билета: {corr_matrix.loc['survived', 'fare']:.3f} (положительная = дороже билет = выше шанс)\")\n", "print(f\" Возраст: {corr_matrix.loc['survived', 'age']:.3f} (слабая корреляция)\")" ], "id": "12ede302d3d767ef" }, { "metadata": {}, "cell_type": "markdown", "source": [ "# ============================================\n", "# ПОЛНЫЙ КОД СО ВСЕМИ ГРАФИКАМИ\n", "# ============================================\n", "\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "# Загрузка данных\n", "df = sns.load_dataset('titanic')\n", "\n", "# Очистка данных\n", "df['age'].fillna(df['age'].median(), inplace=True)\n", "df['fare'].fillna(df['fare'].median(), inplace=True)\n", "\n", "# Настройка стиля\n", "plt.rcParams['figure.figsize'] = (12, 6)\n", "sns.set_style(\"whitegrid\")\n", "\n", "print(\"=\" * 60)\n", "print(\"📊 ПОСТРОЕНИЕ ГРАФИКОВ ДЛЯ АНАЛИЗА ДАННЫХ\")\n", "print(\"=\" * 60)\n", "\n", "# ============================================\n", "# ГРАФИК 1: ГИСТОГРАММА (Histogram)\n", "# ============================================\n", "print(\"\\n1️⃣ ГИСТОГРАММА - Распределение возрастов пассажиров\")\n", "\n", "plt.figure(figsize=(12, 6))\n", "\n", "# Разделяем выживших и погибших\n", "survived = df[df['survived'] == 1]['age']\n", "died = df[df['survived'] == 0]['age']\n", "\n", "plt.hist(survived, bins=20, alpha=0.7, label='Выжившие',\n", " color='green', edgecolor='black', linewidth=1.5)\n", "plt.hist(died, bins=20, alpha=0.7, label='Погибшие',\n", " color='red', edgecolor='black', linewidth=1.5)\n", "\n", "plt.xlabel('Возраст (лет)', fontsize=12, fontweight='bold')\n", "plt.ylabel('Количество пассажиров', fontsize=12, fontweight='bold')\n", "plt.title('ГРАФИК 1: Распределение возрастов (Выжившие vs Погибшие)',\n", " fontsize=14, fontweight='bold')\n", "plt.axvline(survived.mean(), color='darkgreen', linestyle='--', linewidth=2,\n", " label=f'Средний возраст выживших: {survived.mean():.1f}')\n", "plt.axvline(died.mean(), color='darkred', linestyle='--', linewidth=2,\n", " label=f'Средний возраст погибших: {died.mean():.1f}')\n", "plt.legend(loc='upper right', fontsize=10)\n", "plt.grid(alpha=0.3)\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "print(f\"✅ ГРАФИК 1 построен! Средний возраст выживших: {survived.mean():.1f}, погибших: {died.mean():.1f}\")\n", "\n", "# ============================================\n", "# ГРАФИК 2: ТОЧЕЧНЫЙ ГРАФИК (Scatterplot)\n", "# ============================================\n", "print(\"\\n2️⃣ ТОЧЕЧНЫЙ ГРАФИК - Возраст vs Стоимость билета\")\n", "\n", "plt.figure(figsize=(12, 6))\n", "\n", "# Цветовая схема: зеленые - выжившие, красные - погибшие\n", "colors = df['survived'].map({0: 'red', 1: 'green'})\n", "sizes = df['age'].fillna(30) * 2 # Размер точек зависит от возраста\n", "\n", "scatter = plt.scatter(df['age'], df['fare'], c=colors, alpha=0.6, s=sizes, edgecolors='black', linewidth=0.5)\n", "\n", "plt.xlabel('Возраст (лет)', fontsize=12, fontweight='bold')\n", "plt.ylabel('Стоимость билета ($)', fontsize=12, fontweight='bold')\n", "plt.title('ГРАФИК 2: Зависимость стоимости билета от возраста пассажира',\n", " fontsize=14, fontweight='bold')\n", "\n", "# Добавляем линию тренда\n", "z = np.polyfit(df['age'].dropna(), df['fare'].dropna(), 1)\n", "p = np.poly1d(z)\n", "x_trend = np.linspace(df['age'].min(), df['age'].max(), 100)\n", "plt.plot(x_trend, p(x_trend), 'b--', linewidth=2, label='Линия тренда')\n", "\n", "# Легенда\n", "from matplotlib.patches import Patch\n", "legend_elements = [\n", " Patch(facecolor='green', alpha=0.6, label='Выжившие'),\n", " Patch(facecolor='red', alpha=0.6, label='Погибшие'),\n", " Patch(facecolor='blue', alpha=0.6, label='Линия тренда')\n", "]\n", "plt.legend(handles=legend_elements, loc='upper right', fontsize=10)\n", "plt.grid(alpha=0.3)\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "correlation = df['age'].corr(df['fare'])\n", "print(f\"✅ ГРАФИК 2 построен! Корреляция между возрастом и ценой билета: {correlation:.3f}\")\n", "\n", "# ============================================\n", "# ГРАФИК 3: BOXPLOT (Ящик с усами)\n", "# ============================================\n", "print(\"\\n3️⃣ ЯЩИК С УСАМИ - Распределение цен на билеты по классам\")\n", "\n", "plt.figure(figsize=(10, 6))\n", "\n", "# Создаем boxplot с кастомными цветами\n", "boxplot = sns.boxplot(x='pclass', y='fare', data=df,\n", " palette='Set2', linewidth=2,\n", " fliersize=5, flierprops=dict(marker='o', markerfacecolor='red', markersize=6))\n", "\n", "plt.xlabel('Класс билета (1 - первый/роскошный, 3 - третий/эконом)', fontsize=12, fontweight='bold')\n", "plt.ylabel('Стоимость билета ($)', fontsize=12, fontweight='bold')\n", "plt.title('ГРАФИК 3: Распределение стоимости билетов по классам обслуживания',\n", " fontsize=14, fontweight='bold')\n", "\n", "# Добавляем аннотации со средними значениями\n", "for i, pclass in enumerate([1, 2, 3], 1):\n", " mean_fare = df[df['pclass'] == pclass]['fare'].mean()\n", " plt.text(i - 0.8, mean_fare + 10, f'Средняя: ${mean_fare:.0f}',\n", " fontsize=10, ha='center', bbox=dict(boxstyle=\"round,pad=0.3\", facecolor=\"yellow\", alpha=0.7))\n", "\n", "plt.xticks([0, 1, 2], ['1 класс (люкс)', '2 класс (стандарт)', '3 класс (эконом)'], rotation=15)\n", "plt.grid(axis='y', alpha=0.3)\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "print(f\"✅ ГРАФИК 3 построен!\")\n", "print(f\" Средние цены: 1 класс: ${df[df['pclass']==1]['fare'].mean():.0f}, \"\n", " f\"2 класс: ${df[df['pclass']==2]['fare'].mean():.0f}, \"\n", " f\"3 класс: ${df[df['pclass']==3]['fare'].mean():.0f}\")\n", "\n", "# ============================================\n", "# ДОПОЛНИТЕЛЬНЫЙ ГРАФИК 4: Тепловая карта (Heatmap)\n", "# ============================================\n", "print(\"\\n4️⃣ ТЕПЛОВАЯ КАРТА - Корреляция параметров\")\n", "\n", "plt.figure(figsize=(10, 8))\n", "\n", "# Выбираем числовые параметры\n", "numeric_cols = ['survived', 'pclass', 'age', 'sibsp', 'parch', 'fare']\n", "corr_matrix = df[numeric_cols].corr()\n", "\n", "# Создаем тепловую карту\n", "sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0,\n", " square=True, linewidths=2, fmt='.3f',\n", " cbar_kws={'label': 'Коэффициент корреляции', 'shrink': 0.8},\n", " annot_kws={'size': 12, 'weight': 'bold'})\n", "\n", "plt.title('ГРАФИК 4: Матрица корреляции параметров выживаемости',\n", " fontsize=14, fontweight='bold')\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "print(\"✅ ГРАФИК 4 построен!\")\n", "print(\" Ключевые корреляции с выживаемостью (survived):\")\n", "print(f\" • Класс билета (pclass): {corr_matrix.loc['survived', 'pclass']:.3f} (отрицательная)\")\n", "print(f\" • Цена билета (fare): {corr_matrix.loc['survived', 'fare']:.3f} (положительная)\")\n", "\n", "# ============================================\n", "# ДОПОЛНИТЕЛЬНЫЙ ГРАФИК 5: Столбчатая диаграмма\n", "# ============================================\n", "print(\"\\n5️⃣ СТОЛБЧАТАЯ ДИАГРАММА - Выживаемость по классам\")\n", "\n", "plt.figure(figsize=(10, 6))\n", "\n", "# Считаем выживаемость по классам\n", "survival_by_class = df.groupby('pclass')['survived'].mean() * 100\n", "\n", "bars = plt.bar([1, 2, 3], survival_by_class.values,\n", " color=['gold', 'silver', '#CD7F32'],\n", " edgecolor='black', linewidth=2, alpha=0.8)\n", "\n", "# Добавляем значения на столбцы\n", "for bar, value in zip(bars, survival_by_class.values):\n", " plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 2,\n", " f'{value:.1f}%', ha='center', va='bottom', fontsize=12, fontweight='bold')\n", "\n", "plt.xlabel('Класс билета', fontsize=12, fontweight='bold')\n", "plt.ylabel('Выживаемость (%)', fontsize=12, fontweight='bold')\n", "plt.title('ГРАФИК 5: Процент выживших пассажиров по классам',\n", " fontsize=14, fontweight='bold')\n", "plt.xticks([1, 2, 3], ['1 класс\\n(люкс)', '2 класс\\n(стандарт)', '3 класс\\n(эконом)'])\n", "plt.ylim(0, 100)\n", "plt.grid(axis='y', alpha=0.3)\n", "\n", "# Добавляем среднюю линию\n", "plt.axhline(df['survived'].mean() * 100, color='red', linestyle='--', linewidth=2,\n", " label=f'Общая выживаемость: {df[\"survived\"].mean()*100:.1f}%')\n", "plt.legend()\n", "\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "print(\"✅ ГРАФИК 5 построен!\")\n", "print(f\" Выживаемость: 1 класс: {survival_by_class[1]:.1f}%, \"\n", " f\"2 класс: {survival_by_class[2]:.1f}%, \"\n", " f\"3 класс: {survival_by_class[3]:.1f}%\")\n", "\n", "# ============================================\n", "# ИТОГИ\n", "# ============================================\n", "print(\"\\n\" + \"=\" * 60)\n", "print(\"📊 ИТОГИ ПОСТРОЕНИЯ ГРАФИКОВ\")\n", "print(\"=\" * 60)\n", "print(\"✅ Построено 5 графиков:\")\n", "print(\" 1. Гистограмма (Histogram) - распределение возрастов\")\n", "print(\" 2. Точечный график (Scatterplot) - возраст vs цена билета\")\n", "print(\" 3. Ящик с усами (Boxplot) - распределение цен по классам\")\n", "print(\" 4. Тепловая карта (Heatmap) - корреляция параметров\")\n", "print(\" 5. Столбчатая диаграмма (Bar chart) - выживаемость по классам\")\n", "print(\"=\" * 60)" ], "id": "870930145d19645" }, { "metadata": {}, "cell_type": "markdown", "source": [ "## 📝 ВЫВОДЫ ПО РЕЗУЛЬТАТАМ АНАЛИЗА\n", "\n", "### Ключевые результаты:\n", "1. **Объем данных**: Проанализировано {len(df)} пассажиров\n", "2. **Общая выживаемость**: {df['survived'].mean()*100:.1f}%\n", "\n", "### Факторы, влияющие на выживаемость:\n", "- **Класс билета**: Пассажиры 1-го класса выживали значительно чаще\n", "- **Пол**: Женщины выживали чаще мужчин\n", "- **Возраст**: Дети выживали чаще взрослых\n", "- **Цена билета**: Более дорогие билеты коррелируют с более высокими шансами\n", "\n", "### Рекомендации для системы управления:\n", "1. Учитывать категории пользователей при приоритизации\n", "2. Внедрить систему лояльности для постоянных клиентов\n", "3. Анализировать поведение разных сегментов аудитории\n", "\n" ], "id": "bb76a6b35ff61162" }, { "metadata": {}, "cell_type": "markdown", "source": "", "id": "ad6c90dab130cf29" }, { "metadata": {}, "cell_type": "code", "source": "", "id": "4c1457863ccaa86", "outputs": [], "execution_count": null } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }