KNN(K最近邻分类)算法
如果有一个数据集中,有N类数据。输入没有标分类的数据集后,我们可以将预测集中的数据,和训练集的数据相比较,提取和预测数据最相似(距离最近)的K个数据,选择这K个数据中出现次数最多的标签,作为新数据的分类。
KNN算法的思想非常简洁直观:
1、计算测试数据与各个训练数据之间的距离;
2、按照距离的递增关系进行排序;
3、选取距离最小的K个点;
4、确定前K个点所在类别的出现频率;
5、返回前K个点中出现频率最高的类别作为测试数据的预测分类。
KNN算法的优点:
1、简单,易于实现;
2、因为找的是最近邻的数据点,因此当某些点数量稀少时,划分越准确,适合对稀有点分类;
3、使用多分类问题。
算法实现
我们利用一个案例,按照KNN算法的思想,逐步实现算法。
KNN案例:优化约会网站的配对效果
项目概述
海伦使用约会网站寻找约会对象。经过一段时间之后,她发现曾交往过三种类型的人:
- 1:不喜欢的人
- 2:魅力一般的人
- 3:极具魅力的人
她希望:
- 不喜欢的人则直接排除掉
- 工作日与魅力一般的人约会
- 周末与极具魅力的人约会
现在她收集到了一些约会网站未曾记录的数据信息,这更有助于匹配对象的归类。
开发流程
海伦把这些约会对象的数据存放在文本文件 datingTestSet2.txt 中,总共有 1000 行。海伦约会的对象主要包含以下 3 种特征:
Col1
:每年获得的飞行常客里程数Col2
:玩视频游戏所耗时间百分比Col3
:每周消费的冰淇淋公升数
文本文件数据格式如下:
40920 8.326976 0.953952 3
14488 7.153469 1.673904 2
26052 1.441871 0.805124 1
75136 13.147394 0.428964 1
38344 1.669788 0.134296 1
读取数据
import matplotlib.pyplot as plt
import pandas as pd
data = pd.read_csv('datingTestSet2.txt',sep = '\t',header = None)
X = np.array(data.iloc[:,:-1])
y = np.array(data.iloc[:,-1])
切分数据
我们可以直接调用sklearn的函数将数据集切分为训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
计算测试集数据和训练集间的距离,进行分类。
我们先用最简单的思想分类:将想要预测的样本,和训练集中每个样本的特征直接相减的绝对值之和作为距离,将距离最近的训练样本的标签标记为预测样本的标签。
class KNN:
def __init__(self):
pass
def train(self,X_train,y_train):
#读取训练集
self.X_train = np.array(X_train)
self.y_train = np.array(y_train)
def predict(self,X_test):
(m,d) = np.shape(X_test) #测试集的数量和特征数
y_pred = np.zeros((m)) #将预测的标签初始化为0
for i in range(m):
distance = np.sum(np.abs(self.Xtrain - X_test[i,:]),axis = 1) #求距离的绝对之和
min_index = np.argmin(distance) #找到最近点的索引
y_pred[i] = self.y_train[min_index] #将最近点的分类给新数据标记
return y_pred
我们可以将这个算法称为“最近邻算法“,直接取找最近的一个数据进行分类标记,我们将这个算法扩展到K近邻算法。
可以扩展的方向:
- 选择不同的距离公式
- 选