无监督机器学习算法没有任何监督者提供任何种类的指导。这就是为什么它们与一些人所说的真正的人工智能密切相关。
在无监督学习中,没有正确的答案,也没有教师的指导。算法需要发现数据中有趣的模式进行学习。
什么是集群?
基本上,它是一种无监督学习方法,是一种常用的统计数据分析技术,应用于许多领域。聚类的主要任务是将观测值集划分为若干子集,称为簇,使同一簇中的观测值在某种意义上相似,而与其他簇中的观测值不同。简单地说,聚类的主要目的是根据相似性和不相似性对数据进行分组。
例如,下图展示了不同聚类中类似类型的数据 −

数据聚类算法
以下是一些常见的聚类算法,用于对数据进行聚类 −
K-均值算法
K-均值聚类算法是著名的数据聚类算法之一。我们需要假设星团的数量已经被知道。这也称为平坦聚类。它是一种迭代聚类算法。对于该算法,需遵循以下步骤 −
步骤1 − 我们需要指定期望的K个子群数量。
步骤2 − 确定簇的数量,并随机将每个数据点分配到一个簇。换句话说,我们需要根据聚类数量来分类数据。
在此步骤中,应计算簇质心。
由于这是一个迭代算法,我们需要每次迭代更新K个重心的位置,直到找到全局最优,换句话说,重心到达的最优位置。
以下代码将帮助你在 Python 中实现 K-均值聚类算法。我们将使用Scikit-learn模块。
让我们导入所需的包 −
python
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
import numpy as np
from sklearn.cluster import KMeans
以下代码行将帮助生成包含四个斑点的二维数据集,使用sklearn.dataset 包中的make_blob。
python
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)
我们可以通过以下代码可视化该数据集 −
python
plt.scatter(X[:, 0], X[:, 1], s = 50);
plt.show()

这里,我们初始化kmean为KMeans算法,并要求参数为多少簇(n_clusters)。
python
kmeans = KMeans(n_clusters = 4)
我们需要用输入数据训练K均值模型。
python
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_
以下代码将帮助我们根据数据绘制和可视化机器的发现,并根据需找到的簇数进行拟合。
python
plt.scatter(centers[:, 0], centers[:, 1], c = 'black', s = 200, alpha = 0.5);
plt.show()

平均移位算法
它是另一种在无监督学习中广泛且强大的聚类算法。它不做任何假设,因此是一种非参数算法。它也被称为层级聚类或均值偏移聚类分析。以下步骤是该算法的基本步骤 −
-
首先,我们需要从分配给他们自身集群的数据点开始。
-
现在,它计算重心并更新新重心的位置。
-
通过重复这一过程,我们会向星团的峰值靠近,即向密度较高的区域移动。
-
该算法在质心不再移动的阶段停止。
借助以下代码,我们正在用 Python 实现平均偏移聚类算法。我们将使用 Scikit-learn 模块。
让我们导入所需的包 −
python
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。
python
from sklearn.datasets.samples_generator import make_blobs
我们可以通过以下代码可视化数据集
python
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()

现在,我们需要用输入数据训练平均偏移集群模型。
python
ms = MeanShift()
ms.fit(X)
labels = ms.labels_
cluster_centers = ms.cluster_centers_
以下代码将根据输入数据打印簇中心和预期簇数 −
python
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
以下代码将帮助根据我们的数据绘制和可视化机器的发现,并根据需找到的簇数进行拟合。
python
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 ( p-q \\right )}{max\\left ( p,q \\right )}
这里, 是该数据点不属于的最近簇中点的平均距离。, 是星团内所有点的平均距离。
为了找到最优的聚类数量,我们需要再次运行聚类算法,通过从 sklearn 包导入度量模块。在下例中,我们将运行K均值聚类算法,以求出最优的聚类数量 −
如图所示导入必要的软件包 −
python
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
import numpy as np
from sklearn.cluster import KMeans
借助以下代码,我们将利用 sklearn.dataset 包中的 make_blob 生成包含四个斑点的二维数据集。
python
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)
初始化变量如图所示 −
python
scores = []
values = np.arange(2, 10)
我们需要对所有数值迭代K-均值模型,同时还需要用输入数据进行训练。
python
for num_clusters in values:
kmeans = KMeans(init = 'k-means++', n_clusters = num_clusters, n_init = 10)
kmeans.fit(X)
现在,用欧几里得距离度量 − 估计当前聚类模型的轮廓分数
python
score = metrics.silhouette_score(X, kmeans.labels_,
metric = 'euclidean', sample_size = len(X))
以下代码行将帮助显示簇数以及Silhouette分数。
python
print("\nNumber of clusters =", num_clusters)
print("Silhouette score =", score)
scores.append(score)
您将获得以下输出 −
python
Number of clusters = 9
Silhouette score = 0.340391138371
num_clusters = np.argmax(scores) + values[0]
print('\nOptimal number of clusters =', num_clusters)
现在,最优簇数的输出如下 −
python
Optimal number of clusters = 2
寻找最近邻
如果我们想构建像电影推荐系统这样的推荐系统,就需要理解"寻找最近邻"的概念。这是因为推荐系统采用了最近邻的概念。
寻找最近邻的概念可以定义为从给定数据集中寻找输入点最近的点的过程。该KNN)K最近邻算法的主要用途是构建分类系统,根据输入数据点与不同类别的接近程度对数据点进行分类。
下文给出的 Python 代码有助于寻找给定数据集的 K 最近邻 −
如下所示导入所需的软件包。这里,我们使用 sklearn 包中的 NearestNeighbors 模块
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors
现在定义输入数据−
python
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],])
现在,我们需要定义最近邻 −
python
k = 3
我们还需要给出最近邻的测试数据 −
python
test_data = [3.3, 2.9]
以下代码可以可视化并绘制由我们定义的输入数据 −
python
plt.figure()
plt.title('Input data')
plt.scatter(A[:,0], A[:,1], marker = 'o', s = 100, color = 'black')

现在,我们需要构建K最近邻。对象还需要训练
python
knn_model = NearestNeighbors(n_neighbors = k, algorithm = 'auto').fit(X)
distances, indices = knn_model.kneighbors([test_data])
现在,我们可以打印K个最近邻如下
python
print("\nK Nearest Neighbors:")
for rank, index in enumerate(indices[0][:k], start = 1):
print(str(rank) + " is", A[index])
我们可以可视化最近邻和测试数据点
python
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 最近邻
python
1 is [ 3.1 2.3]
2 is [ 3.9 3.5]
3 is [ 4.4 2.9]
K-最近邻分类器
K最近邻(KNN)分类器是一种使用最近邻算法来分类给定数据点的分类模型。我们在上一节实现了KNN算法,现在我们将用该算法构建一个KNN分类器。
KNN分类器的概念
K最近邻分类的基本概念是找到一个预定义的数字,即距离新样本最近的训练样本的"k"−,该样本需要分类。新样本会直接从邻居那里获得标签。KNN 分类器有一个固定的用户定义常数,用于确定需要确定的邻居数量。对于距离,标准欧几里得距离是最常见的选择。KNN 分类器直接基于已学习的样本工作,而非制定学习规则。KNN算法是所有机器学习算法中最简单的之一。它在大量分类和回归问题中取得了相当成功,例如字符识别或图像分析。
示例
我们正在构建一个KNN分类器来识别数字。为此,我们将使用MNIST数据集。我们将把这段代码写进Jupyter Notebook。
如下所示导入所需的软件包。
这里我们使用 sklearn.neighbors 包中的 KNeighborsClassifier 模块 −
python
from sklearn.datasets import *
import pandas as pd
%matplotlib inline
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
import numpy as np
以下代码将显示数字图像,以验证我们测试的图像------
python
def Image_display(i):
plt.imshow(digit['images'][i],cmap = 'Greys_r')
plt.show()
现在,我们需要加载MNIST数据集。实际上总共有1797张图像,但我们使用前1600张作为训练样本,剩余197张将保留用于测试。
python
digit = load_digits()
digit_d = pd.DataFrame(digit['data'][0:1600])
现在,在显示这些图像时,我们可以看到输出如下 −
python
Image_display(0)
Image_display(0)
0的图像显示如下 −

Image_display(9)
9的图像显示如下 −

digit.keys()
现在,我们需要创建训练和测试数据集,并向 KNN 分类器提供测试数据集。
python
train_x = digit['data'][:1600]
train_y = digit['target'][:1600]
KNN = KNeighborsClassifier(20)
KNN.fit(train_x,train_y)
以下输出将生成 K 个最近邻分类器构造器 −
python
KNeighborsClassifier(algorithm = 'auto', leaf_size = 30, metric = 'minkowski',
metric_params = None, n_jobs = 1, n_neighbors = 20, p = 2,
weights = 'uniform')
我们需要通过提供任意大于1600(即训练样本)的数字来创建测试样本。
python
test = np.array(digit['data'][1725])
test1 = test.reshape(1,-1)
Image_display(1725)
Image_display(6)
6的图像显示如下 −

现在我们将预测测试数据如下 −
python
KNN.predict(test1)
上述代码将生成以下输出−
python
array([6])
现在,考虑以下情况 −
python
digit['target_names']
上述代码将生成以下输出−
python
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])