2015-05-12 24 views
13

Python'da paralel metinler arasında sözcük hizalamaları oluşturmak için NLTK's alignment module kullanıyorum. Bifekslerin hizalanması özellikle hatırı sayılır bir korpora göre yapıldığında zaman alıcı bir süreç olabilir. Bir günde toplu olarak hizalamalar yapmak ve bu hizalamaları daha sonra kullanmak güzel olurdu. Bir model oluşturmak kezPython NLTK hizalama modelleri daha sonra kullanmak üzere nasıl kaydedilir?

from nltk import IBMModel1 as ibm 
biverses = [list of AlignedSent objects] 
model = ibm(biverses, 20) 

with open(path + "eng-taq_model.txt", 'w') as f: 
    f.write(model.train(biverses, 20)) // makes empty file 

, nasıl (1) diske ve (2) daha sonra yeniden kaydedebilirsiniz?

cevap

7

hemen cevap, bunu turşu https://wiki.python.org/moin/UsingPickle

görmektir Ama IBMModel1 bir lambda işlevini döndürür, bunun nedeni pickle/cPickle biz

Yani (https://github.com/nltk/nltk/blob/develop/nltk/align/ibm1.py#L74 ve https://github.com/nltk/nltk/blob/develop/nltk/align/ibm1.py#L104 bakınız) varsayılan ile turşu mümkün değildir dill kullanın. Öncelikle, dill yükleme bölümüne bakın Sonra Can Python pickle lambda functions?

$ pip install dill 
$ python 
>>> import dill as pickle 

: Bir olan IBMModel1 nesne, turşu çalışırsanız

>>> import dill as pickle 
>>> from nltk.corpus import comtrans 
>>> bitexts = comtrans.aligned_sents()[:100] 
>>> with open('model1.pk', 'rb') as fin: 
...  ibm = pickle.load(fin) 
... 
>>> aligned_sent = ibm.align(bitexts[0]) 
>>> aligned_sent.words 
['Wiederaufnahme', 'der', 'Sitzungsperiode'] 

:

>>> import dill 
>>> import dill as pickle 
>>> from nltk.corpus import comtrans 
>>> from nltk.align import IBMModel1 
>>> bitexts = comtrans.aligned_sents()[:100] 
>>> ibm = IBMModel1(bitexts, 20) 
>>> with open('model1.pk', 'wb') as fout: 
...  pickle.dump(ibm, fout) 
... 
>>> exit() 

turşusu modeli kullanmak için lambda işlevi, bu ile biter:

>>> import cPickle as pickle 
>>> from nltk.corpus import comtrans 
>>> from nltk.align import IBMModel1 
>>> bitexts = comtrans.aligned_sents()[:100] 
>>> ibm = IBMModel1(bitexts, 20) 
>>> with open('model1.pk', 'wb') as fout: 
...  pickle.dump(ibm, fout) 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex 
    raise TypeError, "can't pickle %s objects" % base.__name__ 
TypeError: can't pickle function objects 

(Not: Yukarıdaki kod parçası 3.0.0 NLTK sürümü geliyor):

IBMModel1 bir lambda fonksiyonu döndürdüğü için NLTK 3.0.0 ile python3 olarak

, ayrıca aynı sorunla karşı karşıya gelecek

[email protected]:~$ python3 
Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import pickle 
>>> from nltk.corpus import comtrans 
>>> from nltk.align import IBMModel1 
>>> bitexts = comtrans.aligned_sents()[:100] 
>>> ibm = IBMModel1(bitexts, 20) 
>>> with open('mode1.pk', 'wb') as fout: 
...  pickle.dump(ibm, fout) 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
_pickle.PicklingError: Can't pickle <function IBMModel1.train.<locals>.<lambda> at 0x7fa37cf9d620>: attribute lookup <lambda> on nltk.align.ibm1 failed' 

>>> import dill 
>>> with open('model1.pk', 'wb') as fout: 
...  dill.dump(ibm, fout) 
... 
>>> exit() 

[email protected]:~$ python3 
Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import dill 
>>> from nltk.corpus import comtrans 
>>> with open('model1.pk', 'rb') as fin: 
...  ibm = dill.load(fin) 
... 
>>> bitexts = comtrans.aligned_sents()[:100] 
>>> aligned_sent = ibm.aligned(bitexts[0]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'IBMModel1' object has no attribute 'aligned' 
>>> aligned_sent = ibm.align(bitexts[0]) 
>>> aligned_sent.words 
['Wiederaufnahme', 'der', 'Sitzungsperiode'] 

(Not: http://docs.pythonsprints.com/python3_porting/py-porting.html bkz python3 olarak, picklecPickle olan) Sen hizalama modeli tasarrufu tartıştılar

+0

: Bundan sonra

from nltk.align import IBMModel1 as IBM from nltk.align import AlignedSent import dill as pickle biverses = [list of AlignedSent objects] model = ibm(biverses, 20) for sent in range(len(biverses)): biverses[sent].alignment = model.align(biverses[sent]).alignment 

Eğer turşu olarak dereotu ile kaydedebilirsiniz, Ne denediğinden emin değilim, ama lambdalar görmedim ve vanilya turşusu ile "modeli" nin seçilmesinden ve çıkarılmasından hiç problem yaşamadım. – alexis

+0

@alexis Bu ilginç, güncellenmiş cevapla aynı hatayı aldınız mı? – alvas

+0

Henüz denemek için bir şansım olmadı; ama farklı deneyimleri (modülün çok değişmiş olduğunu fark etmemiştim) açıklayan python 2 ile soldurma işlemini test etmiş olabilirim. Denediğimde size haber vereceğim. – alexis

3

ancak soru hakkında daha fazla gibi görünüyor Hizaladığınız hizalanmış bitex'leri kaydetme: "Bir günde toplu olarak hizalamaları yapmak ve bu hizalamaları daha sonra kullanmak güzel olurdu." Bu soruya cevap vereceğim.

nltk ortamında, corpus benzeri bir kaynak kullanmanın en iyi yolu, bir corpus okuyucusu ile erişmek. NLTK tutuklama açısından yazarlar gelmiyor ama NLTK en AlignedCorpusReader tarafından desteklenen biçim üretmek çok kolaydır: (NLTK 3 versiyonu) bu kadar

model = ibm(biverses, 20) # As in your question 

out = open("folder/newalignedtext.txt", "w") 
for pair in biverses: 
    asent = model.align(pair) 
    out.write(" ".join(asent.words)+"\n") 
    out.write(" ".join(asent.mots)+"\n") 
    out.write(str(asent.alignment)+"\n") 

out.close() 

. Daha sonra yeniden ve comtrans veritabanını kullandık istesem de tam olarak hizalanmış cümleler kullanabilirsiniz: Gördüğünüz gibi, hizalama nesnenin kendisini gerekmez

from nltk.corpus.reader import AlignedCorpusReader 

mycorpus = AlignedCorpusReader(r"folder", r".*\.txt") 
biverses_reloaded = mycorpus.aligned_sents() 

. Hizalanmış cümleler, gömülü olasılıkları incelemek istemediğiniz sürece bir corpus okuyucu, ile yüklenebilir ve aligner'ın kendisi oldukça yararsızdır.

Yorum: Hizalayıcı nesnesini bir "model" olarak çağıracağımdan emin değilim. NLTK 2'de, hizalayıcı yeni metni hizalayacak şekilde ayarlanmamıştır - bir align() yöntemine bile sahip değildir. NLTK 3'te align() işlevi yeni metni hizalayabilir ancak yalnızca python 2'den kullanılıyorsa; Python 3'teki, görünüşe göre farklı türlerdeki nesneleri karşılaştırmak için sıkılaştırılmış kurallardan dolayı kırılmıştır. Yine de hizalayıcıyı seçip yeniden yüklemek istediğinizde, cevabımıma ekleyeceğim; Gördüğüm şeyden vanilya cPickle ile yapılabilir.

+0

Hizalayıcı işlevi, bir kaynak dil sözcüğü verilen her hedef dil kelimesinin olasılığını öğrenmesi nedeniyle bir modeldir. Bunu büyük bir karma tablo olarak saklamak mümkün olsa da, varsayılan bir deyim döndüren bir lambda işlevi olarak saklamak için karar verdi kodun yazarın. https://github.com/nltk/nltk/blob/develop/nltk/align/ibm1.py#L74 – alvas

+0

Öğrenilmiş olasılıklar dikkate alındığında, olasılıkları yeni verilere atamak mümkündür, bu yüzden bir model denir. Bununla birlikte, yeni veriler verildiğinden, modelin kaydedilmesinin doğal olmadığına katılıyorum, olasılık modelini yeniden oluşturabilirsiniz. Teorik açıklama için http://www.cs.columbia.edu/~mcollins/courses/nlp2011/notes/ibm12.pdf adresine bakınız. – alvas

+0

BTW, 'nltk.align' python3'te bozuk değil. – alvas

1

istediğiniz ve bu, bir AlignedSent listesi olarak saklayabilirsiniz gibi görünüyor eğer: Ben

with open('alignedtext.pk', 'wb') as arquive: 
    pickle.dump(biverses, arquive) 
İlgili konular