分类算法
一、sklearn转换器和预估器
1 转换器 - 特征工程的父类
- fit_transform()
- fit() 计算 每一列的平均值、标准差
- transform() (x - mean) / std进行最终的转换
2 估计器(sklearn机器学习算法的实现)
估计器(estimator)–一类实现算法的API
- 实例化一个estimator
- estimator.fit(x_train, y_train) 计算 —— 训练,调用完毕,模型生成
- 模型评估:
1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
y_test == y_predict
2)计算准确率 accuracy = estimator.score(x_test, y_test)
二、K-近邻算法(KNN)
1. 什么是K-近邻算法
核心思想:
根据你的“邻居”来推断出你的类别
2. K-近邻算法(KNN)原理
K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法总体来说KNN算法是相对比较容易理解的算法
定义:
如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属―某一个类别,则该样本也属于这个类别。
k = 1 容易受到异常点的影响
如何确定谁是邻居?
计算距离:
距离公式
欧氏距离
曼哈顿距离 --绝对值距离
明可夫斯基距离
注意:
- k 值取得过小,容易受到异常点的影响
- k 值取得过大,样本不均衡的影响
3.K-近邻算法API
sklearn.neighbor.KNeighborsClassifier(n_neighbors=5, algorithm='auto')
- n_neighbors:int型k值,k_neighbors查询默认使用的邻居数(默认为5)
- algorithm:{‘auto’,‘ball_tree’,‘kd_tree’}之一,‘ball_tree’将会使用 BallTree,‘kd_tree"将使用KDTree。'auto’将尝试根据传递给fit方法的值来决定最合适的算法。(不同实现方式影响效率)
4.案例1:鸢尾花种类预测
- 获取数据
- 数据集划分
- 特征工程
标准化
KNN预估器流程 - 模型评估
数据集介绍
lris数据集是常用的分类实验数据集,由Fisher,1936收集整理。lris也称鸢尾花卉数据集,是一类多重变量分析的数据集。
示例:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def knn_iris():
# 用knn算法对鸢尾花进行分类
# 步骤:
#获取数据
#数据集划分
#特征工程
#标准化
#KNN预估器流程
#模型评估
#1获取数据
iris = load_iris()
#2数据集划分 随机数种子?
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=6)
#3特征工程 标准化
#在划分前就标准化会让训练集内容干扰测试集结果,导致标准化的数据有偏差
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
#为什么测试集可以直接transform?因为transfer是一个对象会将计算结果保存在对象的属性中
#fit直接用于计算
#默认训练集和测试集有同样的均值和标准差!
#y_train:目标值,分类
#4 KNN 调入训练,预估器流程
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 模型评估
#方法1:直接比对真实值 预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对:\n",y_test == y_predict)
#方法2:计算准确率
score = estimator.score(x_test,y_test)
print("准确率:\n",score)
return None
if __name__ == '__main__':
#码1:Kn算法
knn_iris();
结果:
5 K-近邻总结
优点:简单,易于实现,无需训练
缺点:懒惰算法,对测试样本分类时的计算量大,内存开销大;必须指定K值,K值选择不当则分类精度不能保证
使用场景:小数据场景,几千~几万样本
三、模型选择与调优
学习目标:
说明交叉验证过程
说明超参数搜索过程
应用GridSearchCV实现算法参数的调优
应用:
鸢尾花数据集预测
1.交叉验证
将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成4份,其中一份作为验证集。然后经过4次(组)的测谜次都更换不同的验证集。即得到4组模型的结果,取平均值作为最终结果。又称4折交叉验证。
我们之前知道数据分为训练集和测试集,但是为了让从训练得到模型结果更加准确。做以下处理
- 训练集:训练集+验证集
- 测试集:测试集
目的: 为了让被评估的模型更加准确可信
2.超参数搜索—网格搜索(Grid Search)
通常情况下,很多参数是需要手动指定的(如K-近邻算法中的K值),这种叫超参数。
但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型
3.模型选择与调优API
sklearn.model_selection.GridSearchCV(estimator, param_grid=None, cv=None)
对估计器的指定参数进行详尽搜索
- estimator:估计器对象
- param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
- cv:指定几折交叉验证
- fit():输入训练数据
- score():准确率
结果分析:
- 最佳参数:best_params_
- 最佳结果:best_score_
- 最佳估计器:best_estimator_
交叉验证结果:cv_results_
4.鸢尾花案例增加K值调优
# -*-codeing = utf-8 -*-
# @Time : 2023/3/27 9:10
# @Author : 东
# @File : KNN算法调优
# @Software: PyCharm
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
def knn_iris():
# 用knn算法对鸢尾花进行分类
# 步骤:
#获取数据
#数据集划分
#特征工程
#标准化
#KNN预估器流程
#模型评估
# 获取数据
iris = load_iris()
# 2数据集划分 随机数种子?
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=6)
# 3特征工程 标准化
#在划分前就标准化会让训练集内容干扰测试集结果,导致标准化的数据有偏差
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
#为什么测试集可以直接transform?因为transfer是一个对象会将计算结果保存在对象的属性中
#fit直接用于计算
#默认训练集和测试集有同样的均值和标准差!
#y_train:目标值,分类
#4 KNN 调入训练,预估器流程
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 模型评估
#方法1:直接比对真实值 预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对:\n",y_test == y_predict)
#方法2:计算准确率
score = estimator.score(x_test,y_test)
print("准确率:\n",score)
return None
def knn_iris_gscv():
# 用knn算法对鸢尾花进行分类、网格搜索、交叉验证
# 获取数据
iris = load_iris()
# 2数据集划分 随机数种子?
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=6)
# 3特征工程 标准化
#在划分前就标准化会让训练集内容干扰测试集结果,导致标准化的数据有偏差
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
#4 KNN 调入训练,预估器流程
estimator = KNeighborsClassifier()
#加入网格搜索、交叉验证
#参数准备
param_dict = {"n_neighbors":[1,3,5,7,9,11]}
estimator = GridSearchCV(estimator,param_grid=param_dict,cv=10)
estimator.fit(x_train,y_train)
# 模型评估
#方法1:直接比对真实值 预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对:\n",y_test == y_predict)
#方法2:计算准确率
score = estimator.score(x_test,y_test)
print("准确率:\n",score)
#最佳参数:best_params_
print("最佳参数:\n",estimator.best_params_)
#最佳结果:best_score_
print("最佳结果:\n", estimator.best_score_)
#最佳估计器:best_estimator_
print("最佳估计器:\n", estimator.best_estimator_)
#交叉验证结果:cv_results_
print("交叉验证结果:\n", estimator.cv_results_)
return None
if __name__ == '__main__':
#码1:Kn算法
knn_iris();
#码2:调优
knn_iris_gscv();
结果:
四、朴素贝叶斯算法
学习目标:
说明条件概率与联合概率
说明贝叶斯公式,以及特征独立的关系
记忆贝叶斯公式
知道拉普拉斯平滑系数
应用贝叶斯公式实现概率的计算
1.什么是朴素贝叶斯算法
朴素贝叶斯(Naive Bayes): 朴素+贝叶斯,
是一种简单经典的分类算法,它的经典应用案例为人所熟知:文本分类(如垃圾邮件过滤)。
朴素
假设:特征与特征之间相互独立
2.概率论基础
先验概率:即基于统计的概率,是基于以往历史经验和分析得到的结果,不需要依赖当前发生的条件。
后验概率:则是从条件概率而来,由因推果,是基于当下发生了事件之后计算的概率,依赖于当前发生的条件。
条件概率:记事件A发生的概率为P(A),事件B发生的概率为P(B),则在B事件发生的前提下,A事件发生的概率即为条件概率,记为P(A|B)。
贝叶斯公式: 贝叶斯公式便是基于条件概率,通过P(B|A)来求P(A|B)
3.拉普拉斯平滑系数
目的:防止计算出的分类概率为0.
3.算法实现
API:
sklearn.naive_bayes.MultinomialNB(alpha=1.0)
案例:20类新闻分类
3.1 步骤分析
1)获取数据
2)划分数据集
3)特征工程:文本特征抽取
4)朴素贝叶斯预估器流程
5)模型评估
# -*-codeing = utf-8 -*-
# @Time : 2023/3/27 16:30
# @Author : 东
# @File : 02_day_pusuClass.py
# @Software: PyCharm
from sklearn.model_selection import train_test_split # 划分数据集
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer # 文本特征抽取
from sklearn.naive_bayes import MultinomialNB # 朴素贝叶斯
def nb_news():
"""
用朴素贝叶斯算法对新闻进行分类
:return:
"""
# 1)获取数据
news = fetch_20newsgroups(subset='all')
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)
# 3)特征工程:文本特征抽取
transfer = TfidfVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)朴素贝叶斯算法预估器流程
estimator = MultinomialNB()
estimator.fit(x_train, y_train)
# 5)模型评估
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict) # 直接比对
# 方法2:计算准确率
score = estimator.score(x_test, y_test) # 测试集的特征值,测试集的目标值
print("准确率:", score)
return None
if __name__ == "__main__":
nb_news()
结果:
总结:
- 优点: 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率 ;对缺失数据不太敏感,算法也比较简单,常用于文本分类;分类准确度高,速度快
- 缺点: 由于使用了样本属性独立性的假设,所以如果特征属性有关联时其效果不好
五、决策树
学习目标:
说明信息熵的公式以及作用
说明信息增益的公式作用
应用信息熵实现计算特征的不确定性减少程度
了解决策树的三种算法实现
1.认识决策树
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。
高效决策: 看特征先后顺序
2. 决策树分类原理详解
图中有四个特征,年龄、有工作、有自己的房子、信贷情况。
问题: 如何对这些客户进行分类预测? 你是如何去划分?(实现最优解)
决策树真实划分:
->原理
信息熵、信息增益等
需要用到信息论的知识!!!问题:通过例子引入信息嫡
->信息论基础
1)信息
香农 : 消除随机不定性的东西
小明年龄 “我今年18岁” - 信息
小华 "小明明年19岁” - 不是信息
信息的衡量-信息量–信息嫡
2)信息嫡的定义
3.决策树的划分依据之一-----信息增益
定义与公式
特征A对训练数据集D的信息增益g(D.A),定义为集合D的信息嫡H(D)与特征A给定条件下D的信息条件嫡H(DIA)之差,即公式为:
注: 信息增益表示得知特征X的信息而息的不确定性减少的程度使得类Y的信息嫡减少的程度
4. 决策树API
sklearn.tree.DecisionTreeClassifier(criterion='gini', max_depth=None, random_state=None)
- 决策树分类器
- criterion:默认是“gini”系数,也可以选择信息增益的熵‘entropy’
- max_depth:树的深度大小
- random_state:随机数种子
5.决策树用于鸢尾花数据集
案例源码:
from sklearn.datasets import load_iris # 获取数据集
from sklearn.model_selection import train_test_split # 划分数据集
from sklearn.naive_bayes import MultinomialNB # 朴素贝叶斯
from sklearn.tree import DecisionTreeClassifier
def decision_iris():
"""
决策树对鸢尾花进行分类
:return:
"""
# 1)获取数据集
iris = load_iris()
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22) # 随机数种子
# 不用做特征工程:标准化
# 3)决策树预估器
estimator = DecisionTreeClassifier(criterion='entropy')
estimator.fit(x_train, y_train)
# 4)模型评估
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接必读真实值和预测值:\n", y_test == y_predict) # 直接比对
# 方法2:计算准确率
score = estimator.score(x_test, y_test) # 测试集的特征值,测试集的目标值
print("准确率:", score)
return None
if __name__ == "__main__":
decision_iris()
结果:
6.决策树可视化
1 保存树的结构到dot文件
sklearn.tree.export_graphviz() # 该函数能够导入dot文件
tree.export.graphviz(estimator, out_file='tree.dot', feature_names=[","])
2 网站显示结构
http://webgraphviz.com/
在上述例子中引入包:
from sklearn.tree import export_graphviz
并加上代码
export_graphviz(estimator,out_file="iris_tree.dot",feature_names=iris.feature_names)
运行生成的iris_tree.dot文件。
将其复制粘贴到网站里,生成:
7.决策树总结
- 优点:简单的理解和解释,树木可视化
- 缺点:决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合
- 改进:
剪枝cart算法(决策树API当中已经实现,随机森林参数调优有相关介绍)
随机森林
8.案例:泰坦尼克号乘客生存预测
流程分析:特征值、目标值
1)获取数据
2)数据处理:缺失值处理,特征值->字典类型,
3)准备好特征值、目标值
4)划分数据集
5)特征工程:字典特征处理
6)决策树预估器流程
7)模型评估
import pandas as pd
# 1、获取数据
path = "C:/Users/zdb/Desktop/machine_learning/DataSets/titanic.csv"
titanic = pd.read_csv(path) #1313 rows × 11 columns
# 筛选特征值和目标值
x = titanic[["pclass", "age", "sex"]]
y = titanic["survived"]
# 2、数据处理
# 1)缺失值处理
x["age"].fillna(x["age"].mean(), inplace=True)
# 2)转换成字典
x = x.to_dict(orient="records")
from sklearn.model_selection import train_test_split
# 3、数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# 4、字典特征抽取
from sklearn.feature_extraction import DictVectorizer
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
from sklearn.tree import DecisionTreeClassifier, export_graphviz
# 3)决策树预估器
estimator = DecisionTreeClassifier(criterion='entropy')
estimator.fit(x_train, y_train)
# 4)模型评估
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接必读真实值和预测值:\n", y_test == y_predict) # 直接比对
# 方法2:计算准确率
score = estimator.score(x_test, y_test) # 测试集的特征值,测试集的目标值
print("准确率:", score)
# 可视化决策树
export_graphviz(estimator, out_file='titanic_tree.dot', feature_names=transfer.get_feature_names())
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plot_tree(decision_tree=estimator)
plt.show()
六、随机森林
集成学习方法之随机森林
学习目标:
说明随机森林每棵决策树的建立过程
直达为什么需要随机有放回(Booststrap)的 抽样
说明随机森林的超参数
1.什么是集成学习方法
集成学习方法通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各种独立地学习和做出预测。这些预测最后结合成组合预测,因此优于任何一个单分类做出的预测
2.什么是随机森林
在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别数输出的类别的众数而定
例如,如果训练了5棵树,5棵树的结果是True ,1棵树的结果是False,那么最终结果为True
3.随机森林原理过程
两个随机:
训练集随机:BoostStrap,N个样本中随机有放回抽样
特征值随机:从M个特征中随机抽取m个特征,M>>m
训练集:特征值、目标值
为什么采用BootStrap抽样
1、为什么要随机抽样训练集?
如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的
2、为什么要有放回地抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”,也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树的投票表决
4.随机森林API
随机森林分类器
sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion='gini', max_depth=None, /
bootstrap=True, random_state=None, min_samples_split=2)
- n_estimators:integer,optional(default=10)森林里的树木数量,可以用网格搜索
- criteria:string,可选(default=‘gini’),分割特征的测量方法
- max_depth:integer或None,可选(默认无),树的最大深度5,8,15,25,30 可以用网格搜索
- max_teatures=‘auto’,每个决策树的最大特征数量
- if ‘auto’ ,then max_features = sqrt(n_features)
- if ‘sqrt’ ,then max_features = sqrt(n_features)
- if ‘log2’ ,then max_features = log2(n_features)
- if None,then max_features = n_features
- booststrap:boolean,optional(default=True)是否在构建树时使用放回抽样
- min_samples_split:节点划分最少样本数
- min_samples_leaf:叶子节点的最小样本数
超参数:n_estimator,max_depth,min_samples_split,min_samples_leaf
在之前的代码中增加这个代码块
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
estimator = RandomForestClassifier()
# 加入网格搜索与交叉验证
# 参数准备
param_dict = {"n_estimators":[120,200,300,500,800,1200], "max_depth":[5,8,15,25,30]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3) # 10折,数据量不大,可以多折
estimator.fit(x_train, y_train)
# 5、模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接必读真实值和预测值:\n", y_test == y_predict) # 直接比对
# 方法2:计算准确率
score = estimator.score(x_test, y_test) # 测试集的特征值,测试集的目标值
print("准确率:", score)
# 查看最佳参数:best_params_
print("最佳参数:", estimator.best_params_)
# 最佳结果:best_score_
print("最佳结果:", estimator.best_score_)
# 最佳估计器:best_estimator_
print("最佳估计器:", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:", estimator.cv_results_)
5.随机森林总结
- 在当前所有算法中,具有极好的准确率
- 能够有效地运行在大数据集上,处理具有高维特征的输入样本,而且不需要降维
- 能够评估各个特征在分类问题上的重要性
备注–参考学习:
B站-黑马程序员3天快速入门python机器学习
笔记内容随时补充,如需相关资料可私信本人