Artificial Intelligence With Python 简明教程

AI with Python - Unsupervised Learning: Clustering

无监督机器学习算法没有任何提供任何指导的监督者。这就是为什么它们与某些被称为真正的人工智能密切相关。

在无监督学习中,没有正确答案,也没有指导。算法需要发现数据中用于学习的有趣模式。

What is Clustering?

从根本上讲,这是一种无监督学习方法,是一种在许多领域中使用的统计数据分析的常用技术。聚类主要是将一组观察分成子集(称为簇)的任务,以便同一簇中的观察在某种意义上相似,并且与其他簇中的观察不同。简而言之,我们可以说,聚类的主要目标是根据相似性和相异性对数据进行分组。

例如,下图显示了不同簇中类似类型的数据 -

clustering

Algorithms for Clustering the Data

以下是用于聚类数据的几种常见算法 -

K-Means algorithm

K 均值聚类算法是用于聚类数据的一种众所周知的算法。我们需要假设已经知道簇的数量。这也称为平面聚类。它是一种迭代聚类算法。此算法需要遵循以下步骤 -

Step 1 - 我们需要指定 K 个子组的所需数量。

Step 2 - 固定簇的数量,并将每个数据点随机分配给一个簇。或者换句话说,我们需要根据簇的数量对我们的数据进行分类。

在此步骤中,应计算簇质心。

由于这是一个迭代算法,我们需要通过每一次迭代更新 K 个质心的位置,直到找到全局最优值,或者换句话说,质心达到其最佳位置。

以下代码将有助于在 Python 中实现 K 均值聚类算法。我们将使用 Scikit-learn 模块。

让我们导入必要的软件包 −

import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
import numpy as np
from sklearn.cluster import KMeans

以下代码行将有助于通过使用 sklearn.dataset 包中的 make_blob 来生成包含四个斑点的二维数据集。

from sklearn.datasets.samples_generator import make_blobs

X, y_true = make_blobs(n_samples = 500, centers = 4,
            cluster_std = 0.40, random_state = 0)

我们可以使用以下代码可视化数据集 -

plt.scatter(X[:, 0], X[:, 1], s = 50);
plt.show()
k means algorithm

在这里,我们将 kmeans 初始化为 KMeans 算法,其中包含需要多少个簇(n_clusters)的必需参数。

kmeans = KMeans(n_clusters = 4)

我们需要使用输入数据训练 K-means 模型。

kmeans.fit(X)
y_kmeans = kmeans.predict(X)
plt.scatter(X[:, 0], X[:, 1], c = y_kmeans, s = 50, cmap = 'viridis')

centers = kmeans.cluster_centers_

以下给出的代码将帮助我们根据我们的数据绘制和可视化机器的发现,以及根据要找到的簇的数量进行拟合。

plt.scatter(centers[:, 0], centers[:, 1], c = 'black', s = 200, alpha = 0.5);
plt.show()
k means algorithm2

Mean Shift Algorithm

这是无监督学习中使用的另一种流行且强大的聚类算法。它不会做出任何假设,因此它是非参数算法。它也称为层次聚类或均值漂移聚类分析。以下将是此算法的基本步骤 -

  1. 首先,我们需要从分配给自己的簇的数据点开始。

  2. 现在,它计算质心并更新新质心的位置。

  3. 通过重复此过程,我们可以更接近簇的峰值,即向密度更高的区域靠近。

  4. 此算法在质心不再移动的阶段停止。

在以下代码的帮助下,我们在 Python 中实现了 Mean Shift 聚类算法。我们将使用 Scikit-learn 模块。

让我们导入必要的软件包 −

import numpy as np
from sklearn.cluster import MeanShift
import matplotlib.pyplot as plt
from matplotlib import style
style.use("ggplot")

下面的代码将通过使用 sklearn.dataset 包中的 make_blob 帮助生成包含四个 Blob 的二维数据集。

from sklearn.datasets.samples_generator import make_blobs

我们可以用以下代码可视化数据集

centers = [[2,2],[4,5],[3,10]]
X, _ = make_blobs(n_samples = 500, centers = centers, cluster_std = 1)
plt.scatter(X[:,0],X[:,1])
plt.show()
mean shif algorithm

现在,我们需要使用输入数据训练 Mean Shift 聚类模型。

ms = MeanShift()
ms.fit(X)
labels = ms.labels_
cluster_centers = ms.cluster_centers_

以下代码将按输入数据打印聚类中心和预期的聚类数目

print(cluster_centers)
n_clusters_ = len(np.unique(labels))
print("Estimated clusters:", n_clusters_)
[[ 3.23005036 3.84771893]
[ 3.02057451 9.88928991]]
Estimated clusters: 2

下面给出的代码将帮助绘制和可视化机器基于我们数据的发现,以及根据要找到的聚类数目的拟合。

colors = 10*['r.','g.','b.','c.','k.','y.','m.']
   for i in range(len(X)):
   plt.plot(X[i][0], X[i][1], colors[labels[i]], markersize = 10)
plt.scatter(cluster_centers[:,0],cluster_centers[:,1],
   marker = "x",color = 'k', s = 150, linewidths = 5, zorder = 10)
plt.show()
number of clusters

Measuring the Clustering Performance

真实世界的数据并不会自然地组织到一定数量的独特聚类中。由于这个原因,可视化和得出推论并不容易。这就是我们也需要测量聚类性能及其质量的原因。这可以通过轮廓分析来完成。

Silhouette Analysis

此方法可用于通过测量聚类之间的距离来检查聚类的质量。基本上,它提供了一种通过给出自举得分来评估聚类数目等参数的方法。此得分是一个指标,用于测量一个聚类中的每个点与邻近聚类中的点的接近程度。

Analysis of silhouette score

此得分在 [-1, 1] 的范围内。以下是对此得分的分析:

  1. Score of +1 − 接近 +1 的得分表明该样本远离邻近聚类。

  2. Score of 0 − 分数 0 表明该样本位于或非常接近于两个邻近聚类之间的决策边界。

  3. Score of -1 − 负得分表明样本已分配到错误的聚类。

Calculating Silhouette Score

在本节中,我们将了解如何计算轮廓得分。

轮廓得分可使用以下公式计算:

轮廓得分 = \frac{\left ( p-q \right )}{max\left ( p,q \right )}

此处,𝑝 是到最近聚类中数据点(该数据点不属于该聚类)的平均距离。而 𝑞 是到自身聚类中所有点之间的平均聚类内距离。

为了找到最优聚类数目,我们需要通过从 sklearn 包中导入 metrics 模块来再次运行聚类算法。在以下示例中,我们将运行 K 均值聚类算法来查找最优聚类数目:

导入必要的包,如下所示

import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
import numpy as np
from sklearn.cluster import KMeans

通过以下代码的帮助,我们将通过使用 sklearn.dataset 包中的 make_blob 生成包含四个 Blob 的二维数据集。

from sklearn.datasets.samples_generator import make_blobs

X, y_true = make_blobs(n_samples = 500, centers = 4, cluster_std = 0.40, random_state = 0)

按照所示初始化变量−

scores = []
values = np.arange(2, 10)

我们需要对 K-means 模型进行所有值的迭代,还需要使用输入数据进行训练。

for num_clusters in values:
kmeans = KMeans(init = 'k-means++', n_clusters = num_clusters, n_init = 10)
kmeans.fit(X)

现使用欧氏距离度量估计当前聚类模型的轮廓得分 −

score = metrics.silhouette_score(X, kmeans.labels_,
metric = 'euclidean', sample_size = len(X))

下列代码行将有助于显示簇数量以及轮廓得分。

print("\nNumber of clusters =", num_clusters)
print("Silhouette score =", score)
scores.append(score)

您将收到以下输出 −

Number of clusters = 9
Silhouette score = 0.340391138371

num_clusters = np.argmax(scores) + values[0]
print('\nOptimal number of clusters =', num_clusters)

现在,最佳簇数的输出如下 −

Optimal number of clusters = 2

Finding Nearest Neighbors

如果我们想要构建推荐系统(例如,电影推荐系统),那么就需要理解寻找最近邻域的概念。这是因为推荐系统利用最近邻域的概念。

concept of finding nearest neighbors 可以定义为从给定数据集寻找与输入点最接近点的过程。这种 KNN(K-最近邻域)算法的主要用途是构建分类系统,根据输入数据点到各个类别的接近程度对数据点进行分类。

下方给出的 Python 代码有助于寻找给定数据集的 K-最近邻域 −

按照所示导入必要的包。此处,我们正在使用 sklearn 包中的 NearestNeighbors 模块

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

现在,我们来定义输入数据 −

A = np.array([[3.1, 2.3], [2.3, 4.2], [3.9, 3.5], [3.7, 6.4], [4.8, 1.9],
             [8.3, 3.1], [5.2, 7.5], [4.8, 4.7], [3.5, 5.1], [4.4, 2.9],])

现在,我们需要定义最近邻域 −

k = 3

我们还需要指定要从中寻找最近邻域的测试数据 −

test_data = [3.3, 2.9]

下列代码可以可视化和绘制我们定义的输入数据 −

plt.figure()
plt.title('Input data')
plt.scatter(A[:,0], A[:,1], marker = 'o', s = 100, color = 'black')
finding nearest neighbors

现在,我们需要构建 K 最近邻域。该对象也需要接受训练

knn_model = NearestNeighbors(n_neighbors = k, algorithm = 'auto').fit(X)
distances, indices = knn_model.kneighbors([test_data])

现在,我们可以按照所示打印 K 最近邻域 −

print("\nK Nearest Neighbors:")
for rank, index in enumerate(indices[0][:k], start = 1):
   print(str(rank) + " is", A[index])

我们可以将最近邻域与测试数据点一起可视化

plt.figure()
plt.title('Nearest neighbors')
plt.scatter(A[:, 0], X[:, 1], marker = 'o', s = 100, color = 'k')
plt.scatter(A[indices][0][:][:, 0], A[indices][0][:][:, 1],
   marker = 'o', s = 250, color = 'k', facecolors = 'none')
plt.scatter(test_data[0], test_data[1],
   marker = 'x', s = 100, color = 'k')
plt.show()
test data point

Output

K Nearest Neighbors

1 is [ 3.1 2.3]
2 is [ 3.9 3.5]
3 is [ 4.4 2.9]

K-Nearest Neighbors Classifier

K-最近邻域 (KNN) 分类器是一种使用最近邻域算法对给定数据点进行分类的分类模型。我们在上一部分中已经实现了 KNN 算法,现在我们准备使用该算法构建一个 KNN 分类器。

Concept of KNN Classifier

K-最近邻域分类的基本原理是寻找预先定义的数目,即与新样本(必须进行分类)距离最近的“k”个训练样本。新样本将从邻域本身获取其标签。KNN 分类器有一个用户定义的固定常数,用于确定邻域数。对于距离,标准欧氏距离是最常见的选择。KNN 分类器直接针对学习的样本进行处理,而不是创建学习规则。KNN 算法属于所有机器学习算法中最简单的算法之一。它在很多分类和回归问题(例如,字符识别或图像分析)中都取得了相当不错的效果。

Example

我们正在构建一个 KNN 分类器来识别数字。为此,我们将使用 MNIST 数据集。我们将在 Jupyter Notebook 中编写此代码。

导入必需的软件包,如下所示。

此处我们正在使用 sklearn.neighbors 包中的 KNeighborsClassifier 模块 −

from sklearn.datasets import *
import pandas as pd
%matplotlib inline
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
import numpy as np

以下代码将显示数字图像以验证我们必须测试的图像 −

def Image_display(i):
   plt.imshow(digit['images'][i],cmap = 'Greys_r')
   plt.show()

现在,我们需要加载 MNIST 数据集。实际上,总共是 1797 幅图像,但我们将前 1600 幅图像用作训练样本,剩下的 197 幅将保留用于测试目的。

digit = load_digits()
digit_d = pd.DataFrame(digit['data'][0:1600])

现在,在显示图像时,我们可以看到以下输出 −

Image_display(0)

Image_display(0)

0 的图像显示如下 −

image display zero

Image_display(9)

9 的图像显示如下 −

image display nine

digit.keys()

现在,我们需要创建训练和测试数据集,并将测试数据集提供给 KNN 分类器。

train_x = digit['data'][:1600]
train_y = digit['target'][:1600]
KNN = KNeighborsClassifier(20)
KNN.fit(train_x,train_y)

以下输出将创建 K 近邻分类器构造函数 −

KNeighborsClassifier(algorithm = 'auto', leaf_size = 30, metric = 'minkowski',
   metric_params = None, n_jobs = 1, n_neighbors = 20, p = 2,
   weights = 'uniform')

我们需要通过提供任意大于训练样本的 1600 的数字来创建测试样本。

test = np.array(digit['data'][1725])
test1 = test.reshape(1,-1)
Image_display(1725)

Image_display(6)

6 的图像显示如下 −

image display six

现在,我们将预测测试数据,如下所示 −

KNN.predict(test1)

上述代码将生成以下输出 −

array([6])

现在,考虑以下内容 −

digit['target_names']

上述代码将生成以下输出 −

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])