使用 sklearn 和 Spark 计算不同轮廓分数

当我使用 Spark 和 sklearn 对相同的数据和相同的预测值计算轮廓分数时,我得到了不同的结果。

以下是使用 Spark 的代码:

>>> prediction.show()+---+---+---------+----------+|  a|  b| features|prediction|+---+---+---------+----------+|  1|  1|[1.0,1.0]|         1||  2|  2|[2.0,2.0]|         1||  3|  3|[3.0,3.0]|         0||  4|  4|[4.0,4.0]|         0|+---+---+---------+----------+>>> from pyspark.ml.evaluation import ClusteringEvaluator>>> evaluator = ClusteringEvaluator()>>> silhouette = evaluator.evaluate(prediction)>>> silhouette0.7230769230769223

以下是使用 sklearn 的代码:

>>> from sklearn.cluster import KMeans>>> from sklearn import metrics>>> x=[[1,1],[2,2],[3,3],[4,4]]>>> prediction = KMeans(n_clusters=2,max_iter=1000,random_state=123).fit_predict(x)>>> predictionarray([1, 1, 0, 0], dtype=int32)>>> silhouette = metrics.silhouette_score(x, prediction)>>> silhouette0.46666666666666673

如上所示,尽管输入相同,分数却大不相同。这是为什么呢?


回答:

主要区别在于使用了不同的距离度量

Spark 使用平方欧几里得距离作为距离度量,而 sklearn 默认使用普通欧几里得距离。

Spark 选择这种距离度量的原因是为了实现更高效和并行计算。方程的一部分可以预先计算,将计算复杂度从 O(N^2^*D) 降低到 O(C*D*N/W),其中 N 是点的数量,D 是它们的维度,W 是工作者的数量,C 是集群的数量(假设相当低)。Spark 关于轮廓分数的数学推导和实现已在 github 上记录(此处)。


证明:

我们可以分析问题中的例子,并使用欧几里得距离和平方欧几里得距离手动计算轮廓分数。

我们有第一个集群,点为 (1,1)(2,2),集群中心位于 (1.5,1.5),第二个集群点为 (3,3)(4,4),集群中心位于 (3.5,3.5)

最终的轮廓分数是所有样本轮廓分数的平均值。由于问题中的四个点完全对称并且只有两个集群,计算其中一个集群的分数就足够了(这里我选择了第一个集群)。

下面 a 是集群内平均距离(与同一集群中所有点的平均距离),b 是集群间平均距离(与点不属于的最接近集群中所有点的平均距离)。分数计算公式为 (b-a) / max(b,a)

欧几里得距离:

  • (1,1):

    • a = sqrt((2-1)^2 + (2-1)^2) = sqrt(2)
    • b = (sqrt((3-1)^2 + (3-1)^2) + sqrt((4-1)^2 + (4-1)^2))) / 2 = (sqrt(8) + sqrt(18)) / 2 = 3.5355
    • 点分数 = (3.5355 – sqrt(2)) / 3.5355 = 0.6
  • (2,2):

    • a = sqrt((2-1)^2 + (2-1)^2) = sqrt(2)
    • b = (sqrt((3-2)^2 + (3-2)^2) + sqrt((4-2)^2 + (4-2)^2))) / 2 = (sqrt(2) + sqrt(8)) / 2 = 2.1213
    • 点分数 = (2.1213 – sqrt(2)) / 2.1213 = 0.33333

轮廓分数 = (0.6 + 0.33333) / 2 = 0.4666667

平方欧几里得距离:

  • (1,1):

    • a = (2-1)^2 + (2-1)^2 = 2
    • b = ((3-1)^2 + (3-1)^2 + (4-1)^2 + (4-1)^2) / 2 = (8 + 18) / 2 = 13
    • 点分数 = (13 – 2) / 13 = 0.84615
  • (2,2):

    • a = (2-1)^2 + (2-1)^2 = 2
    • b = ((3-2)^2 + (3-2)^2 + (4-2)^2 + (4-2)^2) / 2 = (2 + 8) / 2 = 5
    • 点分数 = (5 – 2) / 5 = 0.6

轮廓分数 = (0.84615 + 0.6) / 2 = 0.723075

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注