• 复习KNN并实现


    今天复习了一下KNN算法,用两种方法手动实现,在iris数据集上训练及测试。
    KNN理论很简单,略,这里直接上代码。

    import numpy as np
    import functools
    from collections import Counter
    from sklearn import datasets
    from sklearn.model_selection import train_test_split
    
    
    # 导入iris数据
    iris = datasets.load_iris()
    X = iris.data
    y = iris.target
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=2003)
    
    
    def euc_dis(instance1, instance2):
        """
        计算两个样本instance1和instance2之间的欧式距离
    
        :param instance1: 第一个样本, array型
        :param instance2: 第二个样本, array型
        :return 二者欧式距离
        """
    
        distance = np.sqrt(functools.reduce(lambda a, b: a ** 2 + b ** 2, instance1 - instance2))
        # 或者可以写作:
        # distance = np.sqrt(sum((instance1-instance2)**2))
    
        return distance
    
    
    def knn_classify(X, y, testInstance, k):
        """
        给定一个测试数据testInstance, 通过KNN算法来预测它的标签。
    
        :param X: 训练数据的特征
        :param y: 训练数据的标签
        :param testInstance: 测试数据,这里假定一个测试数据 array型
        :param k: 选择多少个neighbors
        :return 返回testInstance的预测标签 = {0,1,2}
        """
    
        dist = []    # [(类别, 距离)]
        for i in range(len(X)):
            # 计算输入实例与每个样本的欧式距离
            distance = euc_dis(testInstance, X[i])
            category = y_train[i]
            dist.append((category, distance))
            # dist.append((distance, category))
    
        # dist按距离升序排序,取前k个样本
        dist_asc = sorted(dist, key=lambda x: x[1])[:k]
        print("前k个样本的dist_asc:", dist_asc)
    
        # 统计这k个样本的类别及数量
        cate_dict = {}    # {类别:数量}
        for item in dist_asc:
            if item[0] in cate_dict.keys():
                cate_dict[item[0]] += 1
            else:
                cate_dict[item[0]] = 1
        print("cate_dict:", cate_dict)
        # 按数量判定类别
        label = sorted(cate_dict.items(), key=lambda x: x[1], reverse=True)[0][0]
        print("类别:", label)
        return label
    
    def knn_classify_simple(X, y, testInstance, k):
        """
        【简易版实现】
        给定一个测试数据testInstance, 通过KNN算法来预测它的标签。
    
        :param X: 训练数据的特征
        :param y: 训练数据的标签
        :param testInstance: 测试数据,这里假定一个测试数据 array型
        :param k: 选择多少个neighbors
        :return 返回testInstance的预测标签 = {0,1,2}
        """
    
        distances = [euc_dis(testInstance, x) for x in X]
        knn_index = np.argsort(distances)[:k]    # knn_index记录最近邻的下标
        count = Counter(y[knn_index])
        label = count.most_common()[0][0]
        return label
    
    # 预测结果
    predictions = [knn_classify(X_train, y_train, data, 3) for data in X_test]
    # predictions = [knn_classify_simple(X_train, y_train, data, 3) for data in X_test]
    print(predictions)
    correct = np.count_nonzero((predictions == y_test) == True)
    print("Accuracy is: %.3f" % (correct / len(X_test)))    # 0.921
    
    

    决策边界

    决策边界分成两大类,分别是线性决策边界非线性决策边界。拥有线性决策边界的模型我们称为线性模型,反之非线性模型

    k值的选择

    随着K值的增加,决策边界会变得更加平滑。决策边界的平滑也意味着模型的稳定性。这个其实很好理解,平时工作当中多个人共同决策要比一个人决策会大概率上减少犯错误。但稳定不代表,这个模型就会越准确

    平衡稳定性和准确率的方法:交叉验证

  • 相关阅读:
    js人工智能对话框
    html 实现相册
    thinkphp5 三种重定向(跳转)
    thinkphp5 分页实现
    常用的Mysql数据库操作语句大全
    FormData之file图片上传
    FormData对象
    input file 上传图片时限制格式
    form 中Enctype=multipart/form-data 的作用
    thinkphp5 不刷新退出
  • 原文地址:https://www.cnblogs.com/elisha/p/14024810.html
Copyright © 2020-2023  润新知