如何在python中生成一组类似的字符串

时间:2016-11-01 11:08:02

标签: python string python-3.x machine-learning string-matching

我想知道如何基于Levenshtein distance生成一组类似的字符串(字符串编辑距离)。理想情况下,我喜欢传入一个源字符串(即用于生成与其类似的其他字符串的字符串),需要生成的字符串数量和作为参数的阈值,即字符串之间的相似性。生成的集应该大于阈值。我想知道我应该用Python个包来实现这个目标吗?或者任何想法如何实现这个?

2 个答案:

答案 0 :(得分:1)

我认为你可以用另一种方式来思考问题(逆转)。

  • 给出一个字符串,说它是 sittin
  • 给定阈值(编辑距离),说它是k
  • 然后您应用不同的编辑组合"在k-steps。

例如,让我们说k = 2.并假设您拥有的edit modes是:

  • 删除一个字符
  • 添加一个字符
  • 用另一个字符替换另一个字符。

然后逻辑如下:

input = 'sittin'
for num in 1 ... n:  # suppose you want to have n strings generated
  my_input_ = input
  # suppose the edit distance should be smaller or equal to k;
  # but greater or equal to one
  for i in in 1 ... randint(k): 
    pick a random edit mode from (delete, add, substitute)
    do it! and update my_input_

如果您需要坚持使用预定义的字典,这会增加一些复杂性,但仍然可行。在这种情况下,编辑必须有效。

答案 1 :(得分:0)

大量借用@greeness answer中的伪代码,我想我会包括我以前对DNA序列使用的代码。
这可能不是您的确切用例,但我认为它应该很容易适应。

import random
dna = set(["A", "C", "G", "T"])

class Sequence(str):

    def mutate(self, d, n):
        mutants = set([self])
        while len(mutants) < n:
            k = random.randint(1, d)
            for _ in range(k):
                mutant_type = random.choice(["d", "s", "i"])
                if mutant_type == "i":
                    mutants.add(self.insertion(k))
                elif mutant_type == "d":
                    mutants.add(self.deletion(k))
                elif mutant_type == "s":
                    mutants.add(self.substitute(k))
        return list(mutants)


    def deletion(self, n):
        if n >= len(self):
            return ""
        chars = list(self)
        i = 0
        while i < n:
            idx = random.choice(range(len(chars)))
            del chars[idx]
            i += 1
        return "".join(chars)

    def insertion(self, n):
        chars = list(self)
        i = 0
        while i < n:
            idx = random.choice(range(len(chars)))
            new_base = random.choice(list(dna))
            chars.insert(idx, new_base)
            i += 1
        return "".join(chars)

    def substitute(self, n):
        idxs = random.sample(range(len(self)), n)
        chars = list(self)
        for i in idxs:
            new_base = random.choice(list(dna.difference(chars[i])))
            chars[i] = new_base
        return "".join(chars)

要使用此功能,您可以执行以下操作

s = Sequence("AAAAA")
d = 2  # max edit distance
n = 5  # number of strings in result
s.mutate(d, n)
>>> ['AAA', 'GACAAAA', 'AAAAA', 'CAGAA', 'AACAAAA']