监督与无监督
简单介绍一下监督这个概念,监督是supervised的直译,我个人觉得不太准确,翻译成有标注和无标注可能更加准确。也就是说如果模型在学习的时候,既能够看到样本的特征又可以看到样本的结果,那么就是有监督学习,如果只能看到特征,但是并不能知道这些特征对应的结果,那么就是无监督学习。
之前我们介绍的线性回归和逻辑回归模型就是典型的有监督模型,因为模型在训练的时候知道样本的结果,并且根据我们设计的损失函数朝着贴近样本真实结果的方向“努力”。而今天介绍的KNN算法则是一个经典的无监督学习模型,算法在训练的时候并不知道正确的结果是什么,也因此模型根本没有损失函数这个概念,那么自然整个算法的运行原理也和监督模型大相径庭。
算法概述
算法原理
采集一批有标注结果的样本,设为s 遍历每一个未知结果的样本 遍历s,计算s中的每一个样本和的距离 根据距离进行排序,选出距离小的k个样本 选出这k个样本中出现频次多的类别作为的结果
在距离计算的方法当中,欧氏距离和曼哈顿距离常用,除了这两种之外还有切比雪夫距离和闵可夫斯基距离等,一般不太常用,我们不多做赘述,感兴趣的可以自行谷歌。
代码实现
def classify(vector, dataSet, labels, k):
dis = []
for i in range(len(dataSet)):
data = dataSet[i]
d = calculate_distance(vector, data)
dis.append(d)
dis_index = sorted(enumerate(dis), key=lambda x: x[1])
label_map = {}
for i in range(k):
label = labels[dis_index[i][]]
if label in label_map:
label_map[label] += 1
else:
label_map[label] = 1
maxi =
label = None
for i in label_map:
if label_map[i] > maxi:
maxi = label_map[i]
label = i
return label
def calculate_distance(vectorA, vectorB):
d =
for i in range(len(vectorA)):
d += (vectorA[i] - vectorB[i]) * (vectorA[i] - vectorB[i])
return math.sqrt(d)
import random
import numpy as np
from collections import Counter
def classify(x, dataset, labels, K):
x, dataset = np.array(x), np.array(dataset)
# 通过numpy计算距离,numpy有广播机制
# 会自动将x和dataset当中的每一行计算距离
dis = np.sqrt(np.sum((x - dataset) ** 2, axis=1))
# 按照距离排序,返回结果对应的下标
topKIdices = np.argsort(dis)[:K]
labels = np.array(labels)
# 使用Counter进行计数,返回数量多的
counter = Counter(labels[topKIdices])
return counter.most_common(1)[][]
def create_data_set():
dataset = np.array([[0.5, ], [, 0.5], [1.5, 1], [1, 1.5]])
labels = ['A', 'A', 'B', 'B']
return dataset, labels