🚀 STEP 30: 独立プロジェクト
学んだスキルを総動員して、自分でプロジェクトを完成させる
📋 このステップの目標
- 3つのプロジェクトから1つ以上を選んで完成させる
- これまで学んだ全てのスキルを実践する
- GitHubにポートフォリオとして公開する
所要時間: 各プロジェクト2〜4時間
🎯 プロジェクトを選ぼう
以下の3つのプロジェクトから、興味のあるものを選んでください。複数挑戦することをお勧めします。
初級
🚢 プロジェクト1: Titanic生存予測
📊 プロジェクト概要
- 目標:乗客の情報から生存したかどうかを予測
- 問題タイプ:二値分類(生存 or 死亡)
- データ:891件のトレーニングデータ
- 評価指標:Accuracy(正解率)
- 目標スコア:80%以上
データの取得と確認
Titanicデータセットの特徴量:
Pclass:チケットクラス(1=1等、2=2等、3=3等)Sex:性別Age:年齢(欠損あり)SibSp:同乗の兄弟・配偶者の数Parch:同乗の親・子供の数Fare:運賃Embarked:乗船港(C, Q, S)
# Titanicデータセットの読み込みと確認
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.impute import SimpleImputer
# seabornに含まれるTitanicデータを使用
import seaborn as sns
df = sns.load_dataset(‘titanic’)
# 基本情報を確認
print(“データの形状:”, df.shape)
print(“\n最初の5行:”)
print(df.head())
# 欠損値を確認
print(“\n欠損値の数:”)
print(df.isnull().sum())
# 前処理とモデル構築の例
# 使用する列を選択
features = [‘pclass’, ‘sex’, ‘age’, ‘sibsp’, ‘parch’, ‘fare’, ‘embarked’]
target = ‘survived’
# データを準備
df_model = df[features + [target]].copy()
# 欠損値を処理
# age: 中央値で補完
df_model[‘age’] = df_model[‘age’].fillna(df_model[‘age’].median())
# embarked: 最頻値で補完
df_model[‘embarked’] = df_model[‘embarked’].fillna(df_model[‘embarked’].mode()[0])
# カテゴリカル変数をエンコード
# sex: male=0, female=1
df_model[‘sex’] = LabelEncoder().fit_transform(df_model[‘sex’])
# embarked: One-Hot Encoding
df_model = pd.get_dummies(df_model, columns=[‘embarked’], drop_first=True)
# 特徴量と目的変数を分離
X = df_model.drop(target, axis=1)
y = df_model[target]
print(“前処理後の特徴量:”)
print(X.head())
# 特徴量エンジニアリングの例
def create_titanic_features(df):
“””Titanicデータ用の特徴量作成”””
df = df.copy()
# 家族サイズ = 兄弟配偶者 + 親子 + 自分
df[‘FamilySize’] = df[‘sibsp’] + df[‘parch’] + 1
# 一人かどうか
df[‘IsAlone’] = (df[‘FamilySize’] == 1).astype(int)
# 年齢グループ
df[‘AgeGroup’] = pd.cut(
df[‘age’],
bins=[0, 12, 18, 35, 60, 100],
labels=[0, 1, 2, 3, 4] # 子供, 若者, 成人, 中年, 高齢
).astype(int)
return df
# 特徴量を作成
X = create_titanic_features(X)
print(“追加した特徴量:”)
print(X[[‘FamilySize’, ‘IsAlone’, ‘AgeGroup’]].head())
# モデルの構築と評価
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
# データを分割
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# スケーリング
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# モデルを比較
models = {
‘Logistic Regression’: LogisticRegression(max_iter=1000),
‘Random Forest’: RandomForestClassifier(n_estimators=100, random_state=42)
}
print(“モデル比較(5-Fold CV):”)
for name, model in models.items():
scores = cross_val_score(model, X_train_scaled, y_train, cv=5)
print(f” {name}: {scores.mean():.4f} (±{scores.std():.4f})”)
✅ Titanicプロジェクトのポイント
- 欠損値処理:Age、Embarkedの欠損を適切に補完
- 特徴量作成:FamilySize、IsAloneが効果的
- Name列:「Mr.」「Mrs.」などの敬称を抽出すると精度向上
中級
💳 プロジェクト2: クレジットカード不正検知
📊 プロジェクト概要
- 目標:取引が不正かどうかを検知
- 問題タイプ:不均衡データの二値分類
- データ:約28万件(不正は0.17%のみ)
- 評価指標:Recall(再現率)、F1-Score、AUC
- 目標スコア:Recall 80%以上
⚠️ 不均衡データの注意点
不正取引は全体のわずか0.17%。Accuracyは意味がありません。
「全部正常と予測」しても99.83%の正解率になってしまうからです。
Recall(不正を見逃さない)を重視しましょう。
# 不均衡データの対処法
from sklearn.utils import resample
from imblearn.over_sampling import SMOTE # pip install imbalanced-learn
# 方法1: アンダーサンプリング(多数派を減らす)
def undersample(X, y):
“””多数派クラスをサンプリングして少数派に合わせる”””
# 少数派と多数派を分離
X_majority = X[y == 0]
y_majority = y[y == 0]
X_minority = X[y == 1]
y_minority = y[y == 1]
# 多数派を少数派と同じ数にダウンサンプリング
X_majority_downsampled = resample(
X_majority,
replace=False, # 重複なし
n_samples=len(X_minority), # 少数派と同じ数
random_state=42
)
y_majority_downsampled = resample(
y_majority,
replace=False,
n_samples=len(y_minority),
random_state=42
)
# 結合
X_balanced = pd.concat([X_majority_downsampled, X_minority])
y_balanced = pd.concat([y_majority_downsampled, y_minority])
return X_balanced, y_balanced
# 方法2: SMOTE(少数派を増やす)
from imblearn.over_sampling import SMOTE
def apply_smote(X_train, y_train):
“””
SMOTEで少数派クラスを人工的に増やす
SMOTE = Synthetic Minority Over-sampling Technique
少数派サンプル間を補間して、新しいサンプルを生成
“””
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)
print(f”SMOTE前: {len(y_train)} サンプル”)
print(f” 正常: {sum(y_train == 0)}, 不正: {sum(y_train == 1)}”)
print(f”SMOTE後: {len(y_resampled)} サンプル”)
print(f” 正常: {sum(y_resampled == 0)}, 不正: {sum(y_resampled == 1)}”)
return X_resampled, y_resampled
# 方法3: class_weightを使う(最も簡単)
from sklearn.ensemble import RandomForestClassifier
# class_weight=’balanced’ で自動的に重みを調整
# 少数派クラスのサンプルに高い重みを与える
model = RandomForestClassifier(
n_estimators=100,
class_weight=’balanced’, # 不均衡に対応
random_state=42
)
# 評価は Recall と F1-Score を使う
from sklearn.metrics import classification_report, confusion_matrix
# model.fit(X_train, y_train)
# y_pred = model.predict(X_test)
# print(classification_report(y_test, y_pred))
評価指標の選び方(不均衡データ):
Recall(再現率):不正のうち、どれだけ検知できたか → 高いほど見逃しが少ないPrecision(適合率):不正と予測したうち、本当に不正だった割合F1-Score:RecallとPrecisionの調和平均AUC-ROC:総合的な分類性能
中級
👥 プロジェクト3: 顧客セグメンテーション
📊 プロジェクト概要
- 目標:顧客を類似したグループに分類
- 問題タイプ:教師なし学習(クラスタリング)
- データ:顧客の購買履歴
- 評価指標:シルエットスコア
- 成果物:顧客グループの特徴分析
# RFM分析による顧客セグメンテーション
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
# RFM特徴量を計算する関数
def calculate_rfm(df, customer_id_col, date_col, amount_col, reference_date):
“””
RFM分析の特徴量を計算
RFM = Recency, Frequency, Monetary
– Recency: 最後の購入からの日数(小さいほど良い顧客)
– Frequency: 購入回数(多いほど良い顧客)
– Monetary: 合計購入金額(多いほど良い顧客)
Parameters:
df: 購買履歴データ
customer_id_col: 顧客IDの列名
date_col: 購入日の列名
amount_col: 購入金額の列名
reference_date: 基準日(通常は最新の日付)
“””
# 日付型に変換
df[date_col] = pd.to_datetime(df[date_col])
# 顧客ごとに集計
rfm = df.groupby(customer_id_col).agg({
date_col: lambda x: (reference_date – x.max()).days, # Recency
customer_id_col: ‘count’, # Frequency
amount_col: ‘sum’ # Monetary
})
# 列名を変更
rfm.columns = [‘Recency’, ‘Frequency’, ‘Monetary’]
return rfm
# 使用例(ダミーデータ)
# rfm = calculate_rfm(df, ‘customer_id’, ‘purchase_date’, ‘amount’, pd.Timestamp(‘2024-01-01’))
# K-meansクラスタリングの実行
def perform_clustering(rfm_data, n_clusters=4):
“””
K-meansでクラスタリングを実行
Parameters:
rfm_data: RFM特徴量のDataFrame
n_clusters: クラスタ数
Returns:
rfm_data: クラスタラベルを追加したDataFrame
“””
# スケーリング(K-meansはスケールに敏感)
scaler = StandardScaler()
rfm_scaled = scaler.fit_transform(rfm_data)
# K-meansを実行
kmeans = KMeans(
n_clusters=n_clusters,
random_state=42,
n_init=10 # 初期値を10回試して最良を選択
)
# クラスタラベルを取得
rfm_data[‘Cluster’] = kmeans.fit_predict(rfm_scaled)
return rfm_data, kmeans
# エルボー法で最適なクラスタ数を決定
def find_optimal_clusters(data, max_k=10):
“””
エルボー法で最適なクラスタ数を探す
クラスタ数を増やすとSSE(誤差)は減少するが、
減少率が急に緩やかになる点(肘)が最適なクラスタ数
“””
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
sse = [] # Sum of Squared Errors
for k in range(1, max_k + 1):
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(data_scaled)
sse.append(kmeans.inertia_) # SSE
# プロット
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.plot(range(1, max_k + 1), sse, ‘bo-‘)
plt.xlabel(‘クラスタ数’)
plt.ylabel(‘SSE’)
plt.title(‘エルボー法’)
plt.show()
return sse
# クラスタの解釈と可視化
def analyze_clusters(rfm_with_clusters):
“””
各クラスタの特徴を分析
“””
# クラスタごとの平均を計算
cluster_summary = rfm_with_clusters.groupby(‘Cluster’).agg({
‘Recency’: ‘mean’,
‘Frequency’: ‘mean’,
‘Monetary’: ‘mean’
}).round(2)
# 顧客数も追加
cluster_summary[‘Count’] = rfm_with_clusters.groupby(‘Cluster’).size()
print(“クラスタ別の特徴:”)
print(cluster_summary)
# クラスタの解釈(例)
# Recency低 + Frequency高 + Monetary高 → VIP顧客
# Recency高 + Frequency低 + Monetary低 → 離反顧客
return cluster_summary
✅ 顧客セグメンテーションのポイント
- RFM分析:Recency(最近)、Frequency(頻度)、Monetary(金額)の3指標
- スケーリング:K-meansの前に必ず標準化
- クラスタ数:エルボー法 + シルエットスコアで決定
- 解釈:各クラスタに「VIP」「新規」「休眠」などの名前を付ける
📋 プロジェクト実行ガイド
【プロジェクト実行の6ステップ】
ステップ1: 準備(15分)
└─ データの取得
└─ 環境の確認(Google Colab推奨)
ステップ2: EDA(30分)
└─ データの形状、型、欠損値を確認
└─ 目的変数の分布を確認
└─ 相関関係を確認
ステップ3: 前処理(30分)
└─ 欠損値の処理
└─ カテゴリカル変数のエンコード
└─ スケーリング
ステップ4: モデル構築(45分)
└─ 複数のモデルを比較
└─ 交差検証で評価
└─ 最良モデルをチューニング
ステップ5: 評価・改善(30分)
└─ テストデータで最終評価
└─ 特徴量重要度の分析
└─ 必要に応じて特徴量エンジニアリング
ステップ6: レポート作成(30分)
└─ 結果をまとめる
└─ GitHubにアップロード
🐙 GitHubにポートフォリオとして公開
GitHubリポジトリに含めるべきもの:
README.md:プロジェクトの説明notebook.ipynb:分析コード(Jupyter Notebook)data/:データセット(または取得方法の説明)requirements.txt:必要なライブラリ
# README.mdのテンプレート
“””
# プロジェクト名
## 概要
[プロジェクトの目的を1-2文で説明]
## データセット
– データソース: [URL]
– サンプル数: [件数]
– 特徴量数: [数]
## 結果
– 使用モデル: [モデル名]
– 評価指標: [指標名]
– スコア: [値]
## 使用技術
– Python 3.x
– scikit-learn
– pandas
– matplotlib
## 実行方法
1. リポジトリをクローン
2. pip install -r requirements.txt
3. notebook.ipynb を実行
## フォルダ構成
├── README.md
├── notebook.ipynb
├── data/
│ └── dataset.csv
└── requirements.txt
## 著者
[あなたの名前]
“””
✅ コース修了チェックリスト
少なくとも1つのプロジェクトを完成させた
EDA(探索的データ分析)を実施した
適切な前処理を行った
複数のモデルを比較した
交差検証で評価した
ハイパーパラメータをチューニングした
特徴量重要度を分析した
結果をレポートにまとめた
GitHubに公開した
🎓 コース修了後の学習パス
| レベル | 学習内容 | リソース |
|---|---|---|
| Level 1 | Kaggleコンペに参加 | Kaggle Getting Started |
| Level 2 | ディープラーニング基礎 | TensorFlow / PyTorch |
| Level 3 | 専門分野(NLP / CV / 時系列) | 各分野のコース |
| Level 4 | MLOps(モデルのデプロイ) | Flask / FastAPI / Docker |
🎉 おめでとうございます!
「機械学習入門」コースを修了しました!
このコースで学んだスキルは、実務で即戦力となります。
学んだことを忘れないために、定期的に実践することが重要です。
Kaggleのコンペティションに参加したり、自分のデータで分析したりして、
スキルを磨き続けてください!
❓ よくある質問
Q1. どのプロジェクトから始めるべき?
Titanic(初級)から始めることをお勧めします。データが小さく、問題も明確で、オンライン上に多くの参考資料があります。
Q2. スコアが上がらない場合は?
・特徴量エンジニアリングを追加してみる
・異なるモデル(XGBoost、LightGBMなど)を試す
・ハイパーパラメータの範囲を広げる
・外れ値の処理を見直す
・異なるモデル(XGBoost、LightGBMなど)を試す
・ハイパーパラメータの範囲を広げる
・外れ値の処理を見直す
Q3. ポートフォリオとして評価されるには?
・コードにコメントを書く
・なぜその手法を選んだかを説明する
・結果だけでなくプロセスも記録する
・失敗した試みも書く(学びになる)
・なぜその手法を選んだかを説明する
・結果だけでなくプロセスも記録する
・失敗した試みも書く(学びになる)
📝 コース全体のまとめ
✅ このコースで習得したスキル
- Part 1-2:機械学習の基礎概念、Scikit-learnの使い方
- Part 3:回帰分析(線形回帰、正則化、評価指標)
- Part 4:分類問題(ロジスティック回帰、決定木、アンサンブル)
- Part 5:教師なし学習(クラスタリング、次元削減、異常検知)
- Part 6:モデル評価と改善(交差検証、チューニング)
- Part 7:特徴量エンジニアリング
- Part 8:総合プロジェクト
🚀 これからの学習のヒント
- 毎日30分でも機械学習に触れる習慣をつける
- Kaggleのコンペに参加して実力を試す
- 論文やブログで最新手法をキャッチアップ
- コミュニティ(Discord、Slack)に参加して質問・議論
学習メモ
機械学習入門 - Step 30
📋 過去のメモ一覧
▼