数据分析学习笔记--家用热水器用户行为分析与实践识别(代码)
案例基于热水器采集的时间序列数据,将顺序排列的离散的用水时间节点根据水流量和停顿时间间隔划分不同大小的时间区间,每个时间区间可以理解成一次完整用水事件。
定义挖掘目标如下:
1.根据热水器采集到的数据,划分一次完整的用水事件
2.在划分好的一次完整用水事件中,识别出洗浴事件
数据分析步骤:
1.预处理热水器用户用水数据,划分一次完整的用水事件
a.删除冗余属性[‘热水器编号’,‘有无水流’,‘节能模式’,‘当前设置温度’]
b.通过阈值寻优的方式找出最优阈值
c.在大量的状态记录中划分出哪些连续的数据是一次完整的用水事件。
读取数据记录,识别所有水流量不为0的状态记录,将它们的发生时间记为序列t1
对序列t1构建其向前时差列和向后时差列,并分别与阈值进行比较。向前时差超过阈值T,则将它记为新的用水事件的开始编号;如果向后时差超过阈值T,则将其记为用水事件的结束编号。
import pandas as pd
import numpy as np
data = pd.read_excel('../data/original_data.xls')
print('初始状态的数据形状为:', data.shape)
# 删除热水器编号,有无水流,节能模式
data.drop(labels = ["热水器编号","有无水流","节能模式"],
axis = 1,inplace = True)
print('删除冗余特征后的数据形状为:', data.shape)
data.to_csv('../tmp/water_heart.csv',index = False)
threshold = pd.Timedelta('4 min') #阈值为分钟
data['发生时间'] = pd.to_datetime(data['发生时间'],
format = '%Y%m%d%H%M%S') # 转换时间格式
data = data[data['水流量'] > 0] #只要流量大于0的记录
#相邻时间向前差分,比较是否大于阈值
sjKs = data['发生时间'].diff() > threshold
sjKs.iloc[0] = True # 令第一个时间为第一个用水事件的开始事件
sjJs = sjKs.iloc[1:] # 向后差分的结果
# 令最后一个时间作为最后一个用水事件的结束时间
sjJs = pd.concat([sjJs,pd.Series(True)])
# 创建数据框,并定义用水事件序列
sj = pd.DataFrame(np.arange(1,sum(sjKs)+1),columns = ["事件序号"])
sj["事件起始编号"] = data.index[sjKs == 1]+1 # 定义用水事件的起始编号
sj["事件终止编号"] = data.index[sjJs == 1]+1 # 定义用水事件的终止编号
print('当阈值为4分钟的时候事件数目为:',sj.shape[0])
sj.to_csv('../tmp/sj.csv',index = False)
n = 4 #使用以后四个点的平均斜率
threshold = pd.Timedelta(minutes = 5) #专家阈值
data['发生时间'] = pd.to_datetime(data['发生时间'],
format = '%Y%m%d%H%M%S')
data = data[data['水流量'] > 0] #只要流量大于0的记录
# 自定义函数:输入划分时间的时间阈值,得到划分的事件数
def event_num(ts):
d = data['发生时间'].diff() > ts #相邻时间作差分,比较是否大于阈值
return d.sum() + 1 #这样直接返回事件数
dt = [pd.Timedelta(minutes = i) for i in np.arange(1, 9, 0.25)