Photo by Markus Winkler on Unsplash
PHP è un linguaggio molto popolare, e quando qualcosa diventa molto popolare di solito capita che qualcuno se ne esca dicendo “non è figo”, e va bene, succede. Ho letto tanti articoli che dicevano “PHP non è figo per il machine learning” oppure “passa al linguaggio X per farlo, lì funzionerà meglio” (non voglio attaccare un altro linguaggio, sto solo parlando di cose a caso che si trovano su internet).
Sono un amante di PHP, non lo nego: ho provato linguaggi diversi, framework, ho sviluppato applicazioni native, adoro provare cose nuove ma amo anche PHP. A volte però mi sento frenato dal fatto che all'ecosistema PHP mancano alcune funzionalità estremamente interessanti, come delle potenti librerie di Machine Learning.
L'ultima volta che mi è capitato è stato mentre scrivevo la mia tesi di dottorato. La mia tesi trattava di “Indoor Localization”: dovevo studiare le varie tecniche, delineare un possibile approccio per effettuare la localizzazione e, infine, costruire un sistema sperimentale composto da un'interfaccia web per gestire la localizzazione e un client per utilizzarla.
Per studiare l'Indoor Localization ho recuperato molti paper da IEEE Explore grazie all'accesso della mia università, ho studiato diversi approcci e alla fine ho scelto una combinazione di tecniche per affrontare la mia localizzazione, ma non è questo lo scopo di questo articolo.
E cosa c'entra tutto questo con PHP e il Machine Learning? Beh, è abbastanza curioso: tutti i test che ho fatto per imparare come funzionano le SVM erano in python, perché l'ingegnere che mi aiutava con lo sviluppo era esperto di Python, ma io dovevo scrivere un'applicazione web e quell'ingegnere non era pratico di backend. Così mi è venuta un'idea, ho cercato su Google “PHP svm” e il primo risultato è stato “SVM — Manual — PHP” dalla documentazione di PHP.net.
Ext-svm: cosa e perché
E qui arriveranno le critiche: PHP si è appena avvicinato al Machine Learning, altri linguaggi ce l'hanno da anni, perché dovrei sceglierlo? È semplice, perché ext-svm non è altro che un wrapper della libreria libSVM (dai un'occhiata a libsvm su Github), scritta in C++. Questo significa che ogni volta che vuoi eseguire un'operazione SVM usando PHP, questa verrà eseguita a un livello più basso e i risultati verranno propagati a PHP grazie all'interfaccia di ext-svm.
LibSVM is an efficient solver for SVM classification and regression problems. The svm extension wraps this in a PHP interface for easy use in PHP scripts. As of version 0.2.0 the extension requires PHP 7.0 or above.
Per me è stato fantastico! Era tutto ciò che mi serviva per passare da Python (sviluppatori python, per favore non odiatemi), che non conoscevo così bene, a PHP, in cui sono più esperto.
Installare ext-svm
Prima di tutto, l'estensione è disponibile su Pecl, il che significa che se hai accesso a una riga di comando con permessi di amministratore ti basta
pecl install svm
Tieni presente che ext-svm è attualmente in Beta, quindi se hai problemi con pecl, per installarlo comunque ti basta:
pecl install svm-beta
L'output sarà qualcosa di simile a:
downloading svm-0.2.3.tgz ...
Starting to download svm-0.2.3.tgz (130,776 bytes)
.............................done: 130,776 bytes
7 source files, building
[... skipping the whole output ...]
Build process completed successfully
Installing '/usr/lib/php/20190902/svm.so'
install ok: channel://pecl.php.net/svm-0.2.3
Extension svm enabled in php.ini
Se vuoi verificare che l'estensione sia stata installata correttamente ti basta lanciare:
$ php -m | grep svm
svm
L'estensione è ora installata e sei pronto per partire!
Costruisci il tuo primo classificatore
Per costruire il nostro primo classificatore ci atterremo semplicemente all'esempio della documentazione e verificheremo che funzioni. Il nostro classificatore verrà addestrato a partire da un array e controlleremo se riesce a predire un valore del dataset di addestramento.
<?php
$data = array(
array(-1, 1 => 0.43, 3 => 0.12, 9284 => 0.2),
array(1, 1 => 0.22, 5 => 0.01, 94 => 0.11),
);
$svm = new SVM();
$model = $svm->train($data);
$data = array(1 => 0.43, 3 => 0.12, 9284 => 0.2);
$result = $model->predict($data);
echo $result;
Se salvi questo file e poi lo esegui da console, oppure lo metti su un web server e vi accedi, il risultato dovrebbe essere -1. Perché?
Scomponiamo il nostro codice per capire come funziona. Nelle prime due righe troviamo il nostro array di array che rappresenta i dati
$data = array(
array(-1, 1 => 0.43, 3 => 0.12, 9284 => 0.2),
array(1, 1 => 0.22, 5 => 0.01, 94 => 0.11),
);
Se ti concentri sull'array interno, ogni riga può essere divisa in due parti: il risultato e le feature per l'addestramento. Il primo valore dell'array (all'indice 0) è il risultato della classificazione, seguito dalle feature, quindi per array(-1, 1 => 0.43, 3 => 0.12, 9284 => 0.2) il risultato della classificazione sarà -1 e i valori successivi, raggruppati come coppie chiave/valore, sono le feature.
Dopodiché istanziamo la SVM:
$svm = new SVM();
L'istanza SVM può essere regolata chiamando setOptions, per esempio puoi cambiare il kernel prima dell'addestramento:
$svm->setOptions([ SVM::OPT_KERNEL_TYPE => SVM::KERNEL_SIGMOID ]);
I valori delle costanti per regolare le opzioni si trovano nella documentazione della classe SVM su php.net.
Ora che abbiamo la nostra SVM pronta, possiamo addestrare un modello:
$model = $svm->train($data);
Questa riga restituisce un SVMModel che possiamo usare per le predizioni. Se hai un modello molto grande, puoi semplicemente salvarlo su file con save(string $filename) e ricaricarlo dal filesystem con load(string $filename) in questo modo:
$model->save('model.svm');
// later... somewhere in the code
$model->load('model.svm');
Nota bene: save e load restituiscono un valore booleano, puoi controllarlo o ignorarlo, sta a te!
Le ultime tre righe sono il codice di test:
$data = array(1 => 0.43, 3 => 0.12, 9284 => 0.2);
$result = $model->predict($data);
echo $result;
Prendi le feature che hai misurato e vuoi verificare rispetto al modello e le metti in un array, in questo codice l'array si chiama $data. Quelle feature verranno elaborate dalla SVM usando il training set.
Una volta che i nostri dati sono pronti, possiamo chiamare predict per classificare i dati passati in input e ottenere un output float corrispondente alla predizione. Infine, possiamo stamparlo con echo, oppure usarlo altrove.
Costruito, addestrato, predetto
Photo by Stephen Dawson on Unsplash
Ora il tuo sistema ha l'estensione PHP SVM installata, puoi addestrare un modello, salvarlo, ricaricarlo e fare predizioni: da qui in poi, sta tutto a te!