听慕课做Python 机器学习笔记(四):最基础的分类算法——k近邻算法(kNN)

一、k近邻算法(kNN:k-Nearest Neighbors)

在machine learning中新建一个chapter 4文件夹

在特征空间中,每个样本因其特征不同处于不同的位置。对于一个新的样本,看和它最近的k个样本中哪个类别最多,就认为该样本属于哪个类别。

二、kNN基础

用一个假的数据集演示kNN原理

import numpy as np
import matplotlib.pyplot as plt
raw_data_x = [[3.393533211,2.331273301],
              [3.110073483,1.781539638],
              [1.343808831,3.368360954],
              [3.582294042,4.679179110],
              [2.280362439,2.866990263],
              [7.423436942,4.696522875],
              [5.745051997,3.533989803],
              [9.172168622,2.511101045],
              [7.792783481,3.424088941],
              [7.939820817,0.791637231]
             ]
raw_data_y=[0,0,0,0,0,1,1,1,1,1]

原始的样本特征用raw_data_x表示,分别表示肿瘤大小和时间。
原始的样本类别用raw_data_y表示,0表示是良性肿瘤,1表示是恶性肿瘤
将原始的样本用作训练集(即训练使用的特征点X和训练使用的label y),创建成numpy形式的数组:

X_train = np.array(raw_data_x)
y_train = np.array(raw_data_y)

绘制散点图查看特征是什么样的:

plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1],color='g')
plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1],color='r')

在这里插入图片描述
现在对于一个新的数据:

x = np.array([8.093607318,3.365731514])

现在对于这个x,希望预测它属于哪一类,是红色的这一类,还是绿色的这一类。先看一下它的位置:

plt.scatter(X_train[y_train==0,0],X_train[y_train==0,1],color='g')
plt.scatter(X_train[y_train==1,0],X_train[y_train==1,1],color='r')
plt.scatter(x[0],x[1],color='b')

在这里插入图片描述
下面来看一下使用kNN算法的过程

1、首先计算x这个点到每个样本点的距离

使用for循环将每个距离添加到一个距离数组里:

from math import sqrt
distance = []
for x_train in X_train:
    d = sqrt(np.sum((x_train - x)**2))
    distance.append(d)

也可以用一句话更方便地完成上述操作:

distance = [sqrt(np.sum((x_train - x)**2)) for x_train in X_train]

其中求距离用的是欧拉距离:
在这里插入图片描述

2、找到与x最近的是哪些点及其分类

不需要知道最近的距离是多少,而是要知道是哪些点,所以用argsort
先看一下按距离排序的索引:

np.argsort(distance)

array([8, 7, 5, 6, 9, 3, 0, 1, 4, 2], dtype=int64)

找到前k个点的分类(k设置为6):

nearest = np.argsort(distance)
k = 6
topK_y = [y_train[i] for i in nearest[:k]]
topK_y

[1, 1, 1, 1, 1, 0]

3、统计其中各类别的个数

可以方便地使用collection中的Counter这个类,向其中传入一个数组,得到是该数组中元素及元素出现频次的统计。

from collections import Counter
Counter(topK_y)

Counter({1: 5, 0: 1})

得到的结果可以看做是一个字典。
给这个Counter起一个名字votes,将其看做投票的过程(0有1票,1有5票)
可以调用Counter中一个most_common这个方法,找出票数最多的若干个元素,这里找出票数最多的一个元素即可

votes = Counter(topK_y)
votes.most_common(1)

[(1, 5)]

返回的是一个数组,数组中元素是元组,我们只需要知道分类,所以对于x的分类预测可以这样得到

predict_y = votes.most_common(1)[0][0]

1

可知x所属为恶性肿瘤

4、将notebook中代码整理出来写成一个函数

在chapter 4文件夹中新建一个kNN_function文件夹,新建一个kNN.py文件,创建一个kNN_classify函数:

import numpy as np
from math import sqrt
from collections import Counter

def kNN_classify(k,X_train,y_train,x):
	
	assert 1 <= k <= X_train.shape[0],"k must be valid"
	assert X_train.shape[0] == y_train.shape[0],\
		"the size of X_train must equal to the size of y_train"
	assert X_train.shape[1] == x.shape[0],\
		"the feature number of x must be equal to X_train"
		
	distances = [sqrt(np.sum((x_train - x)**2)) for x_train in X_train]
	nearest = np.argsort(distances)
	
	topK_y = [y_train[i] for i in nearest[:k]]
	votes = Counter(topK_y)
	
	return votes.most_common(1)[0][0]

传入的参数中,k是kNN用到的k,X_train,y_train是训练数据集,x是要预测的特征向量,返回x对应y的值是什么。
算法本身只有5行,assert断言保证用户传来的输入合法。

在notebook中运行:

%run kNN_function/kNN.py
predict_y 
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值