机器学习 朴素贝叶斯、决策树、集成学习方法之随机森林
我们知道分类算法主要用于对进行分类,标签型数据有一下几个特点:无序性、非数值性、多样性。比如“性别”可以分为“男”和“女”,但“男”和“女”之间不存在大小、高低等顺序关系,也不是数值,分类算法就是针对这样的数据。
目录
我们知道分类算法主要用于对标签型数据进行分类,标签型数据有一下几个特点:无序性、非数值性、多样性。比如“性别”可以分为“男”和“女”,但“男”和“女”之间不存在大小、高低等顺序关系,也不是数值,分类算法就是针对这样的数据。下面介绍几种分类算法:
一、朴素贝叶斯分类
原理
朴素贝叶斯的核心是贝叶斯定理:

其中P(A)称为"先验概率"(Prior probability),即在B事件发生之前,我们对A事件概率的一个判断,A相当于类别
P(A|B)称为"后验概率"(Posterior probability),即在B事件发生之后,我们对A事件概率的重新评估,也就是我们最终要求的,B相当于特征
那么基本思想就是给定一个包含各种特征的数据样本 B ,然后用朴素贝叶斯计算它各个特征分别属于类别 A 的概率,并选择概率最大的类别作为预测结果。
至于“朴素”二字,则体现在所有特征条件独立,即
公式为:
P(A|B) = P(B1|A)*P(B2|A)*P(B3|A)*,,,*P(Bn|A) * P(A) / P(B1)*P(B2)*P(B3)*,,,*P(Bn)
举个实际例子:

这里有一些西瓜,假设有三种特征,请用朴素贝叶斯分类方法预测最后两种西瓜是好瓜还是坏瓜,这里预测第11个西瓜:
首先由公式P(A|B) = P(B1|A)*P(B2|A)*P(B3|A)*,,,*P(Bn|A) * P(A) / P(B1)*P(B2)*P(B3)*,,,*P(Bn)可以得知 A 有两种类别好瓜与坏瓜,B为纹理、色泽、鼓声三种特征,然后计算过程如下:

拉普拉斯平滑系数
在实际应用中,某些事件或特征可能从未在训练集中出现过,这会导致它们的概率被估计为零,然而也不能完全排除它在未来样本中出现的可能性。拉普拉斯平滑技术可以避免这种“零概率陷阱”,公式为

一般α取值1,m的值为总特征数量
例如,在上述例子中如果出现了一个新瓜,它纹理清晰色泽淡白鼓声沉闷,要判断它的好坏时,我们发现色泽淡白并没有在前面10个瓜中出现过,则此时
p(纹理清晰|好瓜)= (4+1)/(6+3) # +1是因为防止零概率 ,+3是因为有3个特征(纹理,色泽,鼓声)
p(色泽淡白|好瓜)= (0+1)/(6+3)
p(鼓声沉闷|好瓜) = (2+1)/(6+3)
坏瓜的计算方法一样
API
首先导入库:from sklearn.naive_bayes import MultinomialNB
然后生成朴素贝叶斯算法模型:estimator = MultinomialNB(alpha= ),参数alpha代表拉普拉斯平滑系数,一般默认值为1,如果特征值比较稀疏时可以调小
完整代码如下,以鸢尾花数据集为例:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import numpy as np
def test1():
'''朴素贝叶斯分类'''
from sklearn.naive_bayes import MultinomialNB
iris = load_iris(return_X_y=False) #返回包含数据、标签及其他信息的对象
x = iris.data
y = iris.target
#划分数据集
x_train,x_test,y_train,y_test = train_test_split(x, y, test_size=0.2,random_state=22)
#标准化训练集的特征数据集
scaler = MinMaxScaler()
x_train = scaler.fit_transform(x_train)
model = MultinomialNB(alpha=0.01) #生成模型,拉普拉斯平滑系数为0.01
model.fit(x_train, y_train) #训练模型
x_test = scaler.transform(x_test) #标准化测试集的特征数据集
y_pred = model.predict(x_test) #用模型预测
#打印真实值与预测值比较
print(y_test)
print(y_pred)
# 模型评分
print(model.score(x_test, y_test))
if __name__ == "__main__":
test1()
运行结果:

这里有一个基本操作叫划分数据集,具体是这样:
划分数据集

原始数据集 x 划分成了 x_train和 x_test ,原始测试集 y 划分成了 y_train 和 y_test, x_train与y_train始终保持配对关系,而我们就是先用 x_train与y_train 来训练模型让它学习其中的规则,再对模型输入 x_test,让它根据刚才学到的东西 预测出 y_pred,再与真实值 y_test 进行对比,可以评估模型的准确性
所以要 fit_transform() 划分后训练集的特特征数据集,也就是 x_train,还要 transform() 划分后测试集的特征数据集,也就是 x_test.
二、决策树分类
决策树是一种树形结构的分类模型,通过一系列规则对数据进行分割,最终达到分类的目的,它包含决策节点以及叶子节点,决策树的深度即所有节点的最大层次数,关键问题是如何选择最优划分属性。下面介绍两种主要方法:信息增益算法和基尼算法。
1、基于信息增益建立决策树
信息增益算法又称 ID3算法,该算法只能对描述属性为离散型属性的数据集构造决策树。首先要理解几个重要概念:
信息熵
信息熵衡量的是数据的不确定性,信息熵越大,不确定性越大,信息熵的值越小,则数据的纯度越高,计算公式为:

这里D表示数据集,pk表示第 k 类样本在数据集中所占的比例
条件熵
指在某特征的条件下数据集的熵,公式为:

同样D表示数据集,
信息增益
信息增益是用于特征选择的关键指标,核心思想是:通过使用某特征进行分割后,系统的不确定性减少了多少。信息增益越大说明特征的区分程度越大,那么决策树就会越简洁。这里信息增益的程度用信息熵的变化程度来衡量,它的定义为 信息增益 = 原始熵 - 条件熵,公式为:

下面举个实际例子应用信息增益算法:

根据以上信息构建一颗预测是否贷款的决策树,计算过程如下:

可以看到“收入”和“学历”的信息增益是最高的,所以就可以选择这两个其中一个作为决策树的第一个节点,然后继续重复上述做法。重新计算信息增益,继续寻找合适的节点,最终大概如下图:

注意: 以上计算时年龄使用35为界,收入使用10000为界,学历使用高中为界,但在实际API使用中,会有一个参数"max_depth",即深度,属性中具体以多少为界会根据深度调整。
API
导入模块:from sklearn.tree import DecisionTreeClassifier,export_graphviz
生成模型:model=DecisionTreeClassifier(criterion= , max_depth= ),参数 criterion 默认值为“gini”,即采用基尼算法构造决策树,取值为“entropy”时采用信息增益算法构造;参数 max_depth表示决策树的深度,默认值为 None,赋值应为整数
完整代码示例如下。以鸢尾花数据集进行分类:
def test2():
'''信息增益算法建立决策树'''
from sklearn.tree import DecisionTreeClassifier,export_graphviz
#导入数据集
iris = load_iris()
x=iris.data
y=iris.target
#划分数据集
x_train,x_test,y_train,y_test = train_test_split(x, y, test_size=0.2)
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train) #标准化划分后训练集的特征数据集
x_test = scaler.transform(x_test) #标准化划分后测试集的特征数据集
#生成模型
model = DecisionTreeClassifier(criterion="entropy") #选择用信息增益算法构建决策树
# 模型训练
model.fit(x_train, y_train)
# 模型预测
y_pred = model.predict(x_test)
#打印真实值进行比较
print(y_pred)
print(y_test)
#模型评估
print(model.score(x_test, y_test))
if __name__ == "__main__":
# test1()
test2()
运行结果:

2、基于基尼指数建立决策树
基尼指数(Gini Index)是决策树算法中用于评估数据集纯度的一种度量,它衡量的是数据集的不纯度,或者说分类的不确定性。在构建决策树时,基尼指数常被用来决定如何对数据集进行最优划分,以减少不纯度,基尼指数越小,表示数据集的纯度越高。
基尼指数计算公式:

K 表示整个数据集的特征数量,pk表示一个节点包含的样本属于第 k 类的概率
特别地,对于一个二分类问题,如果一个节点包含的样本属于正类的概率是 (p),则属于负类的概率是 (1-p),那么这个节点的基尼指数则为:

举个实际例子:

现在要以工资、压力、平台来构建选择工作的决策树,计算过程如下:

第二次计算就是当一个决策点构建之后,假设以工资为节点,工资为1直接往左走表示好工作,工资为0则继续往下构建第二层决策点,此时就要计算压力和平台的基尼指数,且要去掉工资为1 样本,所以分母为 5
API
用法与信息增益算法构建决策树相同,只是将参数criterion改为“gini”,代码如下:
def test3():
'''gini指数构建决策树'''
from sklearn.tree import DecisionTreeClassifier,export_graphviz
#导入数据集
iris = load_iris()
x = iris.data
y = iris.target
#划分数据集
x_train,x_test,y_train,y_test=train_test_split(x, y, test_size=0.2)
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train) #标准化划分后训练集的特征数据集
x_test = scaler.transform(x_test) #标准化划分后测试集的特征数据集
#生成模型
model = DecisionTreeClassifier(criterion="gini") #用gini指数构建决策树
#模型训练
model.fit(x_train, y_train)
#模型预测
y_pred = model.predict(x_test)
#模型评估
print(y_pred)
print(y_test) #直接打印比较
score = model.score(x_test, y_test)
print(score) #计算准确率
运行结果:

如果想要可视化决策树则需要先保存模型然后:
#可视化决策树
# 保存模型 joblib.dump(estimator, "my_ridge.pkl")
joblib.dump(model, "./src/model/ginitree.pkl")
#可视化 export_graphviz(model,out_file="./src/model/dctree.dot",feature_names=iris.feature_names)
export_graphviz(model, out_file="./src/model/ginitree.dot", feature_names=iris.feature_names)
运行结果:

将 .dot中的内容粘贴到"Webgraphviz",然后点击"generate Graph"生成决策树图即可(因为是国外网站所以要用神秘力量查看)
三、集成学习方法之随机森林
机器学习中有一种大类叫集成学习(Ensemble Learning),其基本思想就是将多个分类器组合,从而实现一个预测效果更好的集成分类器,它有比单一模型更优的泛化性能、鲁棒性和准确性,核心思想就是“集体智慧优于个体”,类似于人类通过团队协作解决问题,用一句老话说就是“三个臭皮皮匠,赛过诸葛亮”。
集成算法大致可以分为:Bagging,Boosting 和 Stacking 三大类型,这里介绍的随机森林方法属于 Bagging类型,大致算法原理如下:
(1)每次有放回地从训练集中取出 n 个训练样本,组成新的训练集;
(2)利用新的训练集,训练得到M个子模型;
(3)对于分类问题,采用投票的方法,得票最多子模型的分类类别为最终的类别;
而对于随机森林,“随机”是指特征随机、训练集随机;“森林”是指多个决策树分类器构成的分类器, 因为随机,所以可以生成多个决策树,树多了也就成了森林
API
model=RandomForestClassifier(n_estimators= ,max_depth= ,criterion= )
其中参数 n_estimators 表示决策树的个数,类型为int,默认值是100;参数max_depth 表示树的最大深度;参数 criterion 有可选项 “gini” 与 “entropy”,前者表示用基尼指数构建决策树,后者表示用信息增益算法构建决策树,当然也可以选其他的比如 KNN算法
代码示例:
def test4():
'''随机森林分类'''
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
#加载数据集
titanic = pd.read_csv("./src/titanic/titanic.csv")
#因为该数据集是混合数据集没有明确区分x与y,以及有些特征值不是数值,所以需要对数据集进行处理
titanic=titanic[["age","pclass","sex","survived"]]#只保留对预测生存有用的几个特征(年龄、船票等级、性别、是否生还)
titanic["age"].fillna(titanic["age"].mean(),inplace=True) #填充年龄的缺失值为平均年龄
#分离目标x和标签y
y = titanic["survived"].to_numpy() #取出(生还)列 再转化为numpy数组,成为标签,也就是 y
x = titanic[["age", "pclass", "sex"]] #取出其余特征组成目标 也就是 x
# print(x) #返回的是 dataframe结构
# age pclass sex
# 0 29.000000 1st female
# 1 2.000000 1st female
# 2 30.000000 1st male
# 3 25.000000 1st female
# 4 0.916700 1st male
# ... ... ... ...
# print(y)
# [1313 rows x 3 columns]
# [[1]
# [0]
# [0]
# ...
# [0]
# [0]
# [0]]
x = x.to_dict(orient="records") #将 DataFrame 转换为适合 DictVectorizer 的输入格式,也就是转换为字典
dictvec = DictVectorizer(sparse=False) #实例化一个DictVectorizer对象
x = dictvec.fit_transform(x) #字典特征向量化
#数据集划分
x_train,x_test,y_train,y_test = train_test_split(x, y, test_size=0.2)
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train) #标准化划分后训练集的特征数据集
x_test = scaler.transform(x_test) #标准化划分后测试集的特征数据集
#生成模型
model = RandomForestClassifier(n_estimators=10, max_depth=4, criterion="entropy")
#模型训练
model.fit(x_train, y_train)
# 模型评估
score = model.score(x_test, y_test)
print(score) #0.844106463878327
运行结果:
![]()
这篇就到此为止,下一篇是非常重要的线性回归(๑•̀ㅂ•́)و✧
以上有问题可以指出
更多推荐

所有评论(0)