【机器学习之KNN算法详解】

一.K-近邻算法(K Nearest Neighbor,简称KNN)

简介:KNN是一种惰性、基于实例的算法。它的工作原理是将新样本的特征与数据集中现有样本的特征进行比较。然后算法选择最接近的k个样本,其中k是用户定义的参数。新样本的输出是基于“k”最近样本的多数类(用于分类)或平均值(用于回归)确定的。

1.1主要应用与分类与回归问题

1.分类问题:预测的目标值是离散的(比如说种类什么的)
分类思想:如果一个样本在特征空间中的 k 个最相似的样本中的大多数属于某一个类别,则该样本也属于这个类别

2.回归问题:预测的目标值是连续的(比如说工资啥的)
回归思想:预测一个样本在特征空间中的目标值,取 k 个最相似的样本的目标值的均值作为该预测样本的预测值

1.2 思考:如何确定样本的相似性?

样本都是属于一个任务数据集的。样本距离越近则越相似,所以我们需要求出样本之间的距离.那么如何去求样本之间的距离呢?
在KNN算法中主要用到求样本之间的距离的方法有欧式距离,曼哈顿距离,切比雪夫距离等等,我们这里将讲一下欧式距离.
欧氏距离:其实我们日常在数学中用得最多的,可以看作就是在坐标系中求两个点之间的直线距离.

原理:从a元素中减去b元素,得到对应坐标之间的差值。将各个差值进行平方求和再开根号,得到的就是两个元素之间的欧式距离

公式:
二维平面上a(x1,y1),b(x2,y2)求欧式距离公式:
在这里插入图片描述
三维空间上a(x1,y1,z1),b(x2,y2,z2)求欧式距离公式:
在这里插入图片描述
n维空间上a(X11,X12,X13,…X1n),b(X21,X22,X23,…X2n)即两个n为向量求欧式距离的公式:
在这里插入图片描述

在得到预测样本与每一个原样本之间的欧式距离后,进行排序,欧式距离越小,表示样本的相似性越大,取相关性较大的前k个样本.针对不同的问题取求解

1.3 分类任务(预测的目标值是离散的):

进行多数表决,统计 K 个样本中哪个类别的样本个数最多,将未知的样本归属到出现次数最多的类别

KNN分类API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5) #导包
n_neighbors:int,可选(默认= 5#k_neighbors查询默认使用的邻居数

具体的使用

# 预测数值属于哪一类
# 0,1 为0类,	2,3为1类
from sklearn.neighbors import KNeighborsClassifier
# 实例化算法API
estimator = KNeighborsClassifier(n_neighbors=1) # 这里我们设置k为1
# x为特征值
X = [[0], [1], [2], [3]]
# y为标签值
y = [0, 0, 1, 1]
# 把特征值和标签值输入进行训练
estimator.fit(X, y)
# 调用训练好的分类器对数字4进行预测,看他是属于哪一个类别
myret = estimator.predict([[4]]) # 对数字4进行预测,是属于(0,1)哪一个分类
print('myret-->', myret)# 输出分类的结果

结果在这里插入图片描述

1.4 回归任务(预测的目标值是连续的):

把取到的 k 个最相似的样本的目标值的均值作为该预测样本的预测的目标值

KNN回归API
sklearn.neighbors.KNeighborsRegressor(n_neighbors=5)
n_neighbors:int,可选(默认= 5#k_neighbors查询默认使用的邻居数

具体实例

from sklearn.neighbors import KNeighborsRegressor # 导包

# 实例化算法API
estimator = KNeighborsRegressor(n_neighbors=2) # 这里我们设置k为2
# x为特征值
X = [[0, 0, 1],
[1, 1, 0],
[3, 10, 10],
[4, 11, 12]]
# y是目标值
y = [0.1, 0.2, 0.3, 0.4]
# 对分类器进行训练
estimator.fit(X, y)
# 调用训练好的分类器进行预测
myret = estimator.predict([[3, 11, 10]])
print('myret-->', myret) # 输出预测的结果

结果:
在这里插入图片描述

1.5 k的取值

1.K值过小:容易受到异常点的影响
2.k值过大:受到样本均衡的问题
3.K=N(N为训练样本个数):结果只取决于数据集中不同类别数量占比,得到的结果一定是占比高的类别,此时模型过于简单,忽略了训练实例中大量有用信息
4.在选择k值的时候,尽量避免k个数据中平均分布,这样就会出现类型(选择困难症)预测的结果会出现比较大偏差,尽量不要选择类别的倍数,其原理也是一样的。

1.6特征预处理

当特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标结果,使得一些模型(算法)无法学习到其它的特征。因此,我们需要先对特征进行预处理。

特征的预处理方式主要有两种:
1.数据归一化:通过对原始数据进行变换把数据映射到【mi,mx】(默认为[0,1])之间
公式为:在这里插入图片描述
数据归一化API:

1.sklearn.preprocessing.MinMaxScaler (feature_range=(0,1))
2.feature_range: 缩放区间
3.fit_transform(X) 将特征进行归一化缩放![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b2a357d6bf6b4c5a8e970c2459e57ede.png#pic_center)

具体实例:

import numpy as np
from sklearn.preprocessing import MinMaxScaler

# 1.准备数据
data = [[90, 2, 10, 40],
[60, 4, 15, 45],
[75, 3, 13, 46]]
# 2. 初始化归一化对象
transformer = MinMaxScaler()
# 3. 对原始特征进行变换
data = transformer.fit_transform(data)
# 4. 打印归一化后得到的结果
print(data)

结果:
在这里插入图片描述

特点:归一化受到最大值与最小值的影响,这种方法容易受到异常数据的影响, 鲁棒性较差,适合传统精确小数据场景

2.数据标准化:通过对原始数据进行标准化,转换为均值为0标准差为1的标准正态分布的数据
公式为:
在这里插入图片描述
数据标准化API:

1.sklearn.preprocessing. StandardScaler()
2.fit_transform(X) 将特征进行归一化缩放

具体实例:

from sklearn.preprocessing import StandardScaler

# 1. 准备数据
data = [[90, 2, 10, 40],
[60, 4, 15, 45],
[75, 3, 13, 46]]
# 2. 初始化标准化对象
transformer = StandardScaler()
# 3. 对原始特征进行变换
data = transformer.fit_transform(data)
# 4. 打印归一化后的结果
print(data)
# 5 打印每1列数据的均值和标准差
print('transfer.mean_-->', transfer.mean_)
print('transfer.var_-->', transfer.var_)

结果:
在这里插入图片描述

特点:对于标准化来说,如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,适合当代嘈杂的大数据环境,和归一化相比其运算量要大很多

1.7最后是一个完整的对鸢尾花分类的小案例

from sklearn.datasets import load_iris  # 导入数据集包
from sklearn.model_selection import train_test_split #划分数据集的包 


from sklearn.preprocessing import StandardScaler  # 数据标准化的包
from sklearn.neighbors import KNeighborsClassifier # 分类的包

# 1.加载数据集
mydataset = load_iris()

# 2.数据集划分
x_train, x_test, y_train, y_test = train_test_split(mydataset.data, mydataset.target, 
test_size=0.3, random_state=22)

# 3 数据标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
# 让训练集的均值和方差转换测试集数据
x_test = transfer.transform(x_test)

# 4 模型训练
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train, y_train)

# 5 模型评估,直接计算准确率,100个样本中模型预测对了多少
myscore = estimator.score(x_test, y_test)
print("myscore-->", myscore)

# 6 模型预测,需要对待测数据执行标准化
print('通过模型查看分类类别-->', estimator.classes_)
mydata = [[5.1, 3.5, 1.4, 0.2],
		  [4.6, 3.1, 1.5, 0.2]]
# 对测试数据进行数据标准化
mydata = transfer.transform(mydata)
print('mydata-->', mydata)
# 把标准化的数据输入模型进行预测,得到分类的类别
mypred = estimator.predict(mydata)
print('mypred-->\n', mypred)

结果:
在这里插入图片描述

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值