美文网首页机器学习KNN
K-近邻算法(KNN)

K-近邻算法(KNN)

作者: 仙灵儿 | 来源:发表于2018-08-16 00:09 被阅读10次

    1、k-近邻算法原理

    简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类。

    • 优点:精度高、对异常值不敏感、无数据输入假定。
    • 缺点:时间复杂度高、空间复杂度高。
    • 适用数据范围:数值型和标称型。

    欧几里得距离(Euclidean Distance)

    欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:

    image.png

    2、在scikit-learn库中使用k-近邻算法

    • 分类问题:from sklearn.neighbors import KNeighborsClassifier

    • 回归问题:from sklearn.neighbors import KNeighborsRegressor

    0)一个最简单的例子

    身高、体重、鞋子尺码数据对应性别

    import numpy as np
    import pandas as pd
    from pandas import Series,DataFrame
    # 是男是女 属于分类问题
    from sklearn.neighbors import KNeighborsClassifier
    
    # 训练样本 X是样本的特征 y是样本的结果(标签)
    # 训练样本的特征
    # 身高 体重 鞋子尺码
    X_train = np.array([
        [177,73,42],
        [150,44,36],
        [177,63,41],
        [160,52,35],
        [165,70,40],
        [179,80,44],
        [156,40,36],
        [155,50,36]
    ])
    y_train = np.array(['male','female','male','female','male','male','female','female'])
    
    # 测试样本
    X_train  # 特征
    y_train  # 结果(标签)
    
    # KNeighborsClassifier 用来获取分类的模型
    # 参数 n_neighbors 指的是 考虑最近的几个 默认是5个
    knn_c = KNeighborsClassifier(n_neighbors=5)
    
    # 参数 X 是训练数据的特征
    # 参数 y 是训练数据的结果(标签)
    knn_c.fit(X_train,y_train)  # knn模型的训练很简单 就是记录一下各个样本的位置
    # 现在这个模型就是已经训练好的模型了
    
    # knn_c.predict() 可以测试
    # 参数X 是要传入的 测试数据 把特征传入 会根据训练好的模型 返回结果
    knn_c.predict([
        [190,100,45],
        [150,35,32]
    ])
    

    1)用于分类

    导包,机器学习的算法KNN、数据鸢尾花

    # scikit-learning 提供数据样本,可以供我们研究机器学习模型
    # 可以使用load方法加载datasets中的各种数据
    from sklearn import datasets
    import matplotlib.pyplot as plt
    

    获取训练样本 datasets.load_iris()

    iris_data = datasets.load_iris()
    iris_data
    
    data = iris_data.data  # 所有样本的特征
    target = iris_data.target  # 所有样本的目标值
    feature_names = iris_data.feature_names  # 特征的名字
    target_names = iris_data.target_names  # 目标值的名称
    

    画图研究前两个特征和分类之间的关系(二维散点图只能展示两个维度)

    # 为了给大家展示 我这里只研究前两个特征 和 分类的关系 (大家自己用knn分类的时候 最好是把四个特征都算上)
    X_train = data[:,0:2]  # 所有行都要,0-2列 2取不到 就是0和1
    X_train  # 训练样本的特征
    # 训练样本的标签(结果)
    y_train = target  # 训练样本的结果
    y_train
    
    # 展示关系用散点图
    # x, y x是一个特征 y是另一个特征 这样 一个点的位置就有了
    # 花萼长度作为x 花萼宽度作为y 对所有样本进行定位 然后 不同的分类用不同的颜色来标注
    # c参数传入的列表是各个样本的分类编号 scatter 对象根据 不同的编号给样本分配不同的颜色
    plt.scatter(X_train[:,0],X_train[:,1],c=y_train)
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    
    knn_c = KNeighborsClassifier(n_neighbors=5)
    # 训练模型
    # 调用 knn_c.fit 方法 传入 训练集数据的特征 和 训练集数据的结果
    knn_c.fit(X_train,y_train)
    # knn_c.fit(data,target)
    # 可以测试了 传入 样本的特征 会返回这个样本的分类
    knn_c.predict([
        [4.5,4.0],
        [7.5,3.0],
        [5.25,2.25]
    ])
    

    第二步预测数据:所预测的数据,自己创造,就是上面所显示图片的背景点

    生成预测数据

    # 获取平面上的所有点
    # 先把x轴线的范围和y轴的范围获取到
    xmin = X_train[:,0].min()-0.5
    xmax = X_train[:,0].max()+0.5
    ymin = X_train[:,1].min()-0.5
    ymax = X_train[:,1].max()+0.5
    
    # x轴范围内要取遍
    x = np.arange(xmin,xmax,0.01)
    # y轴范围内也要取遍
    y = np.arange(ymin,ymax,0.01)
    y
    # 把画布上所有的点都取遍
    xx,yy = np.meshgrid(x,y)
    xx.flatten(),yy.flatten()
    
    # 把对应位置的两个内容取出来 变成新的列表
    X_test = np.c_[xx.flatten(),yy.flatten()]  # 将平面上所有的点取遍 并 用来作为测试数据
    X_test
    plt.scatter(X_test[:,0],X_test[:,1])
    

    对数据进行预测

    y_ = knn_c.predict(X_test)
    y_  # y_是模型预测的结果 真实结果用y_test
    
    # 根据特征绘制样本的位置 根据模型预测的结果 绘制样本的颜色
    plt.scatter(X_test[:,0],X_test[:,1],c=y_)
    
    # 自己制定颜色
    from matplotlib.colors import ListedColormap
    cmap0 = ListedColormap(['red','green','blue'])
    cmap1 = ListedColormap(['#cc99bb','#88ddbb','#8899ff'])
    cmap2 = ListedColormap(['#dd2244','#00ee33','#0011ff'])
    # 把真实的训练数据也画到图上
    plt.scatter(X_test[:,0],X_test[:,1],c=y_)
    plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=cmap0)
    
    # 把真实的训练数据也画到图上
    plt.scatter(X_test[:,0],X_test[:,1],c=y_,cmap=cmap1)
    plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=cmap2)
    

    ocr 光学字符识别(Optical Character Recognition) 我们先做一个基础班:识别数字

    # 图片虽然是二维的数据 但是每行并不是一个样本的多个特性 
    # 每个图片是一个样本 里面的各个点都是其特征 所以我们可以把28*28的点 变成1*784的点(在Excel里画图演示)
    # 图片的每一个像素点都是一个特征
    # 每一个图片是一个样本
    
    data = plt.imread('./digits/0/0_1.bmp')
    data
    plt.imshow(data)
    data.shape
    data = data.flatten()  # 把图片扁平化 变成一行
    data.shape
    plt.imshow(data.reshape(28,28))  # 要显示的时候 还是需要把一行的值 变成28*28
    
    # 读取所有的样本 分成 训练数据 和 测试数据
    # 训练数据集
    X_train = []
    y_train = []
    # 测试数据集
    X_test = []
    y_test = []
    
    for i in range(10):
        for j in range(1,501):
            # print('./digits/%d/%d_%d.bmp'%(i,i,j))
            # 根据路径 读取数据 然后 把28*28的形状 变成1行的形状
            data = plt.imread('./digits/%d/%d_%d.bmp'%(i,i,j)).flatten()
            # 目标值就是 文件夹的名字 也就在i
            target = i
            # 前490个都用来训练 后10个用来测试
            if j<=490:
                X_train.append(data)
                y_train.append(target)
            else:
                X_test.append(data)
                y_test.append(target)
    
    knn = KNeighborsClassifier()
    # 训练
    knn.fit(X_train,y_train)
    # 预测 传入测试的特征值 根据模型 返回 预测的结果
    y_ = knn.predict(X_test)
    y_
    knn.score(X_test,y_test)
    
    # 把图片绘制出来 把 预测结果作为子画布的题目
    plt.figure(figsize=(15,20))
    index = 1
    for i in range(10):
        for j in range(10):
            axes = plt.subplot(10,10,index)
            # 传入测试数据 按照索引从X_test中获取数据 然后变回28*28的形状
            plt.imshow(X_test[index-1].reshape(28,28))
            axes.axis('off')  # 隐藏坐标轴
            # 把真实数据作为坐标系的标题
            axes.set_title(y_[index-1])
            index += 1
    

    相关文章

      网友评论

        本文标题:K-近邻算法(KNN)

        本文链接:https://www.haomeiwen.com/subject/gqwgbftx.html