学习机器学习
今天开始构建模型啦,没想到系统学习构建的第一个模型还是决策树>.<
主要内容:
- ID3算法
- CART算法
- 数据实现并比较
首先需要说的是导入数据
因为之前的实验已经保存过数据了,所以我打算直接把数据导入进来使用,当然在这期间,我也发现了之前代码的一些小纰漏(之前存数据时用的随机种子只用了个,所以导致保存的100个留出法的数据竟然一模一样!所以我稍加改进了之前的代码,让我的100个train/test互不相同。
train = np.load(file="train.npy",allow_pickle = True)# 这个参数据说是因为版本原因所以要加
test = np.load(file="test.npy",allow_pickle = True)
ID3算法
就是采用信息增益的方法来构造决策树,模型都是sklearn里面现成的,直接参数就好,这里因为我们导入数据是三维的,最外面是列表,列表中的每个元素是np.array数据类型,注意他们的索引规则是不一样的。
sum = 0
score = []
for i in range(100):
x_train = train[i][:,1:5]
y_train = train[i][:,5:6]
x_test = test[i][:,1:5]
y_test = test[i][:,5:6]
clf = tree.DecisionTreeClassifier(
criterion ="entropy"
,random_state = 40
)
clf = clf.fit(x_train,y_train)
# print(clf.predict(x_test)) #输出预测结果
# print("准确率为:", clf.score(x_test, y_test)) # 输出准确率
sum+=clf.score(x_test, y_test)
score.append(clf.score(x_test, y_test))
avg = sum/100
print("在测试集上的平均准确率为:",avg)
variance = 0
for i in score:
variance +=(i-avg)**2
print("在测试集上的方差为:",variance/100)
CART算法
代码基本一样,两种树的根本区别就是核心算法不同,这个是按照gini指数来算
sum = 0
score = []
for i in range(100):
x_train = train[i][:,1:5]
y_train = train[i][:,5:6]
x_test = test[i][:,1:5]
y_test = test[i][:,5:6]
clf = tree.DecisionTreeClassifier(
criterion ="gini"
,random_state = 30
)
clf = clf.fit(x_train,y_train)
# print(clf.predict(x_test))
# print("准确率为:", clf.score(x_test, y_test))
sum+=clf.score(x_test, y_test)
score.append(clf.score(x_test, y_test))
avg = sum/100
print("在测试集上的平均准确率为:",avg)
variance = 0
for i in score:
variance +=(i-avg)**2
print("在测试集上的方差为:",variance/100)
剪枝策略
只使用了sklearn自带的剪枝策略,我好像并没有找到西瓜书上的与预剪枝和后剪枝的函数或者什么的.
先贴个代码
# 同样的构建模型
sum = 0
sum2 = 0
for i in range(100):
x_train = train[i][:,1:5]
y_train = train[i][:,5:6]
x_test = test[i][:,1:5]
y_test = test[i][:,5:6]
clf = tree.DecisionTreeClassifier(
criterion ="gini"
,random_state = 30
)
clf = clf.fit(x_train,y_train)
# print("准确率为:", clf.score(x_train, y_train))
# print("准确率为:", clf.score(x_test, y_test))
sum+=clf.score(x_train, y_train)
sum2 += clf.score(x_test, y_test)
print("训练集准确率:",sum/100)
print("测试集准确率:",sum2/100)
sum = 0
sum2 = 0
for i in range(100):
x_train = train[i][:,1:5]
y_train = train[i][:,5:6]
x_test = test[i][:,1:5]
y_test = test[i][:,5:6]
# 这里我们用自带的剪枝参数
clf = tree.DecisionTreeClassifier(criterion="gini"
,random_state=30
,splitter="random"
,max_depth = 4 # 比如我们给定最大深度
,min_samples_leaf=4 # 每个节点最少要包含的样本数
,min_samples_split=2 # 每个节点最少划分的属性数
)
clf = clf.fit(x_train,y_train)
#print("准确率为:", clf.score(x_train, y_train))
sum+=clf.score(x_train, y_train)
sum2 += clf.score(x_test, y_test)
# print("准确率为:", clf.score(x_test, y_test))
print("训练集准确率:",sum/100)
print("测试集准确率:",sum2/100)
再给图说明问题
这里是第一快代码运行结果(无剪枝
这里是第二这个代码块运行的结构(剪枝
结语
决策树还是相当容易发生过拟合的,因为在我实验中发现,一般训练出的模型在训练集上的准确率全部为100% 显然这是不合逻辑的(我们要求的泛型最好),所以适当的剪枝是非常有必要的