📜  带有Python的AI-无监督学习:聚类

📅  最后修改于: 2020-12-11 05:36:34             🧑  作者: Mango

无监督的机器学习算法没有任何监督可提供任何类型的指导。这就是为什么它们与真正的人工智能紧密结合的原因。

在无监督学习中,将没有正确答案,也没有老师来指导。算法需要发现数据中有趣的模式以供学习。

什么是群集?

基本上,它是一种无监督的学习方法,并且是许多领域中用于统计数据分析的常用技术。聚类主要是将观测值集合划分为子集(称为聚类)的任务,以使同一聚类中的观测值在某种意义上相似,而与其他聚类中的观测值不相似。简而言之,可以说聚类的主要目的是基于相似性和不相似性对数据进行分组。

例如,下图显示了不同集群中的同类数据-

聚类

数据聚类算法

以下是一些用于对数据进行聚类的常见算法-

K-均值算法

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

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

步骤2-固定集群的数量,并将每个数据点随机分配给集群。换句话说,我们需要根据聚类数对数据进行分类。

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

因为这是一个迭代算法,所以我们需要在每次迭代时更新K个质心的位置,直到找到全局最优值,换句话说,质心到达了它们的最佳位置。

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

让我们导入必要的包-

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

下面的代码线将有助于在生成的二维数据集,包含四个斑点,通过使用make_blobsklearn.dataset包。

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均值算法

在这里,我们将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均值算法2

均值漂移算法

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

  • 首先,我们需要从分配给它们自己的群集的数据点开始。

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

  • 通过重复此过程,我们将簇的峰值移近,即移向密度较高的区域。

  • 该算法在质心不再移动的阶段停止。

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

让我们导入必要的包-

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

下面的代码将有助于在生成的二维数据集,包含四个斑点,通过使用make_blobsklearn.dataset包。

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

均值Shif算法

现在,我们需要使用输入数据训练均值漂移聚类模型。

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

集群数

衡量集群性能

现实世界中的数据并非自然地组织成许多独特的簇。由于这个原因,不容易可视化和得出推论。这就是为什么我们需要测量集群性能及其质量。可以借助轮廓分析来完成。

轮廓分析

此方法可用于通过测量聚类之间的距离来检查聚类的质量。基本上,它提供了一种通过给出轮廓分数来评估参数(如簇数)的方法。该分数是衡量一个群集中的每个点与相邻群集中的点的接近程度的度量。

轮廓得分分析

分数范围为[-1,1]。以下是该分数的分析-

  • +1得分-接近+1得分表示样本距离相邻簇很远。

  • 得分0-得分0表示样本在两个相邻聚类之间的决策边界上或非常接近。

  • -1分-负分表示样本已分配给错误的聚类。

计算轮廓分数

在本节中,我们将学习如何计算轮廓分数。

剪影分数可以通过使用以下公式计算-

$$ silhouette分数= \ frac {\ left(pq \ right)} {max \ left(p,q \ right)} $$

在此,𝑝是到该数据点不属于的最近群集中的点的平均距离。并且,𝑞是到其自身群集中所有点的群集内平均距离。

为了找到最佳数量的聚类,我们需要通过从sklearn包中导入指标模块来再次运行聚类算法。在以下示例中,我们将运行K-means聚类算法以找到最佳数目的聚类-

如图所示导入必要的程序包-

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

用下面的代码的帮助下,我们将生成的二维数据集,包含四个斑点,通过使用make_blobsklearn.dataset包。

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

下面的代码行将帮助显示群集的数量以及Silhouette得分。

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

寻找最近的邻居

如果我们要构建推荐系统,例如电影推荐系统,那么我们需要了解查找最近邻居的概念。这是因为推荐系统利用了最近邻居的概念。

查找最近邻居概念可以定义为从给定数据集中查找最接近输入点的过程。此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')

寻找最近的邻居

现在,我们需要构建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()

测试数据点

输出

K最近的邻居

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

最近邻分类器

K最近邻(KNN)分类器是使用最近邻居算法对给定数据点进行分类的分类模型。我们在上一节中实现了KNN算法,现在我们将使用该算法构建KNN分类器。

KNN分类器的概念

K最近邻居分类的基本概念是找到预定义的数量,即距离最接近新样本的训练样本的“ k”-,该样本必须进行分类。新样本将从邻居本身获取标签。 KNN分类器具有一个固定的用户定义常量,用于必须确定的邻居数量。对于距离,标准欧几里德距离是最常见的选择。 KNN分类器直接在学习的样本上工作,而不是创建学习规则。 KNN算法是所有机器学习算法中最简单的算法之一。在许多分类和回归问题(例如字符识别或图像分析)中,它已经非常成功。

我们正在建立一个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)

图片显示(0)

图像0显示如下-

图片显示(0)

图像显示(9)

图像9显示如下-

图像显示(9)

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)

图片显示(6)

图像6显示如下-

图片显示(6)

现在我们将预测测试数据如下:

KNN.predict(test1)

上面的代码将生成以下输出-

array([6])

现在,考虑以下内容-

digit['target_names']

上面的代码将生成以下输出-

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