🎤 Introduzione

In questo post illustro come: estrarre tracce audio da filmati (usando, per esempio, YouTube), eseguire una conversione del parlato in testo (speech to text), estrarre conoscenza dal testo non strutturato della trascrizione.

Utilizzo le funzionalità di IBM Watson accessibili mediante Watson Developer Cloud e il linguaggio di programmazione Python.

La scelta di Watson non è vincolante. Funzionalità analoghe potrebbero essere ottenute utilizzando altre soluzioni comparabili come quelle fornite da:

Microsoft Azure ML Google Cloud Platform Amazon AWS ML

e una pletora di servizi online come MonkeyLearn e altri. Per esempio, il riconoscimento vocale accessibile con le Speech API di Google supporta 80 lingue che è un numero ben superiore alle attuali capacità di Watson. Ciononostante, grazie anche alla varietà e profondità della sua offerta, Watson assolve sul mercato un ruolo di riferimento con cui è necessario e utile misurarsi.

🧠 Cos'è IBM Watson?

Anzitutto, che cos'è IBM Watson? Nella sua strategia di diversificazione, IBM ha sempre mostrato una particolare attenzione per l'intelligenza artificiale, anche contribuendo allo sviluppo tecnologico con passaggi importanti: nel 1997, dopo 8 anni di sviluppi, IBM Deep Blue si aggiudicò una rivincita storica a scacchi contro il campione del mondo Kasparov e nel 2011 il nuovo IBM Watson, partecipando al famoso quiz televisivo "Jeopardy!", fu in grado di battere i due campioni in carica.

Il Watson dell'edizione di "Jeopardy!" aveva alle spalle circa 6 anni di sviluppi. In essenza, Watson nasce come un sofisticato sistema di Question Answering (QA) predisposto alla comprensione del linguaggio naturale, alla generazione di ipotesi e all'apprendimento.

Un suo elemento fondamentale è il framework DeepQA che è definito come una massive parallel probabilistic evidence-based architecture e si basa sull'impiego concorrente di molteplici algoritmi di:

  • Analisi della domanda in linguaggio naturale
  • Ricerca delle risposte
  • Classificazione delle risposte secondo la loro plausibilità

Il tutto combinato per ottenere miglioramenti consistenti nell'accuratezza, nel livello di confidenza e nella velocità di processazione.

💻 Architettura Hardware

Gli antichi latini dicevano "mens sana in corpore sano" e, il "corpo" che ospita la mente di Watson, è indubbiamente sano: i dati più recenti descrivono una griglia di 90 server basati su processori in tecnologia proprietaria POWER7 estremamente parallelizzati, per una potenza complessiva di calcolo di 80 teraFLOPS e 16 teraByte di RAM.

🌐 L'Ecosistema Watson

Per essere pienamente compreso, Watson non dovrebbe essere considerato come un supercomputer ma, più correttamente, è un ecosistema basato su:

  1. Continui investimenti e sperimentazioni in un'ampia varietà di contesti operativi: campo finanziario, burocratico, medico, bancario, servizi governativi, viaggi e customer care, culinario

  2. Prodotti commerciali pronti all'uso offerti da IBM come servizi a canone su cloud SaaS. Alcuni esempi: Watson Virtual Agent, Watson Explorer, Watson Analytics, Watson Knowledge Studio

  3. Watson Developer Cloud: un esteso set di servizi cognitivi accessibili mediante API e SDK attraverso la piattaforma PaaS IBM Bluemix

Con Watson Developer Cloud, IBM declina i servizi cognitivi di Watson allo sviluppo personalizzato: aziende e sviluppatori possono aggiungere valore combinando le tecnologie di base (classificazione, conversazione, analisi del contenuto, ecc.), sfruttando i vantaggi del PaaS per tutte le necessità di scaling verticale/orizzontale.

🛠️ Prerequisiti

Prima di proseguire, ecco di cosa abbiamo bisogno:

  • Un account su IBM Bluemix
  • Un ambiente Python 2.7 o 3.2+ con libreria pandas installata

🎵 Estrazione delle Tracce Audio da un Video

⚠️ Attenzione! La scelta di estrarre una traccia audio da un video YouTube è da intendersi come pura sperimentazione, nel pieno rispetto delle policy Google per il download dei video e la loro diffusione.

Un modo semplice per estrarre una traccia audio da un video YouTube consiste nell'usare il tool youtube-dl. È installabile nel modo usuale per i package di Python:

pip install youtube-dl

In particolare, ho casualmente scelto il video What is Machine Learning accessibile all'indirizzo:

Il comando usato per l'estrazione è:

youtube-dl "https://www.youtube.com/watch?v=ty-kTUzMnjk" \
    --extract-audio \
    --audio-format wav \
    --audio-quality 16K \
    --id

Il codice alfanumerico ty-kTUzMnjk usato nel comando di estrazione è l'identificativo univoco del video nell'archivio di YouTube. Una volta acceduto alla pagina del video su YouTube, il codice univoco può essere recuperato dalla barra dell'indirizzo del browser o facendo click sul pulsante "Condividi".

💡 Nota: youtube-dl potrebbe richiedere l'installazione della libreria libav. Sui sistemi Debian/Ubuntu questa libreria è inclusa nel package libav-tools.

Dall'esecuzione di youtube-dl ottengo un file wav (ty-kTUzMnjk.wav) contenente la traccia audio opportunamente codificata secondo i requisiti del servizio di speech recognition.

⚙️ Predisposizione dei Servizi Watson su Bluemix

Assumendo che siamo già registrati su Bluemix, il passo successivo consiste nel configurare un set di credenziali per l'accesso a due servizi specifici:

  • Speech To Text: converte la voce umana in testo scritto
  • AlchemyAPI: è un insieme di API che consentono l'analisi del testo attraverso NLP (Natural Language Processing)

Mediante AlchemyAPI è possibile utilizzare diverse funzioni come:

  • Estrazione di parole chiave
  • Estrazione di entità
  • Analisi delle opinioni
  • Analisi emozionali
  • Tagging concettuale
  • Estrazione di relazioni
  • Classificazione tassonomica

Configurazione Credenziali

Il metodo più semplice consiste, partendo dal cruscotto di Bluemix, nel fare click su "Catalogo" e scrivere nella search bar il nome del servizio. Per esempio, se scriviamo speech e facciamo click su "Filtro", il cruscotto visualizzerà un elenco di servizi incluso quello di nostro interesse: "Speech To Text".

Dalla sezione di gestione, facciamo click su "Credenziali del servizio" e quindi su "Visualizza credenziali", per ottenere le credenziali nel seguente formato:

{
  "url": "https://stream.watsonplatform.net/speech-to-text/api",
  "password": "V6l*******",
  "username": "d6c7fe4f-6644-437f-baf2-*******"
}

Procediamo in modo analogo con il servizio AlchemyAPI:

{
  "url": "https://gateway-a.watsonplatform.net/calls",
  "note": "It may take up to 5 minutes for this key to become active",
  "apikey": "a0e8bb2**************************"
}

🐍 Predisposizione Ambiente Python

Per l'accesso ai servizi di Watson Developer Cloud è disponibile il package Watson Developer Cloud Python SDK installabile nel modo usuale:

pip install --upgrade watson-developer-cloud

🗣️ Conversione della Voce in Testo

Il blocco di codice seguente include le istruzioni per richiedere al servizio Speech to Text la processazione del file wav precedentemente generato:

import json
from os.path import join, dirname
from watson_developer_cloud import SpeechToTextV1
import pickle

speech_to_text = SpeechToTextV1(
    username='d6c7fe4f-6644-437f-baf2-*******',
    password='V6l*******',
    x_watson_learning_opt_out=False
)

filename='./ty-kTUzMnjk'

with open(filename+'.wav', 'rb') as audio_file:
    results=speech_to_text.recognize(audio_file, 
                                     content_type='audio/wav', 
                                     continuous=True, 
                                     timestamps=True, 
                                     word_confidence=True, 
                                     profanity_filter=False, 
                                     word_alternatives_threshold=0.4)

pickle.dump(results, open(filename+'.watson.p','wb'))

Parametri di Configurazione

L'oggetto fondamentale è l'istanza speech_to_text della classe SpeechToTextV1. Alla funzione recognize è necessario passare alcuni parametri:

  • Obbligatori:

    • audio_file: contenuto del file audio
    • content_type='audio/wav': formato audio
  • Opzionali:

    • timestamps=True: per ottenere i timestamp inizio/fine della parola
    • word_confidence=True: per attribuire ad ogni parola un grado di confidenza
    • profanity_filter=False: per disattivare la censura automatica
    • word_alternatives_threshold=0.4: soglia minima di confidenza
    • continuous=True: per il riconoscimento continuo

📊 Elaborazione della Risposta di Watson

La risposta del servizio Speech to Text è una codifica JSON. Per semplificare il recupero dei dati, uso la funzione parse_transcript:

def parse_transcript(data):
    """
    data (dict): as derived from standard Watson API JSON
    returns: two dicts of lists of dicts:
    {
        words: [],
        lines: []
    }
    """
    lines = []
    words = []
    prev_line_end = 0
    line_results = data['results']
    
    for linenum, result in enumerate(line_results):
        if result.get('alternatives'):
            lineobj = result.get('alternatives')[0]
            word_timestamps = [o for o in lineobj['timestamps'] if o[0] != '%HESITATION']
            
            if word_timestamps:
                linewords = []
                word_confidences = [o for o in lineobj['word_confidence'] if o[0] != '%HESITATION']
                prev_word_end = 0
                
                for wordpos, txtobj in enumerate(word_timestamps):
                    word = {}
                    word["line_position"] = wordpos
                    word["line_number"] = linenum
                    word['confidence'] = round(word_confidences[wordpos][1], 3)
                    word["text"] = txtobj[0]
                    word["start"] = txtobj[1]
                    word["end"] = txtobj[2]
                    word["audible_duration"] = round(word["end"] - word["start"], 2)
                    word["pregap"] = round(word["start"] - prev_word_end, 2)
                    prev_word_end = word["end"]
                    linewords.append(word)

                words.extend(linewords)
                
                line = {}
                line['line_number'] = linenum
                line['start'] = linewords[0]['start']
                line['end'] = linewords[-1]['end']
                line['text'] = " ".join([w['text'] for w in linewords])
                line['audible_duration'] = round(line['end'] - line['start'], 2)
                line['confidence'] = round(lineobj['confidence'], 3)
                line['word_count'] = len(words)
                lines.append(line)

    return {'lines': lines, 'words': words}

Conversione in DataFrame

import pandas as pd

data = parse_transcript(results)
lines = pd.DataFrame(data['lines'])
words = pd.DataFrame(data['words'])
Immagine dell'articolo

Struttura dei Dati

DataFrame lines (per ogni frase riconosciuta):

  • audible_duration: durata in secondi della frase
  • confidence: grado di confidenza complessivo sulla frase
  • start/end: timestamp di inizio/fine frase
  • line_number: indice numerico univoco della frase
  • text: testo della frase
  • word_count: numero totale delle parole riconosciute

DataFrame words (per ogni parola riconosciuta):

  • audible_duration: durata in secondi della parola
  • confidence: grado di confidenza sulla parola
  • start/end: timestamp di inizio/fine parola
  • line_number: indice della frase di appartenenza
  • line_position: posizione della parola nella frase
  • text: testo della parola
  • pregap: intervallo di silenzio dalla parola precedente

Trascrizione Completa

L'intera trascrizione può essere ottenuta con:

transcript = "\n".join((lines['text']).tolist())
print(transcript)

Output:

machine learning is a method of teaching computers to make predictions based on some data
it is a branch of artificial intelligence
which automatically improves programs using data
for example a machine learning system could be trained on email messages
to learn to distinguish between spam and non spam messages
after learning it can be used to classify new email messages into spam and non spam folders
various fields where machine learning is frequently used our medical diagnosis
brain machine interfaces
chem informatics
self driving cars
stock market analysis
a recommendation engine using machine learning could be used to recommend the right product to the right customer
over time as more data is added and used by the algorithm the performance of the system improves

🧮 Analisi del T​esto attraverso NLP

Il blocco di codice seguente include le istruzioni per richiedere al servizio AlchemyAPI elaborazioni specifiche della trascrizione:

import json
from os.path import join, dirname
from watson_developer_cloud import AlchemyLanguageV1

alchemy_language = AlchemyLanguageV1(api_key='a0e8bb2**************************')

# get entity, keyword, taxonomy, concepts with a single call
comb = alchemy_language.combined(text=transcript, sentiment=True)

concepts = pd.DataFrame(comb['concepts'])
keywords = pd.DataFrame(comb['keywords'])
taxonomy = pd.DataFrame(comb['taxonomy'])
language_detection = comb['language']

target_phrases = ['machine learning', 'spam',
                'stock market analysis', 
                'recommendation engine',
                'right product',
                'right customer'
                'data',
                'predictions']

# get targeted sentiment
res_targ_sent = alchemy_language.targeted_sentiment(text=transcript, 
                                    targets=target_phrases, 
                                    language='english')

target_sent = pd.DataFrame(res_targ_sent['results'])

# get targeted emotion
res_targ_emot = alchemy_language.targeted_emotion(text=transcript, 
                                    targets=target_phrases, 
                                    language='english')

target_emot = pd.DataFrame(res_targ_emot['results'])

# get document emotion
emot = alchemy_language.emotion(text=transcript)

# get typed relations
relat = alchemy_language.typed_relations(text=transcript)

Funzioni di Analisi Implementate

  1. Estrazione di parole chiave: individuazione delle parole chiave nel testo con grado di rilevanza e analisi del sentiment
  2. Tagging concettuale: identifica concetti generali correlabili al testo
  3. Classificazione tassonomica: classifica il contenuto in una gerarchia di categorie
  4. Analisi emozionale: analizza emozioni specifiche (Rabbia, Paura, Gioia, Tristezza, Disgusto)
  5. Analisi del sentiment: sentiment di frasi target e del testo complessivo
  6. Relazioni tra entità: individuazione delle relazioni di dipendenza tra entità
Immagine dell'articolo

Risultati dell'Analisi

Concetti individuati (in ordine di rilevanza): Machine learning, Computer, Learning, Artificial intelligence, E-mail spam, Cognitive science, Psychology, Scientific method, Computer science, E-mail, Intelligence, Artificial neural network, Alan Turing, Education, Skill, Algorithm, Computer program, Computer vision, Debut albums, Knowledge, Marketing, Fuzzy logic, Information theory, Computational intelligence, Data, Bayesian network, Natural language processing, Stock, Cybernetics, Engine, Medical diagnosis, Machine, Right-wing politics

Parole chiave individuate (in ordine di rilevanza): machine learning, non spam, non spam folders, non spam messages, email messages, new email messages, stock market analysis, artificial intelligence, chem informatics, recommendation engine, various fields, medical diagnosis, brain machine, right product, right customer, data, predictions, example, algorithm, branch, method, computers, interfaces, programs, self, cars

Tassonomia: Watson ha correttamente inquadrato l'argomento centrale, assegnando il punteggio più alto alla classificazione /science/computer science/artificial intelligence. Compare anche /technology and computing/internet technology/email con punteggio più basso a causa dei riferimenti al riconoscimento spam.

Immagine dell'articolo

Analisi Sentiment ed Emotion

Risultati interessanti dall'analisi delle frasi target:

  • Alla parola spam è stato associato un sentiment negative e una emotion sadness
  • Il sentiment è neutral sulla parola stock market analysis con una emotion joy

Sentiment complessivo del documento:

{
    "anger": "0.515118", 
    "joy": "0.140224", 
    "fear": "0.207606", 
    "sadness": "0.097711", 
    "disgust": "0.125342"
}

Relazioni Tipizzate

Watson ha identificato che nel testo l'entità customer è influenzata (affectedBy) dall'entità recommend, qualificando:

  • customer come Person
  • recommend come EventCommunication

Questo tipo di analisi è particolarmente utile per la costruzione di agenti virtuali, chatbot e sistemi che devono capire il contesto dell'interazione.

💰 Aspetto Economico

È interessante valutare l'impatto economico dell'impiego di questi servizi:

Speech to Text: contabilizzato per tempo di impiego (circa 0,02€/Minuto)

  • Per la traccia audio in esame: circa 0,04€

AlchemyAPI: contabilizzato per numero di chiamate (0,00526€/Eventi)

  • Per le informazioni usate in questo post (5 chiamate): circa 0,02€
  • Bonus: le prime 1000 chiamate giornaliere sono gratuite per Organizzazione

Il pricing scala al ribasso in base alla quantità di chiamate. Per esempio, per più di 5 milioni di chiamate il prezzo diventa 0,00015€/Eventi.

🔍 Conclusioni e Applicazioni Future

I tempi di interazione con un sistema come Watson sono molto bassi e le modalità di comunicazione sul piano programmatico sono semplificate al massimo. Cloud + API generation + ML elevano la qualità dell'interazione uomo-macchina ad un livello fatto di dati ed obiettivi.

Potenziali Applicazioni

Una struttura dati come il DataFrame words - in cui per ogni parola riconosciuta è registrata la sua posizione (timestamp inizio/fine) nel flusso audio - apre a operazioni innovative:

  1. Ricerca audio/video con query testuali: cercare occorrenze di parole ottenendo timestamp utilizzabili per estrarre blocchi di fotogrammi specifici

  2. Gestione file multimediali intelligente: categorizzazione e recupero automatico basato sul contenuto reale

  3. Sistemi di sorveglianza avanzati: individuazione e recupero automatizzato di porzioni di registrazioni attraverso filtri testuali complessi

  4. Applicazioni marketing: analisi sentiment e contenuto di materiale audio/video su larga scala

Siamo su un piano di gestione dei file multimediali (dati non strutturati per definizione) dove categorizzazione e recupero possono essere fatti automaticamente in base al reale contenuto. Le possibilità di impiego sono veramente enormi. Ciò che apprezzo non è solo la vastità dei problemi che si possono indirizzare, quanto la facilità con cui si possono assemblare soluzioni altamente scalabili sia tecnicamente sia economicamente.