KNN算法
一 KNN算法介绍
K-近邻算法(K Nearest Neighbor,简称KNN).比如根据你的“邻居”来推断出你的类别.
KNN算法思想:如果一个样本在特征空间中的 k 个最相似的样本中的大多数属于某一个类别,则该样本也属于这个类别 .
KNN算法的应用方式:
-
分类问题处理:
1.计算未知样本到每一个训练样本的距离
2.将训练样本根据距离大小升序排列
3.取出距离最近的 K 个训练样本
4.进行多数表决,统计 K 个样本中哪个类别的样本个数最多
5.将未知的样本归属到出现次数最多的类别
-
回归问题处理:
1.计算未知样本到每一个训练样本的距离
2.将训练样本根据距离大小升序排列
3.取出距离最近的 K 个训练样本
4.把这个 K 个样本的目标值计算其平均值
5.平均值作为未知的样本预测值
二 KNN算法API
# 导包
from sklearn.neighbors import KNeighborsClassifier,KNeighborsRegressor # 分类算法,回归算法
2.1 KNeighborsClassifier 分类算法
英文翻译:
KNeighborsClassifier # 分类算法
estimator # 估量值 估计器
例句:
estimator = KNeighborsClassifier(n_neighbors=3)
API解释:
KNeighborsClassifier() # 创建分类算法对象
n_neighbors=n # 参数 k 的值 即几个样本(邻居)
应用场景:标签不连续通过分类思想解决.
2.2 KNeighborsRegressor 回归算法
英文翻译:
KNeighborsRegressor # 回归算法
estimator # 估量值 估计器
例句:
estimator = KNeighborsRegressor(n_neighbors=4)
API解释:
KNeighborsRegressor() # 创建回归算法对象
n_neighbors=n # 参数 k 的值 即几个样本(邻居)
应用场景:标签连续通过回归思想解决.
三 两个经典案例
3.1 鸢尾花案例
本案例通过提取鸢尾花的特征,通过数据集训练模型使其可以分辨不同种类的鸢尾花.在Anaconda2024版本中已经集成了鸢尾花的数据集.方便大家直接使用.
# 0. 导包
from sklearn.datasets import load_iris # 加载鸢尾花数据集
import seaborn as sns # Seaborn绘图
import matplotlib.pyplot as plt # matplotlib
import pandas as pd # pandas
from sklearn.model_selection import train_test_split # 切割训练集和测试集
from sklearn.preprocessing import StandardScaler # 数据标准化处理
from sklearn.neighbors import KNeighborsClassifier # KNN算法 分类对象
from sklearn.metrics import accuracy_score # 模型评估
# 1.定义函数 用于加载鸢尾花数据集 并简单查看数据集各部分
def dm01_load_iris():
# 1.1加载数据集
iris_data = load_iris()
# 1.2 打印数据集
# print(iris_data)
# 1.3 #打印所有的键 即属性名
# dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
# print(iris_data.keys())
# 1.4 查看数据集字段特征
print(iris_data.data[:5])
# 1.5 查看数据集的标签字段
print(iris_data.target[:5])
# 1.6 查看数据集的标签名
# ['setosa' 'versicolor' 'virginica']
print(iris_data.target_names)
# 1.7 查看数据集的特征名
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
print(iris_data.feature_names)
# 1.8 查看数据集描述信息
# print(iris_data.DESCR)
# 1.9 查看数据集文件名
# print(iris_data.filename)
# 1.10 查看数据集 数据模型
# print(iris_data.data_module)
# 2.定义函数 用于通过 Seaborn散点图的方式 对鸢尾花数据集进行可视化
def dm02_show_iris():
# 1.加载鸢尾花数据集
iris_data = load_iris()
# 2.封装成DF 对象 作为可视化展示的数据源
iris_df = pd.DataFrame(iris_data.data,columns=iris_data.feature_names)
# 3.给DF 对象新增1列 表示:标签
iris_df['label'] = iris_data.target
print(iris_df)
# 4.可视化 散点图
# x: x轴值, 这里是: 花瓣的长度, y: y轴值, 这里是: 花瓣的宽度, hue: 颜色(根据鸢尾花的标签来分组, 不同分组颜色不同), fit_reg=False, 不绘制拟合回归线.
sns.lmplot(data=iris_df,x='petal length (cm)',y='petal width (cm)',hue='label',fit_reg=False)
# 设置标题
plt.title('iris data')
# 绘图
plt.show()
if __name__ == '__main__':
# dm01_load_iris()
dm02_show_iris()
# 3.定义函数实现划分训练集和测试集
def dm03_train_test_split():
# 1.加载数据集
iris_data = load_iris()
# 2. 划分训练集和测试集
# iris_data.data => 特征, 一共150条
# iris_target => 标签, 一共150条
# test_size => 测试集占比, 0.2 => 训练集 : 测试集 => 8 : 2
# random_state => 随机种子, 如果种子一样, 则每次划分的数据集都是一样的.
# 细节: 返回值的时候, 注意下四个参数的顺序, 即: 训练集特征, 测试集特征, 训练集标签, 测试集标签.
x_train,x_test,y_train,y_test = train_test_split(iris_data.data,iris_data.target,test_size=0.2,random_state=66)
# 3.打印划分后的结果
print(f'训练集,x-特征:{len(x_train)}')
print(f'测试集,x-特征:{len(x_test)}')
print(f'训练集,y-标签:{len(y_train)}')
print(f'测试集,y-标签:{len(y_test)}')
# 4.定义函数 实现模型预测和评估
def dm04_predict():
# 1.加载数据
iris_data = load_iris()
# 2.数据预处理 因数据量小且Anaconda2024提前处理过 这里只划分训练集与测试即可
x_train, x_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.2,random_state=66)
# 3.特征工程
# 3.1 特征提取:查看训练集的 特征, 因为特征是已经提取好的, 所以无需我们手动提取了, 即, 特征为: 花萼的长度, 花萼的宽度, 花瓣长度, 花瓣的宽度.
# print(x_train)
# 3.2 特征预处理
# 创建标准化对象
transfer = StandardScaler()
# 标准化训练集的特征
x_train = transfer.fit_transform(x_train)
# 查看结果
# print(x_train)
# 标准化测试集的特征
x_test = transfer.transform(x_test)
# 4.模型训练(机器学习)
# 4.1 创建估计器对象
estimator = KNeighborsClassifier(n_neighbors=5)
# 4.2 模型训练
estimator.fit(x_train,y_train) # 传入 训练集的特征和标签
# 5.模型预测
# 场景1
# 对测试集预测 得到预测后的测试集标签
y_predict = estimator.predict(x_test)
print(f'测试集预测结果为{y_predict}') # [1 0 0 0 1 1 0 2 0 0 1 1 2 2 0 2 1 1 0 2 2 1 2 1 0 1 0 0 1 2]
# 场景2 对新数据集做预测
# step1:定义新的数据集
my_data = [[2.1, 3.5, 5.6, 3.2]]
# step2:对新数据集标准化处理
my_data = transfer.transform(my_data)
# step3:对新数据集做结果分类预测,打印预测结果
my_predict = estimator.predict(my_data)
print(f'新数据集预测结果为{my_predict}') # 新数据集预测结果为[1]
# step4:对新数据集做概率预测,看看在各个标签中的概率
my_predict_proba = estimator.predict_proba(my_data)
print(f'新数据集在各标签概率预测为{my_predict_proba}') # [[0. 0.6 0.4]] 即 占 0 1 2的概率
# 6. 模型评估 KNN(K近邻算法), 评估指标主要是: 预测的准确率.
# 方式1 直接评估 获取准确率
print(f'直接评估准确率为{estimator.score(x_test,y_test)}') # 传入测试集特征和标签 # 0.9
# 方式2 用真实值和预测值评估得到准确率
print(f'真实值和预测值对比评估结果为{accuracy_score(y_test,y_predict)}') # 传入测试集标签和预测值标签 # 0.9
if __name__ == '__main__':
# dm03_train_test_split()
dm04_predict()
3.2 手写数字识别案例
# 背景相关
MNIST手写数字识别
1999年发布,成为分类算法基准测试的基础
MNIST仍然是研究人员和学习者的可靠资源
# 需求
从数万个手写图像的数据集中正确识别数字.
(超级经典的案例,数据集网络资源丰富,本文只手撕代码.)
# 导包
import matplotlib.pyplot as plt # matplotlib绘图
import pandas as pd # pandas
from sklearn.model_selection import train_test_split # 分割训练集和测试集
from sklearn.neighbors import KNeighborsClassifier # KNN 分类算法
import joblib # 加载或保存模型
from collections import Counter # 分组计数
# 1. 定义函数用于查看数字图片
def show_digit(idx):
"""
定义函数用于查看数字图片
:param idx: 行索引
:return: 无
"""
# 1.读取数据 获取df对象
data = pd.read_csv('data/手写数字识别.csv')
# 细节: 非法值校验
if idx < 0 or idx > len(data)-1:
return
# 2. 获取数据: 特征+标签
x = data.iloc[:,1:] # 所有行,第二列到最后
y = data.iloc[:,0] # 所有行,第一列
# 3. 查看数据集
print(f'x的维度{x.shape}') # (42000, 784)
print(f'y的各分类数量{Counter(y)}') #Counter({1: 4684, 7: 4401, 3: 4351, 9: 4188, 2: 4177, 6: 4137, 0: 4132, 4: 4072, 8: 4063, 5: 3795})
# 4.获取具体的某张图片 某一行数据等于一条样本数据
# step1 把一条样本数据转成(28,28)的二维数组 即模拟28*28像素的图片
digit = x.iloc[idx].values.reshape(28,28)
# step2 显示图片
plt.imshow(digit,cmap='gray') # cmap='gray' 灰色显示 即 灰度图
# step3 取消坐标显示
plt.axis('off')
# step4 绘图
plt.show() # 8
# 在main函数中测试
if __name__ == '__main__':
# 显示数字图片
show_digit(10)
# 2.训练模型
def train_model():
# 1.读取数据 获取df对象
data = pd.read_csv('data/手写数字识别.csv')
# 2.获取数据 特征+标签
x = data.iloc[:,1:]
y = data.iloc[:,0]
# 3.特征预处理
# step1 X轴(像素点)的归一化处理
x = x / 255
# step2 划分训练集和测试集
# stratify=y 按照y的类别比例进行分割
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,stratify=y,random_state=66)
# 4.训练模型
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 5.模型评估 评测正确率
my_score = estimator.score(x_test,y_test)
print(f'模型评估的正确率为{my_score}') # 0.9657142857142857
# 6.保存模型
joblib.dump(estimator,'model/knn.pth')
# 3. 测试模型
def use_model():
# 1.加载图片
img = plt.imread('data/demo.png') # 28 * 28像素
plt.imshow(img,cmap='gray') # 灰度图
plt.show() # 2
# 2.加载模型
estimator = joblib.load('model/knn.pth')
# 3.预测图片
img = img.reshape(1,-1) # 1行 所有列 等同于 (1, 784)
y_test = estimator.predict(img)
print(f'预测的数字是{y_test}') # [2]
# 在main函数中测试
if __name__ == '__main__':
# 训练模型
# train_model() # 0.9657142857142857
# 测试模型
use_model()
以上就是要和大分享的KNN算法相关内容,机器学习算法还有很多,后面我还会持续分享其他训练模型的算法.我们下期见!
标签:KNN,iris,print,算法,train,test,data From: https://blog.csdn.net/weixin_50229673/article/details/142709129