超简单|Python实现机器学习算法——KNN

KNN算法简介

KNN算法(k近邻算法)是一种有监督分类算法,它的原理非常简单,下面以一个简单的例子引入。
已知两种酒的标签:赤霞珠和黑皮诺,在这个情景中,我们对酒进行分类的依据是酒精浓度和颜色深度,如下图所示:红色代表赤霞珠,紫色代表黑皮诺,图中有一分类未知的黄点,给定一个K值,我们找到距离黄点最近的K个点,假设K取3,我们发现距离黄点最近的3个点都是红点,0个紫点,根据少数服从多数原则,红:紫 = 3:0,所以认为黄点属于红色这一类,即赤霞珠。

算法实现步骤

根据上面那个例子,我们可以把KNN算法过程总结为以下几个步骤:

  1. 确定一个K值, K值我一般取奇数,方便投票;
  2. 计算已知类别数据集中的点与当前点的距离
  3. 找到距离最小的K个点
  4. 确认这K个点的类别
  5. 把出现次数最多的类别作为当前点的预测类别

如何用python实现KNN算法

#导入需要的库
import numpy as np
import pandas as pd`
import matplotlib.pyplot as plt
#训练数据
rowdata = {'颜色深度':[14.23,13.2,13.16,14.37,13.24,12.07,12.43,11.79,12.37,12.04],
          '酒精浓度':[5.64,4.38,5.68,4.80,4.32,2.76,3.94,3.  ,2.12,2.6 ],
          '品种':[0,0,0,0,0,1,1,1,1,1]}

rowdata中的品种为 0 代表 “黑皮诺”,1 代表 “赤霞珠”, 设置一个未知类别的点,变量名为new_data

#新设置一个未知类别的点
new_data = np.array([4.1,12.8])
#把rowdata转换为DataFrame
wine_data = pd.DataFrame(rowdata)

wine_data信息如下:

	颜色深度	酒精浓度	品种
0	14.23	5.64	0
1	13.20	4.38	0
2	13.16	5.68	0
3	14.37	4.80	0
4	13.24	4.32	0
5	12.07	2.76	1
6	12.43	3.94	1
7	11.79	3.00	1
8	12.37	2.12	1
9	12.04	2.60	1

绘制散点图

#修改样式
plt.style.use('ggplot')
#windows电脑电脑正常显示中文
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(6,4),dpi = 300)
plt.scatter(wine_data[wine_data.品种 == 0]['酒精浓度'], wine_data[wine_data.品种 == 0]['颜色深度'], c = 'purple', label = '黑皮诺' )
plt.scatter(wine_data[wine_data.品种 == 1]['酒精浓度'], wine_data[wine_data.品种 == 1]['颜色深度'], c = 'red' , label = '赤霞珠' )
plt.scatter(new_data[0] , new_data[1] ,c = 'yellow')
plt.scatter(3.5 , 12.2 ,c = 'green')
plt.title('10瓶红酒')
plt.xlabel('酒精浓度')
plt.ylabel('颜色深度')
# 图例添加 1. scatter 里面 添加 label 2. 添加plt.legend()
plt.legend(loc = 2)
# 将新的数据new_data绘制上来
plt.show()

画出的图形如下,我们可以简单的清晰的看到各点分布情况
在这里插入图片描述KNN算法实现步骤

# 1.确定一个k值 为 3
k = 3
# 2.计算已知类别数据集中的点与当前点的距离
distance = np.sqrt(np.sum((wine_data[['酒精浓度','颜色深度']] - new_data)**2,axis=1))
distance
#3.找到距离最小的K个点
#argsort对其排序,返回其索引值,再切片得到最近的k个值
distance.argsort()[:k]
#4.确认这K个点的类别
k_vote = wine_data.loc[distance.argsort()[:k]]['品种']
#5.把出现次数最多的类别作为当前点的预测类别
k_vote.mode()[0]

运行结果显示为0,说明该未知点被划分为黑皮诺这一类

0

Scikit-learn算法库实现KNN分类器

到这儿就算完成了一个简单的KNN算法,虽然很简单但也是手动去计算的,如果算法原理很复杂怎么办?我们不可能都手动去实现,我们可以调用Scikit-learn算法库,能助你一步登天(开玩笑,不可能的)

Sklearn建模流程

Sklearn建模步骤如下:

  1. 实例化 ,建立评估模型对象;
  2. 训练模型
  3. 模型预测
  4. 模型评估
  5. 模型调优

建模过程很简单,几行代码就能搞定

#先导入算法模型API
from sklearn.neighbors import KNeighborsClassifier
# 使用KNN类,实例化一个KNN算法的对象
# 模型命名为knn,这里的n_neighbors就是上面的K,这里K依然取3
# K的最优值可以通过绘制学习曲线来
knn = KNeighborsClassifier(n_neighbors=3)
# 提取出输入数据
x = wine_data.iloc[:,:2].values
# 提取出目标标签
y = wine_data.iloc[:,-1].values
#训练模型
knn.fit(x,y)
# 传入的新数据, 必须和原来的X的维度相同,所以需要改变一下new_data的形状
new_data.reshape(1,2)
#使用模型对未知数据进行预测
knn.predict(new_data.reshape(1,2))
#模型评估
knn.score(new_data.reshape(1,2),knn.predict(new_data.reshape(1,2)))

我们通过训练好的模型可以用于预测未知点,但其实这个模型是不够完美的,在KNN这个算法中,就只有一个参数K,我们还可以通过绘制学习曲线来寻找最优K值

scores = []
for i in range(1,31):
    #建模
    knn = KNeighborsClassifier(n_neighbors=i)
    #训练
    knn.fit(X_train,y_train)
    #评估模型 knn.score(X_test,y_test)
    scores.append(knn.score(X_test,y_test))

画个图来看看

plt.plot(range(1,31),scores)

在这里插入图片描述
从上图可以看出,当k大概取17的时候,模型评分是最高的,比K=3的分数高很多,所以我们可以把重新建模,令n_neighbors = 17。
怎么找到模型得分最高点对应的K值呢?可以通过np.argmax(scores)+1找到对应的K

np.argmax(scores)+1
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值