ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 150
Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 126
Abonament PDF

Microsoft ML.NET 2.0: Cum îmbunătățim un model de machine learning în trei pași simpli

Daniel Costea
Senior Software Developer @ EU Agency



PROGRAMARE


Ca .NET developer am fost tentat de multe ori spre lumea Python datorită a ceea ce oferă în domeniul AI. Îmi amintesc că pregăteam un material pentru un eveniment, în care făceam o demonstrație pentru .NET pe Raspberry Pi. Fiind pe Raspberry Pi nu se poate să reziști prea mult din a folosi datele direct de la senzori. Cum am citit o mulțime de date de la senzori, în mod natural a venit pasul următor, acela de a face ceva cu aceste date. Se cunoaște că partea nevralgica în AI este lipsa datelor. Dacă nu ai date, nu ai distracție. Eu aveam acele date însă nu știam ce să fac cu ele, chiar dacă în ele stătea un potențial uriaș. Acum îmi place să spun că în AI datele nu sunt combustibilul, ci motorul, spre deosebire de programarea clasică.

Prin urmare, am datele, dar nu știu ce să fac cu ele. Să îmi extind cunoștințele spre un alt limbaj nu e neapărat o problemă, dar să învăț librăriile aferente ar deveni repede o problemă de timp și de integrare. Să ne imaginăm un mediu în care toate procesele sunt pregătite pentru o soluție .NET. Să trebuiască să pregătești mediul pentru Python poate fi o problemă serioasă pentru un developer .NET, pentru că este un alt ecosistem.

Momentul în care ML.NET a fost lansat a fost perfect pentru mine pentru că am simțit că am primit o pereche de aripi. ML.NET este simplu de folosit pentru crearea unui model de ML, chiar și de către cei care nu au cunoștințe de Data Science și, poate cel mai important lucru, este un framework .NET în care scrii exclusiv cod C#.

ML.NET este un framework tânăr și are mult de recuperat până să ajungă la nivelul liderilor din AI. Însă nu știu dacă ar trebui să vedem doar dezavantajele. Să ne uitam puțin peste acest whitepaper https://arxiv.org/pdf/1905.05715.pdf:

Using a 9GB Amazon review data set ML.NET trained a sentiment-analysis model with 95% accuracy. Other popular machine learning frameworks failed to process the dataset due to memory errors. Training on 10% of the data set, to let all the frameworks complete training, ML.NET demonstrated the highest speed and accuracy.

The performance evaluation found similar results in other machine learning scenarios, including click-through rate prediction and flight delay prediction.

Model Builder (AutoML)

ML.NET pune, prin Model Builder, la dispoziția developerilor un tool foarte util pentru antrenarea de modele ML pentru o fereastră de timp predefinită, pornind de la un set de date și terminând cu selecția celui mai bun trainer pentru scenariul selectat. Selecția se face în funcție de calitatea modelelor explorate, modelul ML astfel obținut putând fi consumat imediat. În plus, Model Builder este capabil să genereze cod boilerplate cu toți pașii făcuți în mod interactiv oferind un bun punct de pornire în lumea AI.

Model Builder este un tool extraordinar care îți permite preselectarea feature-urilor pe care le dorești intrate în construirea modelului, dar nu îți oferă nicio sugestie despre care feature-uri sunt mai relevante. Pe de altă parte, un model care conține prea multe feature-uri va necesita un timp mai mare de antrenare dar și de predicție. De asemenea, de multe ori, unele feature-uri mai mult alterează calitatea modelului construit decât ajută, demonstrând că prin reducerea atentă a dimensionalității modelului ML am putea crește acuratețea și performanța modelului.

Menționam anterior că Model builder este capabil să genereze cod boilerplate. Dar ca developeri am vrea să automatizam acest proces de antrenare a modelului ML și nu ne satisface să avem codul astfel generat.

În același timp sunt și avantaje: în spatele Model builderului stă AutoML, care oferă experiența de antrenare a modelului ML. Ar fi extraordinar dacă am putea să preluam controlul asupra acestui cod și să facem câțiva pași mai departe analizând calitatea acestui model, pentru a putea face câteva dintre îmbunătățirile dorite.

Presupunând că am încărcat unele date în obiectul training DataView, acestea cele sunt câteva linii care declanșează experimentarea AutoML pentru clasificarea multi-class într-un interval de timp dat. Acesta este scenariul pe care l-am ales pentru acest articol.

Context = new MLContext(seed: 1);     
SweepablePipeline preprocessingPipeline = 
  Context.Transforms.Conversion
   .MapValueToKey(columnInference.ColumnInformation
      .LabelColumnName, columnInference
      .ColumnInformation.LabelColumnName)
   .Append(Context.Auto().Featurizer(data, 
      columnInformation: columnInference
      .ColumnInformation));

var pipeline = preprocessingPipeline   
  .Append(Context.Auto().MultiClassification(
     labelColumnName: columnInference
        .ColumnInformation.LabelColumnName));

AutoMLExperiment experiment = Context.Auto()
  .CreateExperiment()
  .SetPipeline(pipeline)
  .SetMulticlassClassificationMetric(
    MulticlassClassificationMetric.MicroAccuracy, 
    labelColumn: columnInference.ColumnInformation
    .LabelColumnName)
  .SetTrainingTimeInSeconds(time)
  .SetDataset(data);

var experimentResult = await experiment.RunAsync();

AutoML Output:

Best trainer: FastTreeOva Accuracy: 0.926  Training time: 338
------------------------------------------------------------
      MicroAccuracy MacroAccuracy LogLoss LogLossReduction
       0.926         0.929         0.235   0.826

Analiza modelului

"Măsoară de două ori și taie o singură dată."

Aș dori să mergem puțin mai departe și să vedem cum putem îmbunătăți un model de ML. Subliniez, facem acest lucru fără a avea cunoștințe de Data Science, dar deținerea de noțiuni elementare despre Data Science ar ajuta să înțelegi mai bine ce faci.

Am putea crede că cea mai dificilă este construirea modelului de antrenare, pentru că, în mod evident, acolo pare să se întâmple magia lucrurilor. Dar pentru această parte ne ajută Model Builder cu AI sau AutoML. De fapt, cel mai complicat este să construim un model suficient de bun. Pentru a realiza acest lucru, ne vom baza pe analiza din correlation matrix și analiza din PFI, doi pași, pe care dacă i-am automatiza, ar fi extraordinar. Deoarece pentru fiecare model realizat prin AutoML, am putea să avansăm obținând cu efort minim un model mai bun.

Correlation Matrix

În Machine Learning, o matrice de corelație (cunoscută și ca "heatmap") este un tabel care afișează coeficienții de corelație dintre toate perechile posibile de caracteristici existente (cum ar fi produsul cartezian).

În general, a avea mai multe caracteristici este un avantaj, care crește însă dimensionalitatea modelului nostru. Dar chiar avem nevoie de toate aceste caracteristici? Unele caracteristici ar putea fi destul de redundante.

O valoare mai apropiată de 0 înseamnă caracteristici corelate scăzute (sau nu), o valoare mai apropiată de 1 înseamnă caracteristici corelate ridicate, iar o valoare mai apropiată de -1 înseamnă caracteristici inversate înalt corelate.

var matrix = Correlation.PearsonMatrix(dataArray);

Rezultatele din Correlation Matrix (folosind un prag predefinit de 0,9):

Correlation Matrix, threshold: 0.9
-------------------------------------------------------------
        TemperatuTemperatuLuminosit Infrared Distance PIR    Humidity
 Temperature 1.0000   0.9998  0.4831  0.5865  -0.2873  -0.0020   0.0607
Temperature2 0.9998   1.0000  0.4822  0.5855  -0.2859  -0.0018   0.0621
  Luminosity 0.4831   0.4822  1.0000  0.4388  -0.5428   0.1175   0.0457
    Infrared 0.5865   0.5855  0.4388  1.0000  -0.3765   0.0359   0.0051
    Distance -0.2873  -0.2859 -0.5428 -0.3765  1.0000  -0.1412  -0.0824
        PIR  -0.0020  -0.0018 0.1175   0.0359  -0.1412  1.0000   0.0809
    Humidity 0.0607   0.0621  0.0457   0.0051  -0.0824  0.0809   1.0000
-------------------------------------------------------------

---------------------
No Feature         vs. Feature                    Rate
1. Temperature     vs. Temperature2             0.9998

Pentru că Temperature2 și Temperature au măsurători redundante- în realitate, acești senzori sunt foarte apropiați!- putem alege să eliminăm una din ele.

Permutation Feature Importance

Folosind Permutation Feature Importance (PFI), învățăm cum să interpretăm predicțiile modelului de învățare automată ML.NET, deoarece PFI ne arată contribuția relativă pe care fiecare caracteristică o are în predicție. Modul în care funcționează PFI este prin amestecarea aleatorie a datelor, câte o caracteristică la un moment dat, pentru întregul set de date și calcularea scăderii indicatorului de performanță de interes. Cu cât schimbarea este mai mare, cu atât această caracteristică este mai importantă. În plus, evidențiind cele mai relevante caracteristici, ne putem concentra pe utilizarea unui subset de trăsături mai semnificative care pot reduce potențial zgomotul și timpul de antrenament. Trebuie să decidem cu atenție de ce caracteristici nu avem nevoie, deoarece eliminând unele dintre ele mai puțin relevante, riscăm să introducem bias în modelul nostru.

Putem observa ocazional valori negative în rezultatele PFI. În acele cazuri, predicțiile privind datele amestecate ("shuffled" sau "noisy") au fost mai precise decât datele reale. Acest lucru se întâmplă atunci când caracteristica nu a contat (ar fi trebuit să aibă o relevanță apropiată de 0), dar șansa aleatorie a făcut ca predicțiile privind datele amestecate să fie mai precise. Acest lucru este mai frecvent cu seturile de date mici, precum cel din acest exemplu, deoarece există mai mult spațiu pentru noroc sau șansă.

Codul poate părea puțin mai complicat, deoarece trebuie să replicăm pipeline-ul folosit pentru AutoML.

var model = experimentResult.Model as Microsoft.ML.Data.TransformerChain;
var transformedTrainingData = experimentResult.Model
    .Transform(trainingData);

var pfi = Context.MulticlassClassification
     .PermutationFeatureImportance(
      model.LastTransformer, transformedTrainingData, 
      permutationCount: 3);

var metrics = pfi.Select(p => (p.Key, 
  p.Value.MicroAccuracy))
  .OrderBy(m => m.MicroAccuracy.Mean);

Rezultatele PFI (folosind un prag predefinit de 0.02):

PFI (by MicroAccuracy), threshold: 0.02
----------------------------------------------------------------------
    No Feature           MicroAccuracy        95% Mean
    1. Infrared                -0.2467          0.0274
    2. Luminosity              -0.2181          0.0121
    3. Temperature             -0.1224          0.0019
    4. Distance                -0.0795          0.0025
    5. Temperature2            -0.0257          0.0043
    6. CreatedAt               -0.0186          0.0074 
      (candidate for deletion!)
    7. PIR                     -0.0076          0.0033 
      (candidate for deletion!)
    8. Humidity                 0.0000          0.0000 
      (candidate for deletion!)

Extragem trainerul cel mai bun obținut cu AutoML și facem evaluarea sa.

var predictions = experimentResult.BestRun.Model
   .Transform(testingData);

var metrics = Context.MulticlassClassification
   .Evaluate(predictions);

Rezultatele evaluării folosind dataset-ul original:

Best trainer: FastTreeOva     Accuracy: 0.926  Training time: 338
----------------------------------------------------------------------
 MicroAccuracy      MacroAccuracy            LogLoss   LogLossReduction
    0.926              0.929              0.235              0.826

Acum putem să scăpăm de caracteristicile redundante (indicate de matricea de corelație) și de caracteristicile irelevante (indicate de PFI) din setul de date și să trecem la o altă experimentare cu setul de date diminuat și să verificăm din nou setările de evaluare.

Lista de caracteristici arată așa acum:

var features = { "Temperature", "Luminosity",
                 "Infrared", "Distance" };

Rezultatele evaluării cu lista redusă de caracteristici (fără caracteristicile redundante sau irelevante).

Best trainer: FastTreeOva    Accuracy: 0.943  Training time: 342
----------------------------------------------------------------------            MicroAccuracy      MacroAccuracy            LogLoss   LogLossReduction
    0.943              0.942              0.207              0.847

Concluzie

"Mai puțin înseamnă mai mult."

Dacă avem un set de date cu multe caracteristici neprocesate, PFI va marca caracteristicile candidate pentru ștergere. Înlăturând una sau mai multe dintre aceste caracteristici și reantrenând modelul, putem obține un model mai bun. (AutoML se va ocupa de găsirea celui mai bun antrenor pentru un anumit set de caracteristici.)

Dacă Corelation Matrix identifică caracteristici foarte corelate, din nou, este posibil să ștergem astfel de caracteristici una câte una, să facem reantrenarea și să verificăm dacă modelul se îmbunătățește cu noul set de caracteristici.

O îmbunătățire plăcută a codului sursă asociat acestui articol ar fi automatizarea ștergerii celor mai irelevante caracteristici (folosind PFI) sau a celor mai corelate (redundante) caracteristici (folosind Corelation Matrix).

Puteți găsi codul sursă din acest articol aici și mai multe articole despre ML.NET pe blogul personal.

NUMĂRUL 149 - Development with AI

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects