制作带有句子嵌入的平行书籍

平行卡车(图片来自Unsplash



在寻找满足您需求的并行语料库时(无论是训练机器翻译模型还是学习外语),您可能会遇到这样一个事实,即其中没有那么多,特别是如果我们谈论的不是英语,而是一些稀有语言。在本文中,我们将尝试根据雷马克(Remarque)的小说“三个同志”为流行的俄德语言对创建自己的语料库致力于并行阅读书籍的爱好者和机器翻译系统的开发人员。



任务



此任务称为文本对齐,可以通过以下方式在某种程度上解决:



  • 使用启发式。您可以计算文本中句子的数量,文本中单词的数量,并以此为基础进行比较。此方法不能提供良好的质量,但也很有用。
  • sentence embeddings. word2vec sent2vec — "" + """" = "". , , (, ) . .




, , Universal Sentence Encoder, Sentence Transformers LaBSE (Language Agnostic BERT Sentence Embeddings).



, , , . . , — , , . .



, , , , , , , , — "I love cats" " ". , , 1. USE, - , xlm-r-100langs-bert-base LaBSE.



1. Multilingual sentence embedding models



embedding'
sentence transformers/distiluse-base-multilingual-cased 13 (, , , , , , , , , , , ) 500Mb 512
Universal Sentence Encoder 15 ( ) 250Mb (300Mb large version) 512
sentence transfomers/xlm-r-100langs-bert-base 100 *, 1Gb 768
LaBSE 109 , 1.63Gb 768


* sentence transformers , .





- , Colab', jupyter . .



. .



!pip3 install razdel
!pip3 install sentence-transformers


import re
import seaborn as sns
import numpy as np

from scipy import spatial
from matplotlib import pyplot as plt

import razdel
from sentence_transformers import SentenceTransformer




, " " (1936 ) .

. (1959 ). . , . razdel' ( natasha), , ( — »«).



double_dash = re.compile(r'[--]+')
quotes_de = re.compile(r'[»«]+')

ru = re.sub('\n', ' ', text_ru)
ru = re.sub(double_dash, '—', ru)

de = re.sub('\n', ' ', text_de)
de = re.sub(quotes_de, ' ', de)

sent_ru = list(x.text for x in razdel.sentenize(ru))
sent_de = list(x.text for x in razdel.sentenize(de))


:



['   ,  ;      .',
 '      .',
 '—     .',
 '    —     .',
 '        .',
 '          .',
 '        .',
 '        ,  — ,        .',
 '    .',
 '                 .']


:



['Der Himmel war gelb wie Messing und noch nicht verqualmt vom Rauch der Schornsteine.',
 'Hinter den Dächern der Fabrik leuchtete er sehr stark.',
 'Die Sonne mußte gleich aufgehen.',
 'Ich sah nach der Uhr.',
 'Es war noch vor acht.',
 'Eine Viertelstunde zu früh.',
 'Ich schloß das Tor auf und machte die Benzinpumpe fertig.',
 'Um diese Zeit kamen immer schon ein paar Wagen vorbei, die tanken wollten.',
 'Plötzlich hörte ich hinter mir ein heiseres Krächzen, das klang, als ob unter der Erde ein rostiges Gewinde hochgedreht würde.',
 'Ich blieb stehen und lauschte.']


570 561- . , .





, , . , .



def get_batch(iter1, iter2, batch_size):
    l1 = len(iter1)
    l2 = len(iter2)
    k = int(round(batch_size * l2/l1))    
    kdx = 0 - k
    for ndx in range(0, l1, batch_size):
        kdx += k
        yield iter1[ndx:min(ndx + n, l1)], iter2[kdx:min(kdx + k, l2)]




sentence-transformers (distiluse-base-multilingual-cased), , (~500 Mb), .



model_st = SentenceTransformer('distiluse-base-multilingual-cased')


vectors1, vectors2 = [], []

for lines_ru_batch, lines_de_batch in get_batch(sent_ru, sent_de, batch_size):
    batch_number += 1
    vectors1 = [*vectors1, *model_st.encode(lines_de_batch)]
    vectors2 = [*vectors2, *model_st.encode(lines_ru_batch)]


512.



[array([-0.03442561,  0.02094117, ... ,  0.11265451])], dtype=float32)]




. , , — - " ". .



def get_sim_matrix(vec1, vec2, window=10):
    sim_matrix=np.zeros((len(vec1), len(vec2)))
    k = len(vec1)/len(vec2)
    for i in range(len(vec1)):
        for j in range(len(vec2)):
            if (j*k > i-window) & (j*k < i+window):
              sim = 1 - spatial.distance.cosine(vec1[i], vec2[j])
              sim_matrix[i,j] = sim
    return sim_matrix


sim_matrix = get_sim_matrix(vectors1, vectors2, window)




50 . heatmap, seaborn.



plt.figure(figsize=(12,10))
sns.heatmap(sim_matrix, cmap="Greens", vmin=threshold)
plt.xlabel("russian", fontsize=18)
plt.ylabel("chinese", fontsize=18)
plt.show()


对齐前50行



. .



对齐前50行(最适合)



.



对齐全文





, , :



  • . , , , — , , common crawling' , .
  • . , (, , , nich nicht).
  • . , — . .
  • . , , , , , . "" . , .
  • . "". , - . , ( ) . ..




, , , . , — , , , , . , .



   ,  ;      .
Der Himmel war gelb wie Messing und noch nicht verqualmt vom Rauch der Schornsteine.

>> similarity 0.8614717125892639 

      .
Hinter den Dächern der Fabrik leuchtete er sehr stark.

>> similarity 0.6654264330863953 

—     .
Die Sonne mußte gleich aufgehen.

>> similarity 0.7304455041885376 

    —     .
Ich sah nach der Uhr.

>> similarity 0.5894380807876587 

    —     .
Es war noch vor acht.

>> similarity 0.5892142057418823 

        .
Eine Viertelstunde zu früh.

>> similarity 0.6182181239128113 

          .
Ich schloß das Tor auf und machte die Benzinpumpe fertig.

>> similarity 0.7467120289802551 

        .
Um diese Zeit kamen immer schon ein paar Wagen vorbei, die tanken wollten.

>> similarity 0.5018423199653625 

        ,  — ,        .
Plötzlich hörte ich hinter mir ein heiseres Krächzen, das klang, als ob unter der Erde ein rostiges Gewinde hochgedreht würde.

>> similarity 0.6064425110816956 

    .
Ich blieb stehen und lauschte.

>> similarity 0.7030230760574341 

                 .
Dann ging ich über den Hof zurück zur Werkstatt und machte vorsichtig die Tür auf.

>> similarity 0.7700499296188354 

  , ,    .
In dem halbdunklen Raum taumelte ein Gespenst umher.

>> similarity 0.7868185639381409 




, , . ? ? !



[1] Google Colab.



[2] Sentence Transformers.



[3] Universal Sentence Encoder.



[4]语言不可知BERT句子编码器




All Articles