Python for Data Exploration(1)

数据探索

Posted by z-Tracy on December 16, 2017
  • 这篇文章来学习下数据探索主要步骤,一般在我们搜索数据后进行数据挖掘前都需要考虑这样一些问题:数据集的数量和质量是否满足模型构建的要求?其中有什么明显的规律和趋势吗? 各个因素之间有什么样的关联性?
  • 然后通过检验数据质量、绘制相应图标、计算某些特征量等手段对数据的结构和规律进行数据探索。
  • 参考 python数据分析与挖掘实战

数据质量分析

  • 首先应该就是检查数据中的脏数据,脏数据主要包含:缺失值、异常值、重复数据等。

缺失值分析

  • 使用简单的统计分析,可以得到含有缺失值的属性个数,缺失率。对于缺失值处理有删除缺失值、对可能值进行插补、不处理三种情况

我最常用的方式是使用data.describe()查看情况,然后len(data)得出总的数据记录数。对比下缺了多少条数据。

异常值分析

  • 对变量进行描述性统计,最常用的是看最大值和最小值;也可以查看是否服从正态分布,如果服从的话一般异常值被定义为与平均值超过3倍标准差的值;另外一种也是我最常用的的方法,使用箱形图来分析,查看离群值。

案例

  • 我知道文字描述比较抽象的,我们使用真的数据来试一下看看!
# -*- coding:utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] 
plt.rcParams['font.sans-serif'] = ['SimHei'] 
mpl.rcParams['axes.unicode_minus'] = False
%matplotlib inline

catering_sale = 'catering_sale.xls' # 餐饮数据
data = pd.read_excel(catering_sale,index_col=u'日期')
len(data) - data.describe()[:1]
销量
count 1.0
  • 这边就显示了缺失值的数据为1个
# 其实这样也可以,而且比较常用
data.isnull().sum()
销量    1
dtype: int64
# 处理一下,用均值插入
data.fillna(value=data.mean(),inplace=True)
销量
日期
2015-03-01 51.0000
2015-02-28 2618.2000
2015-02-27 2608.4000
2015-02-26 2651.9000
2015-02-25 3442.1000
2015-02-24 3393.1000
2015-02-23 3136.6000
2015-02-22 3744.1000
2015-02-21 6607.4000
2015-02-20 4060.3000
2015-02-19 3614.7000
2015-02-18 3295.5000
2015-02-16 2332.1000
2015-02-15 2699.3000
2015-02-14 2755.2147
2015-02-13 3036.8000
2015-02-12 865.0000
2015-02-11 3014.3000
2015-02-10 2742.8000
2015-02-09 2173.5000
2015-02-08 3161.8000
2015-02-07 3023.8000
2015-02-06 2998.1000
2015-02-05 2805.9000
2015-02-04 2383.4000
2015-02-03 2620.2000
2015-02-02 2600.0000
2015-02-01 2358.6000
2015-01-31 2682.2000
2015-01-30 2766.8000
... ...
2014-08-31 3494.7000
2014-08-30 3691.9000
2014-08-29 2929.5000
2014-08-28 2760.6000
2014-08-27 2593.7000
2014-08-26 2884.4000
2014-08-25 2591.3000
2014-08-24 3022.6000
2014-08-23 3052.1000
2014-08-22 2789.2000
2014-08-21 2909.8000
2014-08-20 2326.8000
2014-08-19 2453.1000
2014-08-18 2351.2000
2014-08-17 3279.1000
2014-08-16 3381.9000
2014-08-15 2988.1000
2014-08-14 2577.7000
2014-08-13 2332.3000
2014-08-12 2518.6000
2014-08-11 2697.5000
2014-08-10 3244.7000
2014-08-09 3346.7000
2014-08-08 2900.6000
2014-08-07 2759.1000
2014-08-06 2915.8000
2014-08-05 2618.1000
2014-08-04 2993.0000
2014-08-03 3436.4000
2014-08-02 2261.7000

201 rows × 1 columns

plt.figure() #建立图像
p = data.boxplot(return_type='dict') #画箱线图,直接使用DataFrame的方法

# 这边的用法如果不清楚 可以直接查看下p即boxplot函数返回的值,就比较清楚了。
x = p['fliers'][0].get_xdata() # 'flies'即为异常值的标签,然后通过get_xdata()返回x坐标
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() #展示箱线图

png

  • 通过箱形图异常值一目了然了吧,共有7个,当然你可以根据自己的业务比如将865、4060.3、4065.2归为正常值,其他几个定为异常值。 根据你的业务情况来。
# 把几个异常值也处理一下
import numpy as np
data.sort_values(u'销量',ascending=False,inplace=True)
data[-3:] = data.mean()[0]
data[:2] = data.mean()[0]

顺便说一下,同样如果你比较喜欢用seaborn也可以用,不过异常值的标记自己琢磨一下,我知道你可以的

import seaborn as sns
f,ax =plt.subplots()
t = sns.boxplot(data=data)

png

数据特征分析

  • 用之前的办法基本可以处理了数据质量问题,下来要来聊聊数据特征分析。这个对于后续的数据分析和建模还是很有启发性的工作。

分布分析

分布分析能揭示数据的分布特征和分布类型。对于定量数据,发现其分布形式是对称的还是非对称的,发现某些特大或特效的可疑值,主要还是通过绘制频率分布图 、直方图、茎叶图进行只管分析;对于定性的分类数据,可以用饼图和条形图直观显示分布情况。

  1. 对于定量变量而言,选择组数和组宽是做频率分布分析最重要的问题。一般按照以下步骤。
    • 求极差
    • 决定组距和组数
    • 决定分点
    • 列出频率分布表
    • 绘制频率分布直方图
  • 我们还是用之前的数据来实现一下看看好吧。
# 极差
Range = data.max()-data.min()
print('最大值是:%.2f' %(data.max()))
print('最小值是:%.2f' %(data.min()))
print('极差为:{:0.2f}'.format(Range.values[0]))
最大值是:4065.20
最小值是:865.00
极差为:3200.20
# 组数,可根据业务来确定组距,这里设为500
# 那么组数就可以计算为:
k = Range/500
print('组数为:{:0.0f}组'.format(k.values[0]))
组数为:6组
  • 绘制频率直方图
# f = plt.subplots(figsize=(5,4))
f = plt.hist(data['销量'],bins=7,normed=True,facecolor='b')
plt.xlabel(r'日销售额/元')
plt.ylabel(r'频率')
plt.title(r'销售额分布直方图')
<matplotlib.text.Text at 0x1e4784359e8>

png

定性数据的分布分析

  • 对于定性变量的分布分析相对比较简单,根据变量的分类类型就可以尝试用饼图、条形图等一般图形来观察。这里也不多做解释。

对比分析

  • 对比分析主要有两种形式
    • 绝对数比较:利用绝对数进行对比寻找差异的方法
    • 相对数比较:由两个有联系的指标进行对比计算,用来反映客观现象之间数量联系程度的综合指标。

相关性分析

  • 分析连续变量之间的线性相关程度的强弱,用适当的统计指标表示出来的过程称为相关分析。
    1. 直接绘制散点图观察(plot.scatter)
    2. 绘制散点图举证(sns.pairplot)
    3. 计算相关系数,比较常用的有Pearson相关系数、Spearman秩相关系数和判定系数。 (其实Pearson相关系数要求连续变量的取值服从正态分布,若不服从则可采用Speraman相关系数)
  • 在python直接有对应的函数,下面我们用实例来看下。
from __future__ import print_function
catering_sale = 'catering_sale_all.xls'
data = pd.read_excel(catering_sale,index_col=u'日期')

data.corr(method='pearson')['百合酱蒸凤爪'].sort_values(ascending = False)
# data['百合酱蒸凤爪'].corr(data['翡翠蒸香茜饺'])
百合酱蒸凤爪     1.000000
乐膳真味鸡      0.455638
原汁原味菜心     0.428316
生炒菜心       0.308496
铁板酸菜豆腐     0.204898
香煎韭菜饺      0.127448
蜜汁焗餐包      0.098085
金银蒜汁蒸排骨    0.016799
翡翠蒸香茜饺     0.009206
香煎罗卜糕     -0.090276
Name: 百合酱蒸凤爪, dtype: float64

这里看到,如果一个用户点了’百合酱蒸凤爪’,则点其他菜品的概率排序是这样的,’乐膳真味鸡’>’原汁原味菜心’>’生炒菜心’>’铁板酸菜豆腐’……

  • 用图表更加直观
data_corr = data.corr()
f,ax = plt.subplots(figsize =(6,6))

sns.heatmap(data_corr,square=True,fmt ='.2f',annot=True,annot_kws={'size':10})
<matplotlib.axes._subplots.AxesSubplot at 0x2b7c9ad35c0>

png

很明显相关性程度很低

python 主要数据探索函数

pandas提供大量的数据探索相关的函数。

基本统计特征函数(Pandas)

  • 计算数据总和:data.sum()
  • 计算数据的均数:data.mean()
  • 计算数据的方差:data.var()
  • 计算数据的标准差:data.std()
  • 计算数据的相关系数矩阵:data.corr()
  • 计算数据的协方差:data.cov()
  • 计算数据的偏度和峰度:data.skew()/data.kurt()

拓展统计特征函数(Pandas)

  • 依次给出前1、2、3、……、n个数的和 :data.cumsum()
  • 依次给出前1、2、3、……、n个数的积 :data.cumprod()
  • 依次给出前1、2、3、……、n个数的最大值 :data.cummax()
  • 依次给出前1、2、3、……、n个数的最小值 :data.cummin()
  • 滚动计算数据的总和(按列计算): pd.rolling_sum(data,k)(k代表指定的烈属)
  • 滚动计算数据的均值(按列计算): pd.rolling_mean(data,k)(k代表指定的烈属)

另外其他还是的rolling_ 系列函数分别是:rolling_var(),rolling_std(), rolling_corr(),rolling_cov(),rolling_skew(),rolling_kurt()

统计作图函数

  • 主要的库有matplotlib和seaborn库,其中seaborn也是基于matplotlib创建的。另外交互式图表可以尝试使用pycharts这个库,基于百度的echart。
  • 主要的方式是直接调用matplotlib,例如plt.boxplot();还有另一个方式是用Dataframe内置方法,例如data.plot(kind=”box”)
  • 具体的方式也比较简单,使用时可以直接查询相应的官方文档。

总结

  • 这一篇主要理了下数据分析前的工作——数据探索的内容,以及相应的pandas对应的用法和作图方法。从而能够发现数据中的一些规律和趋势,为后续建模找到方向。另外数据分析前很重要的一项工作——数据清理工作。对于缺失值、异常值做一些处理。如果这篇文章对你有用或者还有补充希望能留言,让我和其他读者能够学习到。