家用电器用户行为分析与事件识别代码详解+修改后运行无误的代码
運(yùn)行環(huán)境:
ubuntu16.04 64位
pycharm python3.5.2
相關(guān)軟件列表:
cycler (0.10.0)
graphviz (0.7.1)
h5py (2.7.0)
Keras (2.0.4)
matplotlib (2.0.2)
numpy (1.12.1)
pandas (0.20.1)
pip (8.1.1)
protobuf (3.3.0)
pydot (1.2.3)
pyparsing (2.2.0)
python-dateutil (2.6.0)
pytz (2017.2)
PyYAML (3.12)
scipy (0.19.0)
setuptools (20.10.1)
six (1.10.0)
tensorflow (1.1.0)
Theano (0.9.0)
Werkzeug (0.12.2)
wheel (0.29.0)
xlrd (1.0.0)
xlwt (1.2.0)
-------------------------------------------------------------------下面是10-1-----------------------------------------------------------------------------------
#-*- coding: utf-8 -*- #用水事件劃分 import pandas as pdthreshold = pd.Timedelta('4 min') #閾值為分鐘 inputfile = '../data/water_heater.xls' #輸入數(shù)據(jù)路徑,需要使用Excel格式 outputfile = '../tmp/dividsequence.xls' #輸出數(shù)據(jù)路徑,需要使用Excel格式data = pd.read_excel(inputfile) data[u'發(fā)生時(shí)間'] = pd.to_datetime(data[u'發(fā)生時(shí)間'], format = '%Y%m%d%H%M%S') data = data[data[u'水流量'] > 0] #只要流量大于0的記錄 d = data[u'發(fā)生時(shí)間'].diff() > threshold #相鄰時(shí)間作差分,比較是否大于閾值 data[u'事件編號(hào)'] = d.cumsum() + 1 #通過(guò)累積求和的方式為事件編號(hào)data.to_excel(outputfile)這個(gè)代碼什么意思呢?
也就是說(shuō),根據(jù)水流量和時(shí)間間隔的頻率來(lái)判斷用戶第幾次用水,舉個(gè)通俗的例子,就說(shuō)洗菜把。
洗一顆青菜,洗一個(gè)葉子時(shí)需要用水對(duì)吧,但是呢,我把青菜的瓣兒一個(gè)個(gè)扳下來(lái)的這會(huì)兒功夫是不需要用水的對(duì)吧?
在扳的時(shí)候我停掉水龍頭,拌青菜完了之后開(kāi)始洗了,就需要用水,然后洗下一個(gè)青菜,再停水。
那么整個(gè)洗菜的過(guò)程中我有停水,也有用水,整個(gè)過(guò)程視為一次用水事件。
P205中表格的數(shù)據(jù)解釋:
可以看到
20141019172323
與
20141019172325
這兩個(gè)發(fā)生事件只相隔了2秒,水流量反而減少了,這個(gè)可以理解為水龍頭開(kāi)大開(kāi)小導(dǎo)致。
-------------------------------------------------------------------下面是10-2-----------------------------------------------------------------------------------
這個(gè)代碼的意思就是為了尋找書(shū)本p211的圖10-4的斜率為零的線段的起始點(diǎn)。
當(dāng)線段下降很陡的時(shí)候,說(shuō)明線段中的這幾個(gè)點(diǎn)很可能屬于同一個(gè)事件,所以化為一個(gè)事件。
同樣的,當(dāng)線段很平坦,閾值的遞增對(duì)事件總數(shù)影響不大時(shí),那么曲線上的多個(gè)點(diǎn)代表的事件總是說(shuō)明分類比較合理,也就是說(shuō)此時(shí)每個(gè)用水事件之間相隔時(shí)間間隔較大。
-------------------------------------------------------------------下面是10-3-----------------------------------------------------------------------------------
接下來(lái)這個(gè)代碼就是數(shù)據(jù)的輸入輸出之間進(jìn)行模型訓(xùn)練了,書(shū)上的代碼沒(méi)辦法直接運(yùn)行,我進(jìn)行了修改,如下:
#-*- coding: utf-8 -*- #建立、訓(xùn)練多層神經(jīng)網(wǎng)絡(luò),并完成模型的檢驗(yàn) from __future__ import print_function import pandas as pd from keras.utils.vis_utils import plot_modelinputfile1='../data/train_neural_network_data.xls' #訓(xùn)練數(shù)據(jù) inputfile2='../data/test_neural_network_data.xls' #測(cè)試數(shù)據(jù) testoutputfile = '../tmp/test_output_data.xls' #測(cè)試數(shù)據(jù)模型輸出文件 data_train = pd.read_excel(inputfile1) #讀入訓(xùn)練數(shù)據(jù)(由日志標(biāo)記事件是否為洗浴) data_test = pd.read_excel(inputfile2) #讀入測(cè)試數(shù)據(jù)(由日志標(biāo)記事件是否為洗浴) y_train = data_train.iloc[:,4].as_matrix() #訓(xùn)練樣本標(biāo)簽列 x_train = data_train.iloc[:,5:17].as_matrix() #訓(xùn)練樣本特征 y_test = data_test.iloc[:,4].as_matrix() #測(cè)試樣本標(biāo)簽列 x_test = data_test.iloc[:,5:17].as_matrix() #測(cè)試樣本特征from keras.models import Sequential from keras.layers.core import Dense, Dropout, Activation from keras.layers import Dense, Activationmodel = Sequential() #建立模型 model.add(Dense(output_dim=17,input_dim=11)) #添加輸入層、隱藏層的連接 model.add(Activation('relu')) #以Relu函數(shù)為激活函數(shù)model.add(Dense(output_dim=10,input_dim=17)) #添加隱藏層、隱藏層的連接 model.add(Activation('relu')) #以Relu函數(shù)為激活函數(shù)model.add(Dense(input_dim=10,output_dim=1)) #添加隱藏層、輸出層的連接 model.add(Activation('sigmoid')) #以sigmoid函數(shù)為激活函數(shù) #編譯模型,損失函數(shù)為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) #訓(xùn)練模型 model.save_weights('../tmp/net.model') #保存模型參數(shù)r = pd.DataFrame(model.predict_classes(x_test), columns = [u'預(yù)測(cè)結(jié)果']) pd.concat([data_test.iloc[:,:5], r], axis = 1).to_excel(testoutputfile) model.predict(x_test) ############自己添加的######################## plot_model(model, to_file='model.png', show_shapes=True)
代碼運(yùn)行結(jié)果為:
| ? | 熱水事件 | 起始數(shù)據(jù)編號(hào) | 終止數(shù)據(jù)編號(hào) | 開(kāi)始時(shí)間(begin_time) | 根據(jù)日志判斷是否為洗浴(1表示是,0表示否) | 預(yù)測(cè)結(jié)果 |
| 0 | 1 | 73 | 336 | 2015-01-05 9:42:41' | 1 | 1 |
| 1 | 2 | 420 | 535 | '2015-01-05 18:05:28' | 1 | 1 |
| 2 | 3 | 538 | 706 | '2015-01-05 18:25:24' | 1 | 1 |
| 3 | 4 | 793 | 910 | '2015-01-05 20:00:42' | 1 | 1 |
| 4 | 5 | 935 | 1133 | '2015-01-05 20:15:13' | 1 | 1 |
| 5 | 6 | 1172 | 1274 | '2015-01-05 20:42:41' | 1 | 1 |
| 6 | 7 | 1641 | 1770 | '2015-01-06 08:08:26' | 0 | 0 |
| 7 | 8 | 2105 | 2280 | 2015-01-06 11:31:13' | 1 | 1 |
| 8 | 9 | 2290 | 2506 | '2015-01-06 17:08:35' | 1 | 1 |
| 9 | 10 | 2562 | 2708 | '2015-01-06 17:43:48' | 1 | 1 |
| 10 | 11 | 3141 | 3284 | '2015-01-07 10:01:57' | 0 | 1 |
| 11 | 12 | 3524 | 3655 | 2015-01-07 13:32:43' | 0 | 1 |
| 12 | 13 | 3659 | 3863 | '2015-01-07 17:48:22' | 1 | 1 |
| 13 | 14 | 3937 | 4125 | '2015-01-07 18:26:49' | 1 | 1 |
| 14 | 15 | 4145 | 4373 | '2015-01-07 18:46:07' | 1 | 1 |
| 15 | 16 | 4411 | 4538 | '2015-01-07 19:18:08' | 1 | 1 |
| 16 | 17 | 5700 | 5894 | 2015-01-08 7:08:43' | 0 | 1 |
| 17 | 18 | 5913 | 6178 | 2015-01-08 13:23:42' | 1 | 1 |
| 18 | 19 | 6238 | 6443 | 2015-01-08 18:06:47' | 1 | 1 |
| 19 | 20 | 6629 | 6696 | 2015-01-08 20:18:58' | 1 | 1 |
| 20 | 21 | 6713 | 6879 | 2015-01-08 20:32:16' | 1 | 1 |
注意每次預(yù)測(cè)結(jié)果都是不一樣的,上面的預(yù)測(cè)結(jié)果準(zhǔn)確度是80%,如果多訓(xùn)練幾次會(huì)發(fā)現(xiàn)準(zhǔn)確度在60%~80%之間,靠右兩列數(shù)值不同時(shí),則為判斷錯(cuò)誤,相同時(shí),則為判斷正確。
并且會(huì)出現(xiàn)隨機(jī)報(bào)錯(cuò),也就是說(shuō)一次運(yùn)行無(wú)報(bào)錯(cuò),另外一次運(yùn)行報(bào)錯(cuò),屬正常現(xiàn)象,因?yàn)槊看斡?xùn)練都是局部最優(yōu)解。
使用的神經(jīng)網(wǎng)絡(luò)模型為:
總結(jié)
以上是生活随笔為你收集整理的家用电器用户行为分析与事件识别代码详解+修改后运行无误的代码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ubuntu16.04下面使用graph
- 下一篇: args和kwargs以及argv用法