非参数方法不用函数作为生成数据的基本模型,因此非参数模型的鲁棒性更好,但是也存在着很多限制。
给定训练集样本 D = { ( y ( i ) , x ( i ) ) } i = 1 N \displaystyle \mathcal D=\{(y^{(i)},\mathbf x^{(i)})\}^N_{i=1} D={(y(i),x(i))}i=1N,在给定输入点 x \mathbf x x 时预测因变量 y y y。
该问题可以被定义为: f ^ ( x ) = 1 k ∑ x ( i ) ∈ N k ( x , D ) y ( i ) \displaystyle \hat f(\mathbf x)=\frac{1}{k}\sum_{\mathbf x^{(i)}\in N_k(\mathbf x, \mathcal D)}y^{(i)} f^(x)=k1x(i)∈Nk(x,D)∑y(i),其中 N k ( x , D ) N_k(\mathbf x, \mathcal D) Nk(x,D) 是在 { x ( i ) } i = 1 N \{\mathbf x^{(i)}\}^N_{i=1} {x(i)}i=1N 中最接近 x \mathbf x x 的 k k k 个点。
因此,kNN 预测的结果是最接近查询点 x x x 的 k 个训练响应值的样本平均值(即 KNN对输入 x x x 的预测结果是接近 x x x 的训练样本中标签类别最多的类别)。
在KNN中,有一些参数需要明确指定:
如下图所示,黑色直线为目标的回归曲线,红色为样本点,蓝色为KNN的预测曲线,左图为 k = 1 k=1 k=1 时的结果,右图为 k = 9 k=9 k=9 时的结果。
对于线性情况,线性回归的效果比KNN要好一点;但对于非线性情况,KNN的效果要比线性回归好。如下图所示,左侧图为实际曲线与拟合曲线,蓝色曲线为 k = 1 k=1 k=1 时的拟合曲线,红色为 k = 9 k=9 k=9 时的拟合曲线,黑色曲线为目标曲线;右侧图中黑色虚线为线性回归在测试集上预测得到的最小均方误差(MSE),绿色点曲线为MSE随着 1 / k 1/k 1/k 的变化曲线:
随着数据集中数据维度的增加(即 x \mathbf x x 的维度 p p p ),KNN的效果越来越差。事实上,随着维度的增加,线性回归在测试集上的MSE增加,但是影响不大;但是对KNN的影响很大,MSE急速增大。如下图所示,数据维度与 1 / k 1/k 1/k 之间 MSE的变化关系,黑色虚线代表线性回归的MSE,绿色虚线代表KNN 的MSE。
这是因为,随着维度的增大,在高维空间中,很难找到一个点的附近邻居,即 维度灾难。而维度灾难是非参数方法都会面临的问题。
KNN估计属于类别 c c c 的条件概率为:
p c ( x ) = 1 k ∑ x ( i ) ∈ N k ( x , D ) I ( y ( i ) = c ) \displaystyle p_c(\mathbf x)=\frac{1}{k}\sum_{\mathbf x^{(i)}\in N_k(\mathbf x, \mathcal D)}I(y^{(i)}=c) pc(x)=k1x(i)∈Nk(x,D)∑I(y(i)=c),其中 N k ( x , D ) N_k(\mathbf x, \mathcal D) Nk(x,D) 是在 { x ( i ) } i = 1 N \{\mathbf x^{(i)}\}^N_{i=1} {x(i)}i=1N 中最接近 x \mathbf x x 的 k k k 个点。
如 KNN回归一样, k 过小,容易导致过拟合;k 过大,容易导致欠拟合。如下图所示,黑线代表 KNN决策分类边界,紫色曲线代表理想中正确的分类边界。
同样的,KNN分类器也会受到 维度灾难的影响。
机器学习算法库中KNN回归,通过对训练集中最近邻域的目标进行局部插值来预测目标。其函数API接口如下:
sklearn.neighbors.KNeighborsRegressor(n_neighbors=5, *,
weights='uniform',
algorithm='auto',
leaf_size=30,
p=2,
metric='minkowski',
metric_params=None,
n_jobs=None)
各项参数含义如下:
参数1:n_neighbors,int类型, default=5;KNN算法中默认的邻居数量
参数2:weights,字符串型,default='uniform';在预测中使用的权重函数,可选参数有:
'uniform',均匀权重,即所有的邻居采用相同的权重;
'distance',权重是距离的倒数,即距离近的邻居对决策有着更大的影响;
[callable],用户自定义的函数,它接受一个距离数组,并返回一个包含权重的相同形状的数组;
参数3:algorithm,字符串型, default='auto';用于计算最近邻的算法,可选算法有:
'ball_tree', 使用 BallTree;
'kd_tree',使用 KDTree;
'brute',使用暴力搜索;
'auto',尝试根据传递给 fit 方法的值来决定最合适的算法。
注意:稀疏输入将覆盖这个参数的设置,使用蛮力 'brute'。
参数4: leaf_size,int类型, default=30;传递给 BallTree 或 KDTree的叶子大小。
这会影响构造和查询的速度,以及存储树所需的内存;
最优值取决于问题的性质。
参数5, p,int, default=2;明氏距离的幂参数,可为任意整数。
当 p = 1时,相当于取曼哈顿距离(L1范数);
当 p = 2时,相当于欧氏距离(L2范数);
参数6,metric,str类型, default='minkowski';默认为明示距离。
参数7,metric_params,dict类型, default=None;度量函数的其他关键字参数。
参数8:n_jobs,int类型, default=None。
设定用于计算的cpu核数量。如果 n_tragets > 1,而变量 X 又是稀疏的;或者如果 positive=True 时,会在大问题时提供加速。
n_jobs = None 表示 核数量为1;
n_jobs = -1 时,表示cpu中所有的核都参与工作。
参数6的可选类型有:
(1)实数向量空间中的距离度量:
(2)用于二维向量空间的度量:
机器学习算法库中KNN分类,通过对训练集中最近邻域的目标进行局部邻居投票来执行分类。其函数API接口如下:
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, *,
weights='uniform',
algorithm='auto',
leaf_size=30,
p=2,
metric='minkowski',
metric_params=None,
n_jobs=None)
其参数含义与 KNN 回归相同,在此不做重复说明。