1 转换器 - 特征工程的父类
2 估计器(sklearn机器学习算法的实现)
估计器(estimator)–一类实现算法的API
1. 什么是K-近邻算法
核心思想:
根据你的“邻居”来推断出你的类别
2. K-近邻算法(KNN)原理
K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法总体来说KNN算法是相对比较容易理解的算法
定义:
如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属―某一个类别,则该样本也属于这个类别。
k = 1 容易受到异常点的影响
如何确定谁是邻居?
计算距离:
距离公式
欧氏距离
曼哈顿距离 --绝对值距离
明可夫斯基距离
注意:
3.K-近邻算法API
sklearn.neighbor.KNeighborsClassifier(n_neighbors=5, algorithm='auto')
4.案例1:鸢尾花种类预测
数据集介绍
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实现算法参数的调优
应用:
鸢尾花数据集预测
将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成4份,其中一份作为验证集。然后经过4次(组)的测谜次都更换不同的验证集。即得到4组模型的结果,取平均值作为最终结果。又称4折交叉验证。
我们之前知道数据分为训练集和测试集,但是为了让从训练得到模型结果更加准确。做以下处理
通常情况下,很多参数是需要手动指定的(如K-近邻算法中的K值),这种叫超参数。
但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型
sklearn.model_selection.GridSearchCV(estimator, param_grid=None, cv=None)
对估计器的指定参数进行详尽搜索
结果分析:
# -*-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();
学习目标:
说明条件概率与联合概率
说明贝叶斯公式,以及特征独立的关系
记忆贝叶斯公式
知道拉普拉斯平滑系数
应用贝叶斯公式实现概率的计算
朴素贝叶斯(Naive Bayes): 朴素+贝叶斯,
是一种简单经典的分类算法,它的经典应用案例为人所熟知:文本分类(如垃圾邮件过滤)。
朴素
假设:特征与特征之间相互独立
先验概率:即基于统计的概率,是基于以往历史经验和分析得到的结果,不需要依赖当前发生的条件。
后验概率:则是从条件概率而来,由因推果,是基于当下发生了事件之后计算的概率,依赖于当前发生的条件。
条件概率:记事件A发生的概率为P(A),事件B发生的概率为P(B),则在B事件发生的前提下,A事件发生的概率即为条件概率,记为P(A|B)。
贝叶斯公式: 贝叶斯公式便是基于条件概率,通过P(B|A)来求P(A|B)
3.拉普拉斯平滑系数
目的:防止计算出的分类概率为0.
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()
学习目标:
说明信息熵的公式以及作用
说明信息增益的公式作用
应用信息熵实现计算特征的不确定性减少程度
了解决策树的三种算法实现
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。
高效决策: 看特征先后顺序
图中有四个特征,年龄、有工作、有自己的房子、信贷情况。
问题: 如何对这些客户进行分类预测? 你是如何去划分?(实现最优解)
决策树真实划分:
->原理
信息熵、信息增益等
需要用到信息论的知识!!!问题:通过例子引入信息嫡
->信息论基础
1)信息
香农 : 消除随机不定性的东西
小明年龄 “我今年18岁” - 信息
小华 "小明明年19岁” - 不是信息
信息的衡量-信息量–信息嫡
定义与公式
特征A对训练数据集D的信息增益g(D.A),定义为集合D的信息嫡H(D)与特征A给定条件下D的信息条件嫡H(DIA)之差,即公式为:
注: 信息增益表示得知特征X的信息而息的不确定性减少的程度使得类Y的信息嫡减少的程度
sklearn.tree.DecisionTreeClassifier(criterion='gini', max_depth=None, random_state=None)
案例源码:
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()
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)
流程分析:特征值、目标值
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)的 抽样
说明随机森林的超参数
集成学习方法通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各种独立地学习和做出预测。这些预测最后结合成组合预测,因此优于任何一个单分类做出的预测
在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别数输出的类别的众数而定
例如,如果训练了5棵树,5棵树的结果是True ,1棵树的结果是False,那么最终结果为True
两个随机:
训练集随机:BoostStrap,N个样本中随机有放回抽样
特征值随机:从M个特征中随机抽取m个特征,M>>m
训练集:特征值、目标值
为什么采用BootStrap抽样
1、为什么要随机抽样训练集?
如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的
2、为什么要有放回地抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”,也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树的投票表决
随机森林分类器
sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion='gini', max_depth=None, /
bootstrap=True, random_state=None, min_samples_split=2)
超参数: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_)
备注–参考学习:
B站-黑马程序员3天快速入门python机器学习
笔记内容随时补充,如需相关资料可私信本人