Skip to main content

Phonetic Distance

Python Version License: MIT

Una libreria Python avanzata per il calcolo di distanze fonetiche pesate, specificamente progettata per l'analisi di forme dialettali e variazioni linguistiche.

📖 Panoramica

Questo progetto implementa una versione avanzata dell'algoritmo di distanza di Levenshtein che tiene conto delle caratteristiche fonologiche dei suoni. A differenza delle distanze tradizionali basate sui caratteri, questa libreria:

  • Analizza le caratteristiche fonetiche (vocale/consonante, modo, luogo di articolazione, ecc.)
  • Gestisce i diacritici con tokenizzazione Unicode NFD
  • Supporta varianti multiple separate da / in una singola cella
  • Fornisce similarità normalizzate tra 0 e 1
  • È ottimizzata per forme dialettali e trascrizioni fonetiche

🎯 Caso d'uso tipico

Quando si confrontano forme dialettali come "gatto" vs "gàtto", una distanza di Levenshtein tradizionale le considererebbe molto diverse. Questa libreria riconosce che la differenza è solo un accento e assegna una similarità molto alta (0.98).

🚀 Installazione rapida

Questo progetto non richiede dipendenze esterne e funziona con Python 3.8+:

git clone https://github.com/filippovicidomini/phonetic-distance.git
cd phonetic-distance
python3 -c "from phonetic_distance import phon_similarity_normalized; print(phon_similarity_normalized('gatto','gàtto'))"
# Output: 0.98

📚 API Reference

Funzioni principali

tokenize_segments(text: str) -> list[TokenType]

Converte una stringa in token fonetici usando normalizzazione NFD.

from phonetic_distance import tokenize_segments

# Separa base e diacritici
tokens = tokenize_segments('gàtto')
print(tokens)
# [('g', frozenset()), ('a', frozenset({'̀'})), ('t', frozenset()), ('t', frozenset()), ('o', frozenset())]

weighted_levenshtein(seq1, seq2, diac_w=0.1) -> float

Calcola la distanza di Levenshtein pesata tra due sequenze di token.

from phonetic_distance import weighted_levenshtein, tokenize_segments

tokens1 = tokenize_segments('casa')
tokens2 = tokenize_segments('kasa')
distance = weighted_levenshtein(tokens1, tokens2)
print(f"Distanza: {distance}")

phon_similarity_normalized(form1: str, form2: str, **kwargs) -> float

Calcola la similarità fonologica normalizzata (0-1) tra due forme.

from phonetic_distance import phon_similarity_normalized

# Confronto con diacritico
sim1 = phon_similarity_normalized('gatto', 'gàtto')
print(f"gatto vs gàtto: {sim1}")  # 0.98

# Confronto foneticamente simile
sim2 = phon_similarity_normalized('casa', 'kasa') 
print(f"casa vs kasa: {sim2}")   # Alta similarità

# Confronto molto diverso
sim3 = phon_similarity_normalized('gatto', 'mare')
print(f"gatto vs mare: {sim3}")  # Bassa similarità

concept_similarity_normalized(cell_a: str, cell_b: str, **kwargs) -> float

Gestisce celle con varianti multiple separate da / e restituisce la massima similarità.

from phonetic_distance import concept_similarity_normalized

# Varianti multiple
cell1 = "pane/pàn"
cell2 = "pan/pané" 
sim = concept_similarity_normalized(cell1, cell2)
print(f"Similarità concettuale: {sim}")

Parametri opzionali

  • keep_boundaries=False: Include token di confine parola
  • diac_w=0.1: Peso per differenze diacritiche (0.0-1.0)

💡 Esempi pratici

Esempio base: confronto dialettale

from phonetic_distance import phon_similarity_normalized

# Esempi di varianti dialettali italiane
varianti = [
    ('casa', 'kasa'),      # c/k
    ('chiesa', 'chjesa'),  # ie/je  
    ('gatto', 'gàtto'),    # accento
    ('bello', 'bellu'),    # o/u finale
]

for v1, v2 in varianti:
    sim = phon_similarity_normalized(v1, v2)
    print(f"{v1:8} vs {v2:8} → {sim:.3f}")

Esempio avanzato: gestione varianti multiple

from phonetic_distance import concept_similarity_normalized

# Celle con più varianti (tipico nei database dialettali)
esempi = [
    ("pane/pàn", "pan"),
    ("chiesa/chjesa", "chiesa"),  
    ("casa/kasa", "casa"),
    ("bello/bellu/beddu", "bello")
]

for cella1, cella2 in esempi:
    sim = concept_similarity_normalized(cella1, cella2)
    print(f"{cella1:15} vs {cella2:8} → {sim:.3f}")

Esempio: analisi corpus dialettale

from phonetic_distance import concept_similarity_normalized

def trova_varianti_simili(forme, soglia=0.8):
    """Trova coppie di forme con alta similarità."""
    risultati = []
    
    for i, forma1 in enumerate(forme):
        for forma2 in forme[i+1:]:
            sim = concept_similarity_normalized(forma1, forma2)
            if sim >= soglia:
                risultati.append((forma1, forma2, sim))
    
    return sorted(risultati, key=lambda x: x[2], reverse=True)

# Esempio con forme dialettali
corpus = [
    "casa", "kasa", "koza", 
    "gatto", "gàtto", "gattu",
    "chiesa", "chjesa", "ghiesa"
]

varianti = trova_varianti_simili(corpus, soglia=0.85)
for v1, v2, sim in varianti:
    print(f"{v1} ≈ {v2} ({sim:.3f})")

🏗️ Struttura del progetto

phonetic-distance/
├── phonetic_distance/          # Package principale
│   ├── __init__.py            # Esporta API pubblica
│   └── core.py                # Implementazione algoritmi
├── examples/
│   └── usage.py               # Esempi di utilizzo
├── tests/                     # Test suite
│   ├── conftest.py           
│   └── test_similarity.py     
├── data/
│   └── dictionary.txt         # Dizionario forme
├── scripts/
│   └── update_dictionary.py   # Gestione dizionario
├── wd.py                      # Compatibilità legacy
├── pyproject.toml            # Configurazione package
├── requirements.txt          # Dipendenze (vuoto)
└── README.md                 # Questa documentazione

🔬 Come funziona

1. Tokenizzazione NFD

Le stringhe sono normalizzate in NFD (Normalized Form Decomposed), separando caratteri base da diacritici:

"gàtto" → [('g',∅), ('a',{̀}), ('t',∅), ('t',∅), ('o',∅)]

2. Costi basati su feature

I costi di sostituzione considerano caratteristiche fonetiche:

  • Vocali: apertura, anteriorità, arrotondamento
  • Consonanti: luogo, modo, voce

3. Gestione diacritici

Differenze diacritiche hanno penalità ridotte (default 0.1).

4. Normalizzazione

La distanza viene normalizzata per la lunghezza massima delle sequenze.

🧪 Test

Esegui i test per verificare l'installazione:

cd phonetic-distance
python -m pytest tests/ -v

Oppure test rapido:

python examples/usage.py

🛠️ Estendere la libreria

Aggiungere nuove basi fonetiche

Modifica BASE_FEATS in phonetic_distance/core.py:

BASE_FEATS = {
    'a': {'vowel', 'open', 'central'},
    'e': {'vowel', 'mid', 'front'},
    # Aggiungi qui nuove basi...
}

Gestire dizionario

Usa lo script per aggiornare il dizionario:

python scripts/update_dictionary.py --add "nuova_forma"

📋 Requisiti

  • Python: 3.8 o superiore
  • Dipendenze: Nessuna (solo libreria standard)
  • Sistema: Qualsiasi OS (Windows, macOS, Linux)

🤝 Contribuire

  1. Segnala problemi via GitHub Issues
  2. Proponi miglioramenti con le Pull Request
  3. Aggiungi nuove feature fonetiche seguendo il formato esistente
  4. Migliora la documentazione e gli esempi

Compatibilità legacy

Il modulo wd.py mantiene compatibilità con codice precedente:

import wd  # Deprecation warning ma funziona
# Equivalente a: import phonetic_distance

📄 Licenza

Questo progetto è rilasciato sotto licenza MIT. Libero per uso commerciale e non commerciale.

🚀 Versioni future

  • Supporto per feature prosodiche (tono, stress)
  • Algoritmi di clustering foneticamente consapevoli
  • Export in formati standard (JSON, CSV)
  • Interfaccia web per confronti rapidi
  • Modelli pre-addestrati per lingue specifiche

Autore: Filippo Vicidomini
Versione: 0.1.0
Homepage: https://github.com/filippovicidomini/phonetic-distance

Metadata

Release files for phonetic-distance 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for phonetic-distance 0.1.0
File Size Uploaded
phonetic_distance-0.1.0.tar.gz 9.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for phonetic-distance 0.1.0
File Interpreter ABI Platform
phonetic_distance-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.5 kB

Release files / phonetic_distance-0.1.0.tar.gz

Download URL phonetic_distance-0.1.0.tar.gz
Size 9.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ca0cc04c6e16ce96a03946695a5bfa6bf4ae00b301fc2e715f14bdcd3e30d097
BLAKE2b-256 checksum
How to use checksums
0e87cd4bfb559288642665cf0c2727dc1c2bd42d8bf59988d25f7162c5bd0802
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.2

Release files / phonetic_distance-0.1.0-py3-none-any.whl

Download URL phonetic_distance-0.1.0-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5550db067be61f22553303320d47edbb71a1a3e7dd8be6c6cd9b19180beb97ef
BLAKE2b-256 checksum
How to use checksums
e3882ba97c22a2647b450a9a2877d4ce36a367a8679319dbbeb51306ce8c400e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.2

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page