#导入本节需要的包
import pandas as pd
import numpy as np
import random as rnd
import seaborn as sns
import matplotlib.pyplot as plt
import random
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
数据质量分析
- 数据质量分析:其主要任务是检查原始数据中是否存在脏数据。
-
脏数据:不符合要求,以及不能直接进行相应分析的数据。在常见的数据挖掘工作中,脏数据包括如下内容。
- 缺失值。
- 异常值。
- 不一致的值。
- 重复数据及含有特殊符号(如#、¥、*)的数据。
缺失值分析
-
缺失值产生的原因
- 有些信息暂时无法获取,或者获取信息的代价太大。
- 有些信息是被遗漏的。可能是因为输人时认为不重要、忘记填写或对数据理解错误等一些人为因素而遗漏,也可能是由于数据采集设备的故障、存储介质的故障、传输媒体的故障等非,人为原因而丢失。
- 属性值不存在。在某些情况下,缺失值并不意味着数据有错误。对一些对象来说某些属性值是不存在的,如一个未婚者的配偶姓名、一个儿童的固定收入等。
-
缺失值的影响
- 数据挖掘建模将丢失大量的有用信息。
- 数据挖掘模型所表现出的不确定性更加显著,模型中蕴涵的规律更难把握。
- 包含空值的数据会使建模过程陷人混乱,导致不可靠的输出。
- 缺失值的分析
使用简单的统计分析,可以得到含有缺失值的属性的个数,以及每个属性的未缺失数、缺失数与缺失率等。
从总体上来说,缺失值的处理分为删除存在缺失值的记录、对可能值进行插补和不处理3种情况。
异常值分析
异常值分析是检验数据是否有录入错误以及含有不合常理的数据。异常值是指样本中的个别值,其数值明显偏离其余的观测值。异常值也称为离群点,异常值的分析也称为离群点分析。以下是异常值分析的常用方法:
简单统计量分析
可以先对变量做一个描述性统计,进而查看哪些数据是不合理的。最常用的统计量是最大值和最小值,用来判断这个变量的取值是否超出了合理的范围。如客户年龄的最大值为199岁,则该变量的取值存在异常。
$3\sigma$原则
如果数据服从正态分布,在$3\sigma$原则下,异常值被定义为一组测定值中与平均值的偏差超过3倍标准差的值。在正态分布的假设下,距离平均值$3\sigma$之外的值出现的概率为$P(|x-\mu|>3\sigma)≤0.003$,属于极个别的小概率事件。3
箱型图分析
箱型图提供了识别异常值的一个标准:异常值通常被定义为小于$Q_L-1.5IQR$或大于$Q_U+1.5IQR$的值。
- $Q_L$:下四分位数,表示全部观察值中有四分之一的数据取值比它小;
- $Q_U$:上四分位数,表示全部观察值中有四分之--的数据取值比它大;
- $IQR$:四分位数间距,是上四分位数$Q_U$与下四分位数$Q_L$之差,其间包含了全部观察值的一半。
箱线图法特点
- 对数据分布无要求
- 鲁棒性强:多达25%的数据可以变得任意远而不会很大地扰动四分位数。
箱线图法实例
data = pd.read_excel('Python数据分析与挖掘实战/chapter3/demo/data/catering_sale.xls',encoding='utf-8')
data.head(3)
日期 | 销量 | |
---|---|---|
0 | 2015-03-01 | 51.0 |
1 | 2015-02-28 | 2618.2 |
2 | 2015-02-27 | 2608.4 |
从下面可以看出,数据共201行,但count只有200,说明有一行缺失。
data.shape
(201, 2)
data.describe().T
count | mean | std | min | 25% | 50% | 75% | max | |
---|---|---|---|---|---|---|---|---|
销量 | 200.0 | 2755.2147 | 751.029772 | 22.0 | 2451.975 | 2655.85 | 3026.125 | 9106.44 |
以下是使用箱线图检测异常值的代码:
plt.figure(figsize=(8,8),dpi=80)
p = data.boxplot(return_type='dict')
x = p['fliers'][0].get_xdata()
y = p['fliers'][0].get_ydata()
y.sort()
for i in range(len(y)):
plt.annotate(y[i],xy=(x[i],y[i]),xytext=(x[i]+0.05 -1.4/(y[i]-y[i-1]),y[i]+100))
- $plt.annotate(s,xy=(x,y),xytext=(a,b))$用于给图片上的点添加注释
$s$:注释的内容
$xy$:被注释点的坐标
$xytext$:注释文本的坐标
箱型图中的超过上下界的8个销售额数据可能为异常值。结合具体业务可以把865、4060.3、4065.2归为正常值,将22、51.60、6607.4、9106.44归为异常值。最后确定过滤规则为:日销量在400以下5000以上则属于异常数据,编写过滤程序,进行后续处理。
一致性分析
- 数据不一致性:指数据的矛盾性、不相容性。
直接对不一致的数据进行挖掘,可能会产生与实际相违背的挖掘结果。在数据挖掘过程中,不--致数据的产生主要发生在数据集成的过程中,这可能是由于被挖掘数据是来自于不同的数据源、对于重复存放的数据未能进行一致性更新造成的。例如,两张表中都存储了用户的电话号码,但在用户的电话号码发生改变时只更新了一张表中的数据,那么这两张表中就有了不一致的数据。
数据特征分析
对数据进行质量分析以后,接下来可通过绘制图表、计算某些特征量等手段进行数据的特征分析。
分布分析
- 分布分析:揭示数据分布类型及特点。
数值型变量的分布分析
通常情况下,使用频率分布直方图来描述定量数据的分布。
data = pd.read_excel('Python数据分析与挖掘实战/chapter3/demo/data/catering_fish_congee.xls',names=['日期','销售额'])
data.head(3)
日期 | 销售额 | |
---|---|---|
0 | 2014-04-02 | 900 |
1 | 2014-04-03 | 1290 |
2 | 2014-04-04 | 420 |
sns.distplot(data['销售额'])
plt.xlim(0,4500)
分类型变量的分布分析
data = pd.read_excel('Python数据分析与挖掘实战/chapter3/demo/data/catering_dish_profit.xls')
data.head()
菜品ID | 菜品名 | 盈利 | |
---|---|---|---|
0 | 17148 | A1 | 9173 |
1 | 17154 | A2 | 5729 |
2 | 109 | A3 | 4811 |
3 | 117 | A4 | 3594 |
4 | 17151 | A5 | 3195 |
f,axes = plt.subplots(1,2,figsize=(12,5))
axes[0].pie(data['盈利'],labels=data['菜品名'],autopct=lambda x:str(round(x,2))+'%',)
sns.barplot(data['菜品名'],data['盈利'])
对比分析
- 对比分析:把两个相互联系的指标进行比较,从数量上展示和说明研究对象规模的大小,水平的高低,速度的快慢,以及各种关系是否协调。
对比分析特别适用于指标间的横纵向比较、时间序列的比较分析。在对比分析中,选择合适的对比标准是十分关键的步骤,只有选择合适,才能做出客观的评价,选择不合适,评价可能得出错误的结论。对比分析主要有绝对数对比、相对数对比两种对比方式。
- 绝对数对比
对比的对象为绝对数。
- 相对数对比
对比对象为相对数,有以下几种:
1.结构相对数:将同一总体内的部分数值与全部数值对比求得比重,用以说明事物的性质、结构或质量。如居民食品支出额占消费支出总额比重、产品合格率等。
2.比例相对数:将同一总体内不同部分的数值进行对比,表明总体内各部分的比例关系。如人口性别比例、投资与消费比例等。
3.比较相对数:将同--时期两个性质相同的指标数值进行对比,说明同类现象在不同空间条件下的数量对比关系。如不同地区商品价格对比,不同行业、不同企业间某项指标对比等。
4.强度相对数:将两个性质不同但有--定联系的总量指标进行对比,用以说明现象的强度、密度和普遍程度。如人均国内生产总值用“元/人”表示,人口密度用“人/平方公里”表示。
5.计划完成程度相对数:是某一时期实际完成数与计划数的对比,用以说明计划完成程度。
6.动态相对数:将同一现象在不同时期的指标数值进行对比,用以说明发展方向和变化的速度。如发展速度、增长速度等。
就各菜品的销售数据来看,从时间的维度上分析,可以看到甜品部A、海鲜部B、素菜部C三个部门之间的销售金额随时间的变化趋势,可以了解在此期间哪个部门的销售金额较高,趋势比较平稳,如图所示:
data = pd.read_excel('Python数据分析与挖掘实战/chapter3/demo/data/dish_sale.xls')
data.T
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
月份 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 |
A部门 | 8 | 6 | 6.89 | 6.1 | 6.05 | 6.01 | 6.6 | 6.4 | 5.8 | 6.7 | 6.6 | 5.3 |
B部门 | 7.7 | 6.5 | 7.9 | 7.5 | 8 | 7.4 | 7.5 | 7 | 7.2 | 6.6 | 6.65 | 5.4 |
C部门 | 5.3 | 5.2 | 5.8 | 6.2 | 5.9 | 5.5 | 6.1 | 5.7 | 5.4 | 5.5 | 5.6 | 5.2 |
plt.figure(figsize=(8,4),dpi=100)
plt.plot(data['月份'],data['A部门'],label='A部门')
plt.plot(data['月份'],data['B部门'],label='B部门')
plt.plot(data['月份'],data['C部门'],label='C部门')
plt.legend()
plt.ylim(2,10)
label = plt.ylabel('销售额(万元)')
title = plt.title('三部门销售额对比')
可以看出,三部门的销售额呈递减趋势,其中B部门连续递减的趋势最为明显,可能是原材料不足导致的。
对B部门销售额做进一步分析,对比其三年的销售额,如下所示,可以看出13年14年销售额类似且明显大于12年,且三年销售额均在春夏季增长,秋冬季下降,具有明显的季节性。
data = pd.read_excel('Python数据分析与挖掘实战/chapter3/demo/data/dish_sale_b.xls')
data.T
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
月份 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 |
2014年 | 7.9 | 6 | 6.89 | 7.3 | 7.6 | 7.2 | 7.4 | 7.8 | 7 | 6.7 | 6.6 | 6.3 |
2013年 | 7.7 | 6.5 | 7.9 | 7.5 | 8 | 7.4 | 7.5 | 7 | 7.2 | 6.6 | 6.65 | 6.4 |
2012年 | 5.3 | 5.2 | 5.8 | 6.2 | 5.9 | 5.5 | 6.1 | 5.7 | 5.4 | 5.5 | 5.6 | 5.2 |
plt.figure(figsize=(8,4),dpi=100)
plt.plot(data['月份'],data['2012年'],label='2012年')
plt.plot(data['月份'],data['2013年'],label='2013年')
plt.plot(data['月份'],data['2014年'],label='2014年')
plt.legend()
plt.ylim(2,10)
label = plt.ylabel('销售额(万元)')
title = plt.title('B部门三年销售额对比')
统计量分析
- 集中趋势:均值、中位数、众数
- 离散趋势:极差、方差、变异系数、四分位数间距
周期分析
周期性分析是探索某个变量是否随着时间变化而呈现出某种周期变化趋势。时间尺度相对较长的周期性趋势有年度周期性趋势、季节性周期趋势,相对较短的有月度周期性趋势、周度周期性趋势,其至更短的天、小时周期性趋势。
如下所示是窃电用户与正常用户用电量的周期变化趋势,可以看出,用电量周期性波谷是周末休息导致的。
data_normal = pd.read_csv('Python数据分析与挖掘实战/chapter3/demo/data/user.csv')
data_steal = pd.read_csv('Python数据分析与挖掘实战/chapter3/demo/data/Steal user.csv')
plt.figure(figsize=(8,4),dpi=100)
plt.plot(data_normal['Date'],data_normal['Eletricity'],label='正常用户')
plt.plot(data_steal['Date'],data_steal['Eletricity'],label='窃电用户')
x_major_locator = plt.MultipleLocator(7)
ax = plt.gca()
ax.xaxis.set_major_locator(x_major_locator)
plt.legend()
x_tick = plt.xticks(rotation=45)
贡献度分析
贡献度分析又称帕累托分析,它的原理是帕累托法则,又称20/80定律。同样的投入放在不同的地方会产生不同的效益。例如,对一个公司来讲,80%的利润常常来自于20%最畅销的产品,而其他80%的产品只产生了20%的利润。
data = pd.read_excel('Python数据分析与挖掘实战/chapter3/demo/data/商品销售数据.xlsx')
data.head()
日期(年月日) | 城市 | 门店名称 | 省份 | 单据编码 | 商品类别 | 商品名称 | 销售额 | |
---|---|---|---|---|---|---|---|---|
0 | 2018-01-01 | 白山市 | 白山店 | 吉林省 | SMDBJ18000010 | 日用品 | 微爽日用245mm | 1,076.92 |
1 | 2018-01-01 | 鹤岗市 | 鹤岗店 | 黑龙江省 | SMDBJ18000014 | 零食 | 三全960g奶香馒头 | 2,461.54 |
2 | 2018-01-01 | 鹤岗市 | 鹤岗店 | 黑龙江省 | SMDBJ18000014 | 零食 | 嘉士利115g威化饼 | 3,119.66 |
3 | 2018-01-01 | 辽源市 | 辽源店 | 吉林省 | SMDBJ18000015 | 零食 | 三全960g奶香馒头 | 4,102.56 |
4 | 2018-01-01 | 辽源市 | 辽源店 | 吉林省 | SMDBJ18000015 | 零食 | 丽芝士散装系列 | 2,948.72 |
#data['销售额'] = pd.to_numeric(data['销售额'].apply(lambda x:x.replace(',','')))
grouped = data[['商品名称','销售额']].groupby('商品名称',as_index=False).sum().sort_values('销售额',ascending=False).reset_index(drop=True)
fig,axes = plt.subplots(figsize=(12,6),dpi=100)
p = grouped['销售额'].cumsum()/grouped['销售额'].sum()
sns.barplot(grouped['商品名称'],grouped['销售额'],ax=axes)
ax2 = axes.twinx()
ax2.plot(grouped['商品名称'],p,color='m',marker='o')
plt.annotate('80%',(grouped['商品名称'][10],p[10]),xytext=(grouped['商品名称'][10],0.9),arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
for xtick in axes.get_xticklabels():
xtick.set_rotation(80)
如上图所示,前11种商品占到了销售额的80%,应当增加这几类商品的投入以获得更高营业额。
相关性分析
绘制散点图
绘制散点图矩阵
需要同时考察多个变量间的相关关系时,一一绘制它们间的简单散点图是十分麻烦的。此时可利用散点图矩阵同时绘制各变量间的散点图,从而快速发现多个变量间的主要相关性,这在进行多元线性回归时显得尤为重要。
df = pd.read_csv('Python数据分析与挖掘实战/chapter3/demo/data/iris.data',names = ['sepal length','sepal width',
'petal length', 'petal width','Class'])
df.head()
sepal length | sepal width | petal length | petal width | Class | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
p=sns.pairplot(df)
相关系数的计算
- 皮尔逊相关系数:描述两统计量之间的线性相关关系。
$$\rho=\frac{cov(X,Y)}{\sqrt{DXDY}}$$
- Spearman秩相关系数
$$r_s=1-\frac{6\sum(R_i-Q_i)^2}{n(n^2-1)}$$
$R_i,Q_i$分别为两变量对应值从小到大排序的序数。
- 可决系数
$$R^2=1-\frac{\sum(y_i-\hat y_i)^2}{\sum(y_i-\bar y)^2}$$
可决系数描述的是回归方程对因变量的解释程度,分母为总偏差分子为随机偏差。
data = pd.read_excel('Python数据分析与挖掘实战/chapter3/demo/data/catering_sale_all.xls')
data.head()
日期 | 百合酱蒸凤爪 | 翡翠蒸香茜饺 | 金银蒜汁蒸排骨 | 乐膳真味鸡 | 蜜汁焗餐包 | 生炒菜心 | 铁板酸菜豆腐 | 香煎韭菜饺 | 香煎罗卜糕 | 原汁原味菜心 | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2015-01-01 | 17 | 6 | 8 | 24 | 13.0 | 13 | 18 | 10 | 10 | 27 |
1 | 2015-01-02 | 11 | 15 | 14 | 13 | 9.0 | 10 | 19 | 13 | 14 | 13 |
2 | 2015-01-03 | 10 | 8 | 12 | 13 | 8.0 | 3 | 7 | 11 | 10 | 9 |
3 | 2015-01-04 | 9 | 6 | 6 | 3 | 10.0 | 9 | 9 | 13 | 14 | 13 |
4 | 2015-01-05 | 4 | 10 | 13 | 8 | 12.0 | 10 | 17 | 11 | 13 | 14 |
data.corr()
百合酱蒸凤爪 | 翡翠蒸香茜饺 | 金银蒜汁蒸排骨 | 乐膳真味鸡 | 蜜汁焗餐包 | 生炒菜心 | 铁板酸菜豆腐 | 香煎韭菜饺 | 香煎罗卜糕 | 原汁原味菜心 | |
---|---|---|---|---|---|---|---|---|---|---|
百合酱蒸凤爪 | 1.000000 | 0.009206 | 0.016799 | 0.455638 | 0.098085 | 0.308496 | 0.204898 | 0.127448 | -0.090276 | 0.428316 |
翡翠蒸香茜饺 | 0.009206 | 1.000000 | 0.304434 | -0.012279 | 0.058745 | -0.180446 | -0.026908 | 0.062344 | 0.270276 | 0.020462 |
金银蒜汁蒸排骨 | 0.016799 | 0.304434 | 1.000000 | 0.035135 | 0.096218 | -0.184290 | 0.187272 | 0.121543 | 0.077808 | 0.029074 |
乐膳真味鸡 | 0.455638 | -0.012279 | 0.035135 | 1.000000 | 0.016006 | 0.325462 | 0.297692 | -0.068866 | -0.030222 | 0.421878 |
蜜汁焗餐包 | 0.098085 | 0.058745 | 0.096218 | 0.016006 | 1.000000 | 0.308454 | 0.502025 | 0.155428 | 0.171005 | 0.527844 |
生炒菜心 | 0.308496 | -0.180446 | -0.184290 | 0.325462 | 0.308454 | 1.000000 | 0.369787 | 0.038233 | 0.049898 | 0.122988 |
铁板酸菜豆腐 | 0.204898 | -0.026908 | 0.187272 | 0.297692 | 0.502025 | 0.369787 | 1.000000 | 0.095543 | 0.157958 | 0.567332 |
香煎韭菜饺 | 0.127448 | 0.062344 | 0.121543 | -0.068866 | 0.155428 | 0.038233 | 0.095543 | 1.000000 | 0.178336 | 0.049689 |
香煎罗卜糕 | -0.090276 | 0.270276 | 0.077808 | -0.030222 | 0.171005 | 0.049898 | 0.157958 | 0.178336 | 1.000000 | 0.088980 |
原汁原味菜心 | 0.428316 | 0.020462 | 0.029074 | 0.421878 | 0.527844 | 0.122988 | 0.567332 | 0.049689 | 0.088980 | 1.000000 |
plt.figure(figsize=(7,6),dpi=100)
p = sns.heatmap(data.corr(),annot=True)
可以看出“铁板酸菜豆腐”与“蜜汁焗餐包 ”、“原汁原味菜心”相关度较高。
Python主要数据探索函数
基本统计特征函数
$df:dataframe,D:dataframe或series,s:series$
$D.sum()$:求和
$D.mean()$:求均值
$D.var()$:求方差
$D.std()$:求标准差
$D.corr(method='spearman'),s_1.corr(s_2)$:求相关系数
$D.cov(),s_1.cov(s_2)$:求协方差
$D.skew()$:计算偏度
$D.kurt()$:计算峰度
$D.describe()$:直接给出均值、标准差、最大值、最小值、分位数等
拓展统计特征数
$D.cumsum()$:依此给出前1,2,...n个数据的和。
$D.cumprod()$:依此给出前1,2,...n个数据的积。
$D.cummax()$:依此给出前1,2,...n个数据的最大值。
$D.cummin()$:依此给出前1,2,...n个数据的最小值。
统计作图函数
$plt.plot(x,y)$:绘制线性二维图、折线图。
$D.plot(kind='box')$:这里使用的是DataFrame或Series对象内置的方法作图,默认以Index为横坐标,每列数据为纵坐标自动作图,通过kind参数指定作图类型,支持line(线)、bar(条形)、barh、hist(直方图)、box(箱线图)、kde(密度图)和area、pie(饼图)等,同时也能够接受plt.plot)中接受的参数。
$plt.pie(data)$:绘制饼图,$data$为series。
$plt.hist(s)$:绘制直方图,$s$为series。
$D.boxplot(),plt.plot(kind='box')$:绘制箱线图。
$D.plot(logx=True)$:x轴使用对数坐标轴。
y = pd.Series(np.exp(np.arange(20)))
fig = plt.figure(figsize=(10,4))
ax1 = fig.add_subplot(1,2,1)
p1 = y.plot(label ='原始数据图',legend=True)
ax2 = fig.add_subplot(1,2,2)
p2 = y.plot(label='对数数据图',logy=True,legend=True)
$D.plot(yerr=error)$:绘制误差条形图。D为Pandas的DataFrame或Series,代表着均值数据列,而error则是误差列,此命令在y轴方向画出误差棒图;类似地,如果设置参数xerr= error, 则在x轴方向画出误差棒图。
error = np.random.randn(10)
y = pd.Series(np.sin(np.arange(10)))
p = y.plot(yerr=error)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。