CART决策树的上机实现
1.1 题目的主要研究内容(宋体四号加粗左对齐)
熟悉和掌握决策树的分类原理、实质和过程,掌握决策树典型算法(ID3、C4.5、CART)的核心思想和实现过程。
程序实现CART算法。
理解GINI函数的意义与CART算法的实现原理,在不使用sklearn和使用sklearn的情况下分别实现小数据集和较大数据集的决策树生成。
1.2 题目研究的工作基础或实验条件
(1)硬件环境:计算机
(2)软件环境:windows系统,python环境,pycharm编辑器
1.3 设计思想
在使用机器学习库sklearn和不使用sklearn两种情况下分别实现CART算法例程。
1.4 流程图
1.4.1不使用sklearn机器学习库
所用数据集为某产品销量与三个特征的关系,共34组数据,下图列出了数据集部分数据。
图 1所用数据集示例
主要程序由本组C4.5算法程序修改而来,将C4.5算法程序中的计算信息增益和信息增益率换成计算Gini指数,在选择最优特征时选择使Gini指数最小的特征。主程序流程图如图2所示
图 2主程序流程图
1.4.2 使用sklearn机器学习库
由于上一种方法数据集数据量过小,使得无论是训练结果还是预测结果的准确率都偏低,故我有在鸢尾花数据集上再次进行了决策树的训练,为了使程序更加简洁易读,我使用了sklearn机器学习工具库进行编程。主程序流程图如图3所示
图 3鸢尾花决策树主程序流程图
1.5 主要程序代码(要求必须有注释)
1.5.1 不使用sklearn机器学习库
def main():
#获取训练集,所有属性名称,每个属性的类别,所有标签(最后一列)
dataTrain, featureNames, featureNamesSet,labelList = readDataSet("data/ex3data.csv")
print("dataTrain: \n",dataTrain,"\n","featureNames:\n",featureNames,"\n","featureNamesSet:\n",featureNamesSet,"\n","labelList:\n",labelList)
#获取测试集
#train= pd.read_csv("data/ex3data.csv")
#test = pd.read_csv("data/ex3data.csv")
train= pd.read_csv("data/ex3data.csv")[:25]
test = pd.read_csv("data/ex3data.csv")[25:34]
#print("train:\n",train[:10])
print("train:\n",train[:10])
print("test:\n",test[:10])
#生成决策树
t0 = time.time()
tree = createFullDecisionTree(dataTrain, featureNames,featureNamesSet,labelList)
t1 = time.time()
print("CART算法生成决策树的时间开销:",(t1 - t0)*(10**6),"us")
createPlot(tree,"fig/CART.png")
predictTrain = train.apply(lambda x: tree_predict(tree, x), axis=1)
label_list = train.iloc[:, -1]
score = accuracy_score(label_list, predictTrain)
print('训练补全分支准确率为:' + repr(score * 100) + '%')
#预测
y_predict = test.apply(lambda x: tree_predict(tree, x), axis=1)
label_list = test.iloc[:, -1]
score = accuracy_score(label_list, y_predict)
print('测试集补全分支准确率为:' + repr(score * 100) + '%')
def createFullDecisionTree(dataSet, featureNames, featureNamesSet, labelListParent):
labelList = [x[-1] for x in dataSet]
if(len(dataSet) == 0): # 如果数据集为空,返回父节点标签列表的主要标签
return mainLabel(labelListParent)
elif(len(dataSet[0]) == 1): # 没有可划分的属性,选出最多的label作为该数据集的标签
return mainLabel(labelList)
elif(labelList.count(labelList[0]) == len(labelList)): # 全部都属于同一个Label,返回labList[0]
return labelList[0]
# 不满足上面的边界情况则需要创建新的分支节点
bestFeatureIndex = chooseBestFeature_CART(dataSet) # 根据信息增益,选择数据集中最好的特征下标
bestFeatureName = featureNames.pop(bestFeatureIndex) # 取出属性类别
myTree = {bestFeatureName: {}} # 新建节点,一个字典
featureList = featureNamesSet.pop(bestFeatureIndex) # 取出最佳属性的类别
featureSet = set(featureList) # 剔除属性类别集合
for feature in featureSet: # 遍历最佳属性所有取值
featureNamesNext = featureNames[:]
featureNamesSetNext = featureNamesSet[:][:]
splitedDataSet = splitDataSet(dataSet, bestFeatureIndex, feature) # 剔除最佳特征
# 递归地生成新的节点
# featureNames:数据属性类别, featureNamesSet:属性类别集合, labelListParent:父节点标签列表
# 一个二叉树
myTree[bestFeatureName][feature] = createFullDecisionTree(splitedDataSet, featureNamesNext, featureNamesSetNext, labelList)
return myTree
1.5.2 使用sklearn机器学习库
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn import datasets
#from sklearn.cross_validation import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
from sklearn.model_selection import train_test_split
# 加载鸢尾花数据集
iris = datasets.load_iris()
print(iris)
# 特征数据
iris_feature = iris.data
#print(iris_feature)
# 分类数据
iris_target = iris.target
#print(iris_target)
# 将数据随机的分为训练集和测试集
feature_train, feature_test, target_train, target_test = train_test_split(iris_feature, iris_target, test_size=0.33,random_state=56)
# random_state乱序程度
# 模型训练
# 导入决策树,所有参数为默认,还可以引入损失函数(信息熵,基尼指数);
dt_model = DecisionTreeClassifier(criterion='gini')
# 用决策树训练
dt_model.fit(feature_train, target_train)
# 使用测试数据测试
predict_results = dt_model.predict(feature_test)
#
export_graphviz(
dt_model, #刚刚训练好的树模型
out_file="iris_tree2.dot", #
feature_names=iris.feature_names[:],
class_names=iris.target_names, #标签设置
rounded=True,
filled=True
)
# 利用测试数据测试
print(predict_results)
print(target_test)
# 以下两种评比测试结果,传入参数有区别
scores = dt_model.score(feature_test, target_test)
print(scores)
print('scores2=',accuracy_score(predict_results, target_test))
1.6 运行结果及分析
1.6.1 不使用sklearn机器学习库
图 4 在小数据集上生成的决策树
图 5 决策树准确率
1.6.1 使用sklearn机器学习库
图 6 在鸢尾花数据集上使用sklearn生成的决策树
通过以上两个代码结果我们可以看出