2014-10-20 15 views
8

Sto lavorando per rilevare le rime in Python usando il dizionario di pronuncia Carnegie Mellon University e vorrei sapere: Come posso stimare la somiglianza fonemica tra due parole? In altre parole, esiste un algoritmo in grado di identificare il fatto che "mani" e "piani" sono più vicini alla rima di "mani" e "patatine fritte"?Stima della somiglianza fonemica tra due parole

Alcuni contesto: In un primo momento, ero disposto a dire che due parole in rima se il loro primario ha sottolineato sillaba e tutte le sillabe successive sono identici (c06d se si desidera replicare in Python):

def create_cmu_sound_dict(): 

    final_sound_dict = {} 

    with open('resources/c06d/c06d') as cmu_dict: 
     cmu_dict = cmu_dict.read().split("\n") 
     for i in cmu_dict: 
      i_s = i.split() 
      if len(i_s) > 1: 
       word = i_s[0] 
       syllables = i_s[1:] 

       final_sound = "" 
       final_sound_switch = 0 

       for j in syllables: 
        if "1" in j: 
         final_sound_switch = 1 
         final_sound += j 
        elif final_sound_switch == 1: 
         final_sound += j 

      final_sound_dict[word.lower()] = final_sound 

    return final_sound_dict 

Se io quindi eseguire

print cmu_final_sound_dict["hands"] 
print cmu_final_sound_dict["plans"] 

posso vedere che le mani ei piani suono molto simile. Potrei lavorare per una stima di questa somiglianza da solo, ma ho pensato che dovrei chiedere: ci sono algoritmi sofisticati in grado di legare un valore matematico a questo grado di somiglianza sonora (o uditiva)? Cioè, quali algoritmi o pacchetti si possono usare per matematizzare il grado di somiglianza fonemica tra due parole? Mi rendo conto che questa è una grande domanda, ma sarei molto grato per qualsiasi consiglio che altri possano offrire su questa domanda.

+0

Perché down-vote e spostare per chiudere? Cosa posso fare per migliorare la domanda? – duhaime

+2

Stai cercando qualcosa come l'algoritmo Soundex (http://en.wikipedia.org/wiki/Soundex)? – acfrancis

+0

Non posso parlare per il downvoter, ma la ragione per il voto ravvicinato è che la tua domanda sembra che stia [chiedendo dei consigli] (http://meta.stackoverflow.com/questions/254393/what-exactly-is -a-raccomandazione-domanda). Puoi riformulare la frase per chiedere più chiaramente "* Come posso fare X? *" Piuttosto che "* Quale strumento dovrei usare per fare X? *" –

risposta

3

Cheat.

#!/usr/bin/env python 

from Levenshtein import * 

if __name__ == '__main__': 
    s1 = ['HH AE1 N D Z', 'P L AE1 N Z'] 
    s2 = ['HH AE1 N D Z', 'F R AY1 Z'] 
    s1nospaces = map(lambda x: x.replace(' ', ''), s1) 
    s2nospaces = map(lambda x: x.replace(' ', ''), s2) 
    for seq in [s1, s2, s1nospaces, s2nospaces]: 
     print seq, distance(*seq) 

uscita:

['HH AE1 N D Z', 'P L AE1 N Z'] 5 
['HH AE1 N D Z', 'F R AY1 Z'] 8 
['HHAE1NDZ', 'PLAE1NZ'] 3 
['HHAE1NDZ', 'FRAY1Z'] 5 

libreria: https://pypi.python.org/pypi/python-Levenshtein/0.11.2

Scherzi a parte, però, dal momento che hai solo il testo in input e praticamente il testo-base CMU dict, si è limitato a qualche una sorta di manipolazione dell'input di testo; ma per come la vedo io, c'è solo un numero limitato di fonemi disponibili, quindi puoi prendere quelli più importanti e assegnare "pesi fonematici" a loro. C'è solo 74 di loro nel dizionario CMU si indicò:

% cat cmudict.06.txt | grep -v '#' | cut -f 2- -d ' ' | tr ' ' '\n' | sort | uniq | wc -l 
75 

(75 meno uno per riga vuota)

si sarebbe probabilmente ottenere risultati migliori se hai fatto smth più avanzato al punto 2 : assegna i pesi a particolari combinazioni di fonemi. Quindi potresti modificare una metrica di distanza di tipo Levenshtein, ad es. nella biblioteca sopra, per trovare una metrica "distanza fonematica" ragionevolmente performante che lavori sugli input di testo.

Non molto lavoro per il passaggio 3: profitto.

+0

Questo ignora completamente le caratteristiche fonemiche che rendono "nd" tendenzialmente assimilabile a "n", mentre per es. "nk" non (o tende verso "ngk", o in effetti viene regolarmente realizzato come "ngk"). – tripleee

0

1) ottenere tutto TTS audio per tutte le parole tramite API web o locale SAPI,

2) Estratto di funzioni vocali se si può (1, 2), o almeno di ottenere il potere dei dati vocali

3) Dipende dalla funzione che hai, ecco alcuni approcci.

Se è possibile ottenere la potenza di ciascun campione (frame) di dati vocali (Dim = 1), un modo semplice è senza dubbio calcolare il correlation di due set di funzionalità.

Se si dispone di un altro tipo di caratteristiche, che molto probabilmente avrà più dimensioni, è possibile trattarlo come immagine e controllare il 2d convolution o Dynamic time warping

4) Se si dispone di alcuna conoscenza di elaborazione vocale per l'attività 1,2,3, check out pyphonetics

#pip install pyphonetics 
>>> from pyphonetics import RefinedSoundex 
>>> rs = RefinedSoundex() 
>>> rs.distance('Rupert', 'Robert') 
0 
>>> rs.distance('assign', 'assist', metric='hamming') 
2 
Problemi correlati