第3章 数据探索
3.1 数据质量分析
数据质量分析是数据预处理的前提,也是数据挖掘分析结论有效性和准确性的基础。其主要任务是检查原始数据中是否存在脏数据:
(1)缺失值
(2)异常值(outliers)
(3)不一致的值
(4)重复数据及含有特殊符号的数据
3.1.1 缺失值分析
3.1.2 异常值分析
异常值是指样本中数值明显偏离其余观测值的个别值,也称为离群点。
(1)简单统计量分析
先对变量做描述性统计,检查数据是否合理。常用的统计量是最大、最小值。
(2) 3 σ 3\sigma 3σ原则
若数据服从正态分布,根据 3 σ 3\sigma 3σ原则,异常值定义为一组测量值中与均值偏差超过3倍标准差的值。由正态分布假设可知,与均值距离大于 3 σ 3\sigma 3σ的值出现概率为 P ( ∣ x − μ ∣ > 3 σ ) ≤ 0.003 P(|x - \mu| > 3 \sigma) \leq 0.003 P(∣x−μ∣>3σ)≤0.003,属于极小概率事件。
若数据不服从正态分布,可用远离均值的 n n n倍标准差描述。
(3)箱型图分析
异常值通常定义为小于 Q L − 1.5 I Q R Q_L - 1.5 IQR QL−1.5IQR或大于 Q U + 1.5 I Q R Q_U + 1.5 IQR QU+1.5IQR。
Q L Q_L QL:下四分位数,全部观察值中有四分之一的数据取值比它小;
Q U Q_U QU:上四分位数,全部观察值中有四分之一的数据取值比它大;
I Q R IQR IQR:四分位数间距,上四分位数 Q U Q_U QU与下四分位数 Q L Q_L QL之差,包含全部观察值的一半
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
data = pd.read_excel("../data/catering_sale.xls", index_col=u"日期", header=0)
print(data.describe())
print(data.head())
print("data size: {}".format(data.shape))
fig = plt.figure()
ax = fig.add_subplot(111)
p = data.plot(ax=ax, kind="box", return_type="dict")
plt.show()
x = p["fliers"][0].get_xdata()
y = p["fliers"][0].get_ydata()
y.sort()
销量
count 200.000000
mean 2755.214700
std 751.029772
min 22.000000
25% 2451.975000
50% 2655.850000
75% 3026.125000
max 9106.440000
销量
日期
2015-03-01 51.0
2015-02-28 2618.2
2015-02-27 2608.4
2015-02-26 2651.9
2015-02-25 3442.1
data size: (201, 1)
# Listing 3-1 餐饮销售额数据异常值检测
# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"] # 显示中文字体
plt.rcParams["axes.unicode_minus"] = False # 显示负号
catering_sale = r"../data/catering_sale.xls" # 餐饮数据
data = pd.read_excel(catering_sale, index_col="日期", header=0) # 读取数据,指定“日期”为索引
plt.figure()
p = data.plot.box(return_type='dict')
x = p["fliers"][0].get_xdata() # flier:异常值标签
y = p["fliers"][0].get_ydata()
y.sort()
# annotate添加注释
for i in range(len(x)):
if i > 0:
plt.annotate(y[i], xy=(x[i], y[i]),
xytext=(x[i] + 0.05 - 0.8 / (y[i] - y[i - 1]), y[i]))
else:
plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.08, y[i]))
plt.show()
<Figure size 432x288 with 0 Axes>
该例中,865、4060.3、4065.2可归为正常值;22、51、60、6607.4、9106.44归为异常值。
3.1.3 一致性分析
数据不一致是指数据中存在矛盾、不相容。
3.2 数据特征分析
3.2.1 分布分析
定量数据:频率分布表、频路分布直方图、茎叶图
定性分类数据:饼图、条形图
1. 定量数据的分布分析
选择“组数”和“组宽”
(1)求极差
(2)确定组距与组数
(3)确定分点
(4)列出频率分布表
(5)绘制频率分布直方图
主要原则:
(1)各组间互斥
(2)各组必须包含所有数据
(3)各组组宽相等
例:菜品“捞起生鱼片”销售数据
df_data = pd.read_excel("../data/catering_fish_congee.xls",
header=None,
index_col=0)
print(df_data.describe())
print("data size: {}".format(df_data.shape))
1
count 91.000000
mean 1232.307692
std 940.025008
min 45.000000
25% 420.000000
50% 900.000000
75% 1785.000000
max 3960.000000
data size: (91, 1)
# (1)求极差
# 极差 = 最大值 - 最小值
data_range = (df_data.max() - df_data.min())[1]
print("极差:{}".format(data_range))
# (2)分组
# 组数 = 极差 / 组距
class_interval = 500
class_num = data_range / class_interval
print("组数:{},组距:{}".format(class_num, class_interval))
# (3)确定分点
splits = np.arange(start=0, stop=4500, step=500)
print("分点:{}".format(splits))
# (4)列出频率分布表
dict_bars = {
}
for idx in range(len(splits) - 1):
# dict_bars["{}-{}".format(splits[idx], splits[idx + 1])] = \
# len(df_data[df_data >= splits[idx]].dropna()
# [df_data < splits[idx + 1]].dropna())
dict_bars["{}-{}".format(splits[idx], splits[idx + 1])] = \
len(df_data[(df_data[1] >= splits[idx]) & (df_data[1] < splits[idx + 1])])
df_bars = pd.Series(data=dict_bars) / len(df_data)
print("*" * 10)
print(df_bars.describe())
print("*" * 10)
print("频率分布表:\n{}".format(df_bars))
# (4)绘制频率分布直方图
fig = plt.figure()
ax = fig.add_subplot(111)
df_bars.plot.bar(ax=ax)
plt.xticks(rotation=45)
plt.show()
极差:3915
组数:7.83,组距:500
分点:[ 0 500 1000 1500 2000 2500 3000 3500 4000]
**********
count 8.000000
mean 0.125000
std 0.101047
min 0.032967
25% 0.041209
50% 0.109890
75% 0.153846
max 0.318681
dtype: float64
**********
频率分布表:
0-500 0.318681
500-1000 0.219780
1000-1500 0.131868
1500-2000 0.131868
2000-2500 0.087912
2500-3000 0.032967
3000-3500 0.043956
3500-4000 0.032967
dtype: float64
2. 定性数据分布分析
对于定性变量,常根据变量的分类类型进行分组,可以采用饼图和条形图描述定性变量的分布。
fig = plt.figure(figsize=(10, 4))
ax = fig.add_subplot(121)
df_bars.plot.pie(ax=ax)
ax.set_title("pie chart")
ax = fig.add_subplot(122)
df_bars.plot.bar