Exploratory Data Analysis について
データサイエンティストや分析担当者が、モデリング前にデータセットを調べるためのEDAスキルです。データの概要、分布、変数間の関係、異常、品質を扱い、発見事項や次の仮説の記録も案内します。
主な機能
- 01データ型と要約統計の確認
- 02変数分布の分析
- 03変数間の関係の探索
- 04異常とデータ品質問題の特定
- 05発見事項と仮説の記録
活用シーン
- 01分析前の新しいデータセットの確認
- 02モデリング前のデータ品質チェック
- 03検証する仮説の作成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ aj-geddes/ useful-ai-prompts --skill exploratory-data-analysisインストール後、Claude Code で/exploratory-data-analysisを入力して読み込まれたか確認します。
同梱ファイルtemplates/notebook-template.pyscripts/scaffold-analysis.sh
詳細
探索的データ分析(EDA)
概要
探索的データ分析(EDA)は、データサイエンスプロジェクトにおける重要な最初のステップです。正式なモデリングを行う前に、データセットを体系的に調べ、その特性を理解し、パターンを特定して、データ品質を評価します。
主な概念
- データプロファイリング:基本統計量とデータ型を把握します
- 分布分析:変数の分布を調べます
- 関係性の発見:変数間のパターンを特定します
- 異常検知:外れ値や異常なパターンを見つけます
- データ品質評価:完全性と一貫性を評価します
使用する場面
- 新しいデータセットの分析を始めるとき
- モデリングの前にデータを理解するとき
- データ品質の問題を特定するとき
- 検証する仮説を立てるとき
- ステークホルダーに知見を伝えるとき
Python での実装
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Load and explore data
df = pd.read_csv('customer_data.csv')
# Basic profiling
print(f"Shape: {df.shape}")
print(f"Data types:\n{df.dtypes}")
print(f"Missing values:\n{df.isnull().sum()}")
print(f"Duplicates: {df.duplicated().sum()}")
# Statistical summary
print(df.describe())
print(df.describe(include='object'))
# Distribution analysis - numerical columns
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
df['age'].hist(bins=30, ax=axes[0, 0])
axes[0, 0].set_title('Age Distribution')
df['income'].hist(bins=30, ax=axes[0, 1])
axes[0, 1].set_title('Income Distribution')
# Box plots for outlier detection
df.boxplot(column='age', by='region', ax=axes[1, 0])
axes[1, 0].set_title('Age by Region')
# Categorical analysis
df['category'].value_counts().plot(kind='bar', ax=axes[1, 1])
axes[1, 1].set_title('Category Distribution')
plt.tight_layout()
plt.show()
# Correlation analysis
numeric_df = df.select_dtypes(include=[np.number])
correlation_matrix = numeric_df.corr()
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Matrix')
plt.show()
# Multivariate relationships
sns.pairplot(df[['age', 'income', 'education_years']], diag_kind='hist')
plt.show()
# Skewness and kurtosis
print("\nSkewness:")
print(numeric_df.skew())
print("\nKurtosis:")
print(numeric_df.kurtosis())
# Percentile analysis
print("\nPercentiles for Age:")
print(df['age'].quantile([0.25, 0.5, 0.75, 0.95, 0.99]))
# Missing data patterns
missing_pct = (df.isnull().sum() / len(df) * 100)
missing_pct[missing_pct > 0].sort_values(ascending=False)
# Value count analysis
print("\nCustomer Types Distribution:")
print(df['customer_type'].value_counts(normalize=True))
# Advanced EDA: Groupby analysis
print("\nGroupBy Analysis:")
print(df.groupby('region')[['age', 'income']].agg(['mean', 'median', 'std']))
# Correlation with target variable
if 'target' in df.columns:
target_corr = df.corr()['target'].sort_values(ascending=False)
print("\nFeature Correlation with Target:")
print(target_corr)
# Data type breakdown
print("\nData Type Summary:")
print(df.dtypes.value_counts())
# Unique value count
print("\nUnique Value Counts:")
print(df.nunique().sort_values(ascending=False))
# Variance analysis
print("\nVariance per Feature:")
numeric_cols = df.select_dtypes(include=[np.number]).columns
for col in numeric_cols:
variance = df[col].var()
print(f" {col}: {variance:.2f}")
# Distribution patterns
for col in df.select_dtypes(include=[np.number]).columns:
skew = df[col].skew()
kurt = df[col].kurtosis()
print(f"{col} - Skew: {skew:.2f}, Kurtosis: {kurt:.2f}")
# Bivariate analysis
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
df.groupby('region')['income'].mean().plot(kind='bar', ax=axes[0])
axes[0].set_title('Average Income by Region')
df.groupby('category')['age'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('Average Age by Category')
plt.tight_layout()
plt.show()
# Summary statistics profile
print("\nComprehensive Data Profile:")
profile = {
'Variable': df.columns,
'Type': df.dtypes,
'Non-Null Count': df.count(),
'Null Count': df.isnull().sum(),
'Unique Values': df.nunique(),
}
profile_df = pd.DataFrame(profile)
print(profile_df)
高度な EDA 手法
# Step 15: Interaction analysis
import itertools
numeric_cols = df.select_dtypes(include=[np.number]).columns
interaction_strengths = []
for col1, col2 in itertools.combinations(numeric_cols[:5], 2):
interaction_score = abs(df[col1].corr(df[col2]))
interaction_strengths.append({
'Pair': f"{col1} × {col2}",
'Correlation': interaction_score,
})
interaction_df = pd.DataFrame(interaction_strengths).sort_values('Correlation', ascending=False)
print("\nTop Interactions:")
print(interaction_df.head())
# Step 16: Outlier summary
for col in numeric_cols:
Q1, Q3 = df[col].quantile([0.25, 0.75])
IQR = Q3 - Q1
outliers = df[(df[col] < Q1 - 1.5*IQR) | (df[col] > Q3 + 1.5*IQR)]
if len(outliers) > 0:
print(f"\n{col}: {len(outliers)} outliers detected ({len(outliers)/len(df)*100:.1f}%)")
# Step 17: Generate automated insights
print("\n" + "="*60)
print("AUTOMATED DATA INSIGHTS")
print("="*60)
for col in numeric_cols:
skewness = df[col].skew()
mean_val = df[col].mean()
median_val = df[col].median()
if abs(skewness) > 1:
direction = "right" if skewness > 0 else "left"
print(f"{col}: Highly {direction}-skewed distribution")
if abs(mean_val - median_val) > 0.1 * median_val:
print(f"{col}: Mean and median differ significantly")
print("="*60)
確認すべき主な質問
- データの次元と型はどのようなものですか?
- 主要な変数はどのように分布していますか?
- 変数間にはどのようなパターンがありますか?
- 明らかなデータ品質の問題はありますか?
- どのような外れ値や異常がありますか?
- どのような仮説を立てられますか?
ベストプラクティス
- 可視化の前にデータプロファイリングを行います
- 早い段階でデータ型と欠損値を確認します
- 分析に進む前に分布を可視化します
- 興味深い発見や異常を記録します
- ステークホルダーとの共有用に要約を作成します
- パターンの解釈にはドメイン知識を活用します
よくある落とし穴
- データ品質の確認を省略する
- 小規模なデータセットのパターンを過剰に解釈する
- ドメインの文脈を無視する
- データの可視化が不十分である
- 発見を体系的に記録しない
成果物
- 欠損値と重複を含むデータ品質レポート
- 要約統計量と分布グラフ
- 相関と関係性の可視化
- 注目すべきパターンと異常の一覧
- さらなる調査に向けた仮説
- データクリーニングの推奨事項
コメント
Markdown 対応