Modellen evalueren en verbeteren¶

K. Verbeeck, J. Maervoet¶

Data Science (Theory) -- OGI02i

eval.PNG

Deel 1 : Hoe een model evalueren en verbeteren ?¶

Het doel is om te achterhalen hoe goed we data kunnnen voorspellen die niet aanwezig is in de trainingsdata. De fit op de trainingsdata zelf is dus eigenlijk niet zo belangrijk. Wel het generalisatievermogen van het model. We kunnen dit op 2 verschillende manieren verbeteren :

Cross-validatie : de test set wordt op een meer robuuste manier gekozen

Grid-search : een effectieve methode om parameters goed te leren instellen

Deel 2. Metrieken om beter te evalueren¶

metrieken gebruikt tot dusver :

  • voor classificatie : accuracy : tel het aantal juist geclassificeerde data-elementen in de testset tov de grootte van de testset

  • voor regressie : MSE : mean-squared-error : bereken het verschil tussen voorspelde en werkelijke waarde, kwadrateer deze fouten en neem hier een gemiddelde van

Er zijn echter nog veel metrieken die gebruikt kunnen worden en beter geschikt zijn afhankelijk van de applicatie.

Deel 1 : Hoe een model evalueren en verbeteren ?¶

1.1 Cross-Validatie¶

De typische manier totnogtoe om een model te evalueren is door gebruik te maken van de train_test_split methode, daarna met de trainingsdata een model op te stellen via de fit methode, vervolgens de predict methode te gebruiken op de test set en tenslotte via de score methode na te gaan wat de accuracy is op de test set.

In [1]:
from sklearn.datasets import make_blobs
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

# create a synthetic dataset
X, y = make_blobs(random_state=0)

# split data and labels into a training and a test set
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

# instantiate a model and fit it to the training set
logreg = LogisticRegression(solver='liblinear', multi_class='auto').fit(X_train, y_train)

# evaluate the model on the test set
print("Test set score: {:.2f}".format(logreg.score(X_test, y_test)))
Test set score: 0.88

Cross-validatie¶

Tijdens cross-validatie wordt de data meerdere keren gesplit en worden er dus ook meerdere modellen getrained. Typisch wordt k-fold cross-validatie gebruikt waarbij $\bf{k}$ de parameter is die aangeeft in hoeveel gelijke delen (folds genaamd) de data wordt opgesplitst. Vervolgens worden $\bf{k}$ modellen getraind : het eerste model gebruikt de eerste fold als test-set en al de rest als trainingsset, het tweede model gebruikt de tweede fold als testset en de rest als trainingsset enz..

K-fold_cross_validation_EN.jpg

Cross-Validatie in scikit-learn¶

In [2]:
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression

iris = load_iris()
logreg = LogisticRegression(solver='liblinear', multi_class='auto')

scores = cross_val_score(logreg, iris.data, iris.target, cv = 3)
print("Cross-validation scores: {}".format(scores))
Cross-validation scores: [0.96 0.96 0.94]
In [3]:
scores = cross_val_score(logreg, iris.data, iris.target)
print("Cross-validation scores: {}".format(scores))
Cross-validation scores: [1.         0.96666667 0.93333333 0.9        1.        ]
In [4]:
print("Average cross-validation score: {:.2f}".format(scores.mean()))
Average cross-validation score: 0.96
In [5]:
from sklearn.model_selection import cross_validate
res = cross_validate(logreg, iris.data, iris.target, cv=5,
                     return_train_score=True)
display(res)
{'fit_time': array([0.00200438, 0.00100017, 0.00099945, 0.00099897, 0.00199986]),
 'score_time': array([0.00099516, 0.00099921, 0.00099945, 0.00099778, 0.        ]),
 'test_score': array([1.        , 0.96666667, 0.93333333, 0.9       , 1.        ]),
 'train_score': array([0.95      , 0.96666667, 0.96666667, 0.975     , 0.95833333])}
In [6]:
import pandas as pd
res_df = pd.DataFrame(res)
display(res_df)
print("Mean times and scores:\n", res_df.mean())
fit_time score_time test_score train_score
0 0.002004 0.000995 1.000000 0.950000
1 0.001000 0.000999 0.966667 0.966667
2 0.000999 0.000999 0.933333 0.966667
3 0.000999 0.000998 0.900000 0.975000
4 0.002000 0.000000 1.000000 0.958333
Mean times and scores:
 fit_time       0.001401
score_time     0.000798
test_score     0.960000
train_score    0.963333
dtype: float64

Er is een variantie in accuracy tussen de verschillende folds : sommige folds halen $100\%$, andere $90\%$. Dit kan 2 dingen betekenen:

    - het model is sterk afhankelijk van de geselecteerde fold
    - dit voorbeeld bevat te weinig data

Overzicht Cross-validatie :¶

  • elk datapunt komt exact 1 keer in een test set terecht, dus als alle cv scores hoog genoeg moeten scoren, moet het model voldoende kunnen generaliseren over elk datapunt ! Wanneer je randomness gebruikt om een testset samen te stellen, kan het zijn dat net je moeilijke voorbeelden in de testset terecht komen waardoor de accuracy waarschijnlijk te laag ingeschat wordt. In het omgekeerde geval, kunnen alle makkelijke datapunten in de testset terecht komen, je accuracy wordt waarschijnlijk veel te hoog ingeschat!
  • door de verschillende accuracies op de verschillende folds te zien kan je inschatten wat je best-case prestatie zou kunnen zijn en wat je worst-case scenario is.
  • Door meerdere folds te kiezen kan typisch ook meer data gebruikt worden om het model op te stellen.
    • Stel : gewone split $30%$ versus $70\%$ -> $70%$ van de data wordt gebruikt om het model te bouwen.
    • Stel $k=5$ -> $\frac{4}{5}$de = $ 80\%$ van de data kan gebruikt worden om het model te bouwen.
    • Stel $k=10$ -> $\frac{9}{10}$de = $ 90\%$ van de data kan gebruikt worden om het model te bouwen.
  • Natuurlijk, meer modellen trainen vraagt meer rekenkracht !
  • Merk op : Cross-validatie dient om een model beter/realistischer te evalueren, de techniek op zich geeft geen model als resultaat terug !

Stratified Cross-validatie¶

Merk op : in het geval van classificatie :

Bij het opdelen van de datasets in folds kan je best rekening houden met hoe de verschillende klassen verspreid zijn over de data. Een fold met alleen voorbeelden uit 1 klasse is geen nuttige testset, en dus ook geen nuttige fold!

In [7]:
from sklearn.datasets import load_iris
iris = load_iris()
print("Iris labels:\n{}".format(iris.target))
Iris labels:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

Stel dat er hier 3 folds gemaakt worden, met per fold telkens de data van 1 klasse ???

-> zorg ervoor dat per fold alle klassen gelijkwaardig verdeeld zijn, dit noemt men Stratified cross-validation

Stratified Cross-validation¶

stratified.png

Uit de documentatie van de cv parameter : sklearn.model_selection.cross_val_score :

cv : int, cross-validation generator or an iterable, optional Determines the cross-validation splitting strategy. Possible inputs for cv are:

- None, to use the default 5-fold cross validation,
- integer, to specify the number of folds in a (Stratified)KFold,
- CV splitter,
- An iterable yielding (train, test) splits as arrays of indices.

For integer/None inputs, if the estimator is a classifier and y is either binary or multiclass, StratifiedKFold is used. In all other cases, KFold is used.

Er is echter ook een shuffle parameter !

In [8]:
from sklearn.model_selection import KFold
kfold = KFold(n_splits=3)
print("Cross-validation scores:\n{}".format(
    cross_val_score(logreg, iris.data, iris.target, cv=kfold)))
Cross-validation scores:
[0. 0. 0.]
In [9]:
kfold = KFold(n_splits=3, shuffle=True, random_state=0)
print("Cross-validation scores:\n{}".format(
    cross_val_score(logreg, iris.data, iris.target, cv=kfold)))
Cross-validation scores:
[0.9  0.96 0.96]

Leave-one-out cross validation¶

Beschouw het extreme geval waarbij $k = \; de \; grootte \; van \; de \; dataset$. Elke fold bevat dan exact 1 data element. Deze techniek heet leave-one-out cross validation, deze is uiteraard time-consuming maar vooral interessant voor kleine datasets.

LOO.jpeg

GroupKFold¶

Het zou kunnen dat los van de klassen er nog een andere groepsindeling in de data gemaakt kan worden, bvb. :

- speech recognition : je hebt meerdere recordings van dezelfde stem in je data
- beeldherkenning : je hebt meerdere fotos van dezelfde persoon in je data
- medische applicaties : je hebt meerdere samples van dezelfde patient.

GroupKfold zal ervoor zorgen dat de groep samen blijft en dus ofwel integraal in de training of in de test zit, merk op dit heeft niets te maken met de klaslabels.

groupKfold.png

Deel 1 : Hoe een model evalueren en verbeteren ?¶

1. 2 Grid Search¶

Doel : Zoek de betere waarden van de parameters van een model zodat ze optimaal generaliseren.

Voorbeeld : Elbow methode, evalueer de waarde van parameter $k$ op de test-set

Gevaar : Als de testset gebruikt wordt om de parameters te leren instellen, kunnen we diezelfde set dan nog gebruiken om te evalueren hoe goed het model generaliseert? (want de parameters zijn al getuned voor deze set en er bestaat gevaar op overfitting op de testset)

Oplossing : We hebben nog een derde onafhankelijke set van data nodig eentje die specifiek gebruikt kan worden om de parameter tuning te doen : deze set noemen we de validatie set

validatieset.png

In [10]:
from sklearn.model_selection import train_test_split 

# split data into train+validation set and test set
X_trainval, X_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0)

# split train+validation set into training and validation sets
X_train, X_valid, y_train, y_valid = train_test_split(X_trainval, y_trainval, random_state=1)

print("Size of training set: {}   size of validation set: {}   size of test set:"
      " {}\n".format(X_train.shape[0], X_valid.shape[0], X_test.shape[0]))
Size of training set: 84   size of validation set: 28   size of test set: 38

In [11]:
from sklearn.tree import DecisionTreeClassifier

best_score = 0

# make a grid for parameter tuning
for depth in [1,2,3,4,5]:
    for rs in [0,5,10,20,40]:
    # for each combination of parameters train a decisiontree
        tree = DecisionTreeClassifier(max_depth=depth, random_state=rs)
        tree.fit(X_train, y_train)
        # evaluate for the validation set
        score = tree.score(X_valid, y_valid)
        # store the best scores
        if score > best_score:
            best_score = score
            best_parameters = {'max_depth': depth, 'random_state': rs}

print("Best parameters: ", best_parameters)
Best parameters:  {'max_depth': 3, 'random_state': 0}
In [12]:
# rebuild a model on the combined training and validation set,
# and evaluate it on the test set
tree = DecisionTreeClassifier(**best_parameters)
tree.fit(X_trainval, y_trainval)
training_score = tree.score(X_train, y_train)
test_score = tree.score(X_test, y_test)

print("Training set score with best parameters : {:.2f}".format(training_score))
print("Best score on validation set: {:.2f}".format(best_score))
print("Test set score with best parameters: {:.2f}".format(test_score))
Training set score with best parameters : 1.00
Best score on validation set: 0.93
Test set score with best parameters: 0.97

Unpacking with *args en **kwargs¶

Unpacking.png

zie artikel : https://realpython.com/python-kwargs-and-args/

Deel 1 : Hoe een model evalueren en verbeteren ?¶

1.3 Grid search in combinatie met Cross-validatie¶

Cross-validatie wordt vaak gebruikt in combinatie met grid search, men verwijst vaak gewoon naar de term cross-validatie om beide technieken samen aan te duiden : in plaats van een enkele split te maken tussen training en validatie set, wordt hier cross-validatie gebruikt

In [13]:
# make a grid for parameter tuning
for depth in [1,2,3,4,5]:
    for rs in [0,5,10,20,40]:
    # for each combination of parameters train a decisiontree
        tree = DecisionTreeClassifier(max_depth=depth, random_state=rs)
        # Extra step : perform cross-validation here (trainval will be split in training en validation several times)
        scores = cross_val_score(tree, X_trainval, y_trainval, cv = 5)
        # compute mean cross-validation accuracy
        score = scores.mean()
        # store the best scores
        if score > best_score:
            best_score = score
            best_parameters = {'max_depth': depth, 'random_state': rs}

print("Best parameters: ", best_parameters)
Best parameters:  {'max_depth': 3, 'random_state': 0}
In [14]:
tree = DecisionTreeClassifier(**best_parameters)
tree.fit(X_trainval, y_trainval)
training_score = tree.score(X_trainval, y_trainval)
test_score = tree.score(X_test, y_test)

print("Training set score with best parameters : {:.2f}".format(training_score))
print("Best score on validation set: {:.2f}".format(best_score))
print("Test set score with best parameters: {:.2f}".format(test_score))
Training set score with best parameters : 0.98
Best score on validation set: 0.96
Test set score with best parameters: 0.97

Overzicht :¶

GridSearchCV.png

De combinatie van Grid search met CV is zo populair dat sklearn een aparte klasse GridSearchCV voorziet

In [15]:
param_grid = {'max_depth': [1,2,3,4,5],
              'random_state': [0,5,10,20,40]}
print("Parameter grid:\n{}".format(param_grid))
Parameter grid:
{'max_depth': [1, 2, 3, 4, 5], 'random_state': [0, 5, 10, 20, 40]}
In [16]:
from sklearn.model_selection import GridSearchCV

grid_search = GridSearchCV(DecisionTreeClassifier(), param_grid, cv=5,
                          return_train_score=True)
# do not overfit the parameters !
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0)
grid_search.fit(X_train, y_train)
print("Test set score: {:.2f}".format(grid_search.score(X_test, y_test)))
print("Best parameters: {}".format(grid_search.best_params_))
print("Best cross-validation score: {:.2f}".format(grid_search.best_score_))
print("Best estimator:\n{}".format(grid_search.best_estimator_))
Test set score: 0.97
Best parameters: {'max_depth': 3, 'random_state': 0}
Best cross-validation score: 0.96
Best estimator:
DecisionTreeClassifier(max_depth=3, random_state=0)

Visualisatie van de GridSearchCV aan de hand van een heat map¶

heatmapGridSearch.png

Merk op : Al deze modellen uitrekenen is rekenintensief ! De grid moet m.a.w. goed gekozen worden.

Samenvatting deel 1¶

Doel : generalisatie vermogen van het model verbeteren op reƫle data.

  • 1 test set gebruiken om accuracy te berekenen is erg beperkt

    • cross-validatie en varianten geven je betere accuracy voorspelling maar is uiteraard rekenintensief
  • parametertuning en gridsearch technieken helpen om generalisatievermogen te verhogen, let wel dat je hierbij de testset niet gaat overfitten :

      - maak gebruik van een validatieset
      - doe de combinatie van gridsearch / cross-validatie (opnieuw : rekenintensief!)

Deel 2. Metrieken om beter te evalueren¶

metrieken gebruikt tot dusver :

  • voor classificatie : accuracy : tel het aantal juist geclassificeerde data-elementen in de testset tov de grootte van de testset

  • voor regressie : MSE : mean-squared-error : bereken het verschil tussen voorspelde en werkelijke waarde, kwadrateer deze fouten en neem hier een gemiddelde van

Er zijn echter nog veel metrieken die gebruikt kunnen worden en beter geschikt zijn afhankelijk van de applicatie.

Metrieken voor binaire classificatie¶

We spreken hier meestal over een $positieve$ versus een $negatieve$ klasse.

Zijn we alleen geĆÆnteresseerd in het aantal fouten (= accuracy) dat het geleerd model maakt?

Sommige fouten kunnen erger zijn dan andere :¶

Bvb. een zieke patiƫnt die toch als gezond geclassificeerd wordt is een grotere fout dan een gezonde patiƫnt die doorverwezen wordt naar extra testen omdat hij foutief als ziek geclassificeerd wordt. M.a.w de vals positieven zijn minder erg dan de vals negatieven in dit geval !

Een reƫle (business) targetfunctie zou kunnen zijn : minimaliseer het aantal overlijdens. Het meten van de accuracy zal hier dan geen goede evaluator zijn voor deze target. Eerder moet het aantal vals negatieven geminimaliseerd worden. Wat in dit geval veel specifieker is.

Metrieken voor binaire classificatie¶

In realiteit zijn de meeste datasets niet gebalanceerd :¶

Dit wil zeggen dat er veel meer data voorhanden is van de ene klasse dan van de andere klasse. Stel dat ik heel veel voorbeelden heb van de negatieve klasse, dan zal mijn model : Klassificeer steeds als "NO" best een goede score behalen !

Dus als iemand beweert dat zijn model een test accuracy van $90\%$ haalt wil dat eigenlijk helemaal niet zo veel zeggen als je de eigenschappen van de dataset niet kent!

Confusion matrices¶

confusion%20matrix.png

confusion.png

In [17]:
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits

digits = load_digits()
y = digits.target == 9  # the target becomes binary, classify a number as 9 or not

# this makes the dataset unbalanced : there will be approximately 9 more false than true examples in the dataset
X_train, X_test, y_train, y_test = train_test_split(digits.data, y, random_state=0)
In [18]:
import numpy as np
from sklearn.dummy import DummyClassifier

#the dummy classifier wil always predict false = not 9
dummy_majority = DummyClassifier(strategy='most_frequent').fit(X_train, y_train)
pred_most_frequent = dummy_majority.predict(X_test)
print("Test score: {:.2f}".format(dummy_majority.score(X_test, y_test)))
Test score: 0.90
In [19]:
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier(max_depth=2).fit(X_train, y_train)
pred_tree = tree.predict(X_test)
print("Test score: {:.2f}".format(tree.score(X_test, y_test)))
Test score: 0.92
In [20]:
from sklearn.linear_model import LogisticRegression

random = DummyClassifier().fit(X_train, y_train)
pred_dummy = random.predict(X_test)
print("dummy score: {:.2f}".format(random.score(X_test, y_test)))

logreg = LogisticRegression(C=0.1, solver = 'liblinear').fit(X_train, y_train)
pred_logreg = logreg.predict(X_test)
print("logreg score: {:.2f}".format(logreg.score(X_test, y_test)))
dummy score: 0.90
logreg score: 0.98
In [21]:
from sklearn.metrics import confusion_matrix

print("Confusion matrix Most frequent :\n{}".format(confusion_matrix(y_test, pred_most_frequent)))
print("Confusion matrix Random dummy :\n{}".format(confusion_matrix(y_test, pred_dummy)))
print("Confusion matrix Decision Tree :\n{}".format(confusion_matrix(y_test, pred_tree)))
print("Confusion matrix LogistRegression :\n{}".format(confusion_matrix(y_test, pred_logreg)))
Confusion matrix Most frequent :
[[403   0]
 [ 47   0]]
Confusion matrix Random dummy :
[[403   0]
 [ 47   0]]
Confusion matrix Decision Tree :
[[390  13]
 [ 24  23]]
Confusion matrix LogistRegression :
[[401   2]
 [  8  39]]

Hoe lees je de confusion matrix die $sklearn.metrics$ genegereert : (matrix voor het Logistic Regression model)

confusionLogRegr.png

Modellen vergelijken a.h.v. hun confusion matrix¶

Welk model zou je preferen ?

modellen.png

Relatie met accuracy¶
\begin{equation} \text{Accuracy} = \frac{\text{TP} + \text{TN}}{\text{TP} + \text{TN} + \text{FP} + \text{FN}} \end{equation}
Precision, recall en f-score¶

beperk het aantal valse positieven : verhoog precision

\begin{equation} \text{Precision} = \frac{\text{TP}}{\text{TP} + \text{FP}} \end{equation}

beperk het aantal valse negatieven : verhoog recall (ook sensitivity genoemd)

\begin{equation} \text{Recall} = \frac{\text{TP}}{\text{TP} + \text{FN}} \end{equation}

balanceer de trade-off tussen precision en recall:

\begin{equation} \text{F-score} = 2 \cdot \frac{\text{precision} \cdot \text{recall}}{\text{precision} + \text{recall}} \end{equation}

Al deze scores zijn terug te vinden in sklearn.metrics

Er is een trade-off tussen het optimizeren van recall en precision. Stel je voorspelt alle samples als postief - dan bekom je optimale recall, maar een lage precision want er er zullen veel vals positieven zijn. Omgekeerd, stel er zijn geen valse positieven, dan is de precision perfect, maar dan kunnen veel valse negatieven toch een hele kleine recall geven.

PrecisionRecall.png

De AUC-ROC curve¶

Deze ROC (receiver operating characteristic curve) vertelt hoe goed een binair classificatiemodel een onderscheid kan maken tussen klassen gegeven een treshold. Hoe hoger de AUC (area under the curve) hoe beter het model de 2 klassen van het binaire classificatieprobleem kan onderscheiden.

De ROC curve is een plot waarbij de FPR (false positive rate = aandeel valse positieve tov totaal aantal negatieven - the probability of false alarm) uitgezet wordt t.o.v. de TPR (true positive rate = recall) als je de threshold waarmee een geleerd model een beslissing tot positieve of negatieve classificatie neemt laat variƫren </font>

auc.PNG

Een model dat een classificatieprobleem geleerd heeft zal voor elk datapunt steeds een kans uitrekenen waarmee het kan beslissen of een datapunt positief of negatief is. Hoe groter of lager die kansen hoe zekerder het algoritme is. Met een probabiliteit van $0.5$ is het moeilijk om een beslissing te nemen. Standaard ligt er een treshold op $0.5$. Is de kans groter dan deze waarde wordt het punt positief geclassificeerd.

We kunnen de kansen die het model bekomt voor alle punten uit een validatieset uitzetten in een histogram. Op de x-as staat de voorspelde kans (getal tussen 0 en 1), op de y-as lees je een aantal. We maken een verdeling van de positieve punten uit de validatieset in rood, en een verdeling van de negatieve punten in groen. In onderstaande situatie blijkt dat alle postive punten telkens een kans groter dan $0.5$ voorspeld krijgen, en alle negatieve punten een kans onder $0.5$ krijgen. Alles zal dus perfect voorspeld worden.

Een ROC curve zal nu de threshold laten variƫren van 0 tot 1 en telkens de FPR en TPR uitzetten. Voor een perfect voorspeller geeft dit een perfecte hoek in de curve, de AUC is maximaal. </font>

ROC1.png

meestal overlappen die verdelingen echter: in onderstaande bijvoorbeeld zijn er behoorlijk wat datapunten waarvoor het model een probabiliteit van 0.5 berekende, maar de helft daarvan bleek positief en de andere helft negatief. Door de threshold op een positive klassificatie te verhogen naar 0.7 verkleint het aantal FP, maar vergroot het aantal FN en omgekeerd wanneer we de threshold zouden verlagen naar $0.3$. De ROC curve ontstaat door elke threshold te bekijken en telkens de TPR uit te zetten t.o.v. de FPR. Merk op een accuracy wordt steeds berekend voor 1 threshold waarde ($0.5$)

ROC2.png

De keuze voor een treshold van $0.6$ zal hier de TPR redelijk houden terwijl de FPR toch $0$ blijft

ROC3.png

Link met de confusion matrix

ROCvsconfusion.PNG

Modellen vergelijken met ROC-AUC¶

De AUC is een getal tussen $0$ en $1$ dat samenvat hoe het classificatiemodel presteert over de verschillende thresholds. Je kan het ook bekijken als de kans waarmee een classificatiemodel een ad random gekozen positief voorbeeld hoger zou inschatten als een ad random gekozen negatief voorbeeld.

Stel dat $AUC = 0.75$, dan zal het model met $75\%$ zekerheid een voorbeeld van de positieve klasse hoger gaan ranken dan eentje van de negatieve klasse.

ROC.PNG

modellenVgln.PNG

Samenvatting deel 2¶

  • Accuracy is niet altijd de betere metriek om te gebruiken op reĆ«le data ! In realiteit :
    • data is niet gebalanceerd
    • onderliggende distributies van de data meestal niet zo smooth
    • andere metrieken kunnen soms beter bevatten wat je in realiteit wenst :
      • in geval van binaire classificatie :
        • recall, precisicion, F-score
        • De ROC curve en AUC metriek vormen een maat voor de probabiliteit dat een classifier een random gekozen positief voorbeeld een hogere kans zal geven op positive classificatie dan een random gekozen negatief voorbeeld.

In python : gebruik de scoring parameter om de metriek te wijzigen van accuracy naar bvb AUC

Tutorials :¶

  • https://machinelearningmastery.com/k-fold-cross-validation/
  • Understanding confusion matrix : https://towardsdatascience.com/understanding-confusion-matrix-a9ad42dcfd62
  • ROC curves and Area Under the Curve explained https://www.dataschool.io/roc-curves-and-auc-explained/
  • Understanding AUC - ROC Curve https://towardsdatascience.com/understanding-auc-roc-curve-68b2303cc9c5