venerdì 23 giugno 2017

Dettatura in italiano con Cortana. Qualcosa si sta muovendo

Finalmente le API di Cortana sono state utilizzate per creare un addin per Word e le altre applicazioni Office.
L'addin si chiama Dictate ed è un progetto Microsoft Garage.
Non solo trascrive, ma anche traduce in decine di lingue.
Una manna per gli antichi come me che si ostinano a usare Word invece di Chrome e Google docs.
Una volta attivato l'addin, Cortana non scrive in Word ma nella finestra correntemente attiva, per cui potreste anche scrivere in Wordpad o Notepad mentre sono in primo piano.
Per ora il grosso limite è che non permette di modificare il vocabolario.
Il sistema funziona benissimo in un contesto generico adatto ai creativi, ma i creativi preferiscono usare la tastiera.
Il vocale viene invece utilizzato da coloro che vengono spremuti sul lavoro per scrivere, che so, referti di TAC al torace piuttosto che relazioni sulle caldaie, ma questi hanno bisogno di un vocabolario tecnico e perciò il sistema in sé è ancora poco utile.

venerdì 9 giugno 2017

Come calcolare la frequenza delle parole in un testo in C#

Calcolare la frequenza delle parole in un testo è un problema puramente accademico perché esistono già centinaia di programmi ed esempi di codice pronti per l'uso.
Dovendo comunque scrivere del codice, essendo pigro di natura, sono sempre alla ricerca della procedura più semplice e più breve possibile, ovviamente in C#
L'esempio contempla l'uso delle stopwords


//Testo da esaminare. Ho provato con files fino a 500MB senza attese fastidiose
string text = File.ReadAllText(path, Encoding.Default);

//caratteri separatori che identificano i limiti di una parola
char[] separators = new char[] { ' ', '\r', '\n', ',', '\\', '.', ';', ':', '(', ')', '"', '?', '!', '\'', '-', '«', '/' };

//lista delle parole contenute in text
List<string> words = text.Split(separators, StringSplitOptions.RemoveEmptyEntries).ToList();

//lista delle parole da escludere dal conteggio, le cosiddette stopwords, ad esempio congiunzioni, articoli e preposizioni
List<string> stopwords = File.ReadAllLines("StopWords.txt", Encoding.Default).ToList();

//Rimuove dalla lista le stopwords
//Non è possibili utilizzare Except perché fa una DISTINCT e annulla le frequenze
//Ho trovato molti forum in cui si chiede come utilizzare Contains in modo case insensitive
//O la documentazione è poco chiara o quei post si riferiscono a una versione di .NET antica
//La soluzione è semplice: utilizzare StringComparer
words.RemoveAll(item => stopwords.Contains(item, StringComparer.OrdinalIgnoreCase));

//Infine LINQ per contare le frequenze e presentarle in ordine discendente
var frequencies = words.GroupBy(n => n).Select(n => new { Value = n.Key, Count = n.Count() }).OrderByDescending(a => a.Count);