タイタニックのデータを使ったPythonデータ分析マスター講座：statsmodels、NumPy、pandas、seaborn、matplotlibを使いこなす


## はじめに

データ分析の世界では、適切なツールを使いこなすことが成功への鍵となります。Pythonは、その豊富なライブラリエコシステムにより、データサイエンスの分野で圧倒的な人気を誇っています。本講座では、Pythonのデータ分析における5つの主要ライブラリ - statsmodels、NumPy、pandas、seaborn、matplotlib - に焦点を当てます。

これらのライブラリは、データの操作から高度な統計分析、そして美しい可視化まで、データ分析の全プロセスをカバーします。初心者の方にもわかりやすく、かつ経験者の方にも新たな知見を提供できるよう、基礎から応用まで段階的に解説していきます。

実際のデータセット（タイタニック号の乗客データ）を用いた実践的な例を通じて、各ライブラリの特徴と使い方を学んでいきましょう。この講座を終えれば、あなたもPythonを使ったデータ分析のエキスパートへの道を歩み始めることができるはずです。

さあ、Pythonによるデータ分析の奥深い世界への旅に出発しましょう！

## 第1章: データ分析ライブラリの概要

データ分析において、Pythonは非常に強力なツールです。特に、statsmodels、NumPy、pandas、seaborn、matplotlibといったライブラリは、データの操作、統計分析、可視化に欠かせません。これらのライブラリを使いこなすことで、複雑なデータ分析タスクを効率的に行うことができます。

本記事では、タイタニック号の乗客データを例に、これらのライブラリの基本的な使い方から応用まで、段階的に解説していきます。まずは、必要なライブラリをインポートし、サンプルデータを読み込みましょう。

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm

# サンプルデータの読み込み
titanic = sns.load_dataset('titanic')
titanic = titanic.head(50)  # 最初の50行を使用
```

## 第2章: pandasによるデータの基本操作

pandasは、データフレームという概念を使って、表形式のデータを効率的に扱うことができるライブラリです。ここでは、タイタニックデータの基本的な操作方法を学びます。

```python
# データの概要を確認
print(titanic.info())

# 最初の5行を表示
print(titanic.head())

# 基本的な統計量を表示
print(titanic.describe())

# 特定の列を選択
age_fare = titanic[['age', 'fare']]
print(age_fare.head())

# 条件に基づいてデータをフィルタリング
survivors = titanic[titanic['survived'] == 1]
print(survivors.head())
```

これらの操作を通じて、データの構造や内容を把握することができます。`info()`メソッドはデータの概要を、`head()`メソッドは先頭の数行を、`describe()`メソッドは数値データの基本統計量を表示します。また、特定の列の選択やデータのフィルタリングも簡単に行えます。

## 第3章: NumPyによる数値計算

NumPyは、数値計算のための強力なライブラリです。大規模な配列や行列の操作を高速に行うことができます。ここでは、タイタニックデータを使ってNumPyの基本的な使い方を学びます。

```python
# 年齢データをNumPy配列に変換
ages = titanic['age'].values

# 基本的な統計量の計算
print("平均年齢:", np.mean(ages))
print("年齢の中央値:", np.median(ages))
print("年齢の標準偏差:", np.std(ages))

# 年齢データの正規化
normalized_ages = (ages - np.mean(ages)) / np.std(ages)
print("正規化された年齢データ:", normalized_ages[:5])

# 相関係数の計算
correlation = np.corrcoef(titanic['age'].values, titanic['fare'].values)
print("年齢と運賃の相関係数:", correlation[0, 1])
```

NumPyを使うと、平均、中央値、標準偏差などの基本的な統計量を簡単に計算できます。また、データの正規化や相関係数の計算など、より高度な操作も可能です。これらの操作は、データ分析の前処理や特徴量エンジニアリングの段階で非常に重要です。

## 第4章: matplotlibによる基本的なグラフ作成

matplotlibは、Pythonで最も広く使われているデータ可視化ライブラリです。ここでは、タイタニックデータを使って、基本的なグラフの作成方法を学びます。

```python
# ヒストグラムの作成
plt.figure(figsize=(10, 6))
plt.hist(titanic['age'].dropna(), bins=20, edgecolor='black')
plt.title('乗客の年齢分布')
plt.xlabel('年齢')
plt.ylabel('頻度')
plt.show()

# 散布図の作成
plt.figure(figsize=(10, 6))
plt.scatter(titanic['age'], titanic['fare'], alpha=0.5)
plt.title('年齢と運賃の関係')
plt.xlabel('年齢')
plt.ylabel('運賃')
plt.show()

# 箱ひげ図の作成
plt.figure(figsize=(10, 6))
titanic.boxplot(column='age', by='pclass')
plt.title('クラス別の年齢分布')
plt.suptitle('')  # デフォルトのsuptitleを削除
plt.show()
```

これらのグラフを通じて、データの分布や関係性を視覚的に理解することができます。ヒストグラムは年齢の分布を、散布図は年齢と運賃の関係を、箱ひげ図はクラス別の年齢分布を示しています。matplotlibは非常に柔軟性が高く、グラフのカスタマイズも容易です。

## 第5章: seabornによる統計的データ可視化

seabornは、matplotlibをベースにした統計的データ可視化ライブラリです。より美しく、情報量の多いグラフを簡単に作成できます。ここでは、seabornを使ってタイタニックデータをより詳細に可視化します。

```python
# カテゴリカルデータの可視化
plt.figure(figsize=(10, 6))
sns.countplot(x='class', hue='survived', data=titanic)
plt.title('クラス別の生存者数')
plt.show()

# 数値データの分布の可視化
plt.figure(figsize=(10, 6))
sns.kdeplot(data=titanic, x='age', hue='survived', shade=True)
plt.title('生存状況別の年齢分布')
plt.show()

# ペアプロットの作成
sns.pairplot(titanic[['survived', 'pclass', 'age', 'fare']], hue='survived')
plt.suptitle('変数間の関係', y=1.02)
plt.show()
```

seabornを使うと、カテゴリカルデータの集計や、数値データの分布、複数の変数間の関係性など、より複雑な可視化も簡単に行えます。`countplot`はカテゴリごとの頻度を、`kdeplot`は確率密度推定を、`pairplot`は複数の変数間の関係を一度に可視化します。これらのグラフを通じて、データの特徴やパターンをより深く理解することができます。

## 第6章: statsmodelsによる統計モデリング

statsmodelsは、統計モデルの推定や統計的検定を行うためのライブラリです。ここでは、タイタニックデータを使って、基本的な回帰分析と仮説検定を行います。

```python
# 年齢と運賃の関係を線形回帰で分析
X = sm.add_constant(titanic['age'].dropna())
y = titanic['fare'].dropna()
model = sm.OLS(y, X).fit()
print(model.summary())

# t検定：生存者と死亡者の年齢差を検定
survivors = titanic[titanic['survived'] == 1]['age']
non_survivors = titanic[titanic['survived'] == 0]['age']
t_stat, p_value = sm.stats.ttest_ind(survivors, non_survivors)
print(f"t統計量: {t_stat}, p値: {p_value}")

# カイ二乗検定：性別と生存の関連を検定
crosstab = pd.crosstab(titanic['sex'], titanic['survived'])
chi2, p, dof, expected = sm.stats.chi2_contingency(crosstab)
print(f"カイ二乗統計量: {chi2}, p値: {p}")
```

statsmodelsを使うと、線形回帰モデルの推定や、t検定、カイ二乗検定などの統計的検定を簡単に行うことができます。線形回帰では年齢と運賃の関係を分析し、t検定では生存者と死亡者の年齢差を、カイ二乗検定では性別と生存の関連を検定しています。これらの分析を通じて、データの背後にある統計的な関係性を明らかにすることができます。

## 第7章: pandasによるデータの高度な操作

pandasの高度な機能を使って、タイタニックデータをより深く分析してみましょう。グループ化、ピボットテーブル、時系列データの扱いなどを学びます。

```python
# グループ化と集計
class_stats = titanic.groupby('pclass').agg({
    'survived': 'mean',
    'age': ['mean', 'median'],
    'fare': ['mean', 'median']
})
print(class_stats)

# ピボットテーブル
pivot = pd.pivot_table(titanic, values='fare', index='pclass', columns='sex', aggfunc='mean')
print(pivot)

# 欠損値の処理
print(titanic.isnull().sum())
titanic_filled = titanic.fillna({
    'age': titanic['age'].median(),
    'embarked': titanic['embarked'].mode()[0]
})
print(titanic_filled.isnull().sum())

# カテゴリカル変数のエンコーディング
titanic_encoded = pd.get_dummies(titanic_filled, columns=['sex', 'embarked'])
print(titanic_encoded.head())
```

これらの操作を通じて、データをより深く理解し、機械学習モデルの入力に適した形に変換することができます。グループ化と集計は、カテゴリごとの統計量を計算するのに役立ちます。ピボットテーブルは、複数の変数間の関係を表形式で表現します。欠損値の処理とカテゴリカル変数のエンコーディングは、機械学習の前処理として重要です。

## 第8章: NumPyによる高度な数値計算

NumPyの高度な機能を使って、より複雑な数値計算を行います。ここでは、行列演算や乱数生成などの機能を紹介します。

```python
# 行列演算
X = titanic[['age', 'fare']].dropna().values
X_normalized = (X - X.mean(axis=0)) / X.std(axis=0)
covariance_matrix = np.cov(X_normalized.T)
print("共分散行列:")
print(covariance_matrix)

# 固有値分解
eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix)
print("固有値:", eigenvalues)
print("固有ベクトル:")
print(eigenvectors)

# 乱数生成
random_ages = np.random.normal(titanic['age'].mean(), titanic['age'].std(), 1000)
plt.figure(figsize=(10, 6))
plt.hist(random_ages, bins=30, edgecolor='black')
plt.title('シミュレートされた年齢分布')
plt.xlabel('年齢')
plt.ylabel('頻度')
plt.show()
```

これらの操作は、より高度なデータ分析や機械学習アルゴリズムの実装に役立ちます。共分散行列の計算と固有値分解は、主成分分析（PCA）などの次元削減技術の基礎となります。乱数生成は、シミュレーションやブートストラップ法などで使用されます。

## 第9章: matplotlibによる高度なグラフ作成

matplotlibの高度な機能を使って、より複雑で情報量の多いグラフを作成します。サブプロット、3Dプロット、アニメーションなどを紹介します。

```python
# サブプロット
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

axes[0, 0].hist(titanic['age'].dropna(), bins=20, edgecolor='black')
axes[0, 0].set_title('年齢分布')

axes[0, 1].scatter(titanic['age'], titanic['fare'], alpha=0.5)
axes[0, 1].set_title('年齢と運賃の関係')

titanic.boxplot(column='fare', by='pclass', ax=axes[1, 0])
axes[1, 0].set_title('クラス別の運賃分布')

sns.countplot(x='embarked', hue='survived', data=titanic, ax=axes[1, 1])
axes[1, 1].set_title('乗船港と生存の関係')

plt.tight_layout()
plt.show()

# 3Dプロット
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

scatter = ax.scatter(titanic['age'], titanic['fare'], titanic['pclass'], 
                     c=titanic['survived'], cmap='viridis')

ax.set_xlabel('年齢')
ax.set_ylabel('運賃')
ax.set_zlabel('クラス')
ax.set_title('年齢、運賃、クラス、生存の関係')

plt.colorbar(scatter, label='生存')
plt.show()
```

これらの高度なグラフ作成技術を使うことで、データの多面的な特徴を一度に可視化することができます

## 第10章: seabornによる高度な統計的可視化

seabornの高度な機能を使って、より洗練された統計的可視化を行います。ここでは、回帰プロット、ヒートマップ、バイオリンプロットなどを紹介します。

```python
# 回帰プロット
plt.figure(figsize=(10, 6))
sns.regplot(x='age', y='fare', data=titanic, scatter_kws={'alpha':0.5})
plt.title('年齢と運賃の関係（回帰線付き）')
plt.show()

# ヒートマップ
correlation_matrix = titanic.corr()
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1, center=0)
plt.title('変数間の相関係数')
plt.show()

# バイオリンプロット
plt.figure(figsize=(12, 6))
sns.violinplot(x='pclass', y='age', hue='survived', data=titanic, split=True)
plt.title('クラスと生存状況別の年齢分布')
plt.show()

# ジョイントプロット
sns.jointplot(x='age', y='fare', data=titanic, kind='hex')
plt.suptitle('年齢と運賃の結合分布', y=1.02)
plt.show()
```

これらの高度な可視化技術を使うことで、データの分布や関係性をより詳細に表現することができます。回帰プロットは変数間の線形関係を、ヒートマップは複数の変数間の相関を、バイオリンプロットは分布の形状を、ジョイントプロットは2変数の同時分布を示します。

## 第11章: statsmodelsによる高度な統計モデリング

statsmodelsを使って、より高度な統計モデリングを行います。ここでは、多変量回帰分析、ロジスティック回帰、時系列分析などを紹介します。

```python
# 多変量回帰分析
X = sm.add_constant(titanic[['age', 'pclass']])
y = titanic['fare']
model = sm.OLS(y, X).fit()
print(model.summary())

# ロジスティック回帰
X = sm.add_constant(titanic[['age', 'fare', 'pclass']])
y = titanic['survived']
logit_model = sm.Logit(y, X).fit()
print(logit_model.summary())

# 時系列分析（ダミーデータを使用）
import pandas as pd
import numpy as np

dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
ts_data = pd.Series(np.random.randn(len(dates)), index=dates).cumsum()

from statsmodels.tsa.arima.model import ARIMA
arima_model = ARIMA(ts_data, order=(1, 1, 1))
results = arima_model.fit()
print(results.summary())

# 予測
forecast = results.forecast(steps=30)
plt.figure(figsize=(12, 6))
plt.plot(ts_data, label='観測値')
plt.plot(forecast, label='予測値', color='red')
plt.title('ARIMA モデルによる時系列予測')
plt.legend()
plt.show()
```

これらの高度な統計モデリング技術を使うことで、データの背後にある複雑な関係性を明らかにすることができます。多変量回帰分析は複数の説明変数の影響を、ロジスティック回帰は二値の結果変数を予測するのに使用されます。時系列分析は、時間に依存するデータのパターンを分析し、将来の値を予測するのに役立ちます。

## 第12章: pandasによるデータの結合と再構築

pandasを使って、複数のデータセットの結合や、データの再構築を行います。ここでは、マージ、連結、ピボット、メルトなどの操作を紹介します。

```python
# データの分割
titanic_1 = titanic.iloc[:25]
titanic_2 = titanic.iloc[25:]

# データの連結
titanic_concat = pd.concat([titanic_1, titanic_2])
print(titanic_concat)

# データのマージ（ダミーデータを使用）
passenger_info = titanic[['passengerid', 'name', 'age']]
ticket_info = titanic[['passengerid', 'ticket', 'fare']]
merged_data = pd.merge(passenger_info, ticket_info, on='passengerid')
print(merged_data.head())

# ピボット
pivot_table = titanic.pivot_table(values='fare', index='pclass', columns='sex', aggfunc='mean')
print(pivot_table)

# メルト
melted_data = pd.melt(pivot_table.reset_index(), id_vars=['pclass'], var_name='sex', value_name='avg_fare')
print(melted_data)
```

これらのデータ操作技術は、複数のソースからのデータを統合したり、データの形式を分析に適した形に変換したりする際に非常に有用です。連結とマージは異なるデータセットを組み合わせる際に、ピボットとメルトはデータの形状を変更する際に使用されます。

## 第13章: NumPyによる高性能計算

NumPyの高性能計算機能を活用して、大規模なデータ処理や数値計算を行います。ここでは、ベクトル化操作、ブロードキャスティング、ユニバーサル関数などを紹介します。

```python
# ベクトル化操作
ages = titanic['age'].values
normalized_ages = (ages - np.mean(ages)) / np.std(ages)
print("正規化された年齢:", normalized_ages[:5])

# ブロードキャスティング
fares = titanic['fare'].values
age_fare_ratio = ages[:, np.newaxis] / fares[np.newaxis, :]
print("年齢と運賃の比率行列:")
print(age_fare_ratio[:5, :5])

# ユニバーサル関数
log_fares = np.log(fares)
print("対数変換された運賃:", log_fares[:5])

# 高速なフィルタリング
adult_mask = ages >= 18
adult_fares = fares[adult_mask]
print("成人の運賃:", adult_fares[:5])

# 行列演算
X = titanic[['age', 'fare']].values
X_centered = X - X.mean(axis=0)
cov_matrix = np.dot(X_centered.T, X_centered) / (len(X) - 1)
print("共分散行列:")
print(cov_matrix)
```

これらの高性能計算技術を使うことで、大規模なデータセットに対しても効率的に計算を行うことができます。ベクトル化操作とブロードキャスティングは、ループを使わずに高速な計算を可能にします。ユニバーサル関数は、要素ごとの操作を効率的に行います。また、NumPyの行列演算機能を使うことで、複雑な数学的計算も簡単に実装できます。

## 第14章: matplotlibによるインタラクティブな可視化

matplotlibを使って、インタラクティブな可視化を作成します。ここでは、スライダー、ボタン、ズーム機能などを持つグラフを紹介します。

```python
from matplotlib.widgets import Slider, Button

fig, ax = plt.subplots(figsize=(10, 6))
plt.subplots_adjust(bottom=0.25)

scatter = ax.scatter(titanic['age'], titanic['fare'], c=titanic['survived'], cmap='viridis')
ax.set_xlabel('年齢')
ax.set_ylabel('運賃')
ax.set_title('年齢と運賃の関係（生存状況別）')

axcolor = 'lightgoldenrodyellow'
ax_pclass = plt.axes([0.2, 0.1, 0.6, 0.03], facecolor=axcolor)

s_pclass = Slider(ax_pclass, 'クラス', 1, 3, valinit=1, valstep=1)

def update(val):
    pclass = int(s_pclass.val)
    data = titanic[titanic['pclass'] == pclass]
    scatter.set_offsets(data[['age', 'fare']])
    scatter.set_array(data['survived'])
    fig.canvas.draw_idle()

s_pclass.on_changed(update)

resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'リセット', color=axcolor, hovercolor='0.975')

def reset(event):
    s_pclass.reset()

button.on_clicked(reset)

plt.show()
```

このインタラクティブな可視化では、スライダーを使ってクラスを選択し、それに応じてグラフが更新されます。また、リセットボタンを押すことで初期状態に戻すことができます。このような対話的な要素を加えることで、ユーザーがデータを探索しやすくなります。

## 第15章: seabornによるカスタム統計プロット

seabornを使って、カスタマイズされた統計プロットを作成します。ここでは、複数の統計情報を組み合わせた複雑なプロットを紹介します。

```python
# カスタム統計プロット
plt.figure(figsize=(12, 6))

# バイオリンプロット
sns.violinplot(x='pclass', y='age', data=titanic, inner=None, color='lightgray')

# ボックスプロット
sns.boxplot(x='pclass', y='age', data=titanic, width=0.3, color='white')

# スウォームプロット
sns.swarmplot(x='pclass', y='age', data=titanic, hue='survived', dodge=True)

plt.title('クラス別の年齢分布と生存状況')
plt.xlabel('クラス')
plt.ylabel('年齢')
plt.legend(title='生存', loc='upper right')

plt.show()

# FacetGridを使用した複数のプロット
g = sns.FacetGrid(titanic, col='survived', row='pclass', height=4, aspect=1.5)
g.map(sns.scatterplot, 'age', 'fare')
g.add_legend()
g.fig.suptitle('クラスと生存状況別の年齢と運賃の関係', y=1.05)

plt.show()
```

これらのカスタム統計プロットを使うことで、複数の統計情報を一つのグラフに効果的に組み合わせることができます。バイオリンプロット、ボックスプロット、スウォームプロットを組み合わせることで、分布の形状、四分位数、個々のデータポイントを同時に表現できます。また、FacetGridを使用することで、複数の条件に基づいてデータを分割し、それぞれのサブセットに対して同じ種類のプロットを作成することができます。

## 総括：Pythonによるデータ分析の強力なツールセット

本記事では、Pythonの主要なデータ分析ライブラリであるstatsmodels、NumPy、pandas、seaborn、matplotlibの使用方法を詳しく解説しました。これらのライブラリを組み合わせることで、データの操作、統計分析、可視化を効果的に行うことができます。

pandasを使用してデータの読み込みや前処理を行い、NumPyで高速な数値計算を実行し、matplotlibとseabornで美しく情報量の多いグラフを作成し、statsmodelsで高度な統計モデリングを行うという一連の流れを学びました。

特に、タイタニック号の乗客データを例に、基本的なデータ操作から高度な統計分析まで、段階的に解説を進めました。各ライブラリの基本的な使い方から応用まで、実践的なコード例とともに説明しました。

これらのツールを使いこなすことで、データサイエンティストやアナリストは複雑なデータセットから意味のある洞察を引き出し、データに基づいた意思決定を支援することができます。Pythonとそのエコシステムは、データ分析の強力なツールセットとして、ビジネスや研究の様々な分野で活用されています。

本記事で紹介した技術や概念を基礎として、さらに高度なデータ分析や機械学習の世界に踏み出すことができるでしょう。データ分析の旅は終わりのない学習の過程ですが、これらのライブラリを習得することで、その旅路はより豊かで実り多いものになるはずです。