2016-11-06 153 views
0

我已经编写了一个脚本,它基本上将句子中的所有字符串拆分为多个部分;例如为每个字符串添加特定字符python中的字符串列表

;

"geldigim" -> "gel" "di" "g" "i" "m" 

虽然有些字符串可能会像上面那样拆分,但其中的一些可能会拆分为以下;

"bildi" > "bil" "di" 

或者某些句子根本不能被分割。

"kos" -> "kos" 

它完全取决于将字符串拆分为多个部分的函数。

我想要做的是以下几点:

geldigim -> /gel* *di* *g* *i* *m/ 
bildi -> /bil* *di/ 
kos -> /kos/ 

我做什么;

我有一个有37251512句子的语料库。我写了下面的脚本;

if __name__ == "__main__": 
     io = morfessor.MorfessorIO() 
     print "Importing corpus ..." 
     f = codecs.open("corpus/corpus_tr_en/corpus.tr", encoding="utf-8").readlines() 
     print "Importing morphology model ..." 
     model = io.read_binary_model_file('seg/tr/model.bin') 
     corpus = open('dataset/dataset_tr_en/full_segmented.tr', 'w') 
     for a in range(len(f)): 
       print str(a) + ' : ' + str(len(f)) 
       words = f[a].replace('\n', '').split() 
       line_str = '' 
       for word in words: 
         segmentation = model.viterbi_segment(word)[0] 
         if len(segmentation) == 1: 
           line_str = '/' + segmentation[0] + '/' 
         if len(segmentation) == 2: 
           line_str = '/' + segmentation[0] + '* *' + segmentation[1] + '/' 
         if len(segmentation) > 2: 
           line_str = '' 
           for b in range(len(segmentation)): 
             if (b == 0): 
               line_str = line_str + '/' + segmentation[b] + '*' 
             if (b != 0) and (b != (len(segmentation) - 1)): 
               line_str = line_str + ' *' + segmentation[b] + '* ' 
             if (b == (len(segmentation) - 1)): 
               line_str = line_str + ' *' + segmentation[b] + '/' 
         line_str = line_str + ' ' 
         corpus.write(line_str.encode('utf-8')) 
       corpus.write('\n') 

     corpus.close() 

该脚本遍历每个句子,句子中的每个单词,并与io.read_binary_model_file功能分成部分。

但它对我来说太贵了,它很慢。

你能否告诉我一种能使过程非常快速的方法?

感谢,

+1

是什么viterbi_segment()呢?你能发布这个函数的代码吗? /Teşekkür* * ler/ – Ukimiku

+0

它基本上是一个函数,它基本上适合字符串到由“Morfessor”创建的机器学习模型中。 – yusuf

+0

我在问,因为如果你给我们看代码,也许有办法加快它。 – Ukimiku

回答

2
  • 让·弗朗索瓦·法布尔覆盖string optimization真的很好。
  • 另一头大象是使用readlines()作为37,251512句子。只需使用for a in f,详细解释请参见here
  • 根据您的数据中有多少重复项以及model.viterbi_segment函数的性能,使用单词的set而不是重复单词的全部内容可能会有所帮助。
  • 看来你正在使用python 2#,在这种情况下使用的,而不是xrangerange
  • .replace('\n', '').split()是缓慢的,因为它必须遍历时,你只是要删除的最后一行突破整条线路(可以有在你的情况下不会超过一个)。你可以使用rstrip('\n')`
  • 你的代码有一些重复,例如每行需要以/结尾,但是你有3个地方。
  • 所有这些变化可能是微小的,但它们加起来,你的代码变得更容易阅读和
2

什么可能会减慢很多是line_str使用多个字符串连接,如果你想表现这是不推荐的组成(以及它是好的,对于像filename = base+".txt"但不能用于深加工。

创建linelist来代替,而str.join创建最终的字符串只是将其写入到磁盘中。追加到一个list快得多。

而作为马克西米利安刚才建议,你可以把你的条件变成elif,因为它们是互相排斥的(x2)。还增加了一些更多的微型优化,以提高可读性。

我的你的内循环应该怎么样子的建议:

for word in words: 
     segmentation = model.viterbi_segment(word)[0] 
     lenseg = len(segmentation) 
     if lenseg == 1: 
       line = ['/',segmentation[0],'/'] 
     elif lenseg == 2: 
       line = ['/',segmentation[0],'* *',segmentation[1],'/'] 
     elif lenseg > 2: 
       line = [] 
       for b in range(lenseg): 
         if b == 0: 
           line += ['/',segmentation[0],'*'] 
         elif b != (lenseg - 1): 
           line += [' *',segmentation[b],'* '] 
         else: 
           line+= [' *',segmentation[b],'/'] 
     line.append(" ") 
     corpus.write("".join(line).encode('utf-8')) 

替代方案:

  • 写入每个字符串输出文件每次
  • 写数据到io.StringIO对象和检索写入输出文件。
+1

使用elif而不是多余ifs可能会加速整个事情多一点。 –

+1

对!我非常专注于那些我没有看到的字符串。有意义,虽然它可能是一个微型优化相比字符串问题。也许问题在于维特比功能,但我们没有它。无论如何,如果单词的数量很大,那么列表技巧会加快程序的速度_a lot_(如果我们已经在讨论微观优化,则len(分段)被计算出来3(如果我们已经在讨论微观优化问题,我自己已经有了大文本文件) –

+1

次,把它放在一个变量中(对于len(f)是相同的),第二个if块也可以使用一些elifs,第一个中的分段[b]如果可以写成分段[0]。 –

1

如何内环是这样的:

line = '* *'.join(segmentation) 
corpus.write(("/%s/ " % line).encode('utf-8')) 

的话,因为你可以在同一时间保持输入在内存中,我也尽量保持在内存中的输出,并把它写出一气呵成,也许是这样的:

lines = [] 
for a in range(len(f)): 
    print str(a) + ' : ' + str(len(f)) 
    words = f[a].replace('\n', '').split() 
    for word in words: 
     line = '* *'.join(segmentation) 
     lines.append("/%s/ " % line) 
corpus.write("\n".join(lines).encode('utf-8') 
+1

这会给出相当不同的输出结果,例如,缺少\和额外的空间。 –

+1

如何?不会'/%s /'%line'覆盖那个吗? – Vidar

+1

不好意思,我的错误,我误解了你的代码,我想它应该可以正常工作 –

相关问题