家用电器用户行为分析与事件识别

看了一个例子还不错,所以自己去研究下。刚开始是先复现一遍实验,然后对实验进行一些自己的改进。

背景

居民使用家电过程,会因为地区、气候、用户年龄、性别,形成不同的使用习惯。企业通过分析用户的行为,开发新功能,拓展市场业务。
采集相关数据,以热水器为例子,分析用户的使用行为。其中用水事件识别时最为关键的环节。这个例子就是采集用户的用水数据,分析用户的用水行为特征。
热水器用户用水数据,如下图:
在这里插入图片描述
大约有1万8千条数据,我们要根据数据分出洗浴事件识别模型,对不同地区的用户的用水进行识别,根据识别结果比较不同客户群的客户使用习惯。从而,可以给不同的客户提供合适的个性化产品和相应的营销策略。
目标:
1、根据数据,划分一次完整的用水事件。
2、在划分好的一次完整用水事件中,识别出洗浴事件。

分析方法与过程

本次的建模流程图为:

选择性抽取
实时监控
模型优化
原始数据
训练样本集
实时识别样本数据
数据探索分析
数据清洗
建模样本数据
预处理后的数据
模型训练和评估
模型
自动识别
洗浴识别

建模流程:
1、业务系统
2、数据抽取
3、数据探索与预处理
4、建模和应用
5、结果和反馈

数据抽取

此热水器在状态发生改变或者水流量为非零时,每两秒会采集一条状态数据。由于数据很大,所以采用无放回随机抽样法抽取一部分用水记录作为原始建模数据。

数据探索分析

以下代码在jupyter notebook里完成。
首先通过频率直方图,观察用户用水停顿时间间隔的规律性。
先查看水流量的最大值和最小值,代码:

import pandas as pd
import numpy as np
from pandas import DataFrame
import matplotlib.pyplot as plt
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']

inputfile = '../data/original_data.xls'  # 输入数据路径,需要使用Excel格式
# outputfile = '../tmp/dividsequence.xls'  # 输出数据路径,需要使用Excel格式

data = pd.read_excel(inputfile, encoding='gbk')

# 将该特征转成日期时间格式(***)
data[u'发生时间'] = pd.to_datetime(data[u'发生时间'], format='%Y%m%d%H%M%S')
data = data[data[u'水流量'] > 0]  # 只要流量大于0的记录
# print(len(data))  # 7696

# 将datetime64[ns]转成 以分钟为单位(*****)
data[u'用水停顿时间间隔'] = data[u'发生时间'].diff() / np.timedelta64(1, 'm')
data = data.fillna(0)  # 替换掉data[u'用水停顿时间间隔']的第一个空值

# -----第*1*步-----数据探索,查看各数值列的最大最小和空值情况
data_explore = data.describe().T
data_explore['null'] = len(data) - data_explore['count']
explore = data_explore[['min', 'max', 'null']]
explore.columns = [u'最小值', u'最大值', u'空值数']
explore
                       最小值	          最大值	           空值数
水流量                  	8.0	             77.000000      	0.0
用水停顿时间间隔	        0.0	             2093.366667     	0.0

再将时间间隔划分为各个区间,计算水停顿频率,代码:

# ----第*2*步-----离散化与面元划分
# 将时间间隔列数据划分为0~0.1,0.1~0.2,0.2~0.3....13以上,由数据描述可知,
# data[u'用水停顿时间间隔']的最大值约为2094,因此取上限2100
Ti = list(data[u'用水停顿时间间隔'])  # 将要面元化的数据转成一维的列表
timegaplist = [
    0.0, 0.1, 0.2, 0.3, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 2100
]  # 确定划分区间

cats = pd.cut(Ti, timegaplist, right=False)  # 包扩区间左端,类似"[0,0.1)",(默认为包含区间右端)
x = pd.value_counts(cats)
x.sort_index(inplace=True)
dx = DataFrame(x, columns=['num'])
dx['fn'] = dx['num'] / sum(dx['num'])
dx['cumfn'] = dx['num'].cumsum() / sum(dx['num'])


def f1(x):
    return '%.2f%%' % (x * 100)  # 停顿频率


dx[['f']] = dx[['fn']].applymap(f1)
dx

在这里插入图片描述
可以看出0到0.3分钟的停顿频率最高。
我们继续用matplotlib画出水停顿时间间隔频率分布直方图,代码:

# -----第*3*步-----画用水停顿时间间隔频率分布直方图
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

dx['fn'].plot(kind='bar')
plt.ylabel(u'频率/组距')
plt.xlabel(u'时间间隔(分钟)')
p = 1.0 * dx['fn'].cumsum() / dx['fn'].sum()  # 数值等于 dx['cumfn'],但类型是列表
dx['cumfn'].plot(color='r', secondary_y=True, style='-o', linewidth=2)
plt.annotate(format((p[4]), '.4%'),
             xy=(7, p[4]),
             xytext=(7 * 0.9, p[4] * 0.95),
             arrowprops=dict(
                 arrowstyle="->",
                 connectionstyle="arc3,rad=.2"))  # 添加注释,即85%处的标记。这里包括了指定箭头样式。
plt.ylabel(u'累计频率')

plt.title(u'用水停顿时间间隔频率分布直方图')
plt.grid(axis='y', linestyle='--')

# fig.autofmt_xdate() #自动根据标签长度进行旋转
for label in ax.xaxis.get_ticklabels():  # 此语句完成功能同上,但是可以自定义旋转角度
    label.set_rotation(60)

plt.savefig('Water-pause-times.png', dpi=500, bbox_inches='tight') # 解决图片不清晰,不完整的问题
plt.show()

在这里插入图片描述
刚开始,图像不完整,这是jupyter notebook造成的错误,用vscode 或者Pycharm运行,图像没问题,后来自己加了些代码改进了在jupyter notebook里的输出图像。

数据预处理

由于数据量大,有些数据可能存在缺失值,或者一些无关联的属性,针对这些情况应用了缺失值处理、数据规约和属性构造等来解决问题。
1、数据规约
规约掉“热水器编号”、“有无水流”、“节能模式”。
先看看原始数据,代码:

or_data = pd.read_excel(inputfile, encoding='gbk')
or_data.head()

在这里插入图片描述
然后删掉上面说的3个数据列,代码:

data = or_data.drop(or_data.columns[[0,5,9]],axis=1) # 删掉不相关属性
data.to_excel('data_guiyue.xlsx')
data.head()

在这里插入图片描述

阈值寻优代码

# -*- coding: utf-8 -*-
# 阈值寻优
import numpy as np
import pandas as pd

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

threshold = pd.Timedelta(minutes=5)  # 专家阈值
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'斜率指标'] = h[u'斜率'].abs().rolling(n).mean()  # 采用后n个的斜率绝对值平均作为斜率指标
ts = h[u'阈值'][h[u'斜率指标'].idxmin() - n]
# 所以结果要进行平移(-n)

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

print(ts)
h

0 days 00:04:00

阈值	事件数	斜率	斜率指标
0	00:01:00	232	NaN	NaN
1	00:01:15	227	-20.0	NaN
2	00:01:30	218	-36.0	NaN
3	00:01:45	207	-44.0	NaN
4	00:02:00	201	-24.0	31.0
5	00:02:15	197	-16.0	30.0
6	00:02:30	194	-12.0	24.0
7	00:02:45	191	-12.0	16.0
8	00:03:00	186	-20.0	15.0
9	00:03:15	181	-20.0	16.0
10	00:03:30	178	-12.0	16.0
11	00:03:45	174	-16.0	17.0
12	00:04:00	172	-8.0	14.0
13	00:04:15	172	0.0	9.0
14	00:04:30	171	-4.0	7.0
15	00:04:45	171	0.0	3.0
16	00:05:00	171	0.0	1.0
17	00:05:15	169	-8.0	3.0
18	00:05:30	164	-20.0	7.0
19	00:05:45	164	0.0	7.0
20	00:06:00	163	-4.0	8.0
21	00:06:15	161	-8.0	8.0
22	00:06:30	159	-8.0	5.0
23	00:06:45	158	-4.0	6.0
24	00:07:00	158	0.0	5.0
25	00:07:15	158	0.0	3.0
26	00:07:30	155	-12.0	4.0
27	00:07:45	154	-4.0	4.0
28	00:08:00	153	-4.0	5.0
29	00:08:15	153	0.0	5.0
30	00:08:30	152	-4.0	3.0
31	00:08:45	150	-8.0	4.0

训练多层神经网络代码

运用tf2.0

# -*- coding: utf-8 -*-
# 建立、训练多层神经网络,并完成模型的检验
from __future__ import print_function
import pandas as pd
import tensorflow as tf
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics, callbacks

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].values  # 训练样本标签列
x_train = data_train.iloc[:, 5:17].values  # 训练样本特征
y_test = data_test.iloc[:, 4].values  # 测试样本标签列
x_test = data_test.iloc[:, 5:17].values  # 测试样本特征

print(x_train.shape)
print(y_train.shape)

model = Sequential([layers.Dense(20, activation='relu', input_shape=(11,)),
                    layers.BatchNormalization(),
                    layers.Dropout(0.2),
                    layers.Dense(10, activation='relu'),
                    layers.BatchNormalization(),
                    layers.Dropout(0.2),
                    layers.Dense(1, activation='sigmoid')])

model.summary()
model.compile(optimizer=optimizers.Adam(lr=0.001),
              loss=tf.losses.binary_crossentropy,
              metrics=['acc'])

# 运用tensorboard可视化
log_dir = 'logs'
tensorboard_callback = callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1, write_images=True)

model.fit(x_train, y_train, epochs=1000, validation_data=[x_test, y_test], validation_freq=1,
          callbacks=[tensorboard_callback])
model.save('model.h5')
test_scores = model.evaluate(x_test, y_test)
print('test loss:', test_scores[0])
print('test accuracy:', test_scores[1])

'''
载入模型
print('loaded model from file.')
network = tf.keras.models.load_model('model.h5', compile=True)
network.predict(x_test)
'''

结果:

28/28 [==============================] - 0s 5ms/sample - loss: 0.0486 - acc: 0.9643 - val_loss: 0.3131 - val_acc: 0.9048
Epoch 999/1000

28/28 [==============================] - 0s 6ms/sample - loss: 0.0129 - acc: 1.0000 - val_loss: 0.3007 - val_acc: 0.9048
Epoch 1000/1000

28/28 [==============================] - 0s 6ms/sample - loss: 0.0218 - acc: 1.0000 - val_loss: 0.2849 - val_acc: 0.9048

21/1 [===============================] - 0s 237us/sample - loss: 0.2849 - acc: 0.9048
test loss: 0.28485798835754395
test accuracy: 0.9047619

精度图像:
在这里插入图片描述
之所以抖动是因为加入了dropout
在这里插入图片描述
模型的Main Graph
在这里插入图片描述

网络结构是11–>20–>10–>1,是一个二分类问题,一共有21条数据,准确识别了19条数据,模型对洗浴事件的识别准确率为90.48%
由于训练数据太少,精度可能不够。
代码在我的码云里,链接https://gitee.com/rengarwang/Python_data_analysis_code/tree/master/家电电器用户行为分析

有用请点个赞!!
本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/weixin_45092662。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

  • 5
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
基于bp神经网络的家电用户行为分析事件识别模型的构建是一种利用人工神经网络技术来分析家电用户的行为,并识别出特定事件的方法。这种模型的构建主要包括数据采集、特征提取、模型训练和测试等步骤。 首先,需要对家电用户的行为数据进行采集。可以通过安装传感器或者使用智能家居设备来收集用户与家电的交互数据,例如开关操作、功耗变化等。 然后,对采集到的数据进行特征提取。可以从数据中提取出与用户行为相关的特征,例如使用频率、使用时长、功耗水平等,以便后续的模型分析和判断。 接下来,使用bp神经网络模型进行训练。首先需要对提取到的特征进行归一化处理,以避免不同特征之间的量纲差异对模型训练的影响。然后,将处理后的特征作为输入,用户行为及事件作为目标,使用bp神经网络进行模型的训练。 最后,对训练好的模型进行测试和应用。可以使用新的家电用户数据来测试模型的准确性和可靠性,并识别出特定事件,例如用户是否离家、是否有异常使用等,以提供安全保障和智能管理。 总而言之,基于bp神经网络的家电用户行为分析事件识别模型的构建是一种通过人工神经网络技术来分析用户行为、识别事件的方法,它可以帮助家电用户实现智能化的、个性化的管理和控制,提升用户体验和居家安全性。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值