Data Cleaning Pipeline について
分析やモデリングに使う生データを整えるデータクリーニングパイプラインのスキルです。欠損値、外れ値、重複、形式の不統一への対処に加え、検証や変更記録も扱います。
主な機能
- 01欠損値の補完または削除
- 02外れ値の検出と処理
- 03データ型と形式の標準化
- 04重複データの削除
- 05正規化とスケーリング
- 06検証とクリーニングログ
活用シーン
- 01分析用の生データ準備
- 02モデリング用データセットの前処理
- 03自動クリーニングワークフローの構築
- 04変換後のデータ整合性確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ aj-geddes/ useful-ai-prompts --skill data-cleaning-pipelineインストール後、Claude Code で/data-cleaning-pipelineを入力して読み込まれたか確認します。
同梱ファイルtemplates/notebook-template.pyscripts/scaffold-analysis.sh
詳細
データクリーニングパイプライン
概要
データクリーニングパイプラインは、欠損値、外れ値、データ品質の問題を体系的に処理し、生データや不完全なデータを分析やモデリングに適した、クリーンで標準化された形式に変換します。
使用する場面
- 分析やモデリングに向けて生データセットを準備する
- 欠損値やデータ品質の問題に対処する
- 重複を削除し、形式を標準化する
- 外れ値を検出して処理する
- データの自動前処理ワークフローを構築する
- データの完全性と一貫性を確保する
主な構成要素
- 欠損値の処理:補完と削除の方針
- 外れ値の検出と処理:異常値の特定と処理
- データ型の標準化:正しいデータ型を確保する
- 重複の削除:重複を特定して削除する
- 正規化とスケーリング:値の範囲を標準化する
- テキストクリーニング:テキストデータを処理する
クリーニングの方針
- 削除:行または列を削除する
- 補完:平均値、中央値、または予測モデルで値を補う
- 変換:形式を変換する
- 検証:データ完全性のルールを満たしていることを確認する
Python での実装
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.impute import SimpleImputer, KNNImputer
# Load raw data
df = pd.read_csv('raw_data.csv')
# Step 1: Identify and handle missing values
print("Missing values:\n", df.isnull().sum())
# Strategy 1: Delete rows with critical missing values
df = df.dropna(subset=['customer_id', 'transaction_date'])
# Strategy 2: Impute numerical columns with median
imputer = SimpleImputer(strategy='median')
df['age'] = imputer.fit_transform(df[['age']])
# Strategy 3: Use KNN imputation for related features
knn_imputer = KNNImputer(n_neighbors=5)
numeric_cols = df.select_dtypes(include=[np.number]).columns
df[numeric_cols] = knn_imputer.fit_transform(df[numeric_cols])
# Strategy 4: Fill categorical with mode
df['category'] = df['category'].fillna(df['category'].mode()[0])
# Step 2: Handle duplicates
print(f"Duplicate rows: {df.duplicated().sum()}")
df = df.drop_duplicates()
# Duplicate on specific columns
df = df.drop_duplicates(subset=['customer_id', 'transaction_date'])
# Step 3: Outlier detection and handling
Q1 = df['amount'].quantile(0.25)
Q3 = df['amount'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# Remove outliers
df = df[(df['amount'] >= lower_bound) & (df['amount'] <= upper_bound)]
# Alternative: Cap outliers
df['amount'] = df['amount'].clip(lower=lower_bound, upper=upper_bound)
# Step 4: Data type standardization
df['transaction_date'] = pd.to_datetime(df['transaction_date'])
df['customer_id'] = df['customer_id'].astype('int64')
df['amount'] = pd.to_numeric(df['amount'], errors='coerce')
# Step 5: Text cleaning
df['name'] = df['name'].str.strip().str.lower()
df['name'] = df['name'].str.replace('[^a-z0-9\s]', '', regex=True)
# Step 6: Normalization and scaling
scaler = StandardScaler()
df[['age', 'income']] = scaler.fit_transform(df[['age', 'income']])
# MinMax scaling for bounded range [0, 1]
minmax_scaler = MinMaxScaler()
df[['score']] = minmax_scaler.fit_transform(df[['score']])
# Step 7: Create data quality report
def create_quality_report(df_original, df_cleaned):
report = {
'Original rows': len(df_original),
'Cleaned rows': len(df_cleaned),
'Rows removed': len(df_original) - len(df_cleaned),
'Removal percentage': ((len(df_original) - len(df_cleaned)) / len(df_original) * 100),
'Original missing': df_original.isnull().sum().sum(),
'Cleaned missing': df_cleaned.isnull().sum().sum(),
}
return pd.DataFrame(report, index=[0])
quality = create_quality_report(df, df)
print(quality)
# Step 8: Validation checks
assert df['age'].isnull().sum() == 0, "Age has missing values"
assert df['transaction_date'].dtype == 'datetime64[ns]', "Date not datetime"
assert (df['amount'] >= 0).all(), "Negative amounts detected"
print("Data cleaning pipeline completed successfully!")
パイプラインのアーキテクチャ
class DataCleaningPipeline:
def __init__(self):
self.cleaner_steps = []
def add_step(self, func, description):
self.cleaner_steps.append((func, description))
return self
def execute(self, df):
for func, desc in self.cleaner_steps:
print(f"Executing: {desc}")
df = func(df)
return df
# Usage
pipeline = DataCleaningPipeline()
pipeline.add_step(
lambda df: df.dropna(subset=['customer_id']),
"Remove rows with missing customer_id"
).add_step(
lambda df: df.drop_duplicates(),
"Remove duplicate rows"
).add_step(
lambda df: df[(df['amount'] > 0) & (df['amount'] < 100000)],
"Filter invalid amount ranges"
)
df_clean = pipeline.execute(df)
高度なクリーニング手法
# Step 9: Feature-specific cleaning
df['phone'] = df['phone'].str.replace(r'\D', '', regex=True) # Remove non-digits
# Step 10: Datetime handling
df['created_date'] = pd.to_datetime(df['created_date'], errors='coerce')
df['days_since_creation'] = (pd.Timestamp.now() - df['created_date']).dt.days
# Step 11: Categorical standardization
df['status'] = df['status'].str.lower().str.strip()
df['status'] = df['status'].replace({
'active': 'active',
'inactive': 'inactive',
'pending': 'pending',
})
# Step 12: Numeric constraint checking
df['age'] = df['age'].where((df['age'] >= 0) & (df['age'] <= 150), np.nan)
df['percentage'] = df['percentage'].where((df['percentage'] >= 0) & (df['percentage'] <= 100), np.nan)
# Step 13: Create data quality score
quality_score = {
'Missing %': (df.isnull().sum() / len(df) * 100).mean(),
'Duplicates %': (df.duplicated().sum() / len(df) * 100),
'Complete Features': (df.notna().sum() / len(df)).mean() * 100,
}
# Step 14: Generate cleaning report
cleaning_report = f"""
DATA CLEANING REPORT
====================
Rows removed: {len(df) - len(df_clean)}
Columns: {len(df_clean.columns)}
Remaining rows: {len(df_clean)}
Completeness: {(df_clean.notna().sum().sum() / (len(df_clean) * len(df_clean.columns)) * 100):.1f}%
"""
print(cleaning_report)
主な判断事項
- 欠損値にどのように対処するか(削除するか、補完するか)?
- どの外れ値が正当なビジネスケースに該当するか?
- 許容できる値の範囲はどれくらいか?
- どの重複が真の重複か?
- カテゴリ値をどのように標準化するか?
検証手順
- データ型の一貫性を確認する
- 値の範囲が妥当であることを検証する
- 意図しないデータ損失がないことを確認する
- 適用したすべての変換を記録する
- 変更の監査証跡を作成する
成果物
- 品質指標を含むクリーニング済みデータセット
- すべての手順を記録したデータクリーニングログ
- データの完全性を確認する検証レポート
- 変更前後の比較統計
- クリーニングコードとパイプラインのドキュメント
コメント
Markdown 対応