学习笔记-数据挖掘(时间序列)-探索性数据分析

这篇博客详细介绍了对余额宝数据的探索性数据分析(EDA),涉及时间序列图、直方图等可视化工具,揭示了数据的周期性和趋势性。通过对用户交易、节假日、利率等因素的分析,发现交易量与周末、节假日、银行及支付宝利率有显著关系,特别是在特殊日期如5月20日和6月18日,交易行为异常。此外,大额交易用户在利率下降时更倾向于赎回,新用户交易频繁,女性更倾向于购买,男性更倾向于赎回。
摘要由CSDN通过智能技术生成

探索性数据分析

探索性数据分析(Exploratory Data Analysis,EDA)是指对已有数据在尽量少的先验假设下通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法。

常见数据探索方法

对于时间序列的数据来说常见的有:

  1. 时序图是一个二维图,横轴表示对象,纵轴表示时间,消息在各对象之间横向传递,依照时间顺序纵向排列。优点是可以直接观察得到序列是否存在显著的周期性和趋势性;

  2. 直方图(英语:Histogram)是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本和该样本对应的某个属性的度量,以长条图(bar)的形式具体表现。

  3. 概率密度曲线图是以变数值为横坐标,以累积频率[概率]为纵坐标的曲线图

  4. 箱线图是一种用作显示一组数据分散情况资料的统计图。它能显示出一组数据的最大值、最小值、中位数、及上下四分位数。

  5. 小提琴图是在箱线图基础上的改进;可以用于显示数据分布及概率密度
    且小提琴图结合了箱形图和密度图的特征,主要用来显示数据的分布形状在这里插入图片描述

  6. 相关性分析:分析两个变量之间是否存在相关性,对于不同的数据之间(分类数据,顺序数据,数值数据)有不同的方法:在这里插入图片描述

  7. 独立性分析:判断数据之间是否独立;

数据来源及介绍

资金流入流出预测-挑战Baseline
这个数据集主要包含四个部分,分别为用户基本信息数据、用户申购赎回数据、收益率表和银行间拆借利率表。下面分别介绍四组数据。

用户信息表

用户信息表(user_profile_table)总共随机抽取了约 3 万用户,其中部分用户在 2014 年 9 月份第一次出现,这部分用户只在测试数据中 。因此用户信息表是约 2.8 万 个用户的基本数据,在原始数据的基础上处理后,主要包含了用户的性别、城市和星座。
用户信息表

用户申购赎回数据表

用户申购赎回数据表(user_balance_table)里面有 20130701 至 20140831 申购和赎回信息、以及所有的子类目信息, 数据经过脱敏处理。脱敏之后的数据,基本保持了原数据趋势。数据主要包括用户操作时间和操作记录,其中操作记录包括申购和赎回两个部分。金额的单位是分,即 0.01 元人民币。 如果用户今日消费总量为0,即consume_amt=0,则四个字类目为空。
在这里插入图片描述
在这里插入图片描述

收益率表

收益表为余额宝在 14 个月内的收益率表: mfd_day_share_interest :
收益率表

上海银行间同业拆放利率(Shibor)表

银行间拆借利率表是 14 个月期间银行之间的拆借利率(皆为年化利率): mfd_bank_shibor :
银行收益率表

数据探索

载入各种数据科学以及可视化库

import pandas as  pd
import numpy as np
import warnings 
import datetime
import seaborn as sns
import matplotlib.pyplot as plt
import datetime 
from scipy import stats

载入数据

# 读取数据
data_balance = pd.read_csv('user_balance_table.csv')
data_balance.head()#简略观察数据head()

由于这个是时间序列的数据,利用原始数据中‘report_date’,提取我们需要添加时间信息(年;月;日,周几,今年的第几周)

# 为数据集添加时间戳
data_balance['date'] = pd.to_datetime(data_balance['report_date'], format= "%Y%m%d")
data_balance['day'] = data_balance['date'].dt.day
data_balance['month'] = data_balance['date'].dt.month
data_balance['year'] = data_balance['date'].dt.year
data_balance['week'] = data_balance['date'].dt.week
data_balance['weekday'] = data_balance['date'].dt.weekday

绘制时序图

由于原始数据中每一天发生了多次交易,所以先整合数据,利用group()将每一天的数据汇总:

# 聚合时间数据

total_balance = data_balance.groupby(['date'])['total_purchase_amt','total_redeem_amt'].sum().reset_index()#重置索引防止转换后乱序

这个赛题是为了预测14年9月份每一天的交易额,我们先生成测试集区段数据,并将其与原始数据合并

# 生成测试集区段数据

start = datetime.datetime(2014,9,1)
testdata = []
while start != datetime.datetime(2014,10,1):
    temp = [start, np.nan, np.nan]
    testdata.append(temp)
    start += datetime.timedelta(days = 1)#一个timedalta对象代表了一个时间差
testdata = pd.DataFrame(testdata)
testdata.columns = total_balance.columns
total_balance = pd.concat([total_balance, testdata], axis = 0)

为新生成的数据集total_balance添加时间信息

# 为数据集添加时间戳
total_balance['day'] = total_balance['date'].dt.day
total_balance['month'] = total_balance['date'].dt.month
total_balance['year'] = total_balance['date'].dt.year
total_balance['week'] = total_balance['date'].dt.week
total_balance['weekday'] = total_balance['date'].dt.weekday

经过简单的处理之后,就可以绘制时序图了

import matplotlib.pylab as plt
# 画出每日总购买与赎回量的时间序列图
fig = plt.figure(figsize=(20,6))
plt.plot(total_balance['date'], total_balance['total_purchase_amt'],label='purchase')
plt.plot(total_balance['date'], total_balance['total_redeem_amt'],label='redeem')

plt.legend(loc='best')
plt.title("The lineplot of total amount of Purchase and Redeem from July.13 to Sep.14")
plt.xlabel("Time")
plt.ylabel("Amount")
plt.show()

在这里插入图片描述
可以看出序列有很强的周期性和趋势性,为了方便观察序列的周期性,我们截取14年4月份以后的数据做时序图

# 画出2014年4月份以后的时间序列图
total_balance_1 = total_balance[total_balance['date'] >= datetime.date(2014,4,1)]
fig = plt.figure(figsize=(20,6))
plt.plot(total_balance_1['date'], total_balance_1['total_purchase_amt'],label='purchase')
plt.plot(total_balance_1['date'], total_balance_1['total_redeem_amt'],label='redeem')
plt.legend()
plt.title("The lineplot of total amount of Purchase and Redeem from April.14 to Sep.14")
plt.xlabel("Time")
plt.ylabel("Amount")
plt.show()

在这里插入图片描述
然后再分别画出每一个月的时序图

# 分别画出每个月中每天购买赎回量的时间序列图
fig = plt.figure(figsize=(15,15))

plt.subplot(4,1,1)
plt.title("The time series of total amount of Purchase and Redeem for August, July, June, May respectively")

total_balance_2 = total_balance[total_balance['date'] >= datetime.date(2014,8,1)]
plt.plot(total_balance_2['date'], total_balance_2['total_purchase_amt'],label='purchase')
plt.plot(total_balance_2['date'], total_balance_2['total_redeem_amt'],label='redeem')
plt.legend()


total_balance_3 = total_balance[(total_balance['date'] >= datetime.date(2014,7,1)) & (total_balance['date'] < datetime.date(2014,8,1))]
plt.subplot(4,1,2)
plt.plot(total_balance_3['date'], total_balance_3['total_purchase_amt'],label='purchase')
plt.plot(total_balance_3['date'], total_balance_3['total_redeem_amt'],label='redeem')
plt.legend()


total_balance_4 = total_balance[(total_balance['date'] >= datetime.date(2014,6,1)) & (total_balance['date'] < datetime.date(2014,7,1))]
plt.subplot(4,1,3)
plt.plot(total_balance_4['date'], total_balance_4['total_purchase_amt'],label='purchase')
plt.plot(total_balance_4['date'], total_balance_4['total_redeem_amt'],label='redeem')
plt.legend()


total_balance_5 = total_balance[(total_balance['date'] >= datetime.date(2014,5,1)) & (total_balance['date'] < datetime.date(2014,6,1))]
plt.subplot(4,1,4)
plt.plot(total_balance_5['date'], total_balance_5['total_purchase_amt'],label='purchase')
plt.plot(total_balance_5['date'], total_balance_5['total_redeem_amt'],label='redeem')
plt.legend()

plt.xlabel("Time")
plt.ylabel("Amount")
plt.show()

在这里插入图片描述
从每一个月的时序图中可以看出,数据大致以星期为周期(一个月中大概有4次波峰4次波谷);

对weekday的特征分析

# 画出每个weekday的数据分布于整体数据的分布图
a = plt.figure(figsize=(10,10))
scatter_para = {
   'marker':'.', 's':3, 'alpha':0.3}
line_kws = {
   'color':'k'}
plt.subplot(2,2,1)
plt.title('The distrubution of total purchase')
sns.violinplot(x='weekday', y='total_purchase_amt', data = total_balance_1, scatter_kws=scatter_para, line_kws=line_kws)#2014年4月份以后的数据
plt.subplot(2,2,2)
plt.title('The distrubution of total purchase')
sns.distplot(total_balance_1['total_purchase_amt'].dropna())
plt.subplot(2,2,3)
plt.title('The distrubution of total redeem')
sns.violinplot(x='weekday', y='total_redeem_amt', data = total_balance_1, scatter_kws=scatter_para, line_kws=line_kws)
plt.subplot(2,2,4)
plt.title('The distrubution of total redeem')
sns.distplot(total_balance_1['total_redeem_amt'].dropna())

在这里插入图片描述
从小提琴图可以看出来,双休的总购买量明显少于工作日,且其概率分布图大致是对称的,但总赎回量是明显的左偏分布,即在双休的赎回量明显少于工作日,这个现象可以归于余额宝的收益方式(双休不计入收益),余额宝收益在周三最多。我们从柱状图和盒形图也可以看出同样的趋势;

# 按weekday对数据聚合后取均值
week_sta = total_balance_1[['total_purchase_amt', 'total_redeem_amt', 'weekday']].groupby('weekday', as_index=False).mean()
# 分析翌日的平均数特征
plt.figure(figsize=(12, 5))
ax = plt.subplot(1,2,1)
plt.title('The barplot of average total purchase with each weekday')
ax = sns.barplot(x="weekday", y="total_purchase_amt", data=week_sta, label='Purchase')
ax.legend()
ax = plt.subplot(1,2,2)
plt.title('The barplot of average total redeem with each weekday')
ax = sns.barplot(x="weekday", y="total_redeem_amt", data=week_sta, label='Redeem')
ax.legend()

在这里插入图片描述

# 画出翌日的箱型图
plt.figure(figsize=(12, 5))
ax = plt.subplot(1,2,1)
plt.title('The boxplot of total purchase with each weekday')
ax = sns.boxplot(x="weekday", y="total_purchase_amt", data=total_balance_1)
ax = plt.subplot(1,2,2)
plt.title('The boxplot of total redeem with each weekday')
ax = sns.boxplot(x="weekday", y="total_redeem_amt", data=total_balance_1)

在这里插入图片描述
接下来做不同weekday之间相关性分析,由于这个取值是1~7,会自动识别为数值型变量,所以做相关性分析之前需要先对weekday做独热编码;

# 使用OneHot方法将weekday特征划分,获取划分后特征(数据编码)weekday是定序变量,需用使用独热编码。

from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder()
total_balance = total_balance.reset_index()
week_feature = encoder.fit_transform(np.array(total_balance['weekday']).reshape(-1, 1)).toarray()
week_feature = pd.DataFrame(week_feature,columns=['weekday_onehot']*len(week_feature[0]))#转化为dataframe
feature = pd.concat([total_balance, week_feature], axis = 1)[['total_purchase_amt', 'total_redeem_amt','weekday_onehot','date']]
feature.columns = list(feature.columns[0:2]) + [x+str(i) for i,x in enumerate(feature.columns[2:-1])] + ['date']#取列名

在新的数据集中做weekday之间的相关性分析

# 画出划分后翌日特征与标签的斯皮尔曼相关性(两个定序变量是用spearman相关系数,一个定序变量和一个连续变量也是用spearman相关系数)

f, ax = plt.subplots(figsize = (15, 8))
plt.subplot(1,2,1)
plt.title('The spearman coleration between total purchase and each weekday')
sns.heatmap(feature[[x for x in feature.columns if x not in ['total_redeem_amt', 'date'] ]].corr('spearman'),linewidths = 0.1, vmax = 0.2, vmin=-0.2)
plt.subplot(1,2,2)
plt.title('The spearman coleration between total redeem and each weekday')
sns.heatmap(feature[[x for x in feature.columns if x not in ['total_purchase_amt', 'date'] ]].corr('spearman'),linewidths = 0.1,  vmax = 0.2, vmin=-0.2)

在这里插入图片描述
从上图可以看出来相关性较弱,接下来对weekday做独立性检验,这里采用mvtest方法

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值