Scikit Learn KNN 学习


k-NN(k-Nearest Neighbor)是最简单的机器学习算法之一,本质上是非参数和惰性的。

非参数意味着对基础数据分布没有假设,即模型结构是从数据集确定的。

惰性或基于实例的学习意味着出于模型生成的目的,它不需要任何训练数据点,并且在测试阶段使用整个训练数据。

k-NN算法由以下两步组成:

步骤1

在这一步中,它计算并存储训练集中每个样本的 k 个最近邻。

步骤2

在这个步骤中,对于一个未标记的样本,它从数据集中检索出k个最近的邻居。然后,在这些k-近邻中,它通过投票来预测类别(获得多数票的类别获胜)。

sklearn.neighbors模块实现了k-nearest neighbors算法,为无监督有监督的近邻学习方法提供了方法。

无监督的近邻算法实现了不同的算法(BallTree、KDTree或Brute Force),为每个样本找到最近的邻居。这种无监督的版本基本上只有上面讨论的步骤1,也是许多需要搜索邻居的算法(KNN和K-means是著名的算法)的基础。简而言之,它是实现邻居搜索的无监督学习者。

另一方面,基于监督的邻居学习被用于分类和回归。

无监督 KNN 学习


如前所述,存在许多需要最近邻搜索的算法,如 KNN 和 K-Means。这就是为什么 Scikit-learn 决定将邻居搜索部分实现为它自己的“学习器”。将邻居搜索作为单独的学习器的原因是计算所有成对距离以找到最近邻居显然不是很有效。让我们看看 Sklearn 使用的模块来实现无监督的最近邻学习以及示例。

Scikit-learn 模块

sklearn.neighbors.NearestNeighbors是用于实现无监督最近邻学习的模块。它使用名为 BallTree、KDTree 或 Brute Force 的特定最近邻算法。换句话说,它充当这三种算法的统一接口。

参数

下表是NearestNeighbors模块使用的参数:

序号参数及说明
1

n_neighbors: int, optional

要获取的邻居数量。默认值为 5。

2

radius: float,optional

它限制了邻居返回的距离。默认值为 1.0。

3

algorithm: {'auto', 'ball_tree', 'kd_tree', 'brute'},optional

此参数将采用你要用于计算最近邻居的算法(BallTree、KDTree 或 Brute-force)。如果你提供“auto”,它将尝试根据传递给 fit 方法的值来决定最合适的算法。

4

leaf_size: int, optional

它会影响构建和查询的速度以及存储树所需的内存。它被传递给 BallTree 或 KDTree。虽然最佳值取决于问题的性质,但其默认值为 30。

5

metric: string or callable

它是用于点之间距离计算的度量。我们可以将它作为字符串或可调用函数传递。在可调用函数的情况下,在每对行上调用度量并记录结果值。它比将指标名称作为字符串传递效率低。

我们可以从 scikit-learn 或 scipy.spatial.distance 中选择度量。有效值如下:

Scikit-learn: ['cosine','manhattan','Euclidean','l1','l2','cityblock']

Scipy.spatial.distance:

['braycurtis','canberra','chebyshev','dice','hamming','jaccard','correlation','kulsinski','mahalanobis','minkowski','rogerstanimoto','russellrao', ' sokalmicheme'、'sokalsneath'、'seuclidean'、'sqeuclidean'、'yule']。

默认指标是“Minkowski”。

6

P: int,optional

它是 Minkowski 度量的参数。默认值为 2,相当于使用 Euclidean_distance(l2)。

7

metric_params: dict, optional

这是度量函数的附加关键字参数。默认值为无。

8

N_jobs: int 或 None,optional

它表示要为邻居搜索运行的并行作业的数量。默认值为None。

示例

下面的例子将通过使用sklearn.neighbors.NearestNeighbors模块找到两组数据之间的最近的邻居。

首先,我们需要导入所需的模块和包:

from sklearn.neighbors import NearestNeighbors
import numpy as np

现在,在导入包之后,定义我们要查找最近邻的数据集:

Input_data = np.array([[-1, 1], [-2, 2], [-3, 3], [1, 2], [2, 3], [3, 4],[4, 5]])

接下来,应用无监督学习算法,如下:

nrst_neigh = NearestNeighbors(n_neighbors = 3, algorithm = 'ball_tree')

接下来,用输入数据集拟合模型。

nrst_neigh.fit(Input_data)

现在,找到数据集的 K 邻居。它将返回每个点的邻居的索引和距离。

distances, indices = nbrs.kneighbors(Input_data)
indices
array(
    [
        [0, 1, 3],
        [1, 2, 0],
        [2, 1, 0],
        [3, 4, 0],
        [4, 5, 3],
        [5, 6, 4],
        [6, 5, 4]
    ], dtype = int64
)
distances
array(
    [
        [0. , 1.41421356, 2.23606798],
        [0. , 1.41421356, 1.41421356],
        [0. , 1.41421356, 2.82842712],
        [0. , 1.41421356, 2.23606798],
        [0. , 1.41421356, 1.41421356],
        [0. , 1.41421356, 1.41421356],
        [0. , 1.41421356, 2.82842712]
    ]
)

上面的输出显示每个点的最近邻居是点本身,即在零处。这是因为查询集与训练集匹配。

我们还可以通过生成稀疏图来显示相邻点之间的连接,如下所示:

nrst_neigh.kneighbors_graph(Input_data).toarray()
array(
    [
        [1., 1., 0., 1., 0., 0., 0.],
        [1., 1., 1., 0., 0., 0., 0.],
        [1., 1., 1., 0., 0., 0., 0.],
        [1., 0., 0., 1., 1., 0., 0.],
        [0., 0., 0., 1., 1., 1., 0.],
        [0., 0., 0., 0., 1., 1., 1.],
        [0., 0., 0., 0., 1., 1., 1.]
    ]
)

一旦我们拟合了无监督的近邻模型,数据将根据参数 "algorithm"的设定值被存储在一个数据结构中。之后,我们可以在需要邻居搜索的模型中使用这个无监督学习者的kneighbors

完整的工作/可执行程序

from sklearn.neighbors import NearestNeighbors
import numpy as np
Input_data = np.array([[-1, 1], [-2, 2], [-3, 3], [1, 2], [2, 3], [3, 4],[4, 5]])
nrst_neigh = NearestNeighbors(n_neighbors = 3, algorithm='ball_tree')
nrst_neigh.fit(Input_data)
distances, indices = nbrs.kneighbors(Input_data)
indices
distances
nrst_neigh.kneighbors_graph(Input_data).toarray()

有监督的 KNN 学习


基于监督近邻的学习用于以下方面:

  • 分类,对于带有离散标签的数据

  • 回归,对于具有连续标签的数据。

最近邻分类器

我们可以借助以下两个特征来理解基于邻居的分类:

  • 它是根据每个点的最近邻居的简单多数投票计算得出的。

  • 它只是存储训练数据的实例,这就是为什么它是一种非泛化学习。

Scikit-learn 模块

以下是 scikit-learn 使用的两种不同类型的最近邻分类器:

S.No.分类器和描述
1.KNeighborsClassifier

此分类器名称中的 K 代表 k 个最近邻,其中 k 是用户指定的整数值。因此,顾名思义,该分类器基于 k 个最近邻实现学习。 k 值的选择取决于数据。

2.RadiusNeighborsClassifier

此分类器名称中的 Radius 表示指定半径 r 内的最近邻居,其中 r 是用户指定的浮点值。因此,顾名思义,该分类器基于每个训练点固定半径 r 内的邻居数量来实现学习。

最近邻回归器


它用于数据标签本质上是连续的情况,分配的数据标签是根据其最近邻居的标签的平均值计算的。

以下是 scikit-learn 使用的两种不同类型的最近邻回归器:

近邻回归器


该回归器名称中的K代表k最近的邻居,其中k是用户指定的整数值。因此,顾名思义,这个回归器实现了基于k个近邻的学习。k的值的选择取决于数据。让我们借助于一个实施例子来进一步了解它。

以下是 scikit-learn 使用的两种不同类型的近邻回归器:

示例

在这个例子中,我们将通过使用scikit-learn KNeighborsRegressor在名为Iris Flower的数据集上实现KNN。

首先,导入iris数据集如下:

from sklearn.datasets import load_iris
iris = load_iris()

现在,我们需要将数据拆分为训练数据和测试数据。我们将使用 Sklearn train_test_split函数将数据分成70(训练数据)和20(测试数据)的比例:

X = iris.data[:, :4]
y = iris.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)

接下来,我们将借助 Sklearn 预处理模块进行数据缩放,如下所示:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

接下来,从Sklearn导入KNeighborsRegressor类,并提供邻居的值,如下所示:

import numpy as np
from sklearn.neighbors import KNeighborsRegressor
knnr = KNeighborsRegressor(n_neighbors = 8)
knnr.fit(X_train, y_train)
KNeighborsRegressor(
    algorithm = 'auto', leaf_size = 30, metric = 'minkowski',
    metric_params = None, n_jobs = None, n_neighbors = 8, p = 2,
    weights = 'uniform'
)

现在,我们可以找到 MSE(均方误差)如下:

print ("The MSE is:",format(np.power(y-knnr.predict(X),4).mean()))
The MSE is: 4.4333349609375

现在,用它来预测值如下:

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.neighbors import KNeighborsRegressor
knnr = KNeighborsRegressor(n_neighbors = 3)
knnr.fit(X, y)
print(knnr.predict([[2.5]]))
[0.66666667]

完整的工作/可执行程序

from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data[:, :4]
y = iris.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

import numpy as np
from sklearn.neighbors import KNeighborsRegressor
knnr = KNeighborsRegressor(n_neighbors=8)
knnr.fit(X_train, y_train)

print ("The MSE is:",format(np.power(y-knnr.predict(X),4).mean()))

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.neighbors import KNeighborsRegressor
knnr = KNeighborsRegressor(n_neighbors=3)
knnr.fit(X, y)
print(knnr.predict([[2.5]]))

半径邻居回归器


此回归器名称中的 Radius 表示指定半径 r 内的最近邻居,其中 r 是用户指定的浮点值。因此,顾名思义,这个回归器基于每个训练点固定半径 r 内的邻居数量来实现学习。借助一个实现示例,让我们更深入地了解它:

示例

在这个例子中,我们将通过使用scikit-learn RadiusNeighborsRegressor在名为iris Flower的数据集上实现KNN:

首先,导入iris数据集如下:

from sklearn.datasets import load_iris
iris = load_iris()

现在,我们需要将数据拆分为训练数据和测试数据。我们将使用 Sklearn train_test_split 函数将数据拆分为 70(训练数据)和 20(测试数据)的比例:

X = iris.data[:, :4]
y = iris.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20)

接下来,我们将借助 Sklearn 预处理模块进行数据缩放,如下所示:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

接下来,从Sklearn导入RadiusneighborsRegressor类,并提供radius的值,如下所示:

import numpy as np
from sklearn.neighbors import RadiusNeighborsRegressor
knnr_r = RadiusNeighborsRegressor(radius=1)
knnr_r.fit(X_train, y_train)

现在,我们可以找到 MSE(均方误差)如下:

print ("The MSE is:",format(np.power(y-knnr_r.predict(X),4).mean()))
The MSE is: The MSE is: 5.666666666666667

现在,用它来预测值如下:

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.neighbors import RadiusNeighborsRegressor
knnr_r = RadiusNeighborsRegressor(radius=1)
knnr_r.fit(X, y)
print(knnr_r.predict([[2.5]]))
[1.]

完整的工作/可执行程序

from sklearn.datasets import load_iris

iris = load_iris()

X = iris.data[:, :4]
y = iris.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
import numpy as np
from sklearn.neighbors import RadiusNeighborsRegressor
knnr_r = RadiusNeighborsRegressor(radius = 1)
knnr_r.fit(X_train, y_train)
print ("The MSE is:",format(np.power(y-knnr_r.predict(X),4).mean()))
X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.neighbors import RadiusNeighborsRegressor
knnr_r = RadiusNeighborsRegressor(radius = 1)
knnr_r.fit(X, y)
print(knnr_r.predict([[2.5]]))