汕头信息网

首页 > 花卉 / 正文

鸢尾花数据集,r语言鸢尾花简单分析

网络整理 2023-11-30 花卉

大家好,关于鸢尾花数据集很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于r语言鸢尾花简单分析的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!

本文目录

  1. 鸢尾花数据集分类的意义
  2. 用python实现红酒数据集的ID3,C4.5和CART算法
  3. 06 决策树 - 案例一 - 鸢尾花数据分类、卡方检验

一、鸢尾花数据集分类的意义

鸢尾花数据集是一个经典的机器学习分类问题数据集,常被用于机器学习算法的验证和比较,因此它成为了机器学习入门的经典案例之一。它具有较高的分类准确率和稳定性,可以用于评估不同分类算法的性能和优劣,为算法选择和优化提供参考。此外,鸢尾花数据集中的特征具有较高的区分度和可解释性,可以用于探索特征选择和特征提取方法,提高分类准确率和模型可解释性。最后,鸢尾花数据集的分类问题具有实际应用背景,如根据花的特征对鸢尾花进行分类和识别,可以应用于植物学和农业生产等领域。

二、用python实现红酒数据集的ID3,C4.5和CART算法

ID3算法全称为迭代二叉树3代算法(Iterative Dichotomiser 3)

该算法要先进行特征选择,再生成决策树,其**征选择是基于“信息增益”最大的原则进行的。

但由于决策树完全基于训练集生成的,有可能对训练集过于“依赖”,即产生过拟合现象。因此在生成决策树后,需要对决策树进行剪枝。剪枝有两种形式,分别为前剪枝(Pre-Pruning)和后剪枝(Post-Pruning),一般采用后剪枝。

信息熵:来自于香农定理,表示信息**所含信息的平均不确定性。信息熵越大,表示不确定性越大,所含的信息量也就越大。

设x 1, x 2, x 3,... x n{x_1, x_2, x_3,...x_n}x

为信息**X的n个取值,则x i x_ix

P( X= i)= p i, i= 1, 2, 3,..., n P(X=i)= p_i, i=1,2,3,...,n

H( X)=−∑ i= 1 n p i log⁡ p i H(X)=-\sum_{i=1}^{n}{p_i}\log{p_i}

条件熵:指已知某个随机变量的情况下,信息**的信息熵。

设信息**X中有y 1, y 2, y 3,... y m{y_1, y_2, y_3,...y_m}y

组成的随机变量**Y,则随机变量(X,Y)的联合概率分布为

P( x= i, y= j)= p i j P(x=i,y=j)= p_{ij}

H( X∣ Y)=∑ j= 1 m p( y j) H( X∣ y j) H(X|Y)=\sum_{j=1}^m{p(y_j)H(X|y_j)}

H( X∣ y j)=−∑ j= 1 m p( y j)∑ i= 1 n p( x i∣ y j) log⁡ p( x i∣ y j) H(X|y_j)=-\sum_{j=1}^m{p(y_j)}\sum_{i=1}^n{p(x_i|y_j)}\log{p(x_i|y_j)}

p( x i y j)= p( x i∣ y j) p( y j) p(x_iy_j)= p(x_i|y_j)p(y_j)

H( X∣ Y)=∑ j= 1 m∑ i= 1 n p( x i, y j) log⁡ p( x i) p( x i, y j) H(X|Y)=\sum_{j=1}^m\sum_{i=1}^n{p(x_i, y_j)\log\frac{p(x_i)}{p(x_i, y_j)}}

信息增益:信息熵-条件熵,用于衡量在知道已知随机变量后,信息不确定性减小越大。

d( X, Y)= H( X)− H( X∣ Y) d(X,Y)= H(X)- H(X|Y)

if label not in labelCountDict.keys():

for l, c in labelCountDict.items():

def filterSubDataSet(dataSet, colIndex, value):

"""返回colIndex特征列label等于value,并且过滤掉改特征列的数据集"""

newR= np.append(newR,(r[colIndex+ 1:]))

return np.array(subDataSetList)

"""通过计算信息增益选择最合适的特征"""

featureNum= dataSet.shape[1]- 1

entropy= calShannonEnt(dataSet)

uniqueValues= np.unique(dataSet[:, i])

for v in uniqueValues:#计算条件熵

subDataSet= filterSubDataSet(dataSet, i, v)

p= 1.0* len(subDataSet)/ len(dataSet)

condition_entropy+= p* calShannonEnt(subDataSet)

**Gain= entropy- condition_entropy#计算信息增益

if **Gain>= bestInfoGain:#选择最大信息增益

def creatDecisionTree(dataSet, featNames):

featureName= featNames[:]#拷贝featNames,此处不能直接用赋值**作,否则新变量会指向旧变量的**

classList= list(dataSet[:,-1])

if len(set(classList))== 1:#只有一个类别

if dataSet.shape[1]== 1:#当所有特征属性都利用完仍然无法判断样本属于哪一类,此时归为该数据集中数量最多的那一类

return max(set(classList), key=classList.count)

bestFeatureIndex= chooseFeature(dataSet)#选择特征

bestFeatureName= featNames[bestFeatureIndex]

del featureName[bestFeatureIndex]#移除已选特征列

decisionTree={bestFeatureName:{}}

featureValueUnique= sorted(set(dataSet[:, bestFeatureIndex]))#已选特征列所包含的类别,通过递归生成决策树

copyFeatureName= featureName[:]

subDataSet= filterSubDataSet(dataSet, bestFeatureIndex, v)

decisionTree[bestFeatureName][v]= creatDecisionTree(subDataSet, copyFeatureName)

def classify(decisionTree, featnames, featList):

"""使用训练所得的决策树进行分类"""

firstGenDict= decisionTree[root]

featIndex= featnames.index(root)

for k in firstGenDict.keys():

if isinstance(firstGenDict[k], dict):#若子节点仍是树,则递归查找

classLabel= classify(firstGenDict[k], featnames, featList)

下面用鸢尾花数据集对该算法进行测试。由于ID3算法只能用于标称型数据,因此用在对连续型的数值数据上时,还需要对数据进行离散化,离散化的方法稍后说明,此处为了简化,先使用每一种特征所有连续性数值的中值作为分界点,小于中值的标记为1,大于中值的标记为0。训练1000次,统计准确率均值。

from sklearn.model_selection import train_test_split

data= np.c_[iris.data, iris.target]

for i in range(1000):#对该过程进行10000次

trainData, testData= train_test_split(data)#区分测试集和训练集

featNames= iris.feature_names[:]

for i in range(trainData.shape[1]- 1):#对训练集每个特征,以中值为分界点进行离散化

splitPoint= np.mean(trainData[:, i])

featNames[i]= featNames[i]+'<='+'{:.3f}'.format(splitPoint)

trainData[:, i]= [1 if x<= splitPoint else 0 for x in trainData[:, i]]

testData[:, i]= [1 if x<= splitPoint else 0 for x in testData[:, i]]

decisionTree= creatDecisionTree(trainData, featNames)

classifyLable= [classify(decisionTree, featNames, td) for td in testData]

scoreL.append(1.0* sum(classifyLable== testData[:,-1])/ len(classifyLable))

print'score:', np.mean(scoreL)

输出结果为:score: 0.7335,即准确率有73%。每次训练和预测的准确率分布如下:

然而,在上例中对特征值离散化的划分点实际上过于“野蛮”,此处介绍一种通过信息增益最大的标准来对数据进行离散化。原理很简单,当信息增益最大时,说明用该点划分能最大程度降低数据集的不确定性。

对每个特征所包含的数值型特征值排序

对相邻两个特征值取均值,这些均值就是待选的划分点

用每一个待选点把该特征的特征值划分成两类,小于该特征点置为1,大于该特征点置为0,计算此时的条件熵,并计算出信息增益

选择信息使信息增益最大的划分点进行特征离散化

def filterRawData(dataSet, colIndex, value, tag):

"""用于把每个特征的连续值按照区分点分成两类,加入tag参数,可用于标记筛选的是哪一部分数据"""

if(tag and r[colIndex]<= value) or((not tag) and r[colIndex]> value):

newR= np.append(newR,(r[colIndex+ 1:]))

return np.array(filterDataList)

def dataDiscretization(dataSet, featName):

"""对数据每个特征的数值型特征值进行离散化"""

featureNum= dataSet.shape[1]- 1

entropy= calShannonEnt(dataSet)

for featIndex in range(featureNum):#对于每一个特征

uniqueValues= sorted(np.unique(dataSet[:, featIndex]))

for i in range(len(uniqueValues)- 1):#求出相邻两个值的平均值

meanPoint.append(float(uniqueValues[i+1]+ uniqueValues[i])/ 2.0)

for mp in meanPoint:#对于每个划分点

subEntropy= 0.0#计算该划分点的信息熵

for tag in range(2):#分别划分为两类

subDataSet= filterRawData(dataSet, featIndex, mp, tag)

p= 1.0* len(subDataSet)/ len(dataSet)

subEntropy+= p* calShannonEnt(subDataSet)

**Gain= entropy- subEntropy

if **Gain>= bestInfoGain:

featName[featIndex]= featName[featIndex]+"<="+"{:.3f}".format(bestMeanPoint)

dataSet[:, featIndex]= [1 if x<= bestMeanPoint else 0 for x in dataSet[:, featIndex]]

重新对数据进行离散化,并重复该步骤1000次,同时用sklearn中的DecisionTreeClassifier对相同数据进行分类,分别统计平均准确率。运行代码如下:

from sklearn.tree import DecisionTreeClassifier

import matplotlib.pyplot as plt

for i in range(1000):#对该过程进行1000次

featNames= iris.feature_names[:]

trainData, testData= train_test_split(data)#区分测试集和训练集

trainData_tmp= copy.copy(trainData)

testData_tmp= copy.copy(testData)

discritizationData, discritizationFeatName= dataDiscretization(trainData, featNames)#根据信息增益离散化

for i in range(testData.shape[1]-1):#根据测试集的区分点离散化训练集

splitPoint= float(discritizationFeatName[i].split('<=')[-1])

testData[:, i]= [1 if x<=splitPoint else 0 for x in testData[:, i]]

decisionTree= creatDecisionTree(trainData, featNames)

classifyLable= [classify(decisionTree, featNames, td) for td in testData]

scoreL.append(1.0* sum(classifyLable== testData[:,-1])/ len(classifyLable))

clf= DecisionTreeClassifier('entropy')

clf.fit(trainData[:,:-1], trainData[:,-1])

scoreL_sk.append(clf.score(testData[:,:-1], testData[:,-1]))

print'score:', np.mean(scoreL)

print'score-sk:', np.mean(scoreL_sk)

fig= plt.figure(figsize=(10, 4))

pd.Series(scoreL).hist(grid=False, bins=10)

pd.Series(scoreL_sk).hist(grid=False, bins=10)

(但是。。为什么根据信息熵离散化得到的准确率比直接用均值离散化的准确率还要低啊??哇的哭出声。。)

由于决策树是完全依照训练集生成的,有可能会有过拟合现象,因此一般会对生成的决策树进行剪枝。常用的是通过决策树损失函数剪枝,决策树损失函数表示为:

C a( T)=∑ t= 1 T N t H t( T)+α∣ T∣ C_a(T)=\sum_{t=1}^TN_tH_t(T)+\alpha|T|

(T)表示叶子节点t的熵值,T表示决策树的深度。前项∑ t= 1 T N t H t( T)\sum_{t=1}^TN_tH_t(T)∑

(T)是决策树的经验损失函数当随着T的增加,该节点被不停的划分的时候,熵值可以达到最小,然而T的增加会使后项的值增大。决策树损失函数要做的就是在两者之间进行平衡,使得该值最小。

对于决策树损失函数的理解,如何理解决策树的损失函数?-陶轻松的回答-知乎这个回答写得挺好,可以按照答主的思路理解一下

ID3算法通过信息增益来进行特征选择会有一个比较明显的缺点:即在选择的过程中该算**优先选择类别较多的属性(这些属性的不确定性小,条件熵小,因此信息增益会大),另外,ID3算法无法解决当每个特征属性中每个分类都只有一个样本的情况(此时每个属性的条件熵都为0)。

C4.5算法ID3算法的改进,它不是依据信息增益进行特征选择,而是依据信息增益率,它添加了特征**信息作为惩罚项。定义**信息:

S p l i t I n f o( X, Y)=−∑ i n∣ X i∣∣ X∣ log⁡∣ X i∣∣ X∣ SplitInfo(X, Y)=-\sum_i^n\frac{|X_i|}{|X|}\log\frac{|X_i|}{|X|}

G a i n R a t i o( X, Y)= d( X, Y) S p l i t I n f o( X, Y) GainRatio(X,Y)=\frac{d(X,Y)}{SplitInfo(X, Y)}

在学习分类回归决策树算法时,看了不少的资料和博客。关于这两个算法,ID3算法是最早的分类算法,这个算法刚出生的时候其实带有很多**:

特征选取会倾向于分类较多的特征

即该算法出生时是没有带有连续特征离散化、剪枝等步骤的。C4.5作为ID3的改进版本弥补列ID3算法不少的**:

通过信息最大增益的标准离散化连续的特征数据

在选择特征是标准从“最大信息增益”改为“最大信息增益率”

通过加入正则项系数对决策树进行剪枝

对缺失值的处理体现在两个方面:特征选择和生成决策树。初始条件下对每个样本的权重置为1。

特征选择:在选取最优特征时,计算出每个特征的信息增益后,需要乘以一个**“非缺失值样本权重占总样本权重的比例”**作为系数来对比每个特征信息增益的大小

生成决策树:在生成决策树时,对于缺失的样本我们按照一定比例把它归属到每个特征值中,比例为该特征每一个特征值占非缺失数据的比重

作为ID3的改进版本,C4.5克服了许多**,但是它自身还是存在不少问题:

C4.5的熵运算中涉及了对数运算,在数据量大的时候效率非常低。

C4.5只能用于分类运算不能用于回归

当特征有多个特征值是C4.5生成多叉树会使树的深度加深

————————————————

版权声明:本文为CSDN博主「Sarah Huang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_44794704/article/details/89406612

三、06 决策树 - 案例一 - 鸢尾花数据分类、卡方检验

这次案例还是使用鸢尾花数据分类的数据。

feature_selection是做特征选择的包

feature_selection中的方法 SelectKBest,帮助我们选择K个最优的特征

feature_selection中的方法 chi2-卡方检验,表示使用 chi2的方法帮助我们在 SelectKBest中选择最优的K个最优特征。

2、防中文乱码、去警告、读取数据

总样本数目:150;特征属性数目:4

取得样本前四列特殊数据'花萼长度','花萼宽度','花瓣长度','花瓣宽度'

iris_class='Iris-setosa','Iris-versicolor','Iris-virginica'

y=pd.Categorical(data[4]).codes#把Y转换成分类型的0,1,2

PS:在之前的例子中: 04分类算法- Logistic回归-信贷审批案例,我们自己写过一个分类的算法对部分特征进行哑编码**作: parseRecord(record),其实pandas自己也集成了这个转换算法: pd.Categorical(data[4]).codes,可以把y直接转换成0,1,2。

以上是数据预处理的步骤,和之前的例子类似。

3、数据分割(训练数据和测试数据)

训练数据集样本数目:120,测试数据集样本数目:30

注意:这个demo中的案例在这一步还没有做 KFold-K折交叉验证。当前步骤的主要内容是对数据进行划分。K折就要生成K个互斥的子集。 KFold的工作就是帮助我们划分子集的,划分完后我们将子集扔进建模即可。 02分类算法- Logistic案例中提及过K折交叉验证的内容。

4、数据标准化和数据归一化的区别

思考:行数据和列数据,哪个服从正态分布?显然,列数据是特征,和样本一样都服从正态分布。所以数据标准化和归一化的对象是列。

StandardScaler(基于特征矩阵的列,将属性值转换至服从正态分布)

标准化是依照特征矩阵的列处理数据,其通过求z-score: z-score=(x-μ)/σ的方法,将样本的特征值转换到同一量纲下。z-score是N(0,1)正态分布,即标准正态分布。

常用与基于正态分布的算法,比如回归。

PS:在 04回归算法-最小二乘线性回归案例中对 ss= StandardScaler()数据标准化**作进行了深入分析。

MinMaxScaler(区间缩放,基于最大最小值,将数据转换到0,1区间上的)

提升模型收敛速度,提升模型精度。

Normalizer(基于矩阵的行,将样本向量转换为单位向量)

其目的在于样本向量在点乘运算或其他核函数计算相似性时,拥有统一的标准。

常见用于文本分类和聚类、logistic回归中也会使用,有效防止过拟合。

原始数据各个特征属性的调整最小值:

[-1.19444444-0.83333333-0.18965517-0.04166667]

原始数据各个特征属性的缩放数据值:

[ 0.27777778 0.41666667 0.17241379 0.41666667]

特征选择:从已有的特征中选择出影响目标值最大的特征属性

{分类:F统计量、卡方系数,互信息mutual_**_classif

{连续:皮尔逊相关系数 F统计量互信息mutual_**_classif

这里介绍一种特征选择方法: K方检验 SelectKBest

https://baike.baidu**/item/%E5%8D%A1%E6%96%B9%E6%A3%80%E9%AA%8C/2591853?fr=aladdin

ch2= SelectKBest(chi2,k=3)这步**作本质是一个Transformer的步骤。Transformer的概念参考 05回归算法-多项式扩展、管道Pipeline。

K方检验的本质是:判断两个特征之间的关联程度。

1、男女性别和是否会化妆的关联性是很强的:

2、男女性别和是否出门带口罩的关联性不强:

但大部分属性对结果的关联性我们很难用常识去判断,所以我们可以首先假设样本的特征和目标无关。

假设性别和是否会化妆无关。因此我们设男人中化妆的比例为55%,男人中不化妆的比例是45%

根据实际情况进行计算:(列联表)

(20-55) 2/55+(90-55) 2/55+(80-45) 2/45+(10-45) 2/45

结果越大,说明性别和是否会化妆的关联程度越大,当数值较大时我们可以说拒绝原假设,即原假设错误,真实情况下性别和是否会化妆有很大的影响。(越大越拒绝)

如果结果越小,说明假设正确,我们称之为不拒绝原假设。

注意: K方统计用于离散的特征,对连续的特征无效。

对类别判断影响最大的三个特征属性分布是:

这里False的属性就是K方检验分数最小的那个,如果只取3个特征,False对应的那个特征就会被丢弃。

关于本次鸢尾花数据集和r语言鸢尾花简单分析的问题分享到这里就结束了,如果解决了您的问题,我们非常高兴。

Tags:

猜你喜欢

搜索
网站分类
标签列表