K近邻算法回归和分类

Kneighbors 算法分类和回归

k近邻算法属于有监督学习算法,是一种基本的分类和回归算法。

算法的原理:对一个未分类的数据,通过与它相邻且距离最近的k个已分类的实例来投票,从而确定其所属的类别,即与它距离最近的k个实例多数归属的类别就是此分类实例的类别。

简单理解为近朱者赤近墨者黑。

一般k值选择的不同,会导致不同的结果,选择合适的k值对该算法非常重要。

k值太小,意味着模型太复杂,容易导致过拟合:容易收到噪声的影响。

k值太大,意味着模型太简单,容易导致欠拟合:此时与待分类问题距离较远的样本点也会对分类起作用,使得预测发生错误。

距离的度量

k近邻算法每次都要计算未分类数据与所有知分类的样本数据的距离,然后排序取出距离最近的k个数据来投票得到最终的分类结果,因此距离的计算也是非常重要的一环,距离的计算一般有三种方式:

  • 欧式距离:

L ( x i , x j ) = ( ∑ l = 1 n ( x i ( l ) − x j ( l ) ) 2 ) 1 2 ) L(x_i, x_j)=\left ( \sum_{l=1}^{n}(x_i^{(l)}-x_j^{(l)})^2 \right )^{\frac{1}{2}} ) L(xi,xj)=(l=1n(xi(l)xj(l))2)21)

  • 曼哈顿距离:

L ( x i , x j ) = ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ L(x_i, x_j)=\sum_{l=1}^{n}|x_i^{(l)}-x_j^{(l)}| L(xi,xj)=l=1nxi(l)xj(l)

  • 各个坐标距离的最大值:

KaTeX parse error: Undefined control sequence: \sideset at position 13: L(x_i,x_j)=\̲s̲i̲d̲e̲s̲e̲t̲{}{}{max}_l|x_i…

算法的优缺点

算法的优点:

  • 可以通过不断地实验来找到合适的k值;
  • 算法的准确度较高;
  • 对异常值和噪声有较高的容忍度。

算法的缺点:

  • 每次对一个未标记的样本进行分类时,都需要对与其全部近邻的已标记的样本计算距离和排序
  • k值的选择难以确定;
  • 计算对内存的需求较大。

算法案例

分类任务

在这里使用Jupyter notebook环境:

导包:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier

生成数据:

X, y = make_blobs(n_samples=400, centers=4, cluster_std=1.3, random_state=6)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='rainbow')

在这里插入图片描述

引入封装好的分类函数:

def KneighborsClassifier(X, y, ax=None, n_neighbors=5, weights='uniform', algorithm='auto', cmap='rainbow'):
    """
    采用K近邻算法进行分类
    :param X:待处理的二维矩阵,其中(X[:, 0], X[:, 1])表示二维平面内的一个点
    :param y:监督学习标签
    :param ax:传入提前好的axis对象或默认为None
    :param n_neighbors: 最重要的超参数k值
    :param weights: 'uniform '表示每个点的权重都一样
    :param algorithm: 采用分类的算法 默认为自动
    :param cmap: 采用的颜色映射
    :return:
    """

    # 生成非None的ax对象
    ax = ax or plt.gca()

    # 画出训练数据以及ax对象的设置
    ax.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap='rainbow')
    ax.axis('tight')
    ax.set_xlabel('x', fontsize=16)
    ax.set_ylabel('y', fontsize=16)
    ax.set_title('KNeighborsClassifier', fontsize=19)

    # 获取坐标轴的范围
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    # 建立模型并配置超参数
    # p=2表示采用欧式距离
    model = KNeighborsClassifier(n_neighbors=n_neighbors, weights=weights,
                                 algorithm=algorithm, leaf_size=30, p=2)

    # 用评估器拟合数据
    model.fit(X, y)

    # 画出预测的二维网络
    xx, yy = np.meshgrid(np.linspace(*xlim, num=200),
                         np.linspace(*ylim, num=200))
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

    # 为结果生成彩色图
    n_classes = len(np.unique(y))
    contours = ax.contourf(xx, yy, Z, alpha=0.3, cmap=cmap, zorder=1,
                           levels=np.arange(n_classes + 1) - 0.5)
    # 设置图像边界
    ax.set(xlim=xlim, ylim=ylim)

    return model

查看分类结果:

KneighborsClassifier(X, y)

在这里插入图片描述

回归任务

导包:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor

生成数据:

rng = np.random.RandomState(42)

x = rng.rand(100) * 10
y = np.sin(x) + 0.2 * rng.randn(100)
plt.scatter(x, y)

在这里插入图片描述

导入封装好的函数:

def plusNewAxis(x):
    """
    给数组x增加一个维度的函数
    :param x: 待处理的数组
    :return: np.ndarray
    """
    return x[:, np.newaxis]

def KneighborsRegression(x, y, k=5, ax=None):
    """
    使用k近邻算法做回归分析
    :param x: 回归数据的x坐标
    :param y: 回归数据的y坐标
    :param k: 近邻值的超参数
    :param ax: 传入的ax对象
    :return: model
    """

    # 调整绘制的ax对象
    ax = plt.gca() or ax

    # 转化为机器学习可以利用的维度
    if x.ndim == 1:
        X = plusNewAxis(x)
    else:
        X = x

    # 建立模型并完成拟合
    model = KNeighborsRegressor(k)
    model.fit(X, y)
    # 评估模型得分
    print('模型得分:', model.score(X, y))

    # 生成测试数据
    Min, Max = X.min() - 0.5, X.max() + 0.5
    xfit = np.linspace(Min, Max, 1000)
    Xfit = xfit[:, np.newaxis]
    yfit = model.predict(Xfit)

    # 绘制原始数据
    ax.scatter(x, y, color='b')
    # 绘制回归曲线
    ax.plot(xfit, yfit, color='r')

    # 设置标题与轴信息
    ax.set_title('KNeighbors Regression', fontsize=19)
    ax.set_xlabel('x', fontsize=16)
    ax.set_ylabel('y', fontsize=16)

    # 添加图例
    ax.legend(['row data', 'Regression'], loc='best')

    # 返回模型
    return model

完成回归拟合并计算得分:

KneighborsRegression(x, y)
4 16)
# 添加图例
ax.legend(['row data', 'Regression'], loc='best')

# 返回模型
return model

完成回归拟合并计算得分:

~~~python
KneighborsRegression(x, y)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wwx1239021388/article/details/130001296