本篇主要做的是一個流失預警模型實時查詢的一個測試,需求描述:用戶名單請求判斷是否流失,秒級內返回判斷結果。
操作場景如下:

流失預警模型,預測用戶是否在未來一段時間內流失(牽涉到流失定義,用戶活躍度定義,用戶行為時間定義等)建立,用到了用戶最近行為特征、行為趨勢特征等,最后預測是否流失(1流失,0留存)。在本文的測試之前已經把模型建好。
實驗條件:ubuntu13.04 32位,mysql,
mysqldb,
scikit-learn1.4
安裝Mysql
sudo apt-get install mysql-client-core-5.5
sudo apt-get install mysql-server
安裝python訪問mysql的ODBC
sudo apt-get install python-mysqldb //python操作mysql
登陸mysql 創建倉庫datamining,創建classification表,上傳用戶的行為數據,實驗中是2844900*24個字段(上傳數據的時候,要用
mysql --local-infile=1 -u root -p 登陸,因為需要從本地上傳)
安裝scikit-learn 1.4
sudo apt-get install build-essential python-dev python-numpy python-setuptools python-scipy libatlas-dev libatlas3-base
sudo apt-get install python-sklearn
Scikit-learn是用python寫的機器學習算法庫,里面算法非常多,而且文檔清晰而且完整,API的調用接口都很類似,用起來非常方便。
實測測試描述:隨機生成一個用戶ID,通過ID去mysql查詢該ID的行為特征,然后把該ID的行為通過scikit-learn預先生成好的模型測試,最后返回流失概率結果
代碼如下
# -*- coding: cp936 -*-
from sklearn.ensemble import RandomForestClassifier
import csv_io
import time,random
from sklearn.externals import joblib
from MySQLdb import *
userNum=1 #隨機產生用戶ID
sample=[str(i) for i in xrange(2844900)]
index=random.sample(sample,userNum)
fw=open('user.txt','w')
fw.writelines('\n'.join(index))
fw.close()
print "測試開始"
#計時
old=time.time()
#加載預先生成好的模型
rf=joblib.load('/home/kobe/datamining/model/dt.pkl')
new=time.time()
time_model=new-old
#查詢數據
f = open('user.txt')
index=[i.strip() for i in f.readlines()]
index='\''+'\',\''.join(index)+'\''
command="select * from classification where yyuid in (%s);" % (index)
cn=Connection('localhost','root','*******','datamining') #ip地址,用戶名,密碼,倉庫名字
cur=cn.cursor()
cur.execute(command) #執行命令
rows=cur.fetchall() #取回結果
test = [i[1:] for i in rows]
cur.close()
cn.close
old=time.time()
time_file=old-new
#通過測試
predicted_probs = rf.predict_proba(test)
predicted_probs = ["%f" % x[1] for x in predicted_probs]
new=time.time()
time_result=new-old
#把流失概率寫回文件
csv_io.write_delimited_file("result.csv",predicted_probs)
time_write=time.time()-new
#完成
print "Done!"
print "加載模型",time_model
print "查詢數據",time_file
print "模型測試",time_result
print "寫入結果",time_write
print "總耗時",time_model+time_file+time_result+time_write
最后測試了3種算法,算法都使用了默認參數,結果如下,單位是秒
|
加載模型時間 |
數據查詢時間 |
模型測試時間 |
寫入結果時間 |
前4項總時間 |
決策樹算法 |
0.086 |
0.074 |
0.0096 |
0.000590 |
0.1710 |
隨機森林 |
0.134 |
0.092 |
0.01303 |
0.000595 |
0.2397 |
邏輯回歸 |
0.104 |
0.087 |
0.0118 |
0.0006 |
0.2034 |
總結:從表格結果上看主要的時間是耗在模型加載跟數據查詢上。其中模型加載時間耗時占一半(優化方向:1)把模型一直cache到內存里,有沒有什么方案實現?2) 換別的編程語言。。),數據查詢這一塊,測試中在沒有對classification表建索引的情況下也能有這個效率有點讓我驚訝。當然生產環境下的實時不僅需要考慮這些,還要考慮用戶請求的並發量,用戶行為實時采集和計算(牽涉到流失計算那塊),前端傳ID的時間,結果返回時間等,有這方面經驗的朋友請多拍拍磚,指教下。