【问题标题】:Count number of repeated elements in list considering the ones larger than them计算列表中重复元素的数量,考虑大于它们的元素
【发布时间】:2018-06-15 13:03:07
【问题描述】:

我正在尝试对数据集进行一些聚类分析。我正在使用多种不同的方法来估计集群的数量,然后我将每种方法给出的(集群的数量)放在一个列表中,如下所示:

total_pred =  [0, 0, 1, 1, 0, 1, 1]

现在我想估计真实的聚类数,所以我让上面的方法投票,例如上面,找到1个聚类的模型多于0个,所以我取1作为真实的聚类数。

我这样做:

    counts = np.bincount(np.array(total_pred))
    real_nr_of_clusters = np.argmax(counts))

但是,这种方法存在问题。如果上面的列表包含类似:

[2, 0, 1, 0, 1, 0, 1, 0, 1]

我将得到 0 个集群作为平均值,因为 0 重复的频率更高。但是,如果一个模型找到 2 个集群,则可以安全地假设它认为至少存在 1 个集群,因此实数将为 1。

如何通过修改上面的sn-p来做到这一点?

为了让问题更清楚,这里还有几个例子:

[1, 1, 1, 0, 0, 0, 3] 

应该返回 1,

[0, 0, 0, 1, 1, 3, 4]

也应该返回 1(因为他们中的大多数人都同意至少有 1 个集群)。

【问题讨论】:

  • 我迷路了:I will get 0 clusters as the average, since 0 is repeated more often. However, if one model found 2 clusters, it's safe to assume it considers at least 1 cluster is there, hence the real number would be 1.,特别是第二句话。澄清一下?
  • 我们有一篮苹果。我们带了 20 个人,让他们数苹果。有些人会说 1,有些人会说 2(数量相等),两个人说 6 和 9。说 6 和 9 的人,即使他们相距甚远,都同意那里至少有 2 个苹果(因为他们相信还有更多),所以这里的正确投票平均值是 2。
  • 您的情况存在逻辑问题。您的条件=>(有多少个集群有 x 或更多)。最后一个列表是 {0:7, 1:4, 3:2, 4:1},所以 0 个集群是最好的。这种逻辑总是产生最少数量的集群。
  • 说有 2 个苹果的人,也同意至少有一个苹果。那么,为什么输出不应该是 1? 平均是怎么进来的?
  • [0, 0, 0, 0, 0, 1, 1] 的输出是什么?

标签: python-3.x list numpy


【解决方案1】:

你的逻辑有问题

这是所描述算法的实现。

l = [2, 0, 1, 0, 1, 0, 1, 0, 1]

l = sorted(l, reverse=True)

votes = {x: i for i, x in enumerate(l, start=1)}

输出

{2: 1, 1: 5, 0: 9}

请注意,既然您将投票定义为同意任何小于自身的事物,那么min(l)总是获胜,因为每个人都会同意至少有 min(l) 集群。在这种情况下min(l) == 0

如何解决

平均值和中位数

在此之前,请注意,取平均值或中位数是有效且轻量级的选项,它们都可以满足示例的期望输出。

偏差

虽然,如果您遇到诸如[0, 0, 7, 8, 10] 这样的答案不太可能是5 的高方差投票,那么取平均值可能不是您想要的。

解决此问题的更通用方法是包含选民对接近他们的选票的偏见。当然,2 票赞成的人会更多地同意1 而不是0

您可以通过实施一个指标(注意:这不是数学意义上的指标)来确定投票给x 的实例在多大程度上愿意同意投票给y,规模为01

请注意,这种方法将允许选民就不在名单上的数字达成一致。

我们需要更新我们的代码以考虑应用该伪度量。

def d(x, y):
    return x <= y

l = [2, 0, 1, 0, 1, 0, 1, 0, 1]

votes = {y: sum(d(x, y) for x in l) for y in range(min(l), max(l) + 1)}

输出

{0: 9, 1: 5, 2: 1}

上述指标是一个健全性检查。这是您在问题中提供的那个,它确实最终确定0 获胜。

指标选择

您将不得不稍微调整一下您的指标,但这里有一些可能有意义。

线性距离的倒数

def d(x, y):
    return 1 / (1 + abs(x - y))

l = [2, 0, 1, 0, 1, 0, 1, 0, 1]

votes = {y: sum(d(x, y) for x in l) for y in range(min(l), max(l) + 1)}
# {0: 6.33, 1: 6.5, 2: 4.33}

距离的n次次方的倒数

这是对前一个的概括。随着n 的增长,选民对远程投票的认同度越来越低。

def d(x, y, n=1):
    return 1 / (1 + abs(x - y)) ** n

l = [2, 0, 1, 0, 1, 0, 1, 0, 1]

votes = {y: sum(d(x, y, n=2) for x in l) for y in range(min(l), max(l) + 1)}
# {0: 5.11, 1: 5.25, 2: 2.44}

上界距离

与上一个指标类似,这个指标与您最初描述的指标接近,因为选民永远不会同意高于他们的投票。

def d(x, y, n=1):
    return 1 / (1 + abs(x - y)) ** n if x >= y else 0

l = [2, 0, 1, 0, 1, 0, 1, 0, 1]

votes = {y: sum(d(x, y, n=2) for x in l) for y in range(min(l), max(l) + 1)}
# {0: 5.11, 1: 4.25, 2: 1.0}

正态分布

另一个有意义的选项是normal distributionskewed normal distribution

【讨论】:

  • 这是一个内容丰富且完整的答案。非常感谢,现在我明白为什么我的建议有逻辑错误了。
【解决方案2】:

虽然另一个答案提供了对可能指标和方法的全面审查,但您似乎正在寻求的是找到最接近的集群数量! 所以很简单:

cluster_num=int(np.round(np.mean(total_pred)))

如您所料,它会为您的所有案例返回 1。

【讨论】:

    猜你喜欢
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2021-05-21
    • 2022-01-15
    • 2021-03-09
    • 2011-05-07
    • 2023-03-11
    相关资源
    最近更新 更多