【问题标题】:how to generate a set of similar strings in python如何在python中生成一组相似的字符串
【发布时间】:2017-03-14 12:29:28
【问题描述】:

我想知道如何根据Levenshtein distance(字符串编辑距离)生成一组相似的字符串。理想情况下,我喜欢传入一个源字符串(即用于生成与其相似的其他字符串的字符串)、需要生成的字符串数量和一个阈值作为参数,即在生成的集合应该大于阈值。我想知道我应该使用什么Python 包来实现这一目标?或者知道如何实现这一点?

【问题讨论】:

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


【解决方案1】:

我认为你可以用另一种方式思考这个问题(反过来)。

  • 给定一个字符串,说它是sittin
  • 给定一个阈值(编辑距离),说它是k
  • 然后在 k 步中应用不同“编辑”的组合。

例如,假设 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_

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

【讨论】:

    【解决方案2】:

    大量借用 @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']
    

    【讨论】:

      猜你喜欢
      • 2018-06-15
      • 2016-07-15
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      • 2014-11-19
      • 2013-10-07
      • 1970-01-01
      相关资源
      最近更新 更多