
数据挖掘期中作业(用朴素贝叶斯和决策树挖掘恒星特征)
业务理解(Business Understanding)此次项目的目标是对star.csv数据集中的恒星进行分类挖掘,根据其六个特征使用不同的分类算法建模,对六个标签类别的恒星分类,并探索评估模型的效果。挖掘任务分为四部分:数据准备、数据预处理、建模实例化、评估模型。目标这次数据挖掘任务的目标。将star.csv数据集中的数据预处理,对非数值型的特征数据数值化。用分类器划分训练集、测试集。并用贝叶
- 业务理解(Business Understanding)
此次项目的目标是对star.csv数据集中的恒星进行分类挖掘,根据其六个特征使用不同的分类算法建模,对六个标签类别的恒星分类,并探索评估模型的效果。
挖掘任务分为四部分:数据准备、数据预处理、建模实例化、评估模型。
-
- 目标
这次数据挖掘任务的目标。
将star.csv数据集中的数据预处理,对非数值型的特征数据数值化。用分类器划分训练集、测试集。并用贝叶斯和决策树算法建模并训练模型,实现分类及模型评估,得到混淆矩阵、决策树分类图、热力图等成果形式。
-
- 预期得到什么结果
成果形式:
贝叶斯算法:得到分类准确率达到85%以上的模型。训练集评分、测试集评分、准确率、精确率、召回率和f1分数以及混淆矩阵。
决策树算法:得到分类准确率达到100%的模型。分别根据最大深度、最小样本叶子节点、内部节点再划分所需最小样本数绘制的迭代学习曲线、训练集评分、测试集评分以及三种参数下的决策树分类图。
-
- 思路
- 先准备好库,这次项目要用到的pandas、sklearn、matplotlib库、用于可视化封装的seaborn库以及后面决策树用到的graphviz库。
- 准备数据:导入数据集,预览信息、查看是否有空值、数据类型。
- 数据预处理:将非数值列数值化。
- 分别用贝叶斯和决策树模型实例化,训练模型,预测模型,最后再进行模型评估。
- 得出结论。
- 使用工具和方法
- pandas 之 unique()函数:以数组形式(numpy.ndarray)返回列的所有唯 一值(特征的所有唯一值)
- plt 制图函数。
- replace()函数:将原字符串替换成新的字符串或数值。
- predict()函数:预测模型,根据特征列预测标签列。
- confusion_matrix()混淆矩阵:
sklearn.metrics.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)
y_true: 是样本真实分类结果,y_pred: 是样本预测分类结果
labels:是所给出的类别,通过这个可对类别进行选择
sample_weight : 样本权重
- train_test_split()分类器:
X_train,X_test,y_train,y_test=sklearn.model_selection.train_test_split(train_data,train_target,test_size,random_state,stratify)
# train_data:所要划分的样本特征集
# train_target:所要划分的样本结果
# test_size:样本占比,如果是整数的话就是样本的数量
# random_state:是随机数的种子。
- graphviz库:用于决策树画图。
- 数据理解(Data Understanding)
- 收集数据
数据来源:老师提供的学习通上面的资料
数据简单说明:关于恒星特征和类别的数据(特征包括温度、光度、半径、绝对星等、颜色、光谱型,类别分为6类)
-
- 数据探索
先打开表格大致浏览一遍,再用 pycharm 导入数据集,将数据存为 Dataframe 表结构,使用 info()函数打印出全部信息。并重新定义中文列名方便之后代码编写时找到对应的特征。随后输出数据类型、统计非空值等信息。
-
-
- 数据预览
-
- 前十行的预览结果如图:
图2.2.1-1
通过.shape我们发现,该数据集的维度为240行7列。
2、重新定义列名后的结果:
图2.2.1-2
-
-
- 数据信息
-
分别利用dtypes和.count函数输出数据集中各列的数据类型以及非空值统计。
图2.2.2-1
如图,跟数据类型,不难看出,Star_color和 Spectral_Class列的数据都是非数值型的,故后续需要对其做数值化处理。
由非空值的统计结果我们可以得出,该数据集每列均不存在空值,故不需要进行缺失值处理。
-
-
- 数据示例
-
用for循环遍历二维表中的Star_type列下的每个单元格对应的元素,打印输出。
图2.2.3-1
-
-
- 简单可视化(若有)
-
高斯分布朴素贝叶斯混淆矩阵:
图2.2.4-1
决策树以最大深度为标准绘制的学习曲线:
图2.2.4-2
决策树以最小样本叶子节点为标准绘制的学习曲线:
图2.2.4-3
决策树以内部节点再划分所需最小样本数为标准绘制的学习曲线:
图2.2.4-4
三种指标的决策树分类图:
1、依据最大深度:
图2.2.4-5
- 依据最小样本叶子节点:
图2.2.4-6
- 依据内部节点再划分所需最小样本数:
图2.2.4-7
- 数据准备(Data Preparation)
- 缺失值处理(若有)
图3.1-1
通过统计缺失值数量,我们发现所有特征列对应的数据都没有缺失值,故不需要进行缺失值的处理。
-
- 数据替换(若有)
用.unique()函数对Star_color列去重,统计星系颜色的种类数,得到结果如下图:
图3.2-1
观察结果发现,星系颜色中的数据存在重复项,比如‘Blue’和‘Blue ’,同样都表示蓝色,但因为在录入过程中多输入一个空格,所以在用函数统计时被算成了两类,故需要分别进行替换。
同理,再对Spectral_Class列去重统计,得到如下图的结果:
可见,该列同星系颜色列一样,返回的数据都是非数值型的,需要进行数据替换。
替换方法:
分别用for循环遍历satr数据表中的Star_color和Spectral_Class列,并用replace函数将所有示例用对应的数字来替换。
处理后的结果:
(1)Star_color列:
图3.2-2
- Spectral_Class列:
图3.2-3
-
- 数据切分(训练集/测试集)
1、从sklearn中的model_selection模块导入train_test_split分类器。
2、将处理后的数据切片,取前六列的二维表数据作为特征列,取最后一列的数据作为标签列。
3、用分类器划分数据集,其中,设置测试集规模参数为0.3,随机种子设置为20。
4、查看切分后的训练集和测试集的样本数目、特征列和标签列。
结果截图:
图3.3-1
图3.3-2
图3.3-3
- 建模(Modeling)
- 模型1:朴素贝叶斯
- 建模
- 模型1:朴素贝叶斯
- 由于特征中大部分数据都为连续型数据,故采用高斯分布的朴素贝叶斯模型。
- 首先实例化,告诉分类器,用先验概率值,即训练集中各个类别的概率/总样本数作为指标来划分属性。
- 用fit函数训练模型,参数为xtrain ytrain
- 用predict函数预测测试集中的特征列。
- 分别用score函数评估训练集和测试集的拟合效果。并计算测试集和预测集的准确率、精确率、召回率和f1分数。
-
- 调参
-
因为贝叶斯模型是轻量的模型,所以一般不用调参。
-
- 模型2:决策树
- 建模
- 模型2:决策树
- 首先实例化,设定tree模块的分类树的参数(划分标准为信息熵entropy,分类方式为随机,从而降低重要性较低的信息对训练集拟合的影响。
- 训练模型
- 测试模型
-
- 调参
-
分别绘制以最大深度、最小叶子节点、内部节点再划分所需最小样本数为标准的学习曲线,通过10层的迭代,得到如下图:
图4.2.2-1
图4.2.2-2
图4.2.2-3
由图可知,当max_depth=6,min_samples_leaf=1,min_samples_split=4时,该模型的分类效果达到最好。
调参后,建立模型,重新设定参数,得出分类结果。
- 评估(Evaluation)
- 对于模型的评估
- 模型选择
- 对于模型的评估
根据评估指标,哪种模型比较好,若有可视化可呈现
贝叶斯模型分类结果:
图5.1.1-1
由图可知,该模型的训练集评分、测试集评分、准确率、精确率、召回率和f1分数都达到了85%以上。
决策树模型分类结果:
图5.1.1-2
由图可知,该模型的训练集评分、测试集评分、准确率、精确率、召回率和f1分数都达到了100%的超高水平。
故两者对比,还是决策树效果更好。
比较二者的可视化热图:
朴素贝叶斯:
图5.1.1-3
决策树:
图5.1.1-4
通过比较,朴素贝叶斯混淆矩阵中对角线周围有预测与实际值不符的部分,而决策树混淆矩阵中只有对角线有值,说明预测值和真实值完全吻合,是很完美的模型。
-
- 对于挖掘结果的评估
我的预期是原本想着弄个各项指标都达到80%以上的模型,通过反复调参,两种模型均达到了我的预期效果。
至于新的发现,倒是略有一二:
朴素贝叶斯模型中的高斯分布中,它只适用于连续型数据,而因为数据表中我人为数值化的两列一个是星系颜色、一个是光谱型,这俩都是非数值型的数据。所以替换后虽然数值化了,但毕竟是离散型的标称属性,故最后的分类评分会有误差。
- 实训代码
import pandas as pd
from sklearn import naive_bayes
from matplotlib.patches import Rectangle
import matplotlib.colors as mcolors
import numpy as np
from sklearn import metrics
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
from matplotlib import cm
from sklearn.model_selection import train_test_split
star = pd.read_csv("D:\\starname\\star.csv",encoding="utf-8-sig")
star = pd.DataFrame(star)
star1=star.rename(columns={'Temperature':'温度','Luminosity':'光度','Radius':'半径','Absolute_magnitude':'绝对星等','Star_color':'颜色','Spectral_Class':'光谱型'})
pd.set_option('display.max_rows',None)
pd.set_option('display.max_columns', None)
print('前十行数据预览',star.iloc[:10])
print("维度:",star.shape)
print("信息展示\n",star1.info)
print("数据类型\n",star.dtypes)
print("非空值统计\n",star.count())
print("数据")
starlist = []
print("Star_type列表:\n")
for i in star['Star_type']:
starlist.append(i)
print(starlist)
# 查看维度、数据、数据类型以及非空值数目
# print(star.describe())
# 统计缺失值的情况
print('缺失值数量:\n',star.isnull().sum())
# 统计星球颜色种类
print("星系颜色种类:",star['Star_color'].unique())
# 处理非缺失值,进行数据清洗
for i in star['Star_color']:
if i == 'Red':
star.replace(i,0,inplace=True)
elif i =='Blue White' :
star.replace(i,1,inplace = True)
elif i == 'Blue white' :
star.replace(i,1,inplace=True)
elif i == 'Blue-white':
star.replace(i,1,inplace=True)
elif i == 'Blue-White':
star.replace(i,1,inplace=True)
elif i == 'Blue white ':
star.replace(i, 1, inplace=True)
elif i =='White':
star.replace(i,2,inplace=True)
elif i == 'white':
star.replace(i, 2, inplace=True)
elif i =='Yellowish White':
star.replace(i,3,inplace=True)
elif i =='Pale yellow orange':
star.replace(i,4,inplace=True)
elif i =='Blue' :
star.replace(i,5,inplace=True)
elif i =='Blue ':
star.replace(i, 5, inplace=True)
elif i =='Whitish':
star.replace(i,6,inplace=True)
elif i == 'yellow-white' :
star.replace(i,7,inplace=True)
elif i == 'White-Yellow':
star.replace(i, 7, inplace=True)
elif i == 'Orange':
star.replace(i,8,inplace=True)
elif i=='yellowish' :
star.replace(i, 9, inplace=True)
elif i =='Yellowish':
star.replace(i, 9, inplace=True)
elif i =='Orange-Red':
star.replace(i,10,inplace=True)
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows',None)
print(star['Star_color'])
# 查看光谱类型
print("星系光谱类型:",star['Spectral_Class'].unique())
# 对特征进行数值化
for i in star['Spectral_Class']:
if i == 'M':
star.replace(i,0,inplace=True)
elif i =='B' :
star.replace(i,1,inplace = True)
elif i == 'A' :
star.replace(i,2,inplace=True)
elif i == 'F':
star.replace(i,3,inplace=True)
elif i == 'O':
star.replace(i,4,inplace=True)
elif i == 'K':
star.replace(i, 5, inplace=True)
elif i =='G':
star.replace(i,6,inplace=True)
print(star['Spectral_Class'])
# 切分特征列和标签列
data = star.iloc[:,0:6]
target = star.iloc[:,6:]
print('特征列:',data)
print('标签列:',target)
x_train,x_test,y_train,y_test=train_test_split(data,target,test_size=0.3,random_state=20)
print("训练数据集样本数目:%d,测试数据集样本数目:%d" %(x_train.shape[0],x_test.shape[0]))
# print('训练集',x_train)
c1f=naive_bayes.GaussianNB()
c1f.fit(x_train,y_train)
y_pred=c1f.predict(x_test)
print('预测值',y_pred)
print("贝叶斯分类结果")
print("训练集评分",'%.4f' % c1f.score(x_train,y_train))
print("测试集评分",'%.4f' % c1f.score(x_test,y_test))
print("准确率",'%.4f' % metrics.accuracy_score(y_test,y_pred))
print("精确率",'%.4f' % metrics.precision_score(y_test,y_pred,average='micro'))
print("召回率",'%.4f' % metrics.recall_score(y_test,y_pred,average='micro'))
print("f1分数",'%.4f' % metrics.f1_score(y_test,y_pred,average='micro'))
cm=confusion_matrix(y_true=y_test,y_pred=y_pred)
print('混淆矩阵',cm)
pd.DataFrame(cm)
import seaborn as sns
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
sns.heatmap(cm,annot=True,cmap='YlGnBu')
plt.xlabel('预测',size=12)
plt.ylabel('实际',size=12)
plt.title('高斯分布朴素贝叶斯混淆矩阵',size=15)
plt.show()
#决策树分类算法
from sklearn import tree
# 画图并以迭代的方式不断延伸深度的次数
# 1、根据最大深度绘制迭代学习曲线
import matplotlib.pyplot as plt
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(max_depth=i+2,criterion="entropy",random_state=30,splitter="random")
clf=clf.fit(x_train,y_train)
score=clf.score(x_test,y_test)
test.append(score)
plt.plot(range(1,11),test,label="max_depth")
plt.legend()
plt.show()
# 根据最小样本叶子节点绘制迭代学习曲线
test1 = []
for i in range(10):
clf1 = tree.DecisionTreeClassifier(min_samples_leaf=i+2,criterion="entropy",random_state=30,splitter="random")
clf1=clf1.fit(x_train,y_train)
score1=clf1.score(x_test,y_test)
test1.append(score1)
plt.plot(range(1,11),test1,label="min_samples_leaf")
plt.legend()
plt.show()
# 根据内部节点再划分所需最小样本数绘制迭代学习曲线
test2 = []
for i in range(10):
clf2 = tree.DecisionTreeClassifier(min_samples_split=i+2,criterion="entropy",random_state=30,splitter="random")
clf2=clf2.fit(x_train,y_train)
score2=clf2.score(x_test,y_test)
test2.append(score2)
plt.plot(range(1,11),test2,label="min_samples_split")
plt.legend()
plt.show()
# 确定最优参数,开始进行决策树训练
clf1=tree.DecisionTreeClassifier(criterion="entropy",splitter='random',random_state=50,max_depth=6,min_samples_leaf=1,min_samples_split=4)
clf1=clf1.fit(x_train,y_train)
score1=clf1.score(x_train,y_train)
print("训练集分类分数",score1)
Ypredict = clf1.predict(x_test)
print("测试集分类结果",Ypredict)
scoretest=clf1.score(x_test,y_test)
print("测试集分类分数",scoretest)
print("决策树分类结果")
print("训练集评分",'%.4f' % clf1.score(x_train,y_train))
print("测试集评分",'%.4f' % clf1.score(x_test,y_test))
print("准确率",'%.4f' % metrics.accuracy_score(y_test,Ypredict))
print("精确率",'%.4f' % metrics.precision_score(y_test,Ypredict,average='micro'))
print("召回率",'%.4f' % metrics.recall_score(y_test,Ypredict,average='micro'))
print("f1分数",'%.4f' % metrics.f1_score(y_test,Ypredict,average='micro'))
cm1=confusion_matrix(y_true=y_test,y_pred=Ypredict)
print('混淆矩阵',cm1)
pd.DataFrame(cm1)
import seaborn as sns
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
sns.heatmap(cm1,annot=True,cmap='YlGnBu')
plt.xlabel('预测',size=12)
plt.ylabel('实际',size=12)
plt.title('决策树混淆矩阵',size=15)
plt.show()
import graphviz
# 根据特征列划分数据
feature_name = ['Temperature','Luminosity','Radius','Absolute_magnitude','Star_color','Spectral_Class']
dot_data = tree.export_graphviz(clf,out_file=None,feature_names=feature_name,class_names=["棕矮星","红矮星","白矮星","主序星","超巨星","特超巨星"],filled=True,rounded=True)
graph = graphviz.Source(dot_data.replace("helvetica", "MicrosoftYaHei"))
print(graph)
graph.render(filename=r"tree_test",format='pdf')
dot_data1 = tree.export_graphviz(clf1,out_file=None,feature_names=feature_name,class_names=["棕矮星","红矮星","白矮星","主序星","超巨星","特超巨星"],filled=True,rounded=True)
graph1 = graphviz.Source(dot_data1.replace("helvetica", "MicrosoftYaHei"))
print(graph1)
graph1.render(filename=r"tree_test1",format='pdf')
dot_data2 = tree.export_graphviz(clf2,out_file=None,feature_names=feature_name,class_names=["棕矮星","红矮星","白矮星","主序星","超巨星","特超巨星"],filled=True,rounded=True)
graph2 = graphviz.Source(dot_data2.replace("helvetica", "MicrosoftYaHei"))
print(graph2)
graph2.render(filename=r"tree_test2",format='pdf')
更多推荐
所有评论(0)