Indice dei contenuti
Questo articolo è il primo di una serie di approfondimenti dedicati al Machine Learning, la branca dell'intelligenza artificiale che si pone come obiettivo quello di sviluppare sistemi che consentano ai sistemi computazionali (computer, robot, software, etc.) di apprendere e svolgere azioni ed attività in modo simile a quello degli esseri umani o animali, ovvero imparando dall'esperienza.
In questo approfondimento cercheremo di mettere a fuoco i principali benefici connessi all'apprendimento dei principi del Machine Learning per uno sviluppatore software tradizionale, ovvero abituato a realizzare i propri applicativi seguendo un approccio basato sullo sviluppo di funzioni logiche.
Premessa
Prima ancora di iniziare la nostra panoramica è fondamentale sgombrare il campo da un equivoco di fondo, estremamente diffuso tra i non addetti ai lavori e non di rado colpevolmente portato avanti dalla stampa generalista: le tecniche di programmazione basate sul Machine Learning non sono in alcun modo sostituive, oppositive o alternative all'approccio tradizionale: al contrario, il loro scopo è proprio quello di integrarsi in modo organico all'interno delle metodologie tipiche di programmazione funzionale, procedurale e/o a oggetti, che continuano ad avere un'importanza fondamentale. Di conseguenza, ritenere che uno sviluppatore non possa "adattarsi" all'utilizzo di questi strumenti innovativi è un grosso errore da cui devono guardarsi tutti gli attori coinvolti nel processo di innovazione tecnologica che non di rado comporta l'adozione di simili tecnologie.
- E' dunque sbagliato, per il management aziendale, ritenere che il modo più veloce per garantire un "salto di qualità" da un modello tradizionale a una soluzione basata sul Machine Learning possa essere quello di rimpiazzare il proprio reparto di sviluppo - magari percepito come "anziano" - con un nuovo team, magari formato da sviluppatori più giovani, nella speranza che sia "più esperto" nell'utilizzo delle nuove tecnologie: un simile convincimento ruota infatti attorno all'assunto fallace che questa nuova metodologia possa fare a meno dell'esperienza accumulata in anni di attività volta a informatizzare, sia pure in modo "tradizionale", i processi aziendali, procedimento che - come vedremo - costituisce invece una delle pietre miliari su cui si fonda il concetto stesso di Machine Learning.
- Ed è similmente sbagliato, per uno sviluppatore in età avanzata, pensare di non essere in grado di comprendere il funzionamento degli algoritmi di auto-apprendimento e/o di poterli integrare all'interno dei software che è attualmente in grado di realizzare: anche questo assunto, come avremo modo di approfondire, è in contraddizione con le modalità di utilizzo proprie dei Machine Learning Framework ad oggi disponibili, quasi tutti ideati con l'obiettivo di semplificare al massimo la programmazione e la scrittura del codice sorgente grazie alla disponibilità di un gran numero di librerie già pronte da utilizzare.
Quelli descritti sopra sono soltanto alcuni dei principali errori di valutazione compiuti dai principali attori che decidono di intraprendere (o che sono coinvolti da) un percorso di innovazione aziendale basato sull'introduzione di metodologie di Machine Learning.
In termini più generali, ritenere che un software developer non possa rinnovarsi è un modo di pensare che si pone in aperta contraddizione con il ruolo che tale figura professionale da sempre svolge nel tessuto produttivo mondiale, trattandosi di un lavoro che ha sempre richiesto un percorso di studio e aggiornamento costante. Al contrario, è proprio la capacità di apprendimento continuo e il processo di "stratificazione" delle conoscenze via via accumulate nel corso della propria esperienza lavorativa a definire più di ogni altra cosa la seniority di uno sviluppatore, nonché - per esteso - il suo principale parametro di efficienza e utilità all'interno del proprio team di sviluppo. Non comprendere questo aspetto fondamentale significa non rendersi conto delle dinamiche alla base di un settore, quello dell'Information Technology, che negli ultimi decenni ha raggiunto - per importanza, dimensioni, produttività e responsabilità - un ruolo preminente nella quasi totalità delle aziende a livello mondiale.
A cosa serve il Machine Learning?
Sfatato il mito dello sviluppatore "obsoleto" rimpiazzabile dalla contraddizione in termini prodotta dall'idealizzazione del "giovane esperto" (e magari, perché no, anche più "economico"), cerchiamo di comprendere quali sono i motivi che rendono il Machine Learning uno strumento potenzialmente molto utile per qualsiasi sviluppatore tradizionale. In estrema sintesi, i vantaggi ruotano attorno ai seguenti punti fondamentali:
- Ridurre il tempo speso a scrivere codice, quindi risparmiare tempo nella fase di implementazione iniziale (startup).
- Ottenere risultati migliori più rapidamente, quindi risparmiare tempo (e ottenere un risultato migliore) nel periodo di manutenzione evolutiva (refinement/patching).
- Affrontare problemi non risolvibili con le metodologie di sviluppo tradizionali.
Come si può vedere siamo di fronte a un gain importante, in quanto pertiene ai due aspetti più importanti dell'operatività aziendale: il risparmio sulla componente temporale (che si traduce in riduzione dei costi) e un possibile guadagno in termini di performance (ovvero nel raggiungimento di un livello di servizio più elevato). Ovviamente si tratta di opportunità che non valgono in termini assoluti, ma che riguardano alcune specifiche situazioni che il software developer è tipicamente chiamato ad affrontare nel corso della pluralità di attività che svolge nel corso della sua attività.
Ad esempio, si pensi alla necessità di sviluppare un programma o un algoritmo che corregga gli errori di digitazione: l'approccio funzionale "tradizionale" prevederà quasi certamente l'adozione di una serie di tecniche basate su strutture di controllo (if-then-else), cicli iterativi (foreach, do-while), tecniche di scomposizione e/o manipolazione del testo, e così via; si tratta di un approccio che richiederà quasi certamente la scrittura di molte linee di codice prima di diventare realmente efficace. Il Machine Learning consente di percorrere un approccio alternativo, ovvero l'adozione di un modello di auto-apprendimento che potrebbe richiedere meno tempo da implementare e mettere a punto, specialmente se lo sviluppatore potrà contare su un sufficiente quantitativo di casi di esempio a disposizione da utilizzare per "allenare" il modello in questione.
Quanto detto poc'anzi vale per i primi due vantaggi che abbiamo elencato: il terzo, leggermente più complesso, merita un discorso a parte.
Un approccio innovativo
Ciascuno di noi, grazie alle capacità intellettive e mnemoniche di cui è dotato, è in grado di svolgere un gran numero di attività complesse in modo "semplice": ad esempio, possiamo riconoscere i nostri amici o conoscenti guardando le loro facce o ascoltando le loro voci quando non li vediamo; si tratta di operazioni che svolgiamo senza particolari difficoltà e in modo quasi automatico, senza bisogno di rifletterci o di attivare ragionamenti complessi, al punto di poter affermare che ci vengono "naturali".
Sfortunatamente, i computer e i programmi non funzionano così: riuscire a riprodurre questo tipo di attività con i paradigmi di programmazione tradizionali è pressoché impossibile, in quanto gli strumenti che questi approcci mettono a nostra disposizione (funzioni, classi, etc.) sono pensati per riprodurre una realtà altamente strutturata e predeterminata, o per meglio dire predeterminabile. Si tratta di un limite comune persino alla programmazione orientata agli oggetti, nonostante si tratti di un paradigma pensato per fornire un supporto alla modellazione software basato sulla riproduzione di oggetti (e relative interazioni) simili a quelli del mondo reale; ma si tratta anche in quel caso di una rappresentazione meccanicistica della realtà, basata sulla creazione di prototipi inerti caratterizzati da variabili, metodi e proprietà di ordine funzionale. Non a caso, quasi tutti i corsi sulla programmazione a oggetti propongono classi di esempio che riproducono il funzionamento di utensili di vario tipo (veicoli, sensori, etc) che gestiscono attività di input-output in modo atomico e ripetibile: accelera/decelera, accendi/spegni, somma/sottrai, inserisci/elimina, e via dicendo.
1 2 3 4 5 6 7 |
public bool Spegni() { if (Acceso) { // TODO: implementare lo spegnimento. return true; } else return false; } |
Del resto, come potremmo ragionevolmente implementare all'interno di un metodo "funzionale" attività basate su ragionamenti "interpretativi" come - ad esempio - un'attività di traduzione, senza scrivere migliaia, se non milioni, di righe di codice?
1 2 3 |
public string Traduci(string sourceString, Language lang) { // TODO: implementare la traduzione di [sourceString] nella lingua [lang] } |
Gli esempi di codice di cui sopra ci aiutano a comprendere un punto fondamentale: il limite non è affatto del paradigma di programmazione, ovvero nella programmazione orientata agli oggetti, quanto piuttosto nella mancanza di un approccio implementativo adeguato a risolvere problematiche di questo tipo. In altre parole, ciò di cui realmente abbiamo bisogno non è un nuovo metodo di programmare o intendere la programmazione, ma un set di strumenti che ci consenta di implementare in modo efficiente ed efficace il nostro TODO. Come avremo modo di vedere in questo articolo (e negli articoli successivi), lo scopo dei modelli di Machine Learning è proprio quello di riempire questo gap; ovviamente, però, per poterlo fare in modo efficace devono poter disporre di alcune informazioni (training data) che possano consentir loro di gestire in modo efficace la nostra "richiesta di traduzione".
Questi dati, che consentono al modello di iniziare - ed eventualmente portare avanti - il proprio percorso di (auto)apprendimento, possono essere:
- Forniti insieme alla richiesta, attività che però costringe a ripetere il processo di apprendimento ogni volta con un evidente impatto prestazionale.
- Caricati in precedenza, in modo da non impattare minimamente sulle performance, rinunciando però a migliorare il modello "in tempo reale".
- Caricati in precedenza e aggiornati con i nuovi dati della richiesta, in modo da impattare sulle performance in modo limitato (retraining) e garantendo nel contempo un auto-apprendimento del modello in tempo reale.
Ovviamente, come spesso accade in programmazione, non esiste una scelta "ottimale" per qualsiasi circostanza, ma sarà compito dello sviluppatore individuare quella di volta in volta più indicata a seconda delle caratteristiche proprie del caso specifico: la velocità del processo di apprendimento, a sua volta legata al numero (volume) di dati di training; la pertinenza della richiesta, ovvero la sua efficacia in termini di miglioramento del processo di training; le prestazioni richieste dall'applicativo in rapporto con le risorse a disposizione della macchina che lo ospita; il costo in termini computazionali (o di banda, o altro) delle attività del modello; e tantissimi altri aspetti e/o fattori.
Come si può vedere, la faccenda comincia a farsi complicata: eppure, a ben vedere, si tratta delle medesime dinamiche e problematiche alla base delle scelte che lo sviluppatore è abituato a prendere innumerevoli volte nel corso della sua attività lavorativa. In definitiva, dunque, benché il Machine Learning sia uno strumento nuovo, molte delle problematiche che la sua adozione comporta ricordano piuttosto da vicino quelle di altri strumenti a lui complementari: a partire dal software, o per meglio dire dal paradigma di programmazione, all'interno del quale viene implementato.
Queste somiglianze, di gran lunga superiori alle differenze, saranno ulteriormente dettagliate negli approfondimenti successivi.
Un cambio di prospettiva
Sulla base di quanto detto sopra, appare sempre più evidente come il principale cambiamento che lo sviluppatore è tenuto a compiere non sia tecnico, bensì "filosofico": a ben vedere il Machine Learning non cambia il modo di programmare, quanto piuttosto il modo di pensare alla risoluzione di una determinata tipologia di problemi.
Gli sviluppatori software sono convenzionalmente abituati ad affrontare i problemi in modo logico e matematico, in quanto le metodologie di programmazione che hanno studiato negli ultimi decenni forniscono soluzioni particolarmente efficaci nel momento in cui si adotta quel tipo di approccio. Con l'apprendimento automatico, le cose cambiano profondamente: l'oggetto di analisi si sposta dalla "certezza" di un numero definito di assertion da dimostrare in modo logico/matematico ad una "incertezza" da risolvere per approssimazioni successive in modo statistico/inferenziale.
Lo sviluppatore deve quindi riscoprire la propria indole di scienziato/pioniere, eseguendo esperimenti e analizzando (spesso a posteriori) i risultati: come si può facilmente comprendere, si tratta di un percorso diverso, ma che può restituire ancora una volta grandi soddisfazioni e gratificazioni a una professione che non ha mai smesso di evolvere... a patto di avere ancora la voglia di mettersi in gioco.
Articoli correlati
- INTELLIGENZA ARTIFICIALE
- MACHINE LEARNING