---
title: Machine Learning & AI
---
# Theorie
## Liniaire Regressie
### Enkelvoudig (2D data)
Verband zoeken tussen data om zo een accuraat mogelijke voorspelling te maken
Kan door de kostenfunctie te minimaliseren via de **Least Mean Squares** methode die stelt om de som van de vierkantswortels van de afstand tot de lijn te minimaliseren.
Gaat ook door **Gradient Descent** toe te passen diens princiepe is om een iteratief proces door te gaan voor de optimale parameters $θ_0$ en $θ_1$ te vinden

### **Iteratief voorbeeld:**
| Fixed θ | Functie van $θ_0$ en $θ_1$ |
| -------- | -------- |
| ||
| | |
| | |
| | |
| | |
|| |
|| |
| | |
| | |
### Meervoudig (non-2D data)
Bij meervoudige data moeten we data onderverdelen tussen de **features** en het te voorspellen **target** op basis van toekomstige data.
Hier moeten we best zien nulwaarden en uitschieters te vermijden.
Een goede manier om het target te vinden is door analyse van de correlatie tussen de verschillende properties, kan door een **heatmap** of een **pairplot**.
|  |  |
| -------- | -------- |
### Training the model
Nadat we de data hebben geanaliseerd en voorbereid kunnen we aan het model beginnen.
Eerst moeten we de data opsplitsen in **training** en **testdata**. Een goed ratio is ongeveer 20-30% testdata
### Evaluatie van het model
We kunnne het model op vele verschillende manieren evalueren om te zien of we correcte resultaten krijgen en om te zien hoe we onze hyperparameters kunnen aanpassen om de performantie te verbeteren.
#### Mean Absolute Error
Is het gemiddelde van de absolute fout tussen de voorspelde y-waarden en de effectieve y-waarden uit de test set.
#### Mean Squared Error
Is het gemiddelde van de gekwadrateerde fout tussen de voorspelde y-waarden en de effectieve y-waarden uit de test set.
#### Determinatiecoëfficiënt R²
Zegt hoeveel van de variabiliteit verklaard wordt door het model.
Bij perfecte voorspellingen is R² = 1
Als de R² score negatief is betekent dit dat het model slechter scoort dan een horizontale lijn.
## Feature engineering & Hyper parameter tuning
### Normalisatie
Zorgt ervoor dat de features op dezelfde schaalverdeling staan.
Als we gradient descent gebruiken is het bijvoorbeeld efficienter om eenzelfde schaal te hebben

### Min - Max scaling
Schaalt alle features tussen 0 en 1, wat perfect is voor gaussiaanse distributies met kleinere variantie.
Bij het min-max scaling blijfd de skew (of scheefheid) bewaard, maar is wel nog steeds gevoelig voor uitschieters. Daarom is het mogelijks best practice om eerst de extreme warden te verwijderen om dan de scaling toe te passen.
|  |  |
| -------- | -------- |
### Standard scaling
Brengt de data naar een standaardverdeling, met gemiddelde = 0 en stdev = 1.
Gebruik van standerd scaling vervormt de data zodat de relatieve afstande niet meer gelijk zijn.
Dit is geen garantie van genormaliseerde data op dezelfde schaal.
|  |  |
| -------- | -------- |
### Robust scaling
Lijkt op Min - Max scaling maar gebruikt interquartielafstand ipv range.
Deze houd geen rekening met uitschieters waardoor de range groter is dan bij Min - Max.
|  |  |
| -------- | -------- |
## Feature expansion
### Nieuwe features
Extra features maken die uit de beschikbare data kan gehaald worden.
Bijvoorbeeld:
• Uit de lengte en breedte van een huis de oppervlakte halen als nieuwe feature.
• Uit een start en eindpunt de afstand halen als nieuwe feature.
• Uit een datum afleiden welke dag van de week het is.
### Hogere orde features
Het verband tussen bepaalde features is niet altijd liniair. Een hogere orde feature toepassen geeft de lijn meer flexibiliteit
|  | |
| -------- | -------- |
### One-hot encoding
Encodeert elke label naar kolommen van de mogelije opties om dan binair aan te duiden welke waar is.

## Under- en overfitting
Underfitting treedt op wanneer een model de training data niet kan modelleren en ook niet kan generaliseren op nieuwe data.

Overfitting treedt op wanneer een model de training data te goed modelleert en niet kan
generaliseren op nieuwe data.

Overfitting is ook afhanklijk van de grootte van de trainingset (aantal observaties m).
- Bij weinig observaties: snel overfitting bij complexer model.
- Bij veel observaties: minder snel overfitting bij complexer model.
### Regularisatie
Methode om de mate van bias van een hypothese te regelen en een goed evenwicht te
vinden tussen underfitting en overfitting.
Deze maakt gebruik van een regularisatie-term die een extra kostenterm is die het gebruik van hogere orde features afstraft tenzij ze de globale kostenfunctie doen dalen.
| via L2 (Ridge regression)| via L1 (Lasso regression)|
| ------------------------------------ | ------------------------------------ |
|  |  |
Via Ridge of Lasso regressie met regularisatieparameter α.
• hoe groter α, hoe sterker de regularisatie en dus hoe minder complex het model.
• hoe kleiner α, hoe zwakker de regularisatie en dus hoe complexer het model.
## Logistic Regression (Classification I)
Tekenen van scheidingslijn tussen data classificaties.
Kan gebruikt worden voor:
- Binairy (binomial) classifier
- Multiclass classifier
- Multilabel classifier
Zelfde data preprocessing als liniaire regressie
Bij niet liniair scheidbare data maken we hogere orde features aan, hier ook oppassen met under- en overfitting.

C = inverse regularisatie sterkte.
• kleine waarden voor C zorgen voor een sterke regularisatie (underfitting)
• grote waarden voor C zorgen voor een zwakke regularisatie (overfitting)
### Multi-class classification
| One-vs-All| One-vs-One|
| ------------------------------------ | ------------------------------------ |
| |  |
### Evaluatie van de classifier
Confusion matrix, kan voor:
- Accuracy
- Recall (True Positive Rate)
- Precision (Positive Predictive Value)
- F1 score (harmonisch gewogen gemiddelde van de recall en de precision)

#### Receiver Operating Characteristic
- Gebruikt bij binaire classifiers
- Gebruikt om betere modellen te selecteren en minder goede te verwerpen
|  | |
| -------- | -------- |

#### Area Under ROC Curve
Door de threshold settings te veranderen kan je de accuraatheid van je classifier verbeteren, geeft aan hoe zeker het model moet zijn om de classificatie te maken

## Support Vector Machines
Berekent scheidingslijn met een marge
Hoe hoger C hoe breder de scheidingslijn
Best gebruikt samen met scaling
SVM kernels
**RBF - Radial Basis Function (Gaussian)**
**Polynomial kernel**
**Histogram kernel**
**Lineaire kernel = SVM zonder kernel**

Motivatie voor het gebruik van SVM:
- Kan zowel gebruikt worden voor regressie als classificatie (en zelfs clustering).
- Werkt goed op kleine datasets (in tegenstelling tot neurale netwerken en deep learning).
- Is nog altijd effectief wanneer het aantal features groter is dan het aantal training samples.
- Het werkt goed bij een groot aantal features (high dimensional space).
- Gebruikt niet alle training examples tijdens training ⇒ geheugenefficiënt.
- Geen lokale minima/optima, maar globaal optimum.
Veel features ten opzichte van samples => No kernel SVM
Weinig features maar behoorlijke samples => RBF SVM
Weinig features maar veel samples => Maak meer features en No kernel SVM
**Gamma** = rekening houding met uitschieters
te kein = Underfitting
te grot = Overfitting
Best practice om de scaling method als hyperparameter te zien en er verschillende uit te testen
### Hyperparameters
Implementeren van een SVM:
• Test lineaire kernel (geen kernel) en RBF kernel.
• Tune de parameter C.
• Bij gebruik van RBF kernel: tune zowel de parameters C als gamma.
### Cross Validation
Verschillende types cross-validatie:
• Hold Out
• K-fold cross-validation
• Leave One Out cross-validation
• Bootstrap cross-validation
| Hold out | K-fold |
| ------------------------------------ | ------------------------------------ |
|  |  |
| **Leave One Out** | **Bootstrap** |
|  |  |
### Hyperparameter tuning via cross validation
| Grid-Search | Random Search |
| ------------------------------------ | ------------------------------------ |
|  |  |
| Grid-Search | Bayes optimization |
|  |  |
### Niet-gebalanceerde data
Als de data die je wilt voorspellen/klasseren niet gebalanceerd is dan stelt het probleem zich voor dat je model biased wordt. Dus het is best om te zorgen dat je ongeveer evenveel data hebt van elke klasse.
We kunnen dit oplossen op verschillende manieren:
- Meer data verzamelen van de minderheidsklasse
- Undersampling of Oversampling toepassen
- Andere scoring parameter kiezen
- Class weight balancing
- Data augmentation -> Synthetic Minority Over-sampling Technique (SMOTE)
| SMOTE | Under- and Oversampling |
| :------------------------------------: | :------------------------------------: |
|  |  |
| Image augmentation |
| :------------------------------------: |
|  |
## Naive bayes
### Discriminative vs generative classification
| Discriminative | Generative |
| :------------------------------------: | :------------------------------------: |
|  |  |
| Log Reg, SVM, Decision Trees| Bayes |
| grens tussen twee klasses | distributie van de verschillende klasses |
### Bayes rule
De kans dat iemand kanker heeft bedraagt 1% ⇒ P(kanker) = 0, 01
Van een test is geweten dat:
• In 90% van de gevallen is de test positief als je effectief kanker hebt (sensitiviteit).
• In 90% van de gevallen is de test negatief als je geen kanker hebt (specificiteit).
**Prior**: P(kanker): Zonder de testresultaten te kennen, hoe waarschijnlijk is het dat iemand kanker heeft?
**Likelihood**: P(positief |kanker) hoe waarschijnlijk is het dat de test positief is wanneer de persoon effectief kanker heeft?
**Marginal**: P(positief ) Hoe waarschijnlijk is het dat de test positief is?
**Posterior**: P(kanker|positief ): Wat is de kans dat iemand effectief kanker heeft als de test positief blijkt?
Voorbeeld bij spamdetectie:

Bij deze kan je ook **laplacian smoothing** toevoegen om nieuwe woorden ook te classifiëren.
Voorbeeld van laplacian smoothing:

Bij grote kommagetallen kan het vermenigvuldigen van veel kansen kan resulteren in een floating-point underflow. Dit kunnen we oplossen door **log likelihood** te gebruiken
## Decision trees & Ensemble learning
Ya know, this shit:

### For Classification
Maar hoe bepalen waar de boom te splitesen?
|||
|-|-|
|||
**Entropy en information gain**
Een goede split is deze waarbij de wanorde afneemt en beide kanten ’zuiverder (pure) worden’
**Entropy** : maat voor de wanorde (gemiddelde informatieinhoud)
**Gini impurity**
Alternatief voor het gebruik van de entropy.
De Gini impurity is een maat voor hoe vaak een willekeurig gekozen element van de set verkeerd gelabeld zou worden als het willekeurig werd gelabeld volgens de distributie van de labels in de subset.
Splits telkens bij de split die je de laagste Gini impurity oplevert.

### Random Forest Trees
Problematiek van decision trees:
Decision trees hebben de neiging tot overfitting.
Oplossing: combineer de voorspellingen van verschillende gerandomiseerde trees tot één model

Gebruikt het princiepe van **majority voting** waarbij de meestvoorkomende klassificatie wint.
#### Hyperparameters van RF
**n_estimators**: number of trees in the forest. Meestal hoe meer hoe beter.
**Criterion**: Gini of Entropy (default Gini)
**Maximum number of features**: het maximum aantal features per boom.
• **int** : aantal features
• **float**: percentage
• ’**auto**’: max_features = vierkantswortel van totaal aantal features
• ’**sqrt**’: max_features = vierkantswortel van totaal aantal features
• ’**log2**’: log van het totaal aantal features
• Default worden alle features gebruikt.
**max_depth**: de maximale diepte van de boom. Als je te maken hebt met noisy data is het aan te raden de maximale diepte beperkt te houden.
**min_samples_split**: het minimum aantal samples nodig om binnen een boom te blijven splitsen.
**min_samples_leaf**: het minimum aantal samples dat zich aan een blad van de boom moet bevinden. Hoe groter deze waarde, hoe minder vatbaar voor overfitting.
**Bootstrap aggregating**: Bagging (zie verder). Staat default op True.
**oob_score**: de gemiddelde error bij het testen van een sample op bomen die niet op deze sample getraind zijn geweest.
### Ensemble Learning
Een ensemble is een combinatie van verschillende classifiers die samen een uiteindelijke klasse voorspellen.
Werken meestal beter dan een enkele classifier
De classifiers moeten verschillend zijn van elkaar (diverse classifiers)
Dit is het voorbeeld van een ensemble learner bouwen via **stacking**:

Je kan ook een soort van **bagging** gebruiken om de verschillende modellen licht te varieren om wat voorkeuren weg te werken.

Een betere manier dan bagging om dit uit te werken is **Boosting**
Dikwijls betere accuraatheid dan bagging methode.
Gevoeliger voor overfitting en moeilijker te parallelliseren.
Meest bekend algoritme: AdaBoost (Adaptive Boosting).
Principe: vergelijkbaar met bagging, maar verkeerd geclassificeerde samples
bekomen een grotere kans om in de volgende bag te belanden.

## Unsupervised learning
Unsupervised learning bevat een set aan machine learning technieken om in niet-gelabelde data structuren te zoeken en te beschrijven.
Belangrijke technieken omvatten:
• Clustering
• Anomaly / outlier detection
• Dimensionality reduction
• Blind signal separation
### Clustering
Groeperen van gelijkaardige data
**K-means clustering** is een zeer populaire clustering techniek door zijn eenvoud.
Kan ook gebruikt worden om gelijkenissen uit te drukken zoals de eigenfaces van face recognition.
Gelijkenis uitdrukken via een afstandsfunctie:
• Hoe dicht liggen trainingsamples qua afstand van elkaar in de feature space?
• Veel gebruikte afstandsmaat is de Euclidische afstand
Herhaalde stappen in voorbeeld:
Initialiseer (al dan niet willekeurig) 4 centroïden.
- Wijs de datapunten toe aan de dichtstbij liggende centroïde.
- Verplaats de centroïden naar het gemiddelde van de clusters.
| |  |
| -------- | -------- |
| |  |
| |  |
| |  |
| |  |
Eigenschappen van K-means clustering
- Eenvoudig en resultaten gemakkelijk interpreteerbaar.
- K-means vindt niet altijd het globale optimum (= beste oplossing).
- Uiteindelijke resultaat hangt af van initialisatie van de centroïden.
- Probeer verschillende intialisaties.
- Initaliseer eerste centroïde op een willekeurig datapunt. Leg de tweede centroïde op een het datapunt dat zover mogelijk van het eerste is verwijderd, de derde centroïde zo ver mogelijke van de twee eerste, enzoverder.
- zeer gevoelig aan uitschieters
- Problemen bij clusters met hetzelfde gemiddelde of niet-sferisch clusters. (Oplossing: kernel k-means of spectral clustering
Stragegie om het aantal clusters te bepalen:
- Visuele inspectie van de datapunten (indien mogelijk).
- Silhouette clustering.
- Elbow method.
**Elbow method** voor het vinden van het aantal clusters:
Bepaal voor een verschillend aantal clusters de ’sum of squared error (SSE)’. De SSE de som van de gekwadrateerde afstanden tussen elk datapunt in een cluster en de centroïde van die cluster.

**Hierarchical clustering**

Clusters kunnen voorgesteld worden via een **dendrogram**
| |  |
| -------- | -------- |
Sterktes van hierarchical clustering:
- Geen vooropgesteld aantal clusters nodig. Elk gewenst aantal clusters kan bekomen worden door het dendrogram op de juiste plaats af te snijden.
- De structuur van het dendrogram kan nuttig zijn. Bijvoorbeeld in biologie, productcategorieën.
Bepalen van de afstand tussen twee clusters
- **single linkage**
- **complete linkage**
- **average linkage** (Rekenintensief)
Zeer rekenintensief:
- Het aantal berekeningen is minstens kwadratisch afhankelijk van het aantal datapunten.
- Niet bruikbaar voor grote datasets.
**Self organizing maps**
- Ook ’Kohonen Maps’ genoemd.
- Competitie gebaseerde clustering.
| |  |
| -------- | -------- |
### Support Vector Clustering
#### Kernels

### Exstentions on SVM
#### Multiclass SVM
Verdeelt multi-class in meerdere 1 op 1 svm's om zo de verschillende klasses te vinden.
#### Regression (SVR)
"The model produced by support-vector classification (as described above) depends only on a subset of the training data, because the cost function for building the model does not care about training points that lie beyond the margin. Analogously, the model produced by SVR depends only on a subset of the training data, because the cost function for building the model ignores any training data close to the model prediction." -[Wikipedia](https://en.wikipedia.org/wiki/Support-vector_machine#Regression)

#### Bayes SVM [WIP]
*[needs update](https://en.wikipedia.org/wiki/Support-vector_machine#Bayesian_SVM)*
https://arxiv.org/pdf/1707.05532.pdf
https://github.com/theogf/BayesianSVM
https://github.com/theogf/AugmentedGaussianProcesses.jl
### Dimensionality reduction
Binnen de context van machine learning (en statistiek) staat dimensionality reduction voor het proces waarbij het aantal variabelen (features in een dataset) gereduceerd wordt naar een kleinere set van ’principle variables’.
Meest gebruikte algoritmes voor dimensionality reduction
- **Principle Component Analysis** (PCA) en Kernel PCA
- Linear Discriminant Analysis (LDA)
- Autoencoders
- Missing Values Ratio
- Low variance filter
But why?
- The curse of dimensionality
- Visualisaties in 2D of 3D
- Verwijderen van ruis
- Datacompressie
Toepassingen van dimensionality reduction
- Document classification
- Classificatie van genen (veel genen, weinig samples)
- Gezichtsherkenning
- Spraakherkenning
- Handschriftherkenning
- Compressie
- Intrusion detection
#### Principal Component Analysis
Principal component analysis (PCA) is een wiskundige techniek om het aantal (mogelijks) gecorreleerde features te transformeren naar een kleiner aantal niet-gecorreleerde features die de principle components worden genoemd.
| |  |
| -------- | -------- |
| |  |
Voor images zijn deze ook wel **eigenfaces** genoemd

Kiezen van het aantal principle components - **verklaarde variantie**
PCA zoekt de componenten die maximaal de variantie in de dataset verklaren. We willen zoveel mogelijk informatie overhouden na dimensionality reduction.

### RF for Regression (Extra)
Voorbeeld:
https://i.imgur.com/6qSsWAz.png
Random Forest Trees voor regressie:
https://i.imgur.com/h7FpL2Q.png
## Neurale Netwerken
*"A neural network (NN) is a massively parallel distributed processor that has a natural propensity for storing experimental knowledge and making it available for use. It resembles the brain in two aspects:
• Knowledgde is acquired by the network through a learning process.
• Interneuron connection strenghts known as synaptic weights are used to store the knowledge."*
*\- Simon Haykin, Neural Networks - a comprehensive Foundation*

Kenmerken van een neuraal netwerk:
- Netwerk architectuur
- Leeralgoritme
- Activatiefuncties

[Meer info](https://www.asimovinstitute.org/neural-network-zoo/)

### Backpropagation learning
Past het netwerk zelf aan bij opsporing van fouten

[Meer info](https://becominghuman.ai/back-propagation-is-very-simple-who-made-it-complicated-97b794c97e5c)
Error Functie (leercurve) altijd tekenen om te zien of het netwerk wel leert

De learning rate heeft ene heel grote impact op het net

Deze kan geautomatiseerd worden met "adam"
de initiele weights MOETEN willekeurig ingesteld zijn, anders kan je symmetriën krijgen
#### Activation Functions
Activation function is ook belangrijk voor de performantie

**Step functions**

- Kan alleen ja of nee zeggen (100% of 0%)
- Problemen bij meerdere klasses. Wat als meerdere klasses op 1 staan?
- Backpropagation werkt niet. De afgeleide = 0
Deze zijn moeilijk te trainen aangezien het enkel 0 of 1 is en dus afgeraden
**Liniaire functie**

- Hoeveel layers je ook gebruikt, de uiteindelijke activatie blijft lineair.
- De afgeleide is constant en heeft geen relatie meer met de ingang.
Afgeraden voor complexe data
**Sigmoid functie**

Was zeer populair, maar rekenintensief, dus wordt enkel nog bij Output gebruikt.
Vanishing gradient problem geeft problemen met gradient descent aangezien de uiteinden van de functie afvlakken.
**Hyperbolic Tangent**

Zowat hetzelfde als Sigmoid
**Rectified Linear Unit - Relu** <- verr gud yes

- ReLu is niet-lineair en elke functie kan benaderd worden door combinatie van relu functies.
- Zeer efficiënt naar rekenkracht.
- Sparse activation. Veel activaties worden 0.
- Neurons kunnen afsterven
**Leaky Relu**

beetje rekenintensiever maar gaat nie tin de dead zone geraken
probeer eerst met gewone relu
**Conclusie:**
**Hidden layers:**
- Gebruik eerst ReLu.
- Probeer Leaky ReLu .
- Gebruik geen Sigmoid of Tanh.
**Output layer:**
- Lineair bij regressie.
- Softmax / Sigmoid bij classificatie.
Sofmax is een generalisatie van de Sigmoid
Werkt bij mult-class classificatie.
Deep neural networks zijn heel gevoelig over under- en overfitting
Bij overfitting kan je **Dropout** toepassen door een bepaald percentage neuronen af te zetten.
# Labo
## Packages
``` bash
pip3 install git+https://github.com/darenr/scikit-optimize
```
## Snippets
### Imports
```python
%matplotlib inline
import calendar
import datetime
import re
import nltk
import numpy as np
import pandas as pd
from bs4 import BeautifulSoup
from imblearn.over_sampling import SMOTE
from skopt import BayesSearchCV
import seaborn as sns; sns.set(color_codes=True)
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
from nltk.stem.snowball import SnowballStemmer
from scipy import stats
from scipy.stats import randint, uniform
from sklearn import linear_model, preprocessing, svm
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.linear_model import Lasso, LogisticRegression, Ridge
from sklearn.metrics import (accuracy_score, classification_report,
confusion_matrix, mean_absolute_error,
mean_squared_error, r2_score)
from sklearn.model_selection import (GridSearchCV, RandomizedSearchCV,
train_test_split)
from sklearn.naive_bayes import GaussianNB, MultinomialNB
from sklearn.preprocessing import (MinMaxScaler, PolynomialFeatures,
RobustScaler, StandardScaler)
from sklearn.svm import SVC
```
### Dataset importeren en info krijgen
#### Import data
```python
dataset = pd.read_csv('{data.csv}','{data seperator, ex: ;}',encoding = '{encoding}')
```
#### Describe data
```python
dataset.shape
dataset.info
dataset.describe()
```
#### See data
```python
dataset.head({amount})
dataset.tail({amount})
dataset.loc[[{id}]]
```
### Visualise data
#### Visualiseer de onderlinge correlatiecoëfficiënten
```python
f, ax = plt.subplots(figsize=(10, 8))
corr = dataset.corr()
sns.heatmap(corr, mask=np.zeros_like(corr, dtype=np.bool),
cmap=sns.diverging_palette(220, 10, as_cmap=True),square=True, ax=ax,annot=True)
```
#### Bekijk de gebalanseerdheid van de data
```python
plt.figure(figsize=(8, 8))
sns.countplot('{subject}', data=dataset)
sns.countplot(x="{subjects}", hue="{subject}", data=dataset)
plt.title('Class Balance')
plt.show()
```
#### Describe data
```python
# Pairplot (process heavy)
sns.pairplot(dataset);
# Boxplot
sns.boxplot(x='{y-axis data}', y='{x-axis data}', data=dataset)
```
### Prepare data
#### Bepaalde data moet geyeet worden
```python
dataset = dataset[(np.abs(stats.zscore(dataset)) < 3).all(axis=1)]
dataset.drop('{column}', axis=1, inplace=True)
```
#### Datatypes fixen
```python
dataset['day'] = pd.to_datetime(dataset['date']).dt.day_name()
X = X.astype('float64')
```
#### one-hot encoding
```python
dataset = pd.concat([dataset,pd.get_dummies(dataset['{column}'], prefix='{column}')],axis=1)
dataset.drop(['{column}'],axis=1, inplace=True)
```
#### Normaliseren van de Data
```python
scaler = preprocessing.StandardScaler().fit(X) # Normaliseert naar gemiddelde = 0 en standaardafwijking = 1
scaler = preprocessing.MaxAbsScaler().fit(X) # Deelt elke waarde door de absolute waarde van het maximum
scaler = preprocessing.MinMaxScaler().fit(X) # Trekt van elke waar het min af en deel door (MAX - MIN)
scaler = preprocessing.RobustScaler().fit(X)
X = scaler.transform(X)
```
#### Text preprocessing
```python
# Define function
def text_preprocessing(text, language, minWordSize):
# remove html
text_no_html = BeautifulSoup(str(text),"html.parser" ).get_text()
# remove non-letters
text_alpha_chars = re.sub("[^a-zA-Z']", " ", str(text_no_html))
# convert to lower-case
text_lower = text_alpha_chars.lower()
# remove stop words
stops = set(stopwords.words(language))
text_no_stop_words = ' '
for w in text_lower.split():
if w not in stops:
text_no_stop_words = text_no_stop_words + w + ' '
# do stemming
text_stemmer = ' '
stemmer = SnowballStemmer(language)
for w in text_no_stop_words.split():
text_stemmer = text_stemmer + stemmer.stem(w) + ' '
# remove short words
text_no_short_words = ' '
for w in text_stemmer.split():
if len(w) >=minWordSize:
text_no_short_words = text_no_short_words + w + ' '
return text_no_short_words
# Apply function
language = 'english'
minWordLength = 2
for i in range(X.size - 1):
X[i-1] = text_preprocessing(X[i-1], language, minWordLength)
# Create Bag of Words
count_vect = CountVectorizer()
X_bag_of_words = count_vect.fit(X)
X_bag_of_words = count_vect.transform(X)
tfidf_transformer = TfidfTransformer()
tf_transformer = TfidfTransformer(use_idf=True).fit(X_bag_of_words)
X_tf = tf_transformer.transform(X_bag_of_words)
```
#### Dataset opsplitsen
```python
# features en target
features = list(dataset.columns[:dataset.columns.size])
features.remove('{target}')
X = dataset[features].values
y = dataset['{target}'].values
# training set en test set.
X_train, X_test, y_train, y_test =
train_test_split(X, y, test_size={150 -> 150 samples, 0.33 -> 33 %}, random_state=0)
```
### Modeloptimalisatie
#### Hyperparameter tuning
```python
# Aanmaken van de hogere orde features
graad = 3
poly = PolynomialFeatures(graad)
poly.fit(X_train)
X_train_poly = poly.transform(X_train)
X_test_poly = poly.transform(X_test)
# Modeloptimalisatie met L2 regularisatie via Ridge regression
lregmodel_poly = Ridge(alpha=0.1,tol=0.0001,fit_intercept=True)
lregmodel_poly.fit(X_train_poly,y_train)
# Modeloptimalisatie met L1 regularisatie via Lasso regression
lregmodel = Lasso(alpha=0.1,tol=0.0001,fit_intercept=True)
lregmodel.fit(X_train,y_train)
print('R2 score op test set via L2: ',lregmodel_poly.score(X_test_poly,y_test))
print('R2 score op training set via L2: ',lregmodel_poly.score(X_train_poly,y_train))
```
#### Gereduceerde features
```python
train_r2 = []
test_r2 = []
alphas = np.logspace(-2, 6, 1000)
for alpha in alphas:
lregmodel_poly = Ridge(alpha=alpha,tol=0.0001,fit_intercept=True)
lregmodel_poly.fit(X_train_poly,y_train)
test_r2.append(lregmodel_poly.score(X_test_poly,y_test))
train_r2.append(lregmodel_poly.score(X_train_poly,y_train))
# Plot r2
f, ax = plt.subplots(figsize=(10, 8))
plt.subplot(2, 1, 1)
plt.semilogx(alphas, train_r2, label='Train')
plt.semilogx(alphas, test_r2, label='Test')
plt.legend(loc='lower left')
plt.ylim([0, 1.2])
plt.xlabel('Regularization parameter')
plt.ylabel('R² Performance')
```
### Training the model
#### Linear Regression
```python
linregmodel = linear_model.LinearRegression()
linregmodel.fit(X_train,y_train)
```
#### Logistic Regression
```python
logregclassifier = LogisticRegression(C=10)
logregclassifier.fit(X_train, y_train)
y_pred = logregclassifier.predict(X_test)
print(classification_report(y_test, y_pred))
cf = confusion_matrix(y_test, y_pred)
print(cf)
print(accuracy_score(y_test, y_pred) * 100)
```
#### Naive Bayes
```python
NBclassifier = MultinomialNB(alpha=1)
NBclassifier.fit(X_train, y_train)
y_pred = NBclassifier.predict(X_test)
print(classification_report(y_test, y_pred))
cf = confusion_matrix(y_test, y_pred)
print(cf)
print(accuracy_score(y_test, y_pred) * 100)
```
#### Logistic Regression with Support Vector Machines
Cross validation via Grid Search
```python
model = SVC()
paramaters = [
{'kernel': ['linear'], 'C': np.linspace(0.01,20,10)},
{'kernel': ['rbf'], 'C': np.linspace(0.01,20,10),
'gamma': [0.0001, 0.001, 0.01, 0.1, 0.2]},
{'kernel': ['poly'], 'C':np.linspace(0.01,20,10)} ]
grid_search = GridSearchCV(estimator = model,
param_grid = paramaters,
scoring = 'accuracy',
cv = 15,
n_jobs = -1,
verbose =5)
grid_search = grid_search.fit(X_train, y_train)
best_accuracy = grid_search.best_score_
best_parameters = grid_search.best_params_
y_pred = grid_search.predict(X_test)
cf = confusion_matrix(y_test, y_pred)
print(classification_report(y_test, y_pred))
print(balanced_accuracy_score(y_test, y_pred) * 100)
```
Random Search
```python
model = SVC()
parameters = {'kernel': ['linear','rbf','poly'],
'C': uniform(0.01, 20), # haal C uit een random uniform distribution
'gamma': uniform(0.001, 0.2)}
n_iter_search = 20
random_search = RandomizedSearchCV(model,
param_distributions=parameters,cv=5,n_iter=n_iter_search,n_jobs = -1,verbose=1)
random_search = random_search.fit(X_train, y_train)
best_accuracy = random_search.best_score_
best_parameters = random_search.best_params_
y_pred = random_search.predict(X_test)
cf = confusion_matrix(y_test, y_pred)
print(classification_report(y_test, y_pred))
print(balanced_accuracy_score(y_test, y_pred) * 100)
```
Bayes Optimization
```python
model = SVC()
parameters = {'kernel': ['linear','rbf','poly'], 'C': [1, 10e2],'gamma': (0.01, 0.2,'uniform')}
n_iter_search = 20
Bayes_search = BayesSearchCV(model,parameters,n_iter=n_iter_search,cv=5,verbose=1)
Bayes_search.fit(X_train, y_train)
best_accuracy = Bayes_search.best_score_
best_parameters = Bayes_search.best_params_
y_pred = Bayes_search.predict(X_test)
cf = confusion_matrix(y_test, y_pred)
```
#### Oversampling with SMOTE
```python
sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X_train, y_train)
grid_search = grid_search.fit(X_train, y_train)
```
#### Getting your results
```python
print(classification_report(y_test, y_pred))
print(cf)
print(accuracy_score(y_test, y_pred) * 100)
```
Bayes search
```python
print('Best accuracy : ', Bayes_search.best_score_)
print('Best parameters :',Bayes_search.best_params_ )
```
### Test and evaluate the model
#### Using the model on new data
```python
test = np.array([{values of row fields}])
result = lregmodel.predict(test.reshape(1,-1))
```
#### Evaluatie van het model via de MAE, MSE en de R2-score
```python
y_predicted = lregmodel.predict(X_test)
```
Mean Absolute Error (hoe lager hoe beter)
```python
MAE = mean_absolute_error(y_test,y_predicted)
print('MAE = ',MAE)
```
Mean Squared Error (hoe lager hoe beter)
```python
MSE = mean_squared_error(y_test,y_predicted)
print('MSE = ',MSE)
```
Coefficient of determination = r2 score (hoe hoger hoe beter)
```python
r2 = r2_score(y_test,y_predicted)
print('r2 score = ',r2)
# alternatieve methode
r2 = lregmodel.score(X_test,y_test)
print('r2 score = ', r2)
```
#### Cross-validation
```python
print(f1_score(y_test, y_pred, average='macro'))
print(f1_score(y_test, y_pred, average='micro'))
print(f1_score(y_test, y_pred, average='weighted'))
```
# Examen
## Theorievragen
**Verklaar het werkingsprincipe van Gradient Descent**
Gradient Descent is een soort van iteratief proces die steeds nieuwe gewichten gaat toekennen aan de features tot op een gegeven moment de kostenfunctie het minimum heeft bereikt. Dus met andere woorden tot op een gegeven moment dat ons model het accuraatst zal zijn. Dit principe kan je soort van vergelijken met het instellen van een radiozender. Je draait aan 2 knoppen (veranderen van de gewichten van de features) tot op een gegeven moment dat je het beste signaal hebt voor de zender (laagste kostenfunctie). We normaliseren altijd onze gegevens met een scaler, omdat het principe van Gradient Descent enkel goed kan convergeren op genormaliseerde waarden.
**Principe van regularisatie**
We gebruiken regularisatie om een goed evenwicht te vinden tussen underfitting en overfitting (door een regularisatieparameter toe te voegen). Die regularisatieparameter is eigenlijk een extra kostenterm die bijvoorbeeld hogere orde features zal afstraffen tenzij ze de kostenfunctie doen dalen. Een regularisatieparameter kan voorgesteld worden als lambda. Hoe hoger je uw regularisatieparameter instelt, hoe meer er wordt geregulariseerd dus hoe eenvoudiger uw model wordt (underfitting). Hoe hoe lager je uw regularisatieparameter instelt, hoe minder er wordt geregulariseerd dus hoe complexer het model zal worden (overfitting). Je hebt twee soorten regularisatie: L1 Lasso of L2 Ridge (afhankelijk van hoe R gedefineerd werd)
**Verklaar de werking van een perceptron**
Een perceptron wordt gebruikt in neurale netwerken. Alle features (met hun bijhorende weights) sturen een waarde door naar de perceptron. Binnenin het perceptron wordt er dan een summing function gedaan waardoor je dan een waarde krijgt waarop je een activation function kan laten uitvoeren (bv Sigmoid, of softmax), ... om zo de kans te kunnen bepalen tot welke klasse de inputs behoort.
**Bespreken en uitleggen van een bepaald clustering algoritme**
K-means clustering, (K is het aantal clusters) is een clustering techniek die wordt gebruikt in unsupervised learning, waarbij de data wordt gegroepeerd in clusters. Specifiek bij K-means clustering gebruik je eerst een elbowl method die kijkt hoeveel clusters het beste passen bij deze dataset (door behulp van errorvalues waar je op de grafiek dan duidelijk een knikpunt kan zien liggen). Stel uw elbowl method duidt 4 clusters aan. Dan gaat K-means clustering 4 verschillende centroïden op random plaatsen leggen. En gaat ieder punt zich bij de dichst gelegen centroïde aansluiten. Dan gaat de centroÏde zich verplaatsen naar het gemiddelde van de cluster. En opnieuw gaat de punt zich dan aansluiten bij de dichtsbij liggende centroïde enzovoort tot de centroïden zich niet meer verplaatsen, en dan is de data opgedeeld in 4 clusters (in dit voorbeeld). Dit gebeurt allemaal a.d.h.v. de afstand tussen de punten (euclidische afstand)
**Bespreken van Bagging en Boosting**
Bij Bagging en Boosting splits je uw data op in verschillende sub-datasets. Bij Bagging ga je op iedere sub-dataset een classifier trainen (willekeurig met teruglegging) van uw samples. Met behulp van Majority Voting ga je dan tot 1 beste classifier uitkomen. Bij Boosting (bv AdaBoost) ga je uw data ook splitsen in verschillende sub-datasets. Maar de miss geclasifiseerde items hebben een grotere kans om in de volgende sub data set te zitten.
**Verschil tussen logistic regression en SVM**
Een logistic regression is een classificatiemodel die je alleen maar kan gebruiken in classificatie. SVM’s kan je gebruiken bij zowel regressie als classificatie. Verder heeft logistic regression maar 1 parameter die je kan tunen: de C waarde (om te spelen tussen overfitting en underfitting). Bij een SVM heb je zowel een C waarde als een gamma waarde (bij RBF kernels). Je hebt dus ook meerdere kernels binnen SVM (RBF kernel, linear kernel, ...) Bij logistic regression trek je gewoon een lijn die de klasses het nauwkeurigst snijdt. Maar dat is niet altijd de beste oplossing, want we willen dat ons model altijd zo overtuigend mogelijk is over de keuze, maw waar we veel plaats kunnen tussen laten. Daarvoor voorzien we margins tussen de SVM punten en de lijn zelf.
**Basisidee van PCA**
PCA zoekt de componenten die maximaal de variantie in de dataset verklaren. We willen zoveel mogelijk informatie overhouden na dimensionality reduction. Principal component analysis (PCA) is een wiskundige techniek om het aantal (mogelijks) gecorreleerde features te transformeren naar een kleiner aantal niet-gecorreleerde features die de principle components worden genoemd. Bij onze MNIST dataset werd de reconstructie van de digit aan de hand van 10 principle components gebeurd.
**Vanwaar Naive in Naive Bayes?**
Als je de bayes rule gebruikt, dan moet je eigenlijk in het berekenen van de kans dat een bericht spam of ham is ook rekening moeten houden met de kans om een bepaald woord te vinden gegeven alle andere woorden in het bericht en de kans dat het bericht spam is, dit gaan al zeer snel heel complexe en zware berekeningen worden, dus gaan we eigenlijk de veronderstelling maken dat de woorden in een bericht onafhankelijk zijn van elkaar. Wat uiteraard eigenlijk in het echt niet zo is want ieder bericht heeft een context. Maar hier haar het model geen rekening mee houden dus is het model naief.
**Wat is het nut van dropout?**
Is een manier om overfitting te voorkomen binnen neurale netwerken. Je kan een bepaald percentage uitschakelen van uw neuronen binnen een layer waardoor de andere neuronen moeten inspringen voor de neuronen die afliggen => machine gaat daaruit leren en voorkomt zo overfitting.
**Toepassingen van dimensionality reduction**
Dimensionality reduction is het aantal features verminderen naar een kleinere set van ‘principle variables’. Dit wordt bijvoorbeeld toegepast in face recognition. Waarbij je bv een foto van 28x28 (78 4 features) omzet naar 28 principle variables. Die 28 principle variables zijn de features die eigenlijk het meeste belang hadden aan de dataset en deze worden dan ook bewaard. Dit wordt gebruikt om ruis te vermijden. Bij face recognition mbv dimensionality reduction creëer je dan eigenlijk eigenfaces. Hoe een gezicht er uit zou zien aan de hand van 1 feature. En de 28 beste features die een gezicht kunnen reconstrueren worden bewaard in onze dataset.
**Gebruik en nut van f1 score**
F1 score is een soort van metric die we gebruiken om onze classifier op te oordelen als deze al dan niet goed is. Je hebt 4 verschillende soorten metrics: accuracy, recall, precision en f1 score. F1 score is een harmonisch gemiddelde van uw recall en precision: de formule hiervoor is (2 x (precision * recall)) / (precision * recall). Uit dit resultaat (tussen 0 en 1) zullen we oordelen als het al dan niet een goed model is (streven tot een waarde tot aan 1).
**Hoe omgaan met niet-gebalanceerde data**
Niet gebalanceerde data treed op wanneer er van de ene klasse veel meer samples zijn dan van de andere klasse. Dit is een probleem die we moeten vermijden in ML omdat ons model atlijd een grote voorkeur zal hebben voor de meerderheidsklasse. Dit kunnen we oplossen door class_weight = balanced toe tevoegen tijdens het trainen van ons model, of SMOTE toepassen: gelijkaardige datapunten bijvoegen aan onze dataset van de minderheidsklasse.
**Wat zijn eigenfaces**
We used eigenfaces (the first 10 principal components) to use face recognition in unsupervised learning. An eigenface is a basic form of a face where some specific components of a face are shown.
**Opsporen van Underfitting / Overfitting**