Scikit Learn 简明教程

Scikit Learn - KNN Learning

k-NN(k-近邻),最简单的机器学习算法之一,本质上是非参数化和惰性的。非参数化意味着对底层数据分布没有假设,即,模型结构由数据集确定。惰性或基于实例的学习意味着,出于模型生成目的,它不需要任何训练数据点,而整个训练数据都用于测试阶段。

k-NN 算法包含以下两个步骤:

Step 1

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

Step 2

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

实现了 k-近邻算法的模块 sklearn.neighbors 提供了基于 unsupervisedsupervised 近邻的学习方法的功能。

无监督最近近邻实现了不同的算法(BallTree、KDTree 或 Brute Force)来查找每个样本的最近近邻。此无监督版本基本上只是步骤 1,如上所述,并且是需要邻域搜索的许多算法(KNN 和 K-means 是最著名的算法)的基础。简单来说,它是非监督学习器,用于实现邻域搜索。

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

Unsupervised KNN Learning

如前所述,存在许多算法(如 KNN 和 K-Means 算法)需要最近邻邻搜索。这就是为什么 Scikit-learn 决定将其邻域搜索部分实现为其自己的“学习器”的原因。将邻域搜索作为独立学习器的原因是,计算用于找到最近邻的 all pair-wise 距离明显不是非常有效的。让我们看看 Sklearn 用于实现无监督最近邻学习的模块以及示例。

Scikit-learn module

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

Parameters

下表包含 NearestNeighbors 模块所使用的参数:

Sr.No

Parameter & Description

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 - 整数,可选这是 Minkowski 度量的参数。默认值为 2,等效于使用 Euclidean_distance(l2)。

7

metric_params - 字典,可选这是度量函数的附加关键字参数。默认值为 None。

8

N_jobs - 整数或 None,可选它表示用于邻居搜索的并行作业数。默认值为 None。

Implementation Example

下面的示例将使用 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

Output

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

Output

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]
   ]
)

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

Example

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

nrst_neigh.kneighbors_graph(Input_data).toarray()

Output

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

Complete working/executable program

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()

Supervised KNN Learning

基于监督邻域的学习用于以下方面 −

  1. 带离散标签数据的分类

  2. 带连续标签数据的回归。

Nearest Neighbor Classifier

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

  1. 它从每个点的最近邻点的简单多数投票中计算得出。

  2. 它只是存储训练数据实例,这就是它是一种非泛化学习类型的原因。

Scikit-learn modules

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

S.No.

Classifiers & Description

1.

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

2.

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

Nearest Neighbor Regressor

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

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

KNeighborsRegressor

此回归器名称中的 K 表示 k 个最近邻,其中 kinteger value 指定的用户。因此,顾名思义,此回归器基于 k 个最近邻实现学习。k 的值的选取取决于数据。让我们借助一个实现示例进一步理解这一点。

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

Implementation Example

在此示例中,我们将使用 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 类,并按如下方式提供邻居值。

Example

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

Output

KNeighborsRegressor(
   algorithm = 'auto', leaf_size = 30, metric = 'minkowski',
   metric_params = None, n_jobs = None, n_neighbors = 8, p = 2,
   weights = 'uniform'
)

Example

现在,我们按如下方式查找 MSE(均方误差)——

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

Output

The MSE is: 4.4333349609375

Example

现在,使用它按如下方式预测值——

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]]))

Output

[0.66666667]

Complete working/executable program

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 内的邻居数实现学习。让我们借助一个实现示例进一步理解这一点——

Implementation Example

在此示例中,我们将使用 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)

Example

现在,我们按如下方式查找 MSE(均方误差)——

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

Output

The MSE is: The MSE is: 5.666666666666667

Example

现在,使用它按如下方式预测值——

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]]))

Output

[1.]

Complete working/executable program

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]]))