2016-10-24 20 views
13

Bazı karakterler içeren bir dizim var ve bu karakterlerin organizasyonunu mümkün olan en belirgin hale getirecek şekilde arıyorum. Ben "ascrlyo" harf varsaHarfleri en belirgin şekilde düzenleme?

Örneğin, diğerlerinden daha pronounceable olurdu bazı düzenlemeler vardır. Aşağıdaki "yüksek puan" alabilirsiniz:

scaroly crasoly

Nerede düşük puan alabilirsiniz aşağıdakilerden olarak:

oascrly yrlcsoa

Kullanabileceğim basit bir algoritma var mı? Ya da daha iyisi, bunu elde eden bir Python işlevselliği?

Teşekkür ederiz!

+2

Bunu yapmak için sağlam bir İngilizce fonetik bilgisine ihtiyacınız olacak. Bu gerçekten basit bir sorun değil. – kindall

+0

@kindall Öyle düşünmüştüm, ama birisinin zaten onu zarif bir şekilde çözdüğünü umuyoruz ... –

+3

Bu yardımcı olabileceği gibi görünüyor: http://stackoverflow.com/a/6298193/4996248. Bir Python gibberish dedektörünü tanımlar. En küçük gibberish skoru olan permütasyonu bulun. –

cevap

5

Daha basit bir problemi çözerek başlayın: belirli bir sözcük telaffuz edilebilir mi?

Makine 'denetimli öğrenmeyi' öğrenme burada etkili olabilir. Sözlük kelimelerin ve şifreli kelimelerin bir antrenman kümesinde ikili bir sınıflandırıcıyı eğitin (şifrelenmiş sözcüklerin tümünün önkoşulsuz olduğunu varsayın). Özellikler için, bigram ve trigram saymayı öneririm. Benim gerekçem: 'tns' ve 'srh' gibi unpronounceable trigramlar, tek tek harflerin her biri ortak olsa bile, sözlük sözcüklerinde nadirdir.

fikri eğitimli algoritma pronounceable olarak tek ortak trigrams ile telafuz gibi herhangi nadir trigrams sözcükleri ve kelimeleri sınıflandırmak öğrenecektir olmasıdır.


İşte http://scikit-learn.org/

import random 
def scramble(s): 
    return "".join(random.sample(s, len(s))) 

words = [w.strip() for w in open('/usr/share/dict/words') if w == w.lower()] 
scrambled = [scramble(w) for w in words] 

X = words+scrambled 
y = ['word']*len(words) + ['unpronounceable']*len(scrambled) 

from sklearn.model_selection import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(X, y) 

from sklearn.pipeline import Pipeline 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.naive_bayes import MultinomialNB 

text_clf = Pipeline([ 
    ('vect', CountVectorizer(analyzer='char', ngram_range=(1, 3))), 
    ('clf', MultinomialNB()) 
    ]) 

text_clf = text_clf.fit(X_train, y_train) 
predicted = text_clf.predict(X_test) 

from sklearn import metrics 
print(metrics.classification_report(y_test, predicted)) 

It puanları% 92 doğruluk-öğrenme scikit ile bir uygulama var. Önem verilebilirlik göz önüne alındığında, yine de öznel olan, bu kadar iyi olabilir.

    precision recall f1-score support 

     scrambled  0.93  0.91  0.92  52409 
      word  0.92  0.93  0.93  52934 

    avg/total  0.92  0.92  0.92 105343 

Bu sizin örneklerle kabul eder: Merak edenler için

>>> text_clf.predict("scaroly crasoly oascrly yrlcsoa".split()) 
['word', 'word', 'unpronounceable', 'unpronounceable'] 

, burada 10 o pronounceable sınıflandırır kelimeleri şifreli olup:

  • moro garapm ocenfir onerixoatteme arckinbo raetomoporyo bheral accrene cchmanie suroatipsheq
012 unpronouncable olarak yanlışVe nihayet 10 Sözlük kelimeler:

  • ilch tohubohu Usnea halfpaced pyrostilpnite Lynnhaven acımasız alıştırmak moldproof parça parça
+0

İyi cevap. Bu, fonetik uygunsuzluğun paragonu olduğu için İngilizce için zor bir sorundur. – erip

0

(tamlığı için buraya makine öğrenimini denemek için bana ilham orijinal saf Python çözümdür.

Güvenilir bir çözümün, İngiliz dilinin gelişmiş bir modelini gerektireceğine katılıyorum, ancak belki de tolere edilebilecek kadar kötü olan basit bir buluşsallık bulabiliriz.

: Artık yazım gelen sesleri tanımlamak için basit bir girişimde c?c?(v+cc?)*v*

yazılabilir bu Düzenli ifade olarak

1. contain a vowel sound 
2. no more than two consonant sounds in succession 

: Ben en çok pronouncable deyişle memnun iki temel kural

düşünebiliriz

vowels = "a e i o u y".split() 
consonants = "b bl br c ch cr chr cl ck d dr f fl g gl gr h j k l ll m n p ph pl pr q r s sc sch sh sl sp st t th thr tr v w wr x y z".split() 

Daha sonra normal ifadelerle kurallar mümkündür:

v = "({0})".format("|".join(vowels)) 
c = "({0})".format("|".join(consonants)) 

import re 
pattern = re.compile("^{1}?{1}?({0}+{1}{1}?)*{0}*$".format(v, c)) 
def test(w): 
    return re.search(pattern, w) 

def predict(words): 
    return ["word" if test(w) else "scrambled" for w in words] 

Bu, sözcük/karıştırılmış test kümesinde yaklaşık% 74'lük bir puan alır.

   precision recall f1-score support 

    scrambled  0.90  0.57  0.70  52403 
     word  0.69  0.93  0.79  52940 

avg/total  0.79  0.75  0.74 105343 

Tweaked sürümü% 80 attı.

İlgili konular