实验数据集:垃圾邮件数据集(http://archive.ics.uci.edu/ml/datasets/Spambase)。请从spambase.csv读入数据。
数据集基本信息如下:样本数: 4601,特征数量: 57, 类别:1为垃圾邮件,0为非垃圾邮件。
将样本集划分为70%的训练集,30%作为测试集。分别完成以下内容。
决策树
(1)分别取节点分裂标准为“gini”或“entropy”,分别建立决策树模型,计算训练误差和测试误差;画出对应的决策树。
(2)设置树高,由3到30,分别建模,计算训练误差和测试误差,并将结果可视化。
支持向量机SVM
利用管道、搜索网格的方式,确定SVM对垃圾邮件数据集建模的最优参数。其中:
(1)管道流程定义包括:数据标准化,PCA降维,SVC估计器。
(2)搜索网格参数包括:C值(惩罚系数)、Kernel(核函数)。
#!/usr/bin/env python
# coding: utf-8
# In[145]:
import pandas as pd
import numpy as np
from sklearn import linear_model, model_selection
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn import tree
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.pipeline import make_pipeline
# In[146]:
spam = pd.read_csv(r'spambase.csv')
spam
# In[147]:
data = spam.iloc[:,0:57]
print(data.shape)
target = spam.iloc[:,57]
print(target.shape)
# In[148]:
x_train, x_test, y_train, y_test = model_selection.train_test_split(data,target,
test_size=0.3,random_state=1)
# In[149]:
feature_name = spam.columns[0:57] #数据集中的列名
target_name = spam.columns[57] #数据集中的标签名字
print(feature_name,target_name)
# In[150]:
# 构建一个criterion='gini'决策树模型,树深设置为4
dt = tree.DecisionTreeClassifier(criterion='gini',max_depth=4,random_state= 0) #模型初始化
dt = dt.fit(x_train, y_train) #利用数据集进行训练,需要指定样本及其标签
y_pred2 = dt.predict(x_train)
y_pred = dt.predict(x_test)
y_pred
print("训练误差:",sum(y_pred2 == y_train) / len(y_train))
print("测试误差:",sum(y_pred == y_test) / len(y_test))
result = dt.score(x_test,y_test) #用模型进行分类,从接口中调用需要的信息
print(result)
result = dt.score(x_train,y_train)
print(result)
# In[156]:
# 数据可视化,画出决策树
plt.figure(figsize=(25,20))
plot_tree(dt,filled=True,feature_names=feature_name, class_names=target_name)
# In[157]:
# 构建一个criterion='gini'决策树模型,树深设置为4
dt = tree.DecisionTreeClassifier(criterion='entropy',max_depth=4,random_state= 0) #模型初始化
dt = dt.fit(x_train, y_train) #利用数据集进行训练,需要指定样本及其标签
# In[158]:
y_pred2 = dt.predict(x_train)
y_pred = dt.predict(x_test)
y_pred
# In[159]:
# 预测的准确度(计算训练误差)
print("训练误差:",sum(y_pred2 == y_train) / len(y_train))
print("测试误差:",sum(y_pred == y_test) / len(y_test))
# In[160]:
# 数据可视化,画出决策树
plt.figure(figsize=(25,20))
plot_tree(dt,filled=True,feature_names=feature_name, class_names=target_name)
# In[161]:
test = []
test2 = [] #保存每一次测试的结果
for i in range(3,31):
clf = tree.DecisionTreeClassifier(max_depth=i+1
,random_state=30
,splitter="random"
)
clf = clf.fit(x_train, y_train)
#训练误差
score = clf.score(x_train, y_train)
test.append(score)
score = clf.score(x_test,y_test)
test2.append(score)
plt.plot(range(3,31),test,color="red",label="训练误差")
plt.plot(range(3,31),test2,color="blue",label="测试误差")
plt.xlabel("树深")
plt.ylabel("误差")
plt.legend()
plt.show()
# In[162]:
#对训练集和测试集的X正则化
standardizer = StandardScaler()
X_std = standardizer.fit_transform(x_train)
standardizer = StandardScaler()
X_std_test = standardizer.fit_transform(x_test)
# In[163]:
#建立包括数据标准化预处理和SVM建模的管道模型
pipeline = Pipeline([('scaler',StandardScaler()),('svc',SVC())]) #StandardScaler()是转换器,svc是估计器(建模方法)
#利用管道模型对训练集进行拟合
pipeline.fit(x_train,y_train)
#输出管道模型的的SVM模型评分
print(pipeline.score(x_test, y_test))
# In[164]:
#建立包括数据标准化预处理和SVM建模的管道模型
mp = make_pipeline(StandardScaler(), SVC())
#查处管道的步骤
print(mp.steps)
#利用管道模型对训练集进行拟合
mp.fit(x_train,y_train)
#输出管道模型的的SVM模型评分
print(mp.score(x_test, y_test))
# In[170]:
#设置网格搜索参数
#注意:对于参数 param_grid 的填写要准确,否则容易导致出错,一般是分类器名__参数名,中间是两个下划线。
param = {'svc__C':[1,2,3,10,100],'svc__kernel':["linear", "poly", "sigmoid", "rbf"]}
#建立管道
pipe_cv = Pipeline([('scaler',StandardScaler()),('svc',SVC())])
#建立网格搜索模型,将管道模型加入网格搜索
grid = GridSearchCV(estimator=pipe_cv, param_grid=param, cv=3)
# In[171]:
# In[172]:
#对训练集进行拟合
grid.fit(x_train,y_train)
# In[173]:
#输出模型交叉验证得分、最佳参数和测试集得分
print('运行结果:')
print('===================')
print('交叉验证得分:',grid.best_score_)
print('模型最优参数:',grid.best_params_)
print('测试集得分:',grid.score(x_test,y_test))
#使用线性SVM,核函数不进行高维映射
clf_linear = SVC(kernel='linear',C=100)
clf_linear.fit(X_std, y_train)
#输出支持向量的总数
print(clf_linear.support_vectors_.shape)
#输出支持向量的样本序号
print(clf_linear.support_)
#输出每一类的支持向量个数
print(clf_linear.n_support_)
print(clf_linear.coef_)
print(clf_linear.intercept_)