“预测”一词不属于任何特定类型的机器学习。将新数据“预测”到它所属的集群并没有错;(例如,有许多应用程序将新客户置于预先发现的细分市场中)。与分类中使用的条件概率一样,条件概率并不比无监督方法“强”,因为它的假设建立在正确标记的类别上;不能保证的东西。
这就是为什么有包为聚类算法提供预测功能的原因。这是一个使用带有 kcaa 函数的 flexclust 包的示例。话虽如此,预测步骤通常由有监督的分类器处理,因此方法是将分类器放在学习的集群之上(将集群分配视为“标签”)。
你只需要推理你的弱点。如上所述,分类的弱点是假设标记的数据被正确标记,而聚类的弱点是假设您发现的集群是有效的。无监督方法无法像分类一样进行验证。集群需要各种集群有效性技术以及领域经验(例如,向活动经理展示您的市场细分以验证客户类型)。
最终,您只是将传入向量(新数据)与最相似的集群进行匹配。例如,在 k-means 中,这可以通过找到传入向量和所有簇的质心之间的最小距离来完成。这种模式匹配取决于您使用的数据。
这最适用于具有明确定义的集群对象的集群技术,其中示例位于中心,如 k-means。使用分层技术意味着您需要切割树以获得平坦的集群,然后使用“标签”分配在顶部运行分类器。这伴随着很多假设,因此您需要确保您非常了解您的数据,并使用具有深厚领域经验的非技术用户验证任何集群。
可能的方法 如果您一心想要使用层次聚类,那么这里是一般方法。注意我并不是说这是最好的方法。每种方法都带有许多假设。您将需要努力了解您的数据、尝试许多模型、与利益相关者进行验证等。
如果需要,读者可以使用 Jörn Hees 的教程开始层次聚类:
创建一些示例数据:
from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
import numpy as np
np.random.seed(42)
a = np.random.multivariate_normal([10, 0], [[3, 1], [1, 4]], size=[100,])
b = np.random.multivariate_normal([0, 20], [[3, 1], [1, 4]], size=[50,])
X = np.concatenate((a, b),)
确认合成数据中存在集群:
plt.scatter(X[:,0], X[:,1])
plt.show()

使用 Ward 方差最小化算法生成链接矩阵:(这假设您的数据应该被聚类以最小化欧几里得空间中的整体聚类内方差。如果不是,请尝试曼哈顿、余弦或汉明。您还可以尝试不同的链接选项) .
Z = linkage(X, 'ward')
检查 Cophenetic Correlation Coefficient 以评估集群的质量:
from scipy.cluster.hierarchy import cophenet
from scipy.spatial.distance import pdist
c, coph_dists = cophenet(Z, pdist(X))
0.98001483875742679
计算完整的树状图:
plt.figure(figsize=(25, 10))
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('sample index')
plt.ylabel('distance')
dendrogram(
Z,
leaf_rotation=90., # rotates the x axis labels
leaf_font_size=8., # font size for the x axis labels
)
plt.show()

确定集群的数量(例如,可以通过在树状图中查找任何大的跳跃来手动完成......请参阅 Jörn 的博客以了解绘图功能):

检索集群:(使用我们从阅读树状图确定的最大距离)
from scipy.cluster.hierarchy import fcluster
max_d = 50
clusters = fcluster(Z, max_d, criterion='distance')
将集群分配映射回原始帧:
import pandas as pd
def add_clusters_to_frame(or_data, clusters):
or_frame = pd.DataFrame(data=or_data)
or_frame_labelled = pd.concat([or_frame, pd.DataFrame(clusters)], axis=1)
return(or_frame_labelled)
df = add_clusters_to_frame(X, clusters)
df.columns = ['A', 'B', 'cluster']
df.head()

使用此“标记”数据构建分类器:
在这里,我将只使用原始数据和分配的集群以及一个 knn 分类器:
np.random.seed(42)
indices = np.random.permutation(len(X))
X_train = X[indices[:-10]]
y_train = clusters[indices[:-10]]
X_test = X[indices[-10:]]
y_test = clusters[indices[-10:]]
# Create and fit a nearest-neighbor classifier
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train, y_train)
res = knn.predict(X_test)
print(res)
print(y_test)
预测标签:[2 2 1 1 2 2 1 2 2 1]
测试标签:[2 2 1 1 2 2 1 2 2 1]
与任何分类器一样,您的传入数据需要与您的训练数据具有相同的表示形式。当新数据到达时,您可以根据分类器提供的预测函数运行它(这里我们使用 sci-kit learn 的 knn.predict)。这有效地将新数据分配给它所属的集群。
在机器学习工作流程的模型监控步骤中需要进行持续的集群验证。新数据可以改变您的方法的分布和结果。但是,这并不是无监督所独有的,因为所有机器学习方法都会受到这种影响(所有模型最终都会过时)。正如 Jörn 在上述参考文献中所言,手动检查通常胜过自动化方法,因此建议对扁平集群进行定期目视/手动检查。