忍者ブログ
統計、機械学習、AIを学んでいきたいと思います。 お役に立てば幸いです。

【Kaggle挑戦記】Titanic 攻略 #3:データの「当たり」をつける

最短ルートで初提出(スコア:0.76794)を終えた段階で、次に行うべきは、どのデータ(特徴量)が生存に直結しているのか、論理的な仮説と数値で切り分ける作業です。

1. 仕様確認:データ項目の定義一覧

まずは手元にあるテーブルの定義を正確に把握し、全12項目の中で何が利用可能かを確認します。

項目名 (Column)意味 (Description)型 (Type)補足 (Notes)
PassengerId 乗客ID int 連番。予測には使わない主キー
Survived 生存フラグ int 【正解データ】 0=死亡、1=生存
Pclass チケットクラス int 1=上層(1等)、2=中層(2等)、3=下層(3等)
Name 氏名 object 文字列
Sex 性別 object male / female
Age 年齢 float 欠損値あり
SibSp 兄弟・配偶者数 int 同乗している兄弟や配偶者の数
Parch 両親・子供数 int 同乗している両親や子供の数
Ticket チケット番号 object 文字列
Fare 旅客運賃 float 数値データ
Cabin 客室番号 object 欠損値多
Embarked 出港地 object C / Q / S

2. 仮説:項目の切り分け

各項目が生存に関係しそうかどうかを、とりあえず、勘で事前に切り分けます。

項目名 (Column)関連性の推論
Sex ありそう
Pclass ありそう
Age ありそう
Fare ありそう
SibSp / Parch ありそう
Name なさそう
Embarked なさそう
Ticket / Cabin なさそう
PassengerId なさそう

3. 検証:相関分析の実行(完全なソースコード)

「ありそう」と踏んだ項目について、実際に Survived(生存率) との関係性を算出します。汎用性が高く、まずは全体像を把握するために適しているためピアソンの積率相関係数を採用する。

import pandas as pd

# 1. データの読み込み
train_df = pd.read_csv('train.csv')

# 2. 相関計算のため「文字列」を「数値」に一時変換(エンコード)
train_encoded = train_df.copy()
train_encoded['Sex'] = train_encoded['Sex'].map({'male': 0, 'female': 1})

# 3. 算出対象の項目選定(「ありそう」と踏んだ項目に限定)
target_columns = ['Survived', 'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare']

# 4. 相関係数(ピアソン)の算出
pearson_corr = train_encoded[target_columns].corr(method='pearson')

# 5. 「Survived」との相関を表示
print("--- Survived との相関係数(ピアソン) ---")
print(pearson_corr['Survived'].sort_values(ascending=False))

【 分析結果:生存率との相関係数 】

  • Sex:0.543
  • Fare:0.257
  • Pclass:-0.338
  • Age:-0.077
  • Parch:0.081
  • SibSp:-0.035

4. 前回プログラムの振り返り

第2回の最短ルートで使用した特徴量と、今回の相関計算の結果を照らし合わせます。

# 前回の特徴量選択
features = ["Pclass", "Sex", "SibSp", "Parch"]

前回は「ありそう」と推測した項目のうち、FareAge を除いた 4項目を特徴量として利用しました。今回の計算結果を見ると、利用しなかった Fare が一定の相関(0.25)を示しており、これを特徴量に加えることでモデルの判断材料がどう変化するかを試す価値はありそうです。

また、Age については相関係数こそ低いですが、欠損値を適切に補完した上で投入することで、どのような変化が出るかを検証する必要があります。



PR

【DS検定対策】深層学習の壁を攻略!学習が暴走する「勾配爆発」とは?

ディープラーニングの学習において、勾配が消えてしまう「勾配消失」とは逆に、勾配が指数関数的に大きくなってしまうのが「勾配爆発」です。学習が成立しなくなるこの現象を整理しましょう。

1. 【 問題 】

ニューラルネットワークの学習において、誤差逆伝播法で算出される勾配が極端に大きな値となり、パラメータの更新が異常に大きくなることで学習が発散・不安定になる現象を何と呼ぶでしょうか?

① 勾配消失問題
② 勾配爆発問題
③ オーバーフィッティング
④ 局所最適解


2. 【 解答 】

正解: ② 勾配爆発問題

3. 整理:なぜ「勾配」が暴走するのか?

勾配消失が「1より小さい値の掛け算」で起こるのに対し、勾配爆発は「1より大きな値の掛け算」が繰り返されることで起こります。

【 勾配爆発のイメージ 】

[ 1. 誤差の逆伝播 ]
層をさかのぼる際、重み行列の値を何度も掛け合わせる。

[ 2. 値が急激に膨れ上がる ]
★ ここが勾配爆発!
大きな値(重み)の掛け算が重なり、勾配が巨大な数値になる。

[ 3. パラメータの更新が「跳ねる」 ]
更新幅が大きすぎて、最適値(谷底)を飛び越えて発散してしまう。

--------------------------

結果: 重みが「NaN(非数)」になったり、学習が全く進まなくなったりします。

4. 代表的な対策

1. 勾配クリッピング: 勾配がある一定の閾値を超えたら、強制的に値を抑え込む手法です。
2. バッチ正規化: データの偏りを抑え、勾配が極端な値になるのを防ぎます。
3. 適切な重みの初期化: 最初から重みの値が大きくなりすぎないように調整します。


5. DS検定形式:実戦4択クイズ

問:勾配爆発を防ぐために、算出された勾配のノルム(大きさ)が一定値を超えた場合にその値を制限する手法を何と呼ぶか。

① ドロップアウト   ② 勾配クリッピング   ③ 正則化   ④ 早期終了

【 正解: ② 】

解説: 「クリッピング(切り取り)」という名前の通り、勾配が暴走しないよう上限を設ける手法です。RNN(再帰型ニューラルネットワーク)など、層が深い(時間方向に長い)モデルで特によく使われます。


6. まとめ

DS検定で「勾配が極端に大きな値になる」「学習が発散する」という記述があれば、それは「勾配爆発」を指しています。勾配消失(ReLUなどで対策)と勾配爆発(クリッピングなどで対策)はペアで出題されやすいため、セットで覚えておきましょう!


【DS検定対策】深層学習の壁を攻略!学習が止まる「勾配消失問題」とは?

ディープラーニングの層を深くしすぎると、かえって学習がうまく進まなくなることがあります。その主な原因の一つである「勾配消失問題」の仕組みを正しく理解しましょう。

1. 【 問題 】

ニューラルネットワークの学習において、層が深くなるにつれて誤差の情報(勾配)が極端に小さくなり、入力層に近い層のパラメータがほとんど更新されなくなる現象を何と呼ぶでしょうか?

① 過学習(オーバフィッティング)
② 勾配消失問題
③ 局所最適解へのトラップ
④ 次元の呪い


2. 【 解答 】

正解: ② 勾配消失問題

3. 整理:なぜ「勾配」が消えてしまうのか?

ニューラルネットワークは「誤差逆伝播法」という仕組みで、後ろの層から前の層へと「間違いの修正情報」を伝えていきます。

【 勾配消失のイメージ 】

[ 1. 出力層でエラーを発見 ]
「答えが少しズレているぞ!」という情報を逆方向に送る。

[ 2. 層をさかのぼる(掛け算の連続) ]
活性化関数の微分値を何度も掛け合わせていく。

[ 3. 値がどんどん小さくなる ]
★ ここが勾配消失!
1より小さい値を何度も掛けることで、入力層に届く頃には値が「ほぼゼロ」になる。

--------------------------

結果: 前の方の層にある重みが更新されず、学習がストップしてしまいます。

4. 解決のためのアプローチ

1. 活性化関数の工夫: シグモイド関数ではなく、勾配が消えにくい「ReLU関数」などを使用する。
2. バッチ正規化: 各層の出力を適切な範囲に調整し、学習を安定させる。
3. 適切な重みの初期化: 「Heの初期値」などを用い、最初から値が小さくなりすぎないようにする。


5. DS検定形式:実戦4択クイズ

問:勾配消失問題を緩和するために、隠れ層(中間層)の活性化関数として一般的に推奨される関数はどれか。

① シグモイド関数   ② ReLU関数   ③ ステップ関数   ④ 線形関数

【 正解: ② 】

解説: シグモイド関数は値が大きくなると微分値がほぼ0になるため、勾配消失が起きやすい特徴があります。一方、ReLU(Rectified Linear Unit)関数は入力が正であれば微分値が1のまま保たれるため、深い層でも学習が進みやすくなります。


6. まとめ

DS検定で「誤差逆伝播法」「勾配がゼロに近い」「パラメータが更新されない」というセットが出たら、正解は「勾配消失」です。歴史的に深層学習が停滞した理由の一つでもあるため、背景知識としてもしっかり押さえておきましょう!



【DS検定対策】画像認識の要!CNNを構成する「2つの層」の役割とは?

画像認識の分野で驚異的な精度を発揮する「畳み込みニューラルネットワーク(CNN)」。その最大の特徴は、画像の特徴を抽出するために特殊な2つの層を交互に積み重ねる構造にあります。

1. 【 問題 】

画像認識などに用いられる「畳み込みニューラルネットワーク(CNN)」は、主にどのような役割を持つ2つの層を交互に積み重ねた構造を指すでしょうか?

① 入力層 と 出力層
② 畳み込み層 と プーリング層
③ 回帰層 と 分類層
④ 活性化層 と 損失層


2. 【 解答 】

正解: ② 畳み込み層 と プーリング層

3. 整理:CNNを支える「2つのエンジン」

CNNは、人間の視覚野の仕組みをモデルにしており、「特徴を見つける作業」と「情報を凝縮する作業」を繰り返します。

【 CNNの構造イメージ 】

[ 1. 畳み込み層 (Convolution Layer) ]
「特徴を抽出する」
フィルタ(カーネル)を画像に滑らせ、エッジ(輪郭)などの特徴を抜き出します。

[ 2. プーリング層 (Pooling Layer) ]
「情報を圧縮・頑健にする」
抽出した特徴の位置ズレを許容し、データを小さくします(Maxプーリングなど)。

--------------------------

このセットを何度も繰り返した後、最後に「全結合層」で何の画像かを分類します。

4. なぜこの構造が必要なのか?

1. 局所的な特徴の把握: 画像全体を一度に見るのではなく、小さな領域(フィルタ)ごとに見ることで、複雑な形を捉えられます。
2. 位置不変性: 対象物が画像の中央にあっても端にあっても、正しく「同じもの」だと認識できるようになります(プーリング層の功績)。


5. DS検定形式:実戦4択クイズ

問:畳み込み層において、画像から特徴を抽出するために使用される小さな行列のことを何と呼ぶか。

① ニューロン   ② カーネル(フィルタ)   ③ バイアス   ④ 重み減衰

【 正解: ② 】

解説: 画像の上をスライドさせながら計算を行う小さな行列を「カーネル」または「フィルタ」と呼びます。このカーネル内の数値を学習によって最適化していくのが、CNNの学習プロセスです。


6. まとめ

DS検定において「CNNの構造」を問われたら、まずは「畳み込み層」と「プーリング層」のセットを思い出しましょう。「畳み込みで特徴を見つけ、プーリングでまとめる」という一連の流れを理解しておくことが、深層学習攻略の第一歩です!





【Kaggle挑戦記】Titanic 攻略 #2:最短ルートで初提出(Submit)まで駆け抜ける

前回、データを読み込むところまで成功しました。今回は精度を一旦度外視し、「最短で予測結果を Kaggle に提出(Submit)すること」を目標にします。分析の世界では、まず一度最後まで通してみることが、全体の流れを把握する近道です。

1. 準備:環境構築とデータの再確認

まずは必要なライブラリの導入と、前回ロードしたデータの状態を再読込して準備を整えます。

[ ターミナルでのインストール ]
conda install scikit-learn

[ ライブラリのインポートとバージョン確認 ]
import pandas as pd
import sklearn
print(sklearn.__version__) # 1.7.2 であることを確認

[ データの読み込み(前回の復習) ]
train_df = pd.read_csv('train.csv')
test_df = pd.read_csv('test.csv')

2. 現状把握:AIの「計算」を阻害する Null を特定する

データを読み込んだら、次にすべきはデータの「健康診断」です。プログラムの演算を停止させたり、予測不能に陥らせたりする「Null(欠損値)」「文字列(Object型)」を特定します。

【 1. Null の確認:isnull() と sum() の組み合わせ 】

データセット内に値が存在しない状態を Null と呼びます。pandas の isnull() 関数を実行すると、全データに対して「Null なら True(1)」「値があれば False(0)」というブール値(論理値)のデータセットが内部で生成されます。

これに sum() を繋げることで、True(1) の数を合計し、各項目にいくつ Null が含まれているかを一気に集計できる仕組みです。

# 各項目に含まれる Null の数を集計
print(train_df.isnull().sum())

[ 実行結果 ]
Age 177 # ← 177件の Null(年齢不明)
Cabin 687 # ← 687件の Null(客室不明)
Embarked 2 # ← 2件の Null(港不明)

→ 数値が入るべき場所に値がない(Null)状態では、AIモデルが数学的な行列演算を行えずエラーとなります。何らかの値で埋めるか、除外する判断が必要です。

【 2. データ型(dtypes)の確認:数値化が必要な項目 】

# データの型を確認
print(train_df.dtypes)

[ 実行結果 ]
Name object
Sex object # ← 文字列型。数値への変換が必須
Embarked object # ← 文字列型。数値への変換が必須

object 型と表示される項目は、そのままではモデルの学習には使えません。

3. 最短の「前処理」:AIが読める形に整える

特定した課題に対し、今回は「最短完走」を優先して以下の処理を施します。object 型のうち、今回の予測に採用する Sex のみ数値に置換します。

# 1. 欠損値を埋める(Fare:運賃 などの空欄を中央値で補完)
# ※学習項目に使わない Age や Cabin の Null は一旦放置します
test_df['Fare'] = test_df['Fare'].fillna(test_df['Fare'].median())

# 2. 文字列を数値に変換(Sex を male=0, female=1 に変換)
# ※Embarked も object型ですが、今回は特徴量に含めないため変換をスキップします
train_df['Sex'] = train_df['Sex'].replace({'male': 0, 'female': 1})
test_df['Sex'] = test_df['Sex'].replace({'male': 0, 'female': 1})

4. 学習と予測:標準モデル「ランダムフォレスト」

予測モデルには、強力で使い勝手の良い RandomForestClassifier を使用します。

from sklearn.ensemble import RandomForestClassifier

# Pclass(チケットクラス)、Sex(性別)、SibSp(兄弟・配偶者数)、Parch(両親・子供数)を使用
# これらは Null がなく、かつ数値化が済んでいる項目です
features = ["Pclass", "Sex", "SibSp", "Parch"]
X = train_df[features]
y = train_df["Survived"]
X_test = test_df[features]

# モデル作成・学習
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1)
model.fit(X, y)

# 予測実行
predictions = model.predict(X_test)

5. 出力結果の確認:submission.csv の中身

予測が完了すると、Kaggle 提出用の CSV ファイルが生成されます。中身を確認すると、テストデータの乗客(PassengerId 892番〜)に対して、AIが導き出した「生存(1) / 死亡(0)」のフラグが並んでいることがわかります。

PassengerId,Survived
892,0
893,1
894,0
895,0
896,0
897,0
898,1

6. 実践:Kaggle へのアップロードとスコア確認

作成した submission.csv を Kaggle に提出する最終ステップです。

  1. Titanic コンペのページ右上にある青い [Submit Predictions] ボタンをクリックします。
  2. 専用の提出ページに移動するので、画面中央の「Upload files」エリアに submission.csv をドラッグ&ドロップします。
  3. 右下の [Submit] をクリックします。

数秒後、同じ画面上に以下の結果が表示されます。

submission.csv
Complete · Just now
Score: 0.76794

【 自分の順位を確認する 】

提出履歴から Leaderboard(順位表)へ移動し、自分の立ち位置を確認してみましょう。

9065 XXXX(私の登録名)
Score: 0.76794

順位表を見ると、トップ層には Score 1.00000(正解率100%) がズラリと並んでいます。今の自分とはまだ距離がありますが、最短ルートで完走したことで、戦いの舞台には上がりました。ここからロジックを磨き、上位へと食い込んでいきましょう。頑張ろう、エンジニア諸君!

7. 最短完走:全ソースコード

ここまでの手順を一つにまとめた、提出用ファイルを生成するための全コードです。

import pandas as pd
from sklearn.ensemble import RandomForestClassifier

# 1. データの読み込み
train_df = pd.read_csv('train.csv')
test_df = pd.read_csv('test.csv')

# 2. 最小限の前処理
test_df['Fare'] = test_df['Fare'].fillna(test_df['Fare'].median())
train_df['Sex'] = train_df['Sex'].replace({'male': 0, 'female': 1})
test_df['Sex'] = test_df['Sex'].replace({'male': 0, 'female': 1})

# 3. 予測モデルの作成
# 項目:チケットクラス、性別、兄弟配偶者数、親子数(これらはNullなし・数値済み)
features = ["Pclass", "Sex", "SibSp", "Parch"]
X = train_df[features]
y = train_df["Survived"]
X_test = test_df[features]

model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1)
model.fit(X, y)

# 4. 予測と保存
predictions = model.predict(X_test)
output = pd.DataFrame({'PassengerId': test_df.PassengerId, 'Survived': predictions})
output.to_csv('submission.csv', index=False)

print("Your submission was successfully saved!")

8. まとめ

今回の最短攻略ソースはこれでした!「なぜエラーが出るのか」「何を直すべきか」を特定し、最短で Kaggle にコミットするサイクルを完走しました。これだけで、あなたも立派な Kaggler の仲間入りです。

次回は、今回あえてスルーした「年齢(Age)」の Null をどう埋めるべきか、あるいは「港(Embarked)」をどうモデルに組み込むか。精度向上のための「EDA(探索的データ分析)」に挑戦しましょう!