2016-11-06 195 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

不好意思,我的錯誤,我誤解了你的代碼,我想它應該可以正常工作 –

相關問題