机器学习实战笔记(一):k-近邻算法(Python3 实现)

完整代码地址:https://github.com/cqulun123/Machine-Learning-in-Action

0 k-近邻算法概述

        简单地说, k-近邻算法采用测量不同特征值之间的距离方法进行分类。
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
适用数据范围:数值型和标称型。

工作原理
       存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前 k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

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

1 准备:使用 Python 导入数据

import numpy as np
import operator


def create_data_set():
    """
    函数作用:创建数据集和标签
    set_group:数据集
    set_labels:数据集对应的标签
    """
    set_group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    set_labels = ['A', 'A', 'B', 'B']
    return set_group, set_labels
       现在我们已经知道 Python如何解析数据,如何加载数据,以及kNN算法的工作原理,接下来我们将使用这些方法完成分类任务。 

2 实施 kNN 算法

       其伪代码如下:
对未知类别属性的数据集中的每个点依次执行以下操作:
(1) 计算已知类别数据集中的点与当前点之间的距离;
(2) 按照距离递增次序排序;
(3) 选取与当前点距离最小的k个点;
(4) 确定前k个点所在类别的出现频率;
(5) 返回前k个点出现频率最高的类别作为当前点的预测分类。

def classify0(input_data, data_set, labels_set, k):
    """
    函数作用:使用k-近邻算法将每组数据划分到某个类中
    :param input_data:用于分类的输入数据(测试集)
    :param data_set:输入的训练样本集
    :param labels_set:训练样本标签
    :param k:用于选择最近邻居的数目,即kNN算法参数,选择距离最小的k个点
    :return:返回分类结果
    """
    # data_set.shape[0]返回训练样本集的行数
    data_set_size = data_set.shape[0]
    # 在列方向上重复input_data,1次,行方向上重复input_data,data_set_size次
    diff_mat = np.tile(input_data, (data_set_size, 1)) - data_set
    # diff_mat:输入样本与每个训练样本的差值,然后对其每个x和y的差值进行平方运算
    sq_diff_mat = diff_mat ** 2
    # 按行进行累加,axis=1表示按行。
    sq_distances = sq_diff_mat.sum(axis=1)
    # 开方运算,求出距离
    distances = sq_distances ** 0.5
    # 返回distances中元素从小到大排序后的索引值
    sorted_dist_indices = distances.argsort()
    # 定一个字典:统计类别次数
    class_count = {}

    for i in range(k):
        # 取出前k个元素的类别
        vote_index_label = labels_set[sorted_dist_indices[i]]
        # 统计类别次数
        class_count[vote_index_label] = class_count.get(vote_index_label, 0) + 1
        # 把分类结果进行降序排序,然后返回得票数最多的分类结果
        sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
        return sorted_class_count[0][0]

3 预测数据

if __name__ == '__main__':
    # 创建数据集
    group, labels = create_data_set()
    # 测试集
    test = [3, 0.3]
    # kNN算法进行分类
    test_class = classify0(test, group, labels, 3)
    # 显示分类结果
    print(test_class)

        输出结果为 A,大家也可以改变输入[3, 0.3]为其他值,测试程序的运行结果。 

完整代码如下:

# encoding: utf-8
"""
@author:max bay 
@version: python 3.6
@time: 2018/5/5 0:25
"""

import numpy as np
import operator


def create_data_set():
    """
    函数作用:创建数据集和标签
    set_group:数据集
    set_labels:数据集对应的标签
    """
    set_group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    set_labels = ['A', 'A', 'B', 'B']
    return set_group, set_labels


def classify0(input_data, data_set, labels_set, k):
    """
    函数作用:使用k-近邻算法将每组数据划分到某个类中
    :param input_data:用于分类的输入数据(测试集)
    :param data_set:输入的训练样本集
    :param labels_set:训练样本标签
    :param k:用于选择最近邻居的数目,即kNN算法参数,选择距离最小的k个点
    :return:返回分类结果
    """
    # data_set.shape[0]返回训练样本集的行数
    data_set_size = data_set.shape[0]
    # 在列方向上重复input_data,1次,行方向上重复input_data,data_set_size次
    diff_mat = np.tile(input_data, (data_set_size, 1)) - data_set
    # diff_mat:输入样本与每个训练样本的差值,然后对其每个x和y的差值进行平方运算
    sq_diff_mat = diff_mat ** 2
    # 按行进行累加,axis=1表示按行。
    sq_distances = sq_diff_mat.sum(axis=1)
    # 开方运算,求出距离
    distances = sq_distances ** 0.5
    # 返回distances中元素从小到大排序后的索引值
    sorted_dist_indices = distances.argsort()
    # 定一个字典:统计类别次数
    class_count = {}

    for i in range(k):
        # 取出前k个元素的类别
        vote_index_label = labels_set[sorted_dist_indices[i]]
        # 统计类别次数
        class_count[vote_index_label] = class_count.get(vote_index_label, 0) + 1
        # 把分类结果进行降序排序,然后返回得票数最多的分类结果
        sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
        return sorted_class_count[0][0]


if __name__ == '__main__':
    # 创建数据集
    group, labels = create_data_set()
    # 测试集
    test = [3, 0.3]
    # kNN算法进行分类
    test_class = classify0(test, group, labels, 3)
    # 显示分类结果
    print(test_class) 

4 参考资料

[1] 机器学习实战

[2] 机器学习实战笔记(Python实现)-02-k近邻算法(kNN)

[3]  Python3《机器学习实战》学习笔记(一):k-近邻算法(史诗级干货长文)















猜你喜欢

转载自blog.csdn.net/cqulun123/article/details/80217558