美文网首页
决策树(机器学习1)(代码)

决策树(机器学习1)(代码)

作者: 小火伴 | 来源:发表于2019-02-28 02:50 被阅读0次

实验内容

You are offered an excel file.
In this file, you can get the information of all the students in XXX university. The information includes students’ personal information (such as name, student ID, respective departments, age, native place) and course information (such as name of the courses and their respective grades).
You are asked to build a classification model to divide the grades into five categories: excellent, good, medium, pass, fail. The classification process is based on the information of name and native place. You should also show you results in a visual way.

理论分析

这次实验要求我们按照名字和籍贯,预测学生成绩的等级。因为之前都是跑函数逼近类模型,这次我想尝试一下可解释性强的决策树模型。
决策树是一种简单高效并且具有强解释性的模型,广泛应用于数据分析领域。其本质是一颗由多个判断节点组成的树,如:


在使用模型进行预测时,根据输入参数依次在各个判断节点进行判断游走,最后到叶子节点即为预测结果。
现在有这样的一些数据,需要从姓名和籍贯预测成绩所属类别,共5个等级。


如果我们以籍贯先进行分类,能得到一些结果(在叶子上),但是这样分叶子上不一定是同一类标签。所以我们引入对一个集合进行的有序程度进行量化,然后引入信息增益概念对一次拆分进行量化评价。
熵是信息论中的概念,用来表示集合的无序程度,熵越大表示集合越混乱,反之则表示集合越有序。熵的计算公式为:
E=-P log_2P
信息增益,假设集合 U,一次拆分后变为了两个集合 u1 和 u2 ,则有:
\Delta E=E(U)-(P_{u1} E(u1)+P_{u2}E(u2))

可以通过信息增益量化一次拆分的结果好坏,下一步就是构造决策树,主要步骤如下:
1.遍历每个决策条件(如:籍贯、姓名),对结果集进行拆分
2.计算该决策条件下,所有可能的拆分情况的信息增益,信息增益最大的拆分为本次最优拆分
3.递归执行1、2两步,直至信息增益<=0

实验结果

语言:Python3.6
系统:MacOS 10.13.3
硬件:2.9 GHz Intel Core i5
16 GB 1867 MHz DDR3
1.数据量化
将文本数据转成可计算形式。这里我采用二值词计数向量编码姓名,用one-hot编码籍贯。
例如,名字:abbd -> [1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
籍贯:102 ->[0,1,0,0,0]
将分数按照等间隔5分类成了[0]=excellent, good, medium, pass,[5]= fail。
2.数据可视化
这里做了pca降维
name explained variance ratio: 0.212
ID explained variance ratio: 0.186
猜想:成绩与名字应该没有关系



发现数据确实没有明显的聚集分布。
3.调整模型参数
测试不同的最大深度有什么不一样效果


结果完全的欠拟合。符合猜想。
4.那也得训练模型



无论哪个特征,模型都无法收敛。
  1. 模型导出



实验总结

决策树容易过度拟合数据,它可能专门针对训练集创建出来的分支,其熵值可能会比真实情况有所降低。进行剪枝可以减轻这种现象,人工设置一个信息增益的阀值,自下而上遍历决策树,将信息增益低于该阀值的拆分进行合并
从本实验来看,籍贯与名字对最终成绩影响小于30%。
本次实验简单尝试了决策树算法,该算法虽然简单,但是在很多场景能取得非常好的效果。另外,从决策树发展出了更为高级复杂的随机森林,如果有时间,,可以去深入了解。

代码

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from sklearn.preprocessing import minmax_scale
from sklearn import tree
import graphviz
from sklearn.model_selection import learning_curve,validation_curve
from mpl_toolkits.mplot3d import Axes3D

# file='chengji.csv'
# f_csv=pd.read_csv(file)
# 把籍贯向量化
# '''
# jiguan={}
# ids=(f_csv['籍贯'])
# j=0
# for i in ids:
#     if i not in jiguan:
#         jiguan[i]=j
#         j+=1
# print(jiguan)
# id_list=np.zeros((len(ids),len(jiguan.keys())))#9类
# for i,id in enumerate(ids):
#     id_list[i][jiguan[id]]=1
# print(id_list)
# np.save('idlist.npy',id_list)
# '''

# 名字词向量化
# names=(f_csv['姓名'].values)
# print(names.values)
# names=np.array(names)
# np.save('names.npy',names)
# print(names==names0)

# hash_text=text.HashingVectorizer(n_features=26)
# labels=np.load('label.npy')
# grades_one=np.load('grades_one.npy')
# print(names)
# start=ord('a')
# name_vec=np.zeros((len(names),26),dtype=np.uint8)
# for i,n in enumerate(names):
#     n=set(n)
#     for a in n:
#         name_vec[i][ord(a)-start]=1
#     pass
# print(name_vec)
# np.save('name_vec.npy',name_vec)
# t=hash_text.transform(names)
# exit()
# name_vec=np.load('name_vec.npy')
# id_list=np.load('idlist.npy')

# nb,rf,svm,
#
# for i,l in enumerate(labels):
#     one=np.where(l == 1)[0].ravel()[0]
#     print(one)
#     labels[i]=one

# labels=labels[:,:1].astype(np.int32)
# np.save('label.npy',labels)
# print(labels)
# labels=np.load('label.npy')
# names=np.load('name_vec.npy')
# id_list=np.load('idlist.npy')
# X=np.concatenate((names,id_list),axis=1)
# np.save('X.npy',X)
# exit()
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
cmap=cm.get_cmap('Set1')
np.random.seed(0)

X=np.load('X.npy')[:,:]
labels=np.load('label.npy')
from sklearn.decomposition import PCA
pca = PCA(n_components=1)
name=pca.fit_transform(X[:,:26])
print('pca(n=%d) explained variance ratio: %.3f' %(1, np.sum(pca.explained_variance_ratio_)))
ID=pca.fit_transform(X[:,26:])
print('pca(n=%d) explained variance ratio: %.3f' %(1, np.sum(pca.explained_variance_ratio_)))
ID,name=minmax_scale(ID),minmax_scale(name)
def draw_image(x,y):
    for i in range(5):
        indice=np.where(y==[i])[0]
        xi=x[indice]
        # print(xi)
        # plt.scatter(xi[:,0],xi[:,1],c=cmap(np.ones((len(indice),))*1/(i+1)))
        ax.scatter(xi[:,0],xi[:,1],
        np.ones((len(indice),1))*1/(i+1),
        c=cmap(1-np.ones((len(indice),))*i*0.1)
        )
    pass
nex_x=np.concatenate((name,ID),axis=1)
draw_image(nex_x,labels)
# plt.show()
plt.savefig('showme3d.tiff')

'''
# 决策树
clf=tree.DecisionTreeClassifier(max_depth=7)

clf.fit(X,labels)
print(clf.score(X,labels),np.sum(clf.feature_importances_[:26]))
print(clf.predict([X[0]]),labels[0])
dot_data = tree.export_graphviz(clf, out_file=None,
                            filled=True, rounded=True,
                            special_characters=True)
graph = graphviz.Source(dot_data)
graph.render("grades_by_name",cleanup=True)
'''

相关文章

网友评论

      本文标题:决策树(机器学习1)(代码)

      本文链接:https://www.haomeiwen.com/subject/edjcuqtx.html