k-近邻算法1——简单分类

本节主要内容来自Peter Harrington的《Machine Learning in Action》的中文版本《机器学习实战》

本文中代码

k-近邻算法的基本原理

k-近邻(k-Nearest Neighbors,kNN)算法,采用测量不同特征值之间的距离方法进行分类

  • 优点:精度高、对异常值不敏感、无数据输入假定
  • 缺点:
    计算复杂度高(如果训练数据为n个,则针对每个实例时间复杂度为O(n))
    空间复杂度高(无训练过程,所有的训练数据都需要保存)
    无法给出任何数据的基础结构信息,如平均实例样本和典型实例样本具有什么特征
  • 适用数据范围:数值型和标签型

k-近邻算法的一般流程

  1. 收集数据:可以使用任何方法
  2. 准备数据:距离计算所需要的数值,最好是结构化的数据格式
  3. 分析数据:可以使用任何方法
  4. 训练算法:此步骤不适合k-近邻算法
  5. 测试算法:计算错误率
  6. 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用计算结果进行后续处理

示例1

这是一个非常简单的案例。

准备结构化数据

创建kNN.py文件增加以下代码

from numpy import * #导入科学计算包NumPy
import operator # 运算符模块

def creatDataSet(): # 创建了数据集和标签,用于分类
    group = array([[1.0, 1.1], [1.0, 1.0], [0.0, 0.0], [0.0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

分析数据

## 使用scatter()绘制散点图
import matplotlib.pyplot as plt
import kNN

group, labels = kNN.creatDataSet()

x_coords = group[:, 0]
y_coords = group[:, 1]

# 作出散点图
plt.scatter(x_coords, y_coords, marker='s')

#添加labels
for x, y, z in zip(x_coords, y_coords, labels):
    plt.annotate(
        '%s' %z,
        xy=(x, y),
        xytext=(-8, 8),
        textcoords='offset points',
        ha='center',
        va='top')

plt.xlim([-0.2, 1.2])
plt.ylim([-0.2, 1.2])
plt.show()

运行结果:

创建k近邻分类器

该k近邻分类器将把每组数据划分到某个类中,伪代码如下:
对未知类别属性的数据集中的每个点依次执行以下操作

  1. 计算当前点到已知类别数据集中的点的距离
  2. 按照距离从小到大排序
  3. 选取与当前点距离最小的k个点
  4. 确定前k个点所在类别出现的概率
  5. 返回前k个点出现频率最高的类别作为当前点的预测分类

在kNN.py中,添加代码

def classify0(inX, dataSet, labels, k):
    datasetSize = dataSet.shape[0]
    diffMat = tile(inX, (datasetSize, 1)) - dataSet #复制inX成多个数组与dataSet作差
    squDiffMat = diffMat**2 #每个元素进行平方
    squDistances = squDiffMat.sum(axis=1) #对应相加
    distances = squDistances**0.5 #每个元素进行开方
    sortedDistIndicies = distances.argsort() #对元素按从小到大进行排序
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]] #找出对应标签
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 #构造字典
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

测试或使用算法

创建kNNTest.py, 写入

import kNN

group, label = kNN.creatDataSet()

# print(group)
# print(label)

inX = [[0, 0],[1, 2]]
for inx in inX:
    distance = kNN.classify0(inx, group, label, 2)
    print(distance)

运行结果为

B
A
posted @ 2018-04-17 12:05  Liupeng_Wang  阅读(756)  评论(0编辑  收藏  举报