ExploratoryDataAnalysisSkill ExploratoryDataAnalysis

探索性数据分析(EDA)是一种系统性的数据检查过程,用于在正式建模前理解数据集的特性,识别数据中的模式,并评估数据质量。关键环节包括数据剖析、分布分析、关系发现、异常值检测和数据质量评估。

数据分析 0 次安装 0 次浏览 更新于 3/3/2026

探索性数据分析(EDA)

探索性数据分析 (EDA)

概览

探索性数据分析(EDA)是数据科学项目中至关重要的第一步,系统地检查数据集以了解它们的特性,识别模式,并在正式建模前评估数据质量。

核心概念

  • 数据剖析:理解基本统计和数据类型
  • 分布分析:检查变量的分布情况
  • 关系发现:识别变量之间的模式
  • 异常值检测:寻找异常值和不寻常的模式
  • 数据质量评估:评估完整性和一致性

使用场景

  • 开始新的数据集分析
  • 在建模前理解数据
  • 识别数据质量问题
  • 为测试生成假设
  • 向利益相关者传达洞察

使用Python实现

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 加载和探索数据
df = pd.read_csv('customer_data.csv')

# 基本剖析
print(f"形状:{df.shape}")
print(f"数据类型:
{df.dtypes}")
print(f"缺失值:
{df.isnull().sum()}")
print(f"重复项:{df.duplicated().sum()}")

# 统计总结
print(df.describe())
print(df.describe(include='object'))

# 分布分析 - 数值列
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
df['age'].hist(bins=30, ax=axes[0, 0])
axes[0, 0].set_title('年龄分布')

df['income'].hist(bins=30, ax=axes[0, 1])
axes[0, 1].set_title('收入分布')

# 箱线图用于异常值检测
df.boxplot(column='age', by='region', ax=axes[1, 0])
axes[1, 0].set_title('按地区分的年龄')

# 分类分析
df['category'].value_counts().plot(kind='bar', ax=axes[1, 1])
axes[1, 1].set_title('类别分布')
plt.tight_layout()
plt.show()

# 相关性分析
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('相关性矩阵')
plt.show()

# 多变量关系
sns.pairplot(df[['age', 'income', 'education_years']], diag_kind='hist')
plt.show()

# 偏度和峰度
print("
偏度:")
print(numeric_df.skew())
print("
峰度:")
print(numeric_df.kurtosis())

# 百分位数分析
print("
年龄的百分位数:")
print(df['age'].quantile([0.25, 0.5, 0.75, 0.95, 0.99]))

# 缺失数据模式
missing_pct = (df.isnull().sum() / len(df) * 100)
missing_pct[missing_pct > 0].sort_values(ascending=False)

# 值计数分析
print("
客户类型分布:")
print(df['customer_type'].value_counts(normalize=True))

# 高级EDA:分组分析
print("
分组分析:")
print(df.groupby('region')[['age', 'income']].agg(['mean', 'median', 'std']))

# 与目标变量的相关性
if 'target' in df.columns:
    target_corr = df.corr()['target'].sort_values(ascending=False)
    print("
特征与目标的相关性:")
    print(target_corr)

# 数据类型分解
print("
数据类型总结:")
print(df.dtypes.value_counts())

# 唯一值计数
print("
唯一值计数:")
print(df.nunique().sort_values(ascending=False))

# 方差分析
print("
每个特征的方差:")
numeric_cols = df.select_dtypes(include=[np.number]).columns
for col in numeric_cols:
    variance = df[col].var()
    print(f"  {col}: {variance:.2f}")

# 分布模式
for col in df.select_dtypes(include=[np.number]).columns:
    skew = df[col].skew()
    kurt = df[col].kurtosis()
    print(f"{col} - 偏度:{skew:.2f}, 峰度:{kurt:.2f}")

# 双变量分析
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
df.groupby('region')['income'].mean().plot(kind='bar', ax=axes[0])
axes[0].set_title('按地区分的平均收入')
df.groupby('category')['age'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('按类别分的平均年龄')
plt.tight_layout()
plt.show()

# 综合数据剖析
print("
综合数据剖析:")
profile = {
    '变量': df.columns,
    '类型': df.dtypes,
    '非空计数': df.count(),
    '空计数': df.isnull().sum(),
    '唯一值': df.nunique(),
}
profile_df = pd.DataFrame(profile)
print(profile_df)

高级EDA技术

# 步骤15:交互分析
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({
        '对': f"{col1} × {col2}",
        '相关性': interaction_score,
    })

interaction_df = pd.DataFrame(interaction_strengths).sort_values('相关性', ascending=False)
print("
顶级交互:")
print(interaction_df.head())

# 步骤16:异常值总结
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"
{col}: 检测到{len(outliers)}个异常值({len(outliers)/len(df)*100:.1f}%)")

# 步骤17:生成自动化洞察
print("
" + "="*60)
print("自动化数据洞察")
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 = "右" if skewness > 0 else "左"
        print(f"{col}: 分布高度{direction}偏斜")

    if abs(mean_val - median_val) > 0.1 * median_val:
        print(f"{col}: 均值和中位数差异显著")

print("="*60)

需要问的关键问题

  1. 数据的维度和类型是什么?
  2. 关键变量的分布如何?
  3. 变量之间存在什么模式?
  4. 是否有明显的数据质量问题?
  5. 存在哪些异常值或异常?
  6. 我们可以生成哪些假设?

最佳实践

  • 在可视化之前先进行数据剖析
  • 提早检查数据类型和缺失值
  • 在分析前先可视化分布
  • 记录有趣的发现和异常
  • 为利益相关者沟通创建摘要
  • 使用领域知识解释模式

常见陷阱

  • 跳过数据质量检查
  • 在小数据集中过度解释模式
  • 忽略领域背景
  • 可视化数据不足
  • 未系统记录发现

交付物

  • 包含缺失值和重复项的数据质量报告
  • 统计总结和分布图表
  • 相关性和关系可视化
  • 显著模式和异常列表
  • 进一步调查的假设
  • 数据清洗建议