家用电器用户行为分析与事件识别代码详解+修改后运行无误的代码
運行環境:
ubuntu16.04 64位
pycharm python3.5.2
相關軟件列表:
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' #輸入數據路徑,需要使用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') data = data[data[u'水流量'] > 0] #只要流量大于0的記錄 d = data[u'發生時間'].diff() > threshold #相鄰時間作差分,比較是否大于閾值 data[u'事件編號'] = d.cumsum() + 1 #通過累積求和的方式為事件編號data.to_excel(outputfile)這個代碼什么意思呢?
也就是說,根據水流量和時間間隔的頻率來判斷用戶第幾次用水,舉個通俗的例子,就說洗菜把。
洗一顆青菜,洗一個葉子時需要用水對吧,但是呢,我把青菜的瓣兒一個個扳下來的這會兒功夫是不需要用水的對吧?
在扳的時候我停掉水龍頭,拌青菜完了之后開始洗了,就需要用水,然后洗下一個青菜,再停水。
那么整個洗菜的過程中我有停水,也有用水,整個過程視為一次用水事件。
P205中表格的數據解釋:
可以看到
20141019172323
與
20141019172325
這兩個發生事件只相隔了2秒,水流量反而減少了,這個可以理解為水龍頭開大開小導致。
-------------------------------------------------------------------下面是10-2-----------------------------------------------------------------------------------
這個代碼的意思就是為了尋找書本p211的圖10-4的斜率為零的線段的起始點。
當線段下降很陡的時候,說明線段中的這幾個點很可能屬于同一個事件,所以化為一個事件。
同樣的,當線段很平坦,閾值的遞增對事件總數影響不大時,那么曲線上的多個點代表的事件總是說明分類比較合理,也就是說此時每個用水事件之間相隔時間間隔較大。
-------------------------------------------------------------------下面是10-3-----------------------------------------------------------------------------------
接下來這個代碼就是數據的輸入輸出之間進行模型訓練了,書上的代碼沒辦法直接運行,我進行了修改,如下:
#-*- coding: utf-8 -*- #建立、訓練多層神經網絡,并完成模型的檢驗 from __future__ import print_function import pandas as pd from keras.utils.vis_utils import plot_modelinputfile1='../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 from keras.layers import Dense, Activationmodel = Sequential() #建立模型 model.add(Dense(output_dim=17,input_dim=11)) #添加輸入層、隱藏層的連接 model.add(Activation('relu')) #以Relu函數為激活函數model.add(Dense(output_dim=10,input_dim=17)) #添加隱藏層、隱藏層的連接 model.add(Activation('relu')) #以Relu函數為激活函數model.add(Dense(input_dim=10,output_dim=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) ############自己添加的######################## plot_model(model, to_file='model.png', show_shapes=True)
代碼運行結果為:
| ? | 熱水事件 | 起始數據編號 | 終止數據編號 | 開始時間(begin_time) | 根據日志判斷是否為洗浴(1表示是,0表示否) | 預測結果 |
| 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 |
注意每次預測結果都是不一樣的,上面的預測結果準確度是80%,如果多訓練幾次會發現準確度在60%~80%之間,靠右兩列數值不同時,則為判斷錯誤,相同時,則為判斷正確。
并且會出現隨機報錯,也就是說一次運行無報錯,另外一次運行報錯,屬正?,F象,因為每次訓練都是局部最優解。
使用的神經網絡模型為:
總結
以上是生活随笔為你收集整理的家用电器用户行为分析与事件识别代码详解+修改后运行无误的代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu16.04下面使用graph
- 下一篇: args和kwargs以及argv用法