根据共性对字符串数组进行分类

时间:2009-11-12 04:22:55

标签: python string algorithm classification

我有大量的字符串列表(200000)(多字)。我想根据这些字符串中的字匹配的comman数组对这些字符串进行分组。我不能想到这个

的低计算时间算法

AB 500
  “巴士 AB 500
  “新闻CA
  “新闻CA BLAH”

我的计划是 一个。将它们标记为单词。
湾创建全局数组令牌
C。将这些字符串与常用标记进行比较。

正如你猜测的那样没有用。你能建议一个算法吗? 我在python中写这个..

4 个答案:

答案 0 :(得分:2)

200000并不是那么多,你可以这样做

  1. 拆分每个字符串以获取令牌 例如“新闻CA BLAH” - > [“Blah”,“CA”,“新闻”]
  2. 创建每个列表长度的dict条目,例如如果[“Blah”,“CA”,“新闻”]按顺序排列所有组合
  3. 现在只需循环通过dict并查看组
  4. 示例代码:

    data="""AB 500
    Bus AB 500
    News CA
    News CA BLAH"""
    
    def getCombinations(tokens):
        count = len(tokens)
        for L in range(1,count+1):
            for i in range(count-L+1):
                yield tuple(tokens[i:i+L])
    
    groupDict = {}
    for s in data.split("\n"):
        tokens = s.split()
        for groupKey in getCombinations(tokens):
            if groupKey not in groupDict:
                groupDict[groupKey] = [s]
            else:
                groupDict[groupKey].append(s)
    
    for group, values in groupDict.iteritems():
        if len(values) > 1:
            print group, "->", values
    

    输出:

    ('News', 'CA') -> ['News CA', 'News CA BLAH']
    ('AB',) -> ['AB 500', 'Bus AB 500']
    ('500',) -> ['AB 500', 'Bus AB 500']
    ('CA',) -> ['News CA', 'News CA BLAH']
    ('AB', '500') -> ['AB 500', 'Bus AB 500']
    ('News',) -> ['News CA', 'News CA BLAH']
    

答案 1 :(得分:1)

你的意思是这样吗?

>>> from collections import defaultdict
>>> L=["AB 500",
... "Bus AB 500",
... "News CA",
... "News CA BLAH"]
>>> d=defaultdict(list)
>>> for s in L:
...     for w in s.split():
...         d[w].append(s)
... 
>>> print d["News"]
['News CA', 'News CA BLAH']
>>> print d["CA"]
['News CA', 'News CA BLAH']
>>> print d["500"]
['AB 500', 'Bus AB 500']

答案 2 :(得分:1)

除非重复单词是您用例的重要功能,否则我建议使用集合。即:

thestrings = [
"AB 500",
"Bus AB 500",
"News CA",
"News CA BLAH",
]

thesets = dict((s, set(s.split())) for s in thestrings)

similarities = dict()
for s in thestrings:
  for o in thestrings:
    if s>=o: continue
    sims = len(thesets[s] & thesets[o])
    if not sims: continue
    similarities[s, o] = sims

for s, o in sorted(similarities, similarities.get, reverse=True):
  print "%-16r %-16r %2d" % (s, o, similarities[s, o])

这接近你想要的吗?它确实按照你想要的方式对你给出的4个字符串进行分类,但这当然是一个非常微弱的样本,所以我要仔细检查; - )。

答案 3 :(得分:0)

如果字符串“AB 500 News CA”已添加到您的列表中,会发生什么?这两组字符串是否必须合并?如果没有,如何拆分字符串列表以及为什么?

这类问题的非常一般的工作流程(如果我理解正确的话)是这样的:

  1. 通过反向索引/ All pairs similarity search / Simhashing
  2. 获取候选对列表
  3. 为每对计算一些距离函数并将它们组合成单个权重
  4. 每个加权对((a,b),权重)现在表示图形中的边缘,您可以通过层次聚类/幂迭代将其聚类到“字匹配组”