Scikit Learn - KNN 学习
k-NN(k 最近邻)是最简单的机器学习算法之一,本质上是非参数的和惰性的。非参数意味着对底层数据分布没有任何假设,即模型结构由数据集决定。惰性学习或基于实例的学习意味着,为了生成模型,它不需要任何训练数据点,并且在测试阶段使用整个训练数据。
k-NN 算法包含以下两个步骤 −
步骤 1
在此步骤中,它计算并存储训练集中的每个样本的 k 个最近邻。
步骤 2
在此步骤中,对于未标记的样本,它从数据集中检索 k 个最近邻。然后,在这些 k 个最近邻中,它通过投票来预测类别(获得多数票的类别获胜)。
实现 k 个最近邻算法的模块 sklearn.neighbors 提供了基于无监督和有监督邻域的学习方法的功能。
无监督最近邻算法实现了不同的算法(BallTree、KDTree 或 Brute Force)来为每个样本找到最近邻。这个无监督版本基本上只是上面讨论的第一步,也是许多需要邻域搜索的算法(其中最著名的是 KNN 和 K-means)的基础。简而言之,它是用于实现近邻搜索的无监督学习器。
另一方面,基于近邻的监督学习可用于分类和回归。
无监督 KNN 学习
如上所述,许多算法(例如 KNN 和 K-Means)都需要进行近邻搜索。因此,Scikit-learn 决定将近邻搜索部分实现为一个独立的"学习器"。将近邻搜索作为一个独立的学习器实现的原因是,计算所有成对距离来查找近邻显然效率不高。让我们通过示例来了解 Sklearn 用于实现无监督近邻学习的模块。
Scikit-learn 模块
sklearn.neighbors.NearestNeighbors 是用于实现无监督近邻学习的模块。它使用特定的近邻算法,例如 BallTree、KDTree 或 Brute Force。换句话说,它充当这三种算法的统一接口。
参数
下表列出了 NearestNeighbors 模块使用的参数 −
| Sr.No | 参数及说明 |
|---|---|
| 1 |
n_neighbors − int,可选 要获取的邻居数量。默认值为 5。 |
| 2 |
radius − float,可选 限制邻居与返回值的距离。默认值为 1.0。 |
| 3 |
algorithm − {'auto', 'ball_tree', 'kd_tree', 'brute'},可选 此参数将接受您想要使用的算法(BallTree、KDTree 或 Brute-force)来计算最近邻。如果您提供'auto',它将尝试根据传递给 fit 方法的值来确定最合适的算法。 |
| 4 |
leaf_size − int,可选 它会影响构建和查询的速度以及存储树所需的内存。它传递给 BallTree 或 KDTree。虽然最优值取决于问题的性质,但其默认值为 30。 |
| 5 |
metric − 字符串或可调用函数 这是用于计算点间距离的度量标准。我们可以将其作为字符串或可调用函数传递。如果是可调用函数,则会在每一对行上调用该度量标准,并记录结果值。这比将度量标准名称作为字符串传递效率较低。 我们可以从 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 − 整数,可选 这是明可夫斯基度量的参数。默认值为 2,相当于使用 Euclidean_distance(l2)。 |
| 7 |
metric_params − dict,可选 这是度量函数的附加关键字参数。默认值为 None。 |
| 8 |
N_jobs − int 或 None,可选 它表示用于邻居搜索的并行作业数量。默认值为 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.]
]
)
一旦我们适应了无监督的NearestNeighbors模型,数据将根据参数'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 使用的两种不同类型的最近邻回归器 −
KNeighborsRegressor
此回归器名称中的 K 代表 k 个最近邻,其中 k 是用户指定的整数值。因此,顾名思义,该回归器基于 k 个最近邻进行学习。k 值的选择取决于数据。让我们借助一个实现示例来进一步理解它。
以下是 scikit-learn 使用的两种不同类型的最近邻回归器 −
实现示例
在本例中,我们将使用 scikit-learn 的 KNeighborsRegressor 在名为 Iris Flower 的数据集上实现 KNN。
首先,按如下方式导入鸢尾花数据集 −
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 ("MSE 为:",format(np.power(y-knnr.predict(X),4).mean()))
输出
MSE 为: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]]))
RadiusNeighborsRegressor
此回归器名称中的 Radius 表示指定半径 r 内的最近邻点,其中 r 是用户指定的浮点值。因此,顾名思义,此回归器基于每个训练点在固定半径 r 内的邻居数量进行学习。让我们借助一个实现示例 −
来更深入地理解它实现示例
在本例中,我们将使用 scikit-learn 的 RadiusNeighborsRegressor −
在名为 Iris Flower 的数据集上实现 KNN首先,按如下方式导入鸢尾花数据集 −
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 类,并提供半径值,如下所示:−
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()))
Output
MSE 为: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]]))

