您的位置:首页 > 其它

[DM实战]家用电器用户行为分析与事件识别

2018-01-16 19:10 399 查看
1、家用企业若能深入了解不同用户群的使用习惯,开发新功能,就能开拓新市场。厂商可从热水器智能操作和节能运行等多方面对产品进行优化。

热水器厂商根据洗浴事件识别模型,对不同地区的用户的用水进行识别,根据识别结果比较不同客户群客户群的客户使用习惯、加深对客户的理解等。从而,厂商可以给不同的客户群提供最适合的个性化产品、改进新产品的智能化的研发和制定相应的营销策略。

根据提供的数据实现以下目标:

1)根据热水器采集到的数据,划分一次完整用水事件。

2)在划分好的一次完整用水事件中,识别出洗浴事件。

2、对热水用户的历史用水数据进行选择性抽取,构建专家样本。

本案例对原始数据采用无放回随机抽样法抽取200家热水器用户从2014年1月1日至2014年12月31日的用水记录作为原始建模数据。

3、对步骤2)形成的数据集进行数据探索分析与预处理,包括探索用水事件时间间隔的分布、规约冗余属性、识别用水数据的缺失值,并对缺失值进行处理,根据建模的需要进行属性构造等。根据以上处理,对用水样本数据建立用水事件时间间隔识别模型和划分一次完整的用水事件模型,再在一次完整用水事件划分结果的基础上,剔除短暂用水事件,缩小识别范围。

通过频率分布直方图分析用户用水停顿时间间隔的规律性,从而探究划分一次完整用水事件的时间间隔阈值。

本案例的数据集的特点是数据量涉及上万个用户而且每个用户每天的用水数据多达数万条、存在缺失值、与分析主题无关的属性或未直接反应用水事件的属性等。在数据预处理阶段,针对这些情况相应地应用了缺失值处理、数据规约和属性构造等来解决这些问题。

4、在上一步得到的建模样本数据基础上,建立洗浴事件识别模型,对洗浴事件识别模型进行模型分析评价。

根据建模样本数据和用户记录的包含用水的用途、用水开始时间、用水结束时间等属性的用水日志,建立多层神经网络模型识别洗浴事件。由于洗浴事件与普通用水事件在特征上存在不同,而且这些不同的特征在属性上被体现出来。于是,根据用户提供的用水日志,将其中洗浴事件的数据状态记录作为训练样本训练多层神经网络。然后根据训练好的网络来检验新采集到的数据。

在训练神经网络的时候,选取了“候选洗浴事件”的11个属性作为网络的输入。训练BP网络时给定的输出(教师信号)为1与0,其中1代表该次事件为洗浴事件,0代表该次事件不是洗浴事件。其中。是否为洗浴事件根据用户提供的用水记录日志得到。

在训练神经网络时,对神经网络的参数进行寻优,发现含两个隐层的神经网络训练效果较好,其中两个隐层的隐节点数分别为17、10时训练的效果较好。

5、对上一步形成的模型结果应用并对洗浴事件划分进行优化。

6、调用洗浴事件识别模型,对实时监控的热水器流水数据进行洗浴事件自动识别。

#coding:utf-8
#用水事件划分
import pandas as pd
threshold = pd.Timedelta(minutes=4) #阈值为4分钟
inputfile = './data/water_heater.xls' #输入数据路径,需要使用Excel格式
outputfile = './tmp/dividsequence.xls' #输出数据路径,需要使用Excel格式

data = pd.read_excel(inputfile)
data[u'发生时间'] = pd.to_datetime(data[u'发生时间'], format= '%Y%m%d%H%M%S') #将表格中对应的列数据转化成datetime格式
data = data[data[u'水流量'] > 0] #只要流量大于0的记录
d = data[u'发生时间'].diff() > threshold #相邻时间作差分,比较是否大于阈值
#记录编号 是否大于阈值
# 2 False
# 56 True
# 381 True
# .....
data[u'事件编号'] = d.cumsum() + 1 #通过累积求和的方式为事件编号 cumsum()计算轴向元素累加和,返回由中间结果组成的数组
print("cumsum:", d.cumsum()+1)
#记录编号 事件编号
# 2 1
# 56 2
# 381 3
# 382 3
# .....
data.to_excel(outputfile)
#coding:utf-8
#阈值寻优

import numpy as np
import pandas as pd

inputfile = './data/water_heater.xls'   #输入数据路径,需要使用excel格式
n = 4      #使用以后4个点的平均斜率

threshold = pd.Timedelta(minutes=5)  #专家阈值  表示两个datetime值之间的差(日、秒、毫秒)
data = pd.read_excel(inputfile)
data[u'发生时间'] = pd.to_datetime(data[u'发生时间'], format='%Y%m%d%H%M%S') #数据转化为指定格式
data = data[data[u'水流量']> 0]  #只要流量大于0的记录

def event_num(ts):
d = data[u'发生时间'].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=[u'阈值'])   #定义阈值列
h[u'事件数'] = h[u'阈值'].apply(event_num)   #计算每个阈值对应的事件数
h[u'斜率'] = h[u'事件数'].diff()/0.25    #计算每两个相邻点对应的斜率
h[u'斜率指标'] =pd.rolling_mean(h[u'斜率'].abs(),n)  #采用后n个的斜率绝对值平均作为斜率指标
ts = h[u'阈值'][h[u'斜率指标'].idxmin() - n]
#注:用idxmin返回最小值的index,由于rolling_mean()自动计算的是前n个斜率的绝对值,所以结果要进行评议(-n)

if ts>threshold:
ts = pd.Timedelta(minutes=4)

print(ts)
#coding:utf-8
#建立、训练多层神经网络,并完成模型的检验

import pandas as pd

inputfile1 = './data/train_neural_network_data.xls'  #训练数据
inputfile2 = './data/test_neural_network_data.xls'   #测试数据
testoutputfile = './tmp/test_output_data.xls'   #测试数据模型输出文件
data_train = pd.read_excel(inputfile1)   #读入训练数据(由日志标记事件是否为洗浴)
data_test = pd.read_excel(inputfile2)    #读入测试数据(由日志标记事件是否为洗浴)
y_train = data_train.iloc[:,4].as_matrix()   #训练样本标签列
x_train = data_train.iloc[:,5:17].as_matrix()   #训练样本特征
y_test = data_test.iloc[:,4].as_matrix()   #测试样本标签列
x_test = data_test.iloc[:,5:17].as_matrix()   #测试样本特征

from keras.models import Sequential
from keras.layers.core import Dense,Dropout,Activation

model = Sequential()    #建立模型
model.add(Dense(input_dim=11, units=7))   #添加输入层、隐藏层的连接
model.add(Activation('relu'))    #以Relu函数为激活函数
model.add(Dense(input_dim=17, units=10))    #添加隐藏层、隐藏层的连接
model.add(Activation('relu'))    #以relu函数为激活函数
model.add(Dense(input_dim=10, units=1))   #添加隐藏层、输出层的连接
model.add(Activation('sigmoid'))    #以sigmoid函数为激活函数
#编译模型,损失函数为binary_crossentropy,用adam法求解
model.compile(loss='binary_crossentropy', optimizer='adam')

model.fit(x_train, y_train, nb_epoch=100, batch_size=1)   #训练模型  循环100次  批尺寸为1(每次只训练一个样本,即 Batch_Size = 1)
model.save_weights('./tmp/net.model')   #保存模型参数

r = pd.DataFrame(model.predict_classes(x_test), columns=[u'预测结果'])
pd.concat([data_test.iloc[:, :5],r], axis=1).to_excel(testoutputfile)
model.predict(x_test)
# 1/28 [>.............................] - ETA: 0s - loss: 1.1921e-07
# 28/28 [==============================] - 0s 673us/step - loss: 1.8440

参考自:《python数据分析与挖掘》   --张良均
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: