文章目录
案例数据百度网盘链接-提取码:1234
传送门:
- 数据挖掘实战—财政收入影响因素分析及预测
- 数据挖掘实战—航空公司客户价值分析
- 数据挖掘实战—商品零售购物篮分析
- 数据挖掘实战—基于水色图像的水质评价
- 数据挖掘实战—家用热水器用户行为分析与事件识别
- 数据挖掘实战—电商产品评论数据情感分析
引言
居民在使用家用热水器的过程中,会因为地区气候、不同区域和用户年龄性别差异等原因形成不同的使用习惯。家电企业若能深入了解其产品在不同用户群中的使用习惯,从而产商便可以对不同的客户群提供最适合的个性化产品,制定相应的营销策略,开拓新市场。定义挖掘目标如下:
- 根据热水器采集到的数据,划分一次完整的用水事件
- 在划分好的一次完整用水事件中,识别出洗浴事件
数据挖掘步骤:
- 对热水器用户的历史用水数据进行选择性抽取,构建专家样本
- 数据探索分析与预处理,包括探索水流量的分布情况,删除冗余属性,识别用水数据的缺失值,并对缺失值进行处理,然后根据建模的需要进行属性构造等。最后根据以上处理,对热水器用户用水样本数据建立用水事件时间间隔识别模型和划分一次完整的用水事件模型,接着在一次完整用水事件划分结果的基础上,剔除短暂用水事件、缩小识别范围等。
- 在步骤2得到的建模样本数据基础上,建立洗浴事件识别模型,对洗浴事件识别模型进行模型分析评价
- 应用步骤3形成的模型结果,并对洗浴事件划分进行优化
- 调用洗浴事件识别模型,对实时监控的热水器流水数据进行洗浴事件自动识别。
一、数据探索分析
热水器采集的用水数据包含12个属性:热水器编码、发生时间、开关机状态、加热中、保温中、有无水流、实际温度、热水量、水流量、节能模式、加热剩余时间和当前设置温度等。其解释说明如下:
1.数据质量分析
1.1缺失值分析
data.isnull().sum()
发现没有缺失值
1.2 异常值分析
for column in data.columns:
print(data[column].value_counts())
通过对每一列的值进行统计,发现没有异常值。并且发现热水器编号、节能模式、当前设置温度均为常量
1.3 重复数据分析
data.duplicated().sum()
发现没有重复数据
2.数据特征分析
2.1 分布分析
探索热水器的水流量情况,其中“有无水流”和“水流量”可以直观的显示水量情况
查看有无水流的分布
lv_none = data['有无水流'].value_counts()['无']
lv_move = data['有无水流'].value_counts()['有']
# 直方图展示有无水流列中的情况
plt.rcParams['font.sans-serif'] = [u'simHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(8,8))
# plt.hist(data['有无水流'],bins='auto',color='skyblue')
# 绘制柱状图
plt.bar(x = ['无','有'],height=[lv_none,lv_move],width=0.4,alpha=0.8,color='skyblue')
plt.xlabel('水流状态',fontsize=15)
plt.ylabel('记录数',fontsize=15)
plt.title('不同水流状态记录数',fontsize=20)
从图中可以看出无水流状态比有水流状态要多
查看水流量分布的箱型图
fig,ax = plt.subplots(figsize=(8,8))
sns.boxplot(data['水流量'],orient='v')
ax.set_xlabel('水流量',fontsize=15)
ax.set_title('水流量分布箱型图',fontsize=20)
plt.grid(axis='y') # 网格线
从箱型中可以看出:箱体贴近于0,无水流量或者水流量小的时候多,与水流状态的分布一致
三、数据预处理
1.数据归约之属性归约
在前面,我们已经知道热水器编号、节能模式、当前设置温度均为常量,并且水流状态可以根据“水流量”属性来表现出来。因此,将这四个冗余属性热水器编号、节能模式、当前设置温度、有无水流删除。
# 删除冗余属性
data.drop(labels=['热水器编号','有无水流','节能模式','当前设置温度'],axis=1,inplace=True)
data.to_csv('water_heart.csv',index=False)
2.数据归约之数值归约
热水器用户的用水数据存储在数据库中,记录了各种各样的用水事件,包括洗浴、洗手、刷牙、洗脸、洗衣、洗菜等,而且一次用水事件由数条甚至数千条的状态记录组成。所以首先需要在大量的状态记录中划分出哪些连续的数据是一次完整的用水事件。在用水状态记录中,水流量不为0,表明热水器用户正在使用热水;而水流量为0时,则表明热水器用户用热水时发生停顿或者用热水结束。对于任何一个用水记录,如果它的向前时差超过阈值T,则将它记为事件的开始编号;如果它的向后时差超过阈值T,则将其记为事件的结束编号。
一次完整用水事件的划分步骤:
- 读取数据记录,识别所有水流量不为0的状态记录,将它们的发生时间记为序列t1
- 对序列t1构建其向前时差列和向后时差列,并分别与阈值进行比较。向前时差超过阈值T,则将它记为新的用水事件的开始编号;如果向后时差超过阈值T,则将其记为用水事件的结束编号。
- 循环执行步骤2,直至向前时差列与向后时差列和均值比较完毕,则结束事件划分。
第一步:确定单次用水事件时长阈值
# 确定单词用水事件时长阈值
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)]
h = pd.DataFrame(dt, columns=['阈值']) # 转换数据框,定义阈值列
h['事件数']