STEP 30:独立プロジェクト

🚀 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など)を試す
・ハイパーパラメータの範囲を広げる
・外れ値の処理を見直す
Q3. ポートフォリオとして評価されるには?
・コードにコメントを書く
・なぜその手法を選んだかを説明する
・結果だけでなくプロセスも記録する
・失敗した試みも書く(学びになる)

📝 コース全体のまとめ

✅ このコースで習得したスキル
  • Part 1-2:機械学習の基礎概念、Scikit-learnの使い方
  • Part 3:回帰分析(線形回帰、正則化、評価指標)
  • Part 4:分類問題(ロジスティック回帰、決定木、アンサンブル)
  • Part 5:教師なし学習(クラスタリング、次元削減、異常検知)
  • Part 6:モデル評価と改善(交差検証、チューニング)
  • Part 7:特徴量エンジニアリング
  • Part 8:総合プロジェクト
🚀 これからの学習のヒント
  • 毎日30分でも機械学習に触れる習慣をつける
  • Kaggleのコンペに参加して実力を試す
  • 論文ブログで最新手法をキャッチアップ
  • コミュニティ(Discord、Slack)に参加して質問・議論
📝

学習メモ

機械学習入門 - Step 30

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE