zoukankan      html  css  js  c++  java
  • 机器学习-kNN算法

    1、前沿

        K最近邻(k-Nearest Neighbor,KNN)分类算法可以说是最简单的机器学习算法了。它采用测量不同特征值之间的距离方法进行分类。它的思想很简单:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

    选择k个最相似数据中出现次数最多的分类。其算法描述如下:

    K-近邻算法的一般流程
    (1): 收集数据:提供文本文件
    (2):准备数据:使用 Python 分析文本文件
    (3):分析数据:使用 Matplotlib 画二维扩散图。
    (4):测试算法:使用文本文件的部分数据作为测试样本,计算错误率。
    (5):使用算法:错误率在可接受范围内,就可以运行k-近邻算法进行分类。

    理解可参考大神博客:https://blog.csdn.net/zouxy09/article/details/16955347

    2、kNN基础实践

    from numpy import *

    def createDataSet(): group = array([[0, 0], [0, 0.1], [1.0, 1.1], [1.0, 1.0]]) labels = ['A', 'A', 'B', 'B'] return group, labels def kNNClassify(newInput, dataSet, labels, k): numSamples = dataSet.shape[0] diff = tile(newInput, (numSamples, 1)) - dataSet squaredDiff = diff ** 2 squaredDist = sum(squaredDiff, axis=1) distance = squaredDist ** 0.5 sortedDistIndices = argsort(distance) # 给出每个点在列表中大小的排列 例如:列表[7,9,5,10],结果为[1,2,0,3] classCount = {} for i in range(k): voteLabel = labels[sortedDistIndices[i]] classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # 如果能够取到那么便加 1,如果取不到便为 0。 maxCount = 0 for key, value in classCount.items(): if value > maxCount: maxCount = value maxIndex = key return maxIndex if __name__ == '__main__': dataSet, labels = createDataSet() testX = array([1.2, 1.0]) k = 3 outputLabel = kNNClassify(testX, dataSet, labels, k) print(outputLabel)

    # 自行理解基础,挺简单的。

    3、根据网上修改凯伦约会网站

    import numpy as np
    import matplotlib.pyplot as plt
    
    """
    准备数据  大神博客:https://www.cnblogs.com/asialee/p/9307337.html
    """
    
    
    def file2matrix(filename):
        with open(filename, 'r') as f:
            array_lines = f.readlines()
            number_lines = len(array_lines)
            return_mat = np.zeros((number_lines, 3))
            # 返回的分类标签向量
            class_label_vector = []
            index = 0
            for line in array_lines:
                line = line.strip()
                list_from_line = line.split('	')
                # 将数据前三列提取出来,存放到return_mat的NumPy矩阵中,也就是特征矩阵
                return_mat[index, :] = list_from_line[0:3]
                # 根据文本中标记的喜欢程度进行分类,1代表不喜欢。2代表魅力一般。3代表急剧魅力。
                if list_from_line[-1] == 'didntLike':
                    class_label_vector.append(1)
                elif list_from_line[-1] == 'smallDoses':
                    class_label_vector.append(2)
                elif list_from_line[-1] == 'largeDoses':
                    class_label_vector.append(3)
                index += 1
        return return_mat, class_label_vector
    
    
    """
    分析数据,数据可视化,使用 Matplotlib 创建散点图
    """
    
    
    def show_data(return_mat, class_label_vector):
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.scatter(return_mat[:, 1], return_mat[:, 2], 15.0 * np.array(class_label_vector),
                   15.0 * np.array(class_label_vector))
        plt.show()
    
    
    """
    准备数据:归一化数值。
        因为四组数据中,获取的飞行常客里程数对于计算结果影响远远大于其他两个特征,但这三个特征是同等重要的,
        因此作为三个等权重的特征之一,飞行常客里程数并不该如此严重的影响到计算结果。因此我们通常采用的方法是数值归一化,将取值范围
        处理为0到1之间。
    new_value = (old_value-min)/(max-min)
    """
    
    
    def auto_norm(data_set):
        # 获得每列数据的最小值和最大值
        min_value = data_set.min(0)
        max_value = data_set.max(0)
        # 最大值和最小值的范围
        ranges = max_value - min_value
        m = data_set.shape[0]
        # 原始值减去最小值
        norm_data_set = data_set - np.tile(min_value, (m, 1))
        # 除以最大和最小值的差,得到归一化数据
        norm_data_set = norm_data_set / np.tile(ranges, (m, 1))
        # 返回归一化数据结果,数据范围,最小值
        return norm_data_set, ranges, min_value
    
    
    """
    KNN算法分类器
    in_x:用于分类的数据(测试集)。
    data_set:用于训练的数据(训练集)。
    labels:训练数据的分类标签。
    k :kNN算法参数,选择距离最小的 k 个点。
    sorted_class_count[0][0] 分类结果。
    """
    
    
    def knn_classify(in_x, data_set, labels, k):
        data_set_size = data_set.shape[0]
        diff_mat = np.tile(in_x, (data_set_size, 1)) - data_set
        sq_diff_mat = diff_mat ** 2
        sq_distances = sq_diff_mat.sum(axis=1)
        distances = sq_distances ** 0.5
        sorted_dist_indices = distances.argsort()
        class_count = {}
        for i in range(k):
            vote_label = labels[sorted_dist_indices[i]]
            class_count[vote_label] = class_count.get(vote_label, 0) + 1  # 如果能够取到那么便加 1,如果取不到便为 0。
        max_count = 0
        for key, value in class_count.items():
            if value > max_count:
                max_count = value
                max_index = key
        return max_index
    
    
    """
    测试算法,计算分类器的准确率,验证分类器
    """
    
    
    def dating_class_test():
        file_name = 'F:KNN-masterdatingTestSet.txt'
        dating_data_mat, dating_labels = file2matrix(file_name)
        ho_ratio = 0.1
        norm_data_set, ranges, min_value = auto_norm(dating_data_mat)
        m = norm_data_set.shape[0]
        num_test_vec = int(m * ho_ratio)
        error_count = 0.0
        for i in range(num_test_vec):
            class_fire_result = knn_classify(norm_data_set[i, :], norm_data_set[num_test_vec:m, :],
                                             dating_labels[num_test_vec:m], 4)
            print('分类结果:%d	真实类别:%d' % (class_fire_result, dating_labels[i]))
            if class_fire_result != dating_labels[i]:
                error_count += 1.0
        print('错误率:%f%%' % (error_count / float(num_test_vec * 100)))
    
    
    """
    使用算法,构建完整可用系统
    """
    
    
    def classify_person():
        # 输出结果
        result_list = ['不喜欢', '有些喜欢', '非常喜欢']
        # 三维特征用户输入
        f_miles = float(input('每年飞行常客里程数:'))
        percent_game = float(input('玩游戏所消耗时间百分比:'))
        ice_cream = float(input('每周消费的冰淇淋公升数:'))
        file_name = 'F:KNN-masterdatingTestSet.txt'
        dating_data_mat, dating_labels = file2matrix(file_name)
        norm_data_set, ranges, min_value = auto_norm(dating_data_mat)
        in_arr = np.array([f_miles, percent_game, ice_cream])
        # 测试集归一化
        nor_min_arr = (in_arr - min_value) / ranges
        classifier_result = knn_classify(nor_min_arr, norm_data_set, dating_labels, 3)
        print("你可能%s这个人" % (result_list[classifier_result - 1]))
    
    
    if __name__ == '__main__':
        return_mat, class_label_vector = file2matrix('F:KNN-masterdatingTestSet.txt')
        show_data(return_mat, class_label_vector)
        dating_class_test()
        classify_person()

    kNN算法实现起来还是可以实现的,数据集大神博客有连接的可自行去下载。

  • 相关阅读:
    Linux-文件编程
    Linux-编程基础
    Linux-系统管理
    Linux-命令
    图解HTTP-笔记
    微信小程序发送红包功能。填坑记录
    PHP中使用raw格式发送POST请求
    论一个PHP项目上线的注意点
    PHP CURL 模拟form表单上传遇到的小坑
    使用php的curl函数post返回值为301永久迁移的问题。(301 Moved Permanently)
  • 原文地址:https://www.cnblogs.com/fierydragon/p/10679262.html
Copyright © 2011-2022 走看看