[DM實戰]家用電器用戶行爲分析與事件識別

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數據分析與挖掘》   --張良均

發佈了74 篇原創文章 · 獲贊 18 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章