人工智能入门课程学习(5)—— K近邻算法

1. K近邻算法的简介

1.1 什么是K近邻算法

根据你的“邻居”来推断出你的类别

  • 概念
    • K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法, 总体来说KNN算法是相对比较容易理解的算法
  • 定义
    • 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

来源:KNN算法最早是由Cover和Hart提出的一种分类算法

1.2 电影案例分析

假设我们现在有几部电影
在这里插入图片描述
其中? 号电影不知道类别,如何去预测?我们可以利用K近邻算法的思想
在这里插入图片描述
分别计算每个电影和被预测电影的距离,然后求解
在这里插入图片描述

2.KNN算法的入门使用(API熟悉)

先安装好sklearn,再使用

from sklearn.neighbors import KNeighborsClassifier

# 机器学习的5个步骤
# 1.获取数据
x = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]

# 实例化算法接口
estimator = KNeighborsClassifier(n_neighbors=2)

# 2.数据处理(略)
# 3.特征工程(略)

# 4.训练模型
estimator.fit(x,y)

# 使用训练好的模型预测输入值
estimator.predict([[0.5]])

# 5.模型评估(略)

输出:
在这里插入图片描述

3.K值选择问题

  • K值过小:

    • ​ 容易受到异常点的影响
  • k值过大:

    • 受到样本均衡的问题

在实际应用中,K值一般取一个比较小的数值,例如采用交叉验证法(简单来说,就是把训练数据在分成两组:训练集和验证集)来选择最优的K值。对这个简单的分类器进行泛化,用核方法把这个线性模型扩展到非线性的情况,具体方法是把低维数据集映射到高维特征空间。

4.鸢尾花种类预测

4.1 数据集介绍

Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。关于数据集的具体介绍:
在这里插入图片描述

4.2 scikit-learn中数据集API介绍(数据获取)

  • sklearn.datasets

    • 加载获取流行数据集
    • datasets.load_*()
      • 获取小规模数据集,数据包含在datasets里
  • datasets.fetch_*(data_home=None)

    • 获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是 ~/scikit_learn_data/

sklearn小数据集

sklearn.datasets.load_iris() 加载并返回鸢尾花数据集
在这里插入图片描述

sklearn大数据集

  • sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
    • subset:‘train’或者’test’,‘all’,可选,选择要加载的数据集。
    • 训练集的“训练”,测试集的“测试”,两者的“全部”

sklearn数据集返回值介绍

  • load和fetch返回的数据类型datasets.base.Bunch(字典格式)
    • data:特征数据数组,是 [n_samples * n_features] 的二维 numpy.ndarray 数组
    • target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
    • DESCR:数据描述
    • feature_names:特征名,新闻数据,手写数字、回归数据集没有
    • target_names:标签名
from sklearn.datasets import load_iris
from sklearn.datasets import fetch_20newsgroups

# 获取数据集   bunch字典
iris = load_iris()
iris

在这里插入图片描述

# 获取所有的特征值
iris.data

在这里插入图片描述

# 获取所有的目标值
iris.target

在这里插入图片描述

# 获取所有的特征名称
iris.feature_names

在这里插入图片描述

4.3 数据集的划分

机器学习一般的数据集会划分为两个部分:

  • 训练数据:用于训练,构建模型
  • 测试数据:在模型检验时使用,用于评估模型是否有效

划分比例:

  • 训练集:70% 80% 75%
  • 测试集:30% 20% 25%

数据集划分api

  • sklearn.model_selection.train_test_split(arrays, *options)
    • x 数据集的特征值
    • y 数据集的标签值
    • test_size 测试集的大小,一般为float
    • random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
    • return 测试集特征训练集特征值值,训练标签,测试标签(默认随机取)
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# 1、获取鸢尾花数据集
iris = load_iris()
# 对鸢尾花的数据集进行分割
# 训练集的特征值x_train 测试集的特征值x_test 训练集的目标值y_train 测试集的目标值y_test
# 如果随机种子数random_state一样,则生成的随机数就会是一样的
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=22)

4.4 特征工程-特征预处理

为什么我们要进行归一化/标准化?

  • 特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标结果,使得一些算法无法学习到其它的特征
    在这里插入图片描述
    常用的统一量纲的方法有归一化和标准化,并且主要使用标准化,因为归一化容易受最大最小值为异常值的情况的影响
    特征预处理APIsklearn.preprocessing
    标准化公式:
    在这里插入图片描述

使用

import pandas as pd
from sklearn.preprocessing import MinMaxScaler

在这里插入图片描述
在这里插入图片描述

4.5 K-近邻算法API

  • sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm=‘auto’)
    • n_neighbors:
      • int,可选(默认= 5),k_neighbors查询默认使用的邻居数
    • algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’}
      • 快速k近邻搜索算法,默认参数为auto,可以理解为算法自己决定合适的搜索算法。除此之外,用户也可以自己指定搜索算法ball_tree、kd_tree、brute方法进行搜索,
        • brute是蛮力搜索,也就是线性扫描,当训练集很大时,计算非常耗时。
        • kd_tree,构造kd树存储数据以便对其进行快速检索的树形数据结构,kd树也就是数据结构中的二叉树。以中值切分构造的树,每个结点是一个超矩形,在维数小于20时效率高。
        • ball tree是为了克服kd树高纬失效而发明的,其构造过程是以质心C和半径r分割样本空间,每个节点是一个超球体。

4.6 鸢尾花种类预测的完整实现

Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。关于数据集的具体介绍:
在这里插入图片描述
实现步骤:

  • 1.获取数据集
  • 2.数据基本处理
  • 3.特征工程
  • 4.机器学习(模型训练)
  • 5.模型评估
    在这里插入图片描述

5.交叉验证和网格搜索

5.1 交叉验证

交叉验证:将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成4份,其中一份作为验证集。然后经过4次(组)的测试,每次都更换不同的验证集。即得到4组模型的结果,取平均值作为最终结果。又称4折交叉验证。
在这里插入图片描述
交叉验证目的:为了让被评估的模型更加准确可信
问题:那么这个只是对于参数得出更好的结果,那么怎么选择或者调优参数呢?
(网格搜索)

5.2 网格搜索

通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
在这里插入图片描述

5.3 交叉验证,网格搜索(模型选择与调优)API:

  • sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
    • 对估计器的指定参数值进行详尽搜索
    • estimator:估计器对象
    • param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
    • cv:指定几折交叉验证
    • fit:输入训练数据
    • score:准确率
    • 结果分析:
      • bestscore__:在交叉验证中验证的最好结果
      • bestestimator:最好的参数模型
      • cvresults:每次交叉验证后的验证集准确率结果和训练集准确率结果

5.4 鸢尾花案例增加K值调优

  • 使用GridSearchCV构建估计器
# 1、获取数据集
iris = load_iris()
# 2、数据基本处理 -- 划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 3、特征工程:标准化
# 实例化一个转换器类
transfer = StandardScaler()
# 调用fit_transform
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4、KNN预估器流程
#  4.1 实例化预估器类
estimator = KNeighborsClassifier()

# 4.2 模型选择与调优——网格搜索和交叉验证
# 准备要调的超参数
param_dict = {"n_neighbors": [1, 3, 5]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)
# 4.3 fit数据进行训练
estimator.fit(x_train, y_train)
# 5、评估模型效果
# 方法a:比对预测结果和真实值
y_predict = estimator.predict(x_test)
print("比对预测结果和真实值:\n", y_predict == y_test)
# 方法b:直接计算准确率
score = estimator.score(x_test, y_test)
print("直接计算准确率:\n", score)

在这里插入图片描述

6.案例2:预测facebook签到位置

6.1 数据集介绍

在这里插入图片描述
在这里插入图片描述

官网:https://www.kaggle.com/navoshta/grid-knn/data

6.2 实现过程

1.获取数据集

# 1、获取数据集
facebook = pd.read_csv("./data/FBlocation/train.csv")

2.基本数据处理

# 2.基本数据处理
# 2.1 缩小数据范围
facebook_data = facebook.query("x>2.0 & x<2.5 & y>2.0 & y<2.5")
# 2.2 选择时间特征
time = pd.to_datetime(facebook_data["time"], unit="s")
time = pd.DatetimeIndex(time)
facebook_data["day"] = time.day
facebook_data["hour"] = time.hour
facebook_data["weekday"] = time.weekday
# 2.3 去掉签到较少的地方
place_count = facebook_data.groupby("place_id").count()
place_count = place_count[place_count["row_id"]>3]
facebook_data = facebook_data[facebook_data["place_id"].isin(place_count.index)]
# 2.4 确定特征值和目标值
x = facebook_data[["x", "y", "accuracy", "day", "hour", "weekday"]]
y = facebook_data["place_id"]
# 2.5 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)

3.特征工程–特征预处理(标准化)

# 3.特征工程--特征预处理(标准化)
# 3.1 实例化一个转换器
transfer = StandardScaler()
# 3.2 调用fit_transform
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)

4.机器学习

# 4.机器学习--knn+cv
# 4.1 实例化一个估计器
estimator = KNeighborsClassifier()
# 4.2 调用gridsearchCV
param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5)
# 4.3 模型训练
estimator.fit(x_train, y_train)

5.模型评估

# 5.模型评估
# 5.1 基本评估方式
score = estimator.score(x_test, y_test)
print("最后预测的准确率为:\n", score)

y_predict = estimator.predict(x_test)
print("最后的预测值为:\n", y_predict)
print("预测值和真实值的对比情况:\n", y_predict == y_test)

# 5.2 使用交叉验证后的评估方式
print("在交叉验证中验证的最好结果:\n", estimator.best_score_)
print("最好的参数模型:\n", estimator.best_estimator_)
print("每次交叉验证后的验证集准确率结果和训练集准确率结果:\n",estimator.cv_results_)

7.KNN算法的总结

  • 优点:

    • 简单有效
    • 重新训练的代价低
    • 适合类域交叉样本
      • KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
    • 适合大样本自动分类
      • 该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
  • 缺点:

    • 惰性学习
      • KNN算法是懒散学习方法(lazy learning,基本上不学习),一些积极学习的算法要快很多
    • 类别评分不是规格化
      • 不像一些通过概率评分的分类
    • 输出可解释性不强
      • 例如决策树的输出可解释性就较强
    • 对不均衡的样本不擅长
      • 当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。
    • 计算量较大
      • 目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值