Sklearn DecisionClassifier提取规则
children_left = clf.tree_.children_left # 左节点编号
children_right = clf.tree_.children_right # 右节点编号
feature = clf.tree_.feature # 分割的变量
threshold = clf.tree_.threshold # 分割阈值
impurity = clf.tree_.impurity # 不纯度(gini)
n_node_samples = clf.tree_.n_node_samples # 样本个数
value = clf.tree_.value # 样本分布
#-------------打印------------------------------
print("children_left:",children_left)
print("children_right:",children_right)
print("feature:",feature)
print("threshold:",threshold)
print("impurity:",impurity)
print("n_node_samples:",n_node_samples)
print("value:",value)
在第一题第二问中我们希望的到“训练好的模型的规则在测试集上表现最好的几条”。解读为模型为训练集训练的树,而需要重新编写函数评价树的每个结点在测试集上的表现。我认为每条规则的正确率即为该结点下预测正确的所有样本/该结点往下所有样本。且这种解释符合实际生产知道需求。
由于sklearn的DecisionTree并不提供更深层的属性,最终我编写了一套递归代码用于提起最好的几条规则(结点).
"""在实际生产中我们需要知道在测试集上最优的几个特征以指导生产"""
def get_lastnodenum(test_onesample,node_num):
left_node = children_left[node_num] # 左节点编号
right_node = children_right[node_num]
if left_node < 0 or right_node < 0:
return node_num
else:
if test_onesample[feature[node_num]]<threshold[node_num]:
return get_lastnodenum(test_onesample,left_node)
else:
return get_lastnodenum(test_onesample,right_node)
def last_node_find(test_data):
N=len(test_data)#测试集样本数
return [get_lastnodenum(test_data.to_numpy()[i,:],0) for i in range(N)]
def recursion(node_num,lastnode_PreTrue,lastnode_PreCount,lastnode_num):
#递归遍历节点
left_node = children_left[node_num] # 左节点编号
right_node = children_right[node_num]
if left_node < 0 or right_node < 0:
try:
ind=lastnode_num.index(node_num)
TrueCount_list[node_num]=lastnode_PreTrue[lastnode_num.index(node_num)]
AllCount_List[node_num]=lastnode_PreCount[lastnode_num.index(node_num)]
except:
TrueCount_list[node_num]=0
AllCount_List[node_num]=0
else:
recursion(left_node,lastnode_PreTrue,lastnode_PreCount,lastnode_num)
recursion(right_node,lastnode_PreTrue,lastnode_PreCount,lastnode_num)
TrueCount_list[node_num]=TrueCount_list[left_node]+TrueCount_list[right_node]
AllCount_List[node_num]=AllCount_List[left_node]+AllCount_List[right_node]
def Feature_Extra(clf,test_data,test_label):
PredictCorrect=(clf.predict(test_data)==test_label)
lastnode_list=last_node_find(test_data)#test_data中所有样本所属的尾节点
df = pd.DataFrame({'PredictCorrect':PredictCorrect,'lastnode': lastnode_list})
PreTrue=df.groupby(['lastnode'])['PredictCorrect'].sum()
PreCount=df.groupby(['lastnode'])['PredictCorrect'].count()
lastnode_num=PreTrue.index.to_list()
lastnode_PreTrue=PreTrue.to_list()
lastnode_PreCount=PreCount.to_list()
recursion(0,lastnode_PreTrue,lastnode_PreCount,lastnode_num)
Acc_list=[TrueCount_list[i]/AllCount_List[i] if AllCount_List[i]!=0 else 0 for i in range(n)]
return Acc_list
n=len(children_left)
TrueCount_list=[0]*n
AllCount_List=[0]*n
Acc_list=Feature_Extra(clf,X_test,y_test)
np.array(Acc_list).argsort()