流失预警模型--实时查询
本篇主要做的是一个流失预警模型实时查询的一个测试,需求描述:用户名单请求判断是否流失,秒级内返回判断结果。
操作场景如下:
流失预警模型,预测用户是否在未来一段时间内流失(牵涉到流失定义,用户活跃度定义,用户行为时间定义等)建立,用到了用户最近行为特征、行为趋势特征等,最后预测是否流失(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的时间,结果返回时间等,有这方面经验的朋友请多拍拍砖,指教下。