3、数据探索性分析(EDA):描述性统计、数据分布可视化、相关性分析

数据拿到手,别急着建模。

这是我踩过无数次坑之后,最想对你说的一句话。你想想看,一堆数据扔过来,连它长什么样、有没有异常、变量之间什么关系都不清楚,直接上模型,结果多半是灾难。

EDA,说白了就是给数据做体检。我习惯把它分成三步走:先看描述性统计,再画分布图,最后做相关性分析。这三板斧抡下来,数据的基本盘就摸透了。

3.1 描述性统计:先摸清数据的底细

描述性统计是最基础的一步。它回答几个核心问题:数据集中趋势如何?离散程度多大?有没有缺失值?

我个人习惯用 pandasdescribe() 方法,一行代码就能看到均值、标准差、四分位数等关键指标。

import pandas as pd

# 加载数据
df = pd.read_csv('sales_data.csv')

# 描述性统计
print(df.describe())

输出结果长这样:

指标 销售额 客户年龄 购买次数
count 1000 1000 1000
mean 256.3 34.5 12.1
std 89.2 12.3 8.7
min 0.0 18.0 1.0
25% 180.0 25.0 5.0
50% 250.0 32.0 10.0
75% 320.0 42.0 18.0
max 9999.0 120.0 99.0

关键点:看到 max 值了吗?销售额最大是 9999,而 75% 分位数才 320。这明显是异常值。我在项目中遇到过类似情况,后来发现是某个促销活动期间的数据录入错误。

除了 describe(),我还会单独检查缺失值:

# 检查缺失值
print(df.isnull().sum())

小技巧:缺失值比例超过 30% 的列,我一般直接删除。低于 5% 的,用均值或中位数填充。中间那档,得看业务场景决定。

3.2 数据分布可视化:一图胜千言

描述性统计只能给你数字,但数字有时候会骗人。举个例子,两组数据的均值和标准差可能完全一样,但分布形态天差地别。这就是安斯库姆四重奏告诉我们的道理。

所以,一定要画图。

3.2.1 直方图与箱线图

直方图看分布形态,箱线图看异常值。这两个是黄金搭档。

import matplotlib.pyplot as plt
import seaborn as sns

# 直方图
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
sns.histplot(df['销售额'], bins=30, kde=True)
plt.title('销售额分布')

# 箱线图
plt.subplot(1, 2, 2)
sns.boxplot(y=df['销售额'])
plt.title('销售额箱线图')

plt.tight_layout()
plt.show()

直方图里如果出现长尾,说明数据右偏。箱线图里那些小圆点,就是异常值。嗯,这里要注意:异常值不一定是错误,可能是真实的极端情况。我曾经处理过一份金融数据,那些「异常值」其实是高净值客户的交易记录,删掉反而会丢失重要信息。

3.2.2 分类变量的分布

对于分类变量,用柱状图或者饼图。我更喜欢柱状图,因为饼图在类别多的时候根本看不清。

# 分类变量分布
sns.countplot(x='地区', data=df)
plt.title('各地区客户数量')
plt.show()

避坑指南:我曾经在分析用户画像时,发现某个地区的客户数量异常少。一开始以为是数据采集问题,后来才发现是那个地区的业务员根本没录入数据。所以,分布图不仅能看数据,还能反推数据质量。

3.3 相关性分析:变量之间的悄悄话

变量之间有没有关系?是正相关还是负相关?强度如何?这是相关性分析要回答的问题。

3.3.1 皮尔逊相关系数

最常用的是皮尔逊相关系数,取值范围 [-1, 1]。0.8 以上算强相关,0.3 以下算弱相关。

# 计算相关系数矩阵
corr_matrix = df.corr()
print(corr_matrix)

输出示例:

销售额 客户年龄 购买次数
销售额 1.00 0.12 0.85
客户年龄 0.12 1.00 0.08
购买次数 0.85 0.08 1.00

看到没?销售额和购买次数的相关系数是 0.85,强相关。这符合直觉:买得越多,销售额越高。但客户年龄和销售额只有 0.12,基本没关系。

3.3.2 热力图可视化

数字矩阵看着累,热力图就直观多了。

# 热力图
plt.figure(figsize=(8, 6))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('相关性热力图')
plt.show()

颜色越深,相关性越强。红色代表正相关,蓝色代表负相关。一眼就能看出哪些变量是「铁哥们」,哪些是「陌生人」。

重要提醒:相关性不等于因果性。我见过太多人看到两个变量相关,就以为一个导致另一个。比如冰淇淋销量和溺水人数正相关,但真正的原因是夏天到了。所以,相关性分析只是线索,不是结论。

3.3.3 散点图矩阵

当变量比较多的时候,散点图矩阵能一次性展示所有两两关系。

# 散点图矩阵
sns.pairplot(df[['销售额', '客户年龄', '购买次数', '客单价']])
plt.show()

对角线是分布图,非对角线是散点图。如果某个散点图呈现出明显的线性趋势,那这两个变量大概率有故事。

3.4 EDA 知识体系总览

下面这张图,是我自己总结的 EDA 核心流程。每次做数据分析前,我都会对照着走一遍。

数据探索性分析(EDA)知识体系 EDA 三大核心 描述性统计 集中趋势(均值、中位数) 离散程度(标准差、IQR) 缺失值检查 数据分布可视化 直方图 + KDE 箱线图(异常值检测) 分类变量柱状图 相关性分析 注:三大步骤按顺序执行,但实际分析中可能需要反复迭代

这张图把 EDA 的三大块串起来了。从左到右,从上到下,每一步都有对应的工具和方法。你照着这个框架走,基本不会漏掉关键信息。

我的习惯:每次做完 EDA,我都会写一个简短的总结文档,记录发现了什么异常、哪些变量值得深挖、数据质量如何。这个文档后面建模的时候会反复用到,省得回头再查。

好了,EDA 的核心内容就这些。说白了,就是让你和数据建立「亲密关系」。你越了解它,它就越不会在建模的时候给你挖坑。

专注资料整理