返回介绍

3.数据清洗

发布于 2024-01-28 21:41:24 字数 3830 浏览 0 评论 0 收藏 0

本案例中存在用水数据状态记录缺失的情况,需要对缺失的数据状态记录进行添加。在热水器工作态改变或处于用水阶段时,热水器每2秒(发送阈值)传输一条状态记录,而划分一次完整用水事件时,需要一个开始用水的状态记录和结束用水的状态记录。但是,在划分一次完整用水事件时,发现数据中存在没有结束用水的状态记录情况,该类缺失值问题如表10-16所示。热水器状态发生改变,第5条状态记录和第7条状态记录的时间间隔应该为2秒,而表中两条记录间隔为1小时27分28秒。

表10-16 状态记录中的缺失值

这可能是由于网络故障等原因导致状态记录时间间隔为几十分钟甚至几小时的情况,该类问题若用均值去填充会造成用水时间为几十分钟甚至几小时的误差。对于上述特殊情况,本案例数据进行如下处理:在存在用水状态记录缺失的情况下,填充一条状态记录使水流量为0,发生时间加2秒,其余属性状态不变。即在表10-16的第5条状态记录和第7条状态记录之间加一条记录,即第6条状态记录,如表10-17所示。

表10-17 状态记录中缺失值的处理

10.2.4 模型构建

经过数据预处理后,得到的建模样本数据如表10-18所示。

表10-18 部分建模样本数据示例列表

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

图10-6 BP神经模型识别洗浴事件

在训练神经网络的时候,选取了“候选洗浴事件”的11个属性作为网络的输入,分别为:洗浴时间点、总用水时长、总停顿时长、平均停顿时长、停顿次数、用水时长、用水时长/总用水时长、总用水量、平均水流量、水流量波动和停顿时长波动。训练BP网络时给定的输出(教师信号)为1与0,其中1代表该次事件为洗浴事件,0表示该次事件不是洗浴事件。其中,是否为洗浴事件根据用户提供的用水记录日志得到。

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

使用Python的Keras库来训练神经网络,训练样本为根据用户记录的日志标记好的用水事件,详细代码见代码清单10-3。

代码清单10-3 训练多层神经网络代码

#-*- coding: utf-8 -*-
#建立、训练多层神经网络,并完成模型的检验
from __future__ import print_function
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(11, 17)) #添加输入层、隐藏层的连接
model.add(Activation('relu')) #以Relu函数为激活函数
model.add(Dense(17, 10)) #添加隐藏层、隐藏层的连接
model.add(Activation('relu')) #以Relu函数为激活函数
model.add(Dense(10, 1)) #添加隐藏层、输出层的连接
model.add(Activation('sigmoid')) #以sigmoid函数为激活函数
#编译模型,损失函数为binary_crossentropy,用adam法求解
model.compile(loss='binary_crossentropy', optimizer='adam', class_mode="binary")
model.fit(x_train, y_train, nb_epoch = 100, 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)

代码详见:demo/code/neural_network.py

根据样本,得到训练好的神经网络后,就可以用来识别对应用户的洗浴事件,待检测的样本的11个属性作为输入,输出层输出一个值在[-1,1]范围内,如果该值小于0,则该事件不是洗浴事件,如果该值大于0,则该事件是洗浴事件。某热水器用户记录了两周的热水器用水日志,将前一周的数据作为训练数据,后一周的数据作为测试数据,代入上述模型进行测试。

10.2.5 模型检验

根据该热水器用户提供的用水日志来判断事件是否为洗浴与多层神经网络模型识别结果的比较,如表10-19所示,总共21条检测数据,准确识别了18条数据,模型对洗浴事件的识别准确率为85.5%。

表10-19 用户日志判断结果与模型输出判断结果比较

由于训练数据为一周数据,训练样本过少,可能会造成模型训练不准确,但长期让用户记录用水日志存在一定的操作困难,在这里模型检验用了两周的用户用水日志。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文