Python 有没有一个好的方法来进行这种类型的开采?

Python 有没有一个好的方法来进行这种类型的开采?,python,algorithm,data-mining,Python,Algorithm,Data Mining,我试图找到在X和Y方向上空间最接近的点(最后给出的样本数据集),并查看是否有比我的普通(未经测试)方法更聪明的方法来实现这一点。这些点在空间中的绘图如下所示,我正在尝试查找框内标记的点集,即我要查找的输出是一组组: Group 1: (1,23), (2,23), (3,23)... Group 2: (68,200), (68,201), (68,203), (68,204), (68,100), (68,101), (68,101)... 对于水平带,我想我可以继续使用大小为5或10的小

我试图找到在X和Y方向上空间最接近的点(最后给出的样本数据集),并查看是否有比我的普通(未经测试)方法更聪明的方法来实现这一点。这些点在空间中的绘图如下所示,我正在尝试查找框内标记的点集,即我要查找的输出是一组组:

Group 1: (1,23), (2,23), (3,23)...
Group 2: (68,200), (68,201), (68,203), (68,204), (68,100), (68,101), (68,101)...

对于水平带,我想我可以继续使用大小为5或10的小型滑动窗口(这应该根据全球信息确定,哪种大小将给出最大分组点,但我仍在探索一种好方法)搜索连续的点,因为一个中断将不再被视为水平带

我猜同样的方法也适用于垂直带,但并非在所有情况下都适用,因为水平带和垂直带之间存在细微差异:点在水平方向上应该看起来很接近,以被视为一组,但它们可以出现在任何地方,以被视为垂直带的一部分。观察图中的大垂直带。因此我猜我可以只寻找具有相同x坐标的点(在本例中,x=68)应该给我很多点

除了这个琐碎的解决方案,我想不出什么聪明的方法可以在这里做,因为这个问题对我来说似乎很简单。我是不是遗漏了什么?这是否属于某类已知的问题?如果是,是否有一种好的、可扩展的方法来实现这一点

样本数据集:

1,23
1,23
2,23
3,23
4,23
5,23
6,23
7,23
8,23
9,23
10,23
11,23
12,23
13,23
14,23
15,23
16,23
10,33
11,33
12,33
13,33
14,33
15,33
16,33
17,33
18,33
19,33
2,28
2,28
3,28
34,75
34,76
34,76
34,77
34,78
34,79
34,80
34,81
34,82
34,83
34,75
34,76
34,76
34,77
34,78
34,79
34,80
34,81
400,28
400,28
400,28
68,200
68,201
68,203
68,204
68,100
68,101
68,103
68,104
你可以尝试使用。它包含K-means聚类算法的实现。您可以调整
getclusters
函数的参数来更改所需的集群数量

s = '''
1,23
1,23
2,23
...
68,101
68,103
68,104
'''

from cluster import *

ll = [tuple(map(int,each.split(','))) for each in s.split()]

#horizontal 
cl = HierarchicalClustering(ll, lambda x,y: abs(x[0]-y[0]))

for c in cl.getlevel(1):
    print c

#vertical
cl = HierarchicalClustering(ll, lambda x,y: abs(x[1]-y[1]))

for c in cl.getlevel(1):
    print c

现在有点晚了,但这个问题已经困扰我一段时间了。我 我确信它可以用混合整数/线性规划技术解决 并在这个问题上寻求帮助:

然而,在得到回复后,我发现你的问题 至少据我所知,它是如此简单(当作为约束程序框架时) 你可以用一个简单的程序(你已经有了 知道)。换句话说,约束编程将是解决问题的一种很酷的方法 这个,但是,至少用我发现的方法,会给你同样的答案 简单得多

我将在下面解释我的推理,我将如何用约束实现它 求解包,然后给出最终的、平凡的算法

混合整数规划解 最重要的细节是水平和垂直的区别 组。就我所见,任何垂直对齐的东西都可以在 同一组。但水平组是不同的-组件必须接近 一起

解决约束问题最困难的部分似乎是找到一个 以解算器能够理解的方式描述限制的方式。我不会的 在这里详细介绍一下,但令人沮丧的是,解决方案有限。幸运的是我 认为这里有一个方法可以做到这一点,那就是考虑水平。 邻居:如果一行中有N个点,那么我们有
N-1
组 相邻点(例如,有4个点A、B、C和D,有三对 AB、BC和CD)

对于每一对,我们可以给出一个分数,即它们之间的空格数 (
S_i
)由某个系数
K
和一个0或1的标志(
F_i
)缩放。如果 对在同一水平组中,然后我们将标志设置为1,否则 是零

重要的是要确保所有对的标志集都是完整的 定义解决方案。我们可以跑过任何一行,在每一行都放上一个旗子 在同一水平组中设置1,并分别启动一个新的水平组 时间标志为0。然后,我们可以取大小为1和的所有水平组 将其转换为垂直组:不在水平组中的任何点 必须在垂直组中(即使它只是一个垂直组)

所以我们现在需要的是一种表达最优解的方法 旗帜。我建议我们尽量减少:

sum(1 - F_i) + sum(K * S_i * F_i)
这有两个术语。第一个是每一个的“一减国旗”之和 一对当点位于同一水平组中时,标志为1,且为0 否则。所以最小化这个值等于说我们想要 尽可能少的横向分组。如果这是唯一的限制,那么我们 可以通过将所有
F_i
1设置为零-将所有对设置为一行 同一组的成员

但第二个条件阻止我们选择这样一个极端的解决方案。信息技术 惩罚有差距的群体。如果一对在同一组中,但是 由
S_i
空格分隔,那么我们有一个
K*S_i
的“惩罚”

所以我们有一个折衷方案。我们需要横向分组,但不需要间隙。 最终的解决方案将取决于
K
——如果它很大,我们将不包括 水平组中的任何空格。但当它减少时,我们将开始这样做 所以,直到它非常小(趋于零)时,我们将所有的东西都排成一行 在一个小组里

要使用它,您可以选择一些
K
,计算
S_i
,然后将上面的表达式输入到约束系统中。然后系统将选择
F_i
以最小化表达式。最后,您可以通过如上所述扫描每一行,然后垂直分组单例,将
fi
转换为组模式

解析解 好的,酷。在这一点上,我们有一种方式来表达我们可以给出的问题 到约束引擎

但这是一个微不足道的问题!我们不需要约束引擎 解决这个问题-我们可以看看表达式:

sum(1 - F_i) + sum(K * S_i * F_i)
这两个和在同一对上,所以我们可以把所有的东西都放到和中:

sum(1 - F_i + K * S_i * F_i)
sum(1 + F_i * (K * S_i - 1))
然后提取常数
N + sum(F_i * (K * S_i - 1))
choose some cut-off value, X
place each point in its own, singleton, horizontal group
for each row with more than one point:
    for each neighbouring pair in the row:
        if the space between the pair is less than X:
            join into a single horizontal group
for each column:
    join any remaining singleton groups into a single vertical group