机器学习-专题详述

【代码】如何将sklearn的决策树布署到生产环境

作者 : 老饼 发表日期 : 2022-06-26 09:50:17 更新日期 : 2024-11-17 11:11:45
本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com



在训练好决策树后,我们需要布署到生产上进行预测

本文讲解如何将sklarn的决策树规则提取并布署到生产上




  01. sklearn的决策树-生产环境布署  



本节讲解如何将sklearn的决策树布署到生产环境




     将sklearn的决策树布署到生产环境的方法     


在sklearn中将决策树模型建好之后,要提取决策树规则布署到生产
由于生产环境可能是JAVA环境或其它,往往不能直接调用sklearn的模型对象(或调用很麻烦)
因此,需要先将决策树规则提取出来,再布署到生产
   一个比较通用的布署方案如下: 
一般是采用数据与代码分离的方案,
即只提取数据,在生产环境写出通用预测代码, 需要布署新的模型只需替换数据即
即如下两步:
1. 提取出决策树的模型数据                        
2. 编写一个生产环境上的预测函数              
 一般不弄成一系列的if else,写死代码不便于更换模型




      提取决策树模型数据      


下面是老饼编写的get_tree函数,可以将树数据提取成字典
 具体代码如下:
from sklearn import tree
import numpy as np
def get_tree(sk_tree):
    #--------------拷贝sklearn树模型关键信息--------------------
    children_left       = sk_tree.tree_.children_left.copy()            # 左节点编号
    children_right      = sk_tree.tree_.children_right.copy()          # 右节点编号
    feature          = sk_tree.tree_.feature.copy()               # 分割的变量
    threshold         = sk_tree.tree_.threshold.copy()              # 分割阈值
    impurity          = sk_tree.tree_.impurity.copy()               # 不纯度(gini)
    n_node_samples      = sk_tree.tree_.n_node_samples.copy()           # 样本个数
    value            = sk_tree.tree_.value.copy()                 # 样本分布
    n_sample         = value[0].sum()                          # 总样本个数
    node_num         = len(children_left)                       # 节点个数
    depth = sk_tree.get_depth()
    
    # ------------补充节点父节点信息---------------------------
    parent = np.zeros(node_num).astype(int)
    parent[0] = -1
    branch_idx = np.where(children_left!=-1)[0]
    for i in branch_idx:
        parent[children_left[i]] = i   
        parent[children_right[i]]= i 
    #-------------存成字典-----------------------------------------    
    tree = {
        'children_left':children_left
        ,'children_right':children_right
        ,'feature':feature
        ,'threshold':threshold
        ,'impurity':impurity
        ,'n_node_samples':n_node_samples
        ,'value':value
        ,'depth':depth
        ,'n_sample':n_sample
        ,'node_num':node_num
        ,'parent':parent
        }
    return tree
将sklearn训练好的决策树模型传入get_tree函数,
get_tree函数将其中的决策树模型信息单独提取出来,返回字典对象
自己再根据生产上的使用语言需要,转成对应的数据文件,之后在生产上把数据文件加载成生产语言的数据对象
  get_tree函数的使用可以参考后面《准确性测试》中的代码




  决策树-预测函数(生产环境)   


在生产上编写一个tree_predict 函数,需要预测时就调用tree_predict进行预测
 以下是python的一个Demo(其它语言类似以下逻辑):
import numpy as np
def tree_predict(tree,x):
    node_idx = 0
    t = 0
    while(t<tree['depth']):
        if(x[tree['feature'][node_idx]]<=tree['threshold'][node_idx]):
            node_idx =   tree['children_left'][node_idx]
        else:
            node_idx =   tree['children_right'][node_idx]
        if(tree['children_left'][node_idx]==-1):
            value =tree['value'][node_idx][0]
            pred_class = np.argmax(value)
            pred_prob =  value/value.sum()
            return pred_class,pred_prob
        t =t+1






  02. 决策树布署-准确性测试  




本节验证上述布署方法与直接调用sklearn的预测结果是一致的




     决策树布署-准确性测试     


下面我们编写代码,测试用 以上get_tree和tree_predict方式的预测结果
与sklearn原模型给出的结果是否一致
 具体测试代码如下:
from sklearn.datasets import load_iris
from sklearn import tree
import numpy as np
from get_tree import get_tree
from tree_pred import tree_predict

#----------------数据准备----------------------------
iris = load_iris()                          # 加载数据
X = iris.data
y = iris.target
#---------------模型训练----------------------------------
clf = tree.DecisionTreeClassifier()               # sk-learn的决策树模型
clf = clf.fit(X, y)                        # 用数据训练树模型构建()
#--------------将树提取成简单的字典--------------------------------
tree = get_tree(clf)
#-------------------------
#将tree持久化到服务器,服务器中用tree_predict进行预测即可
#-------------------------

#------------测试函数的准确性-----------------------------
self_pred_y = np.zeros(len(y))
self_pred_prob = np.zeros((len(y),len(tree['value'][0][0])))
for i in range(X.shape[0]):
    pred_class,pred_prob = tree_predict(tree,X[i])
    self_pred_y[i] = pred_class
    self_pred_prob[i] = pred_prob
pred_y = clf.predict(X)
pred_prob = clf.predict_proba(X)
print("与sklearn预测结果差异个数(类别):",np.sum(pred_y != self_pred_y))
print("与sklearn预测结果差异个数(概率):",np.sum(pred_prob != self_pred_prob))
运行结果如下:
 
可以看到,自写函数与sklearn模型的预测结果是一致的





这就是如何将sklearn的决策树布署到生产的方法了~






 End 





联系老饼