Ga naar hoofdinhoud

Machine Learning met Black Friday-dataset Tutorial

In deze tutorial leer je null-waarden opvullen, data preprocessen, dimensionaliteit reduceren met PCA en data splitsen met K-Fold.
· 10 min lezen

Verken met AI

Laten we eerst de basisbibliotheek importeren die we nodig hebben om met de dataset te werken.

import pandas as pd

Lees nu de dataset in en bekijk hem.

bfriday = pd.read_csv("BlackFriday.csv")
bfriday.head(10)
dataset

De bovenstaande regel geeft ons een deel van een dataset bestaande uit 10 rijen en alle kolommen. Als je bfriday.head(x,y) probeert te gebruiken, krijg je een fout, omdat de computer het totale aantal kolommen al als verplicht beschouwt. bfriday.head() geeft je ook output zonder fout; de computer kiest dan zelf het aantal rijen en kolommen.

bfriday.shape #this gives use dimensions of dataset(rows,columns)
(550068, 12)
bfriday['Stay_In_Current_City_Years'].value_counts()# counts the number of values per each range, bfriday['City_Category'].value_counts()
1    193821
2    101838
3     95285
5     84726
0     74398
Name: Stay_In_Current_City_Years, dtype: int64
bfriday.isnull().sum() #colculates no of null values for each category in dataset
User_ID                            0
Product_ID                         0
Gender                             0
Age                                0
Occupation                         0
City_Category                      0
Stay_In_Current_City_Years         0
Marital_Status                     0
Product_Category_1                 0
Product_Category_2            173638
Product_Category_3            383247
Purchase                           0
dtype: int64
b = ['Product_Category_2','Product_Category_3'] #here we are making an array consisting of 2 columns namely Product_Category_2,Product_Category_3
for i in b:
    exec("bfriday.%s.fillna(bfriday.%s.value_counts().idxmax(), inplace=True)" %(i,i))

Nu vullen we lege plekken op met de maximale waarde. We kunnen ook opschonen of lege plekken opvullen met bfriday.Product_Category_2.fillna(bfriday.Product_Category_2.value_counts().idxmax(),inplace=True); op dezelfde manier kun je de kolom Product_category_3 schoonmaken.

X = bfriday.drop(["Purchase"], axis=1)

We hebben nu de kolom met de naam purchase uit de dataset verwijderd en een array X samengesteld die uit alle kolommen bestaat behalve de purchase-kolom.

from sklearn.preprocessing import LabelEncoder#Now let's import encoder from sklearn library
LE = LabelEncoder()
#Now we will encode the data into labels using label encoder for easy computing
X = X.apply(LE.fit_transform)#Here we applied encoder onto data

Nu zetten we de data om naar numerieke vorm met pandas, omdat werken met numerieke data makkelijker is dan met categorische data.

X.Gender = pd.to_numeric(X.Gender)
X.Age = pd.to_numeric(X.Age)
X.Occupation = pd.to_numeric(X.Occupation)
X.City_Category = pd.to_numeric(X.City_Category)
X.Stay_In_Current_City_Years = pd.to_numeric(X.Stay_In_Current_City_Years)
X.Marital_Status = pd.to_numeric(X.Marital_Status)
X.Product_Category_1 = pd.to_numeric(X.Product_Category_1)
X.Product_Category_2 = pd.to_numeric(X.Product_Category_2)
X.Product_Category_3 = pd.to_numeric(X.Product_Category_3)
Y = bfriday["Purchase"]#Here we will made a array named as Y consisting of data from purchase column
from sklearn.preprocessing import StandardScaler
SS = StandardScaler()

Standaardiseer features door het gemiddelde te verwijderen en te schalen naar een variantie van 1. Centring en schaling gebeuren onafhankelijk per feature door de relevante statistieken te berekenen op de samples in de trainingsset. Gemiddelde en standaardafwijking worden vervolgens opgeslagen om op latere data te gebruiken met de transform-methode.

Xs = SS.fit_transform(X)
#You must to transform X into numeric representation (not necessary binary).Because all machine learning methods operate on matrices of number
from sklearn.decomposition import PCA
pc = PCA(4)#here 4 indicates the number of components you want it into.

Lineaire dimensionaliteitsreductie met Singular Value Decomposition van de data projecteert deze naar een ruimte met lagere dimensie. PCA is een van de meest gebruikte en bekende methoden voor dimensionaliteitsreductie. Om machinelearningalgoritmen te versnellen, fit je PCA alleen op de trainingsset. Principal component analysis (PCA)

PCA vervangt oorspronkelijke variabelen door nieuwe variabelen, hoofcomponenten genoemd, die nul covariantie onderling hebben en varianten in afnemende volgorde. Dus, de covariantiematrix tussen de uit de data geëxtraheerde hoofcomponenten.

pca
Bron: 6.3 - Principal Components Analysis (PCA)

We hebben hier iets interessants dat RandomizedPCA heet

Let op: gebruik RandomizedPCA nooit voor sparse data. Het gebruik van RandomizedPCA op sparse data is onjuist, omdat we de data niet kunnen centreren zonder de spaarzaamheid te doorbreken, wat het geheugen kan opblazen bij realistisch grote sparse data. Centreren is echter vereist voor PCA.

principalComponents = pc.fit_transform(X)#Here we are applying PCA to data/fitting data to PCA
pc.explained_variance_ratio_
array([7.35041374e-01, 2.64935995e-01, 1.10061180e-05, 6.21704987e-06])
principalDf = pd.DataFrame(data = principalComponents, columns = ["component 1", "component 2", "component 3", "component 4"])
from sklearn.model_selection import KFold
kf = KFold(20)
#Provides train/test indices to split data in train/test sets. Split dataset into k consecutive folds (without shuffling by default).
#Each fold is then used once as a validation while the k - 1 remaining folds form the training set.
for a,b in kf.split(principalDf):
    X_train, X_test = Xs[a],Xs[b]
    y_train, y_test = Y[a],Y[b]
from sklearn.linear_model import LinearRegression

Regressie onderzoekt twee dingen: (1) doet een set voorspellers goed werk in het voorspellen van een uitkomst­variabele (afhankelijk)? (2) Welke variabelen zijn specifieke, significante voorspellers van de uitkomstvariabele en op welke manier beïnvloeden ze die — aangegeven door de grootte en het teken van de beta-schattingen? Deze regressieschattingen worden gebruikt om de relatie te verklaren tussen één afhankelijke variabele en één of meer onafhankelijke variabelen. De eenvoudigste vorm van de regressievergelijking met één afhankelijke en één onafhankelijke variabele wordt gedefinieerd door de formule y = c + b*x, waarbij y = geschatte afhankelijke variabele, c = constante, b = regressiecoëfficiënt en x = score op de onafhankelijke variabele.

eenvoudig lineair regressiemodel
Bron: Linear Regression
from sklearn.tree import DecisionTreeRegressor

Een beslissingsboom wordt top-down opgebouwd vanaf een rootnode en omvat het opdelen van de data in subsets met vergelijkbare waarden. Een beslissingsboom bouwt modellen in de vorm van een boomstructuur. De dataset wordt stap voor stap opgesplitst in steeds kleinere subsets terwijl er tegelijkertijd een bijbehorende beslissingsboom wordt ontwikkeld. Het eindresultaat is een boom met beslissingsknooppunten en bladknooppunten. Een beslissingsknooppunt (bijv. Outlook) heeft twee of meer takken (bijv. Zonnig, Bewolkt en Regenachtig), elk representatief voor waarden van het geteste attribuut. Een bladknooppunt (bijv. Hours Played) vertegenwoordigt een beslissing over de numerieke target. Het bovenste beslissingsknooppunt in een boom, dat overeenkomt met de beste voorspeller, heet de rootnode. Beslissingsbomen kunnen zowel categorische als numerieke data aan. Beslissingsbomen waarbij de target continue waarden kan aannemen (meestal reële getallen) heten regressiebomen. Als de maximale diepte van de boom te hoog staat, leren beslissingsbomen te fijne details van de trainingsdata en leren ze van de ruis, oftewel ze overfitten.

beslissingsboom
Bron: Decision Trees
from sklearn.ensemble import RandomForestRegressor

Een random forest is een estimator die een aantal beslissingsbomen traint op verschillende subsamples van de dataset en gemiddelden gebruikt om de voorspellende nauwkeurigheid te verbeteren en overfitting te beheersen. De subsamplegrootte is altijd gelijk aan de oorspronkelijke inputgrootte, maar de samples worden met teruglegging getrokken als bootstrap=True. Het idee achter deze techniek is het decorreleren van de verschillende bomen. Het genereert verschillende bootstrapped samples (d.w.z. zelf gegenereerde samples) uit de trainingsdata. Vervolgens verlagen we de variantie in de bomen door ze te middelen. In deze aanpak maakt het model dus een groot aantal beslissingsbomen in Python of R. Het random-forestmodel is erg goed in het verwerken van tabelvormige data met numerieke features, of categorische features met minder dan honderden categorieën. Random forests kunnen de niet-lineaire interactie tussen features en target vastleggen.

Let op: boommogelijke modellen zijn niet ontworpen om met zeer sparse features te werken. Bij sparse inputdata kunnen we ofwel de sparse features vooraf verwerken om numerieke statistieken te genereren, of overschakelen op een lineair model, dat beter geschikt is voor zulke scenario's.

random forest vereenvoudigd
Bron: Random Forest Simple Explanation by William Koehrsen
from sklearn.ensemble import GradientBoostingRegressor

Gradient boosting is een machinelearningtechniek voor regressie- en classificatieproblemen die een predictiemodel produceert in de vorm van een ensemble van zwakke predictiemodellen, meestal beslissingsbomen. Het bouwt het model stapsgewijs op, zoals andere boosting-methoden, en generaliseert ze door optimalisatie van een willekeurige differentieerbare verliesfunctie toe te staan. Boosting kan worden geïnterpreteerd als een optimalisatie-algoritme op een geschikte kostenfunctie. De laatste twee papers introduceerden het beeld van boosting-algoritmen als iteratieve functionele gradient-descent-algoritmen. Dat wil zeggen: algoritmen die een kostenfunctie over functieruimte optimaliseren door iteratief een functie (zwakke hypothese) te kiezen die in de richting van de negatieve gradiënt wijst. Deze functionele gradiëntvisie op boosting heeft geleid tot de ontwikkeling van boosting-algoritmen in veel gebieden van machine learning en statistiek, voorbij regressie en classificatie. Gradient boosting combineert zwakke "learners" iteratief tot één sterke learner. Het is het makkelijkst uit te leggen in de least-squares-regressie-instelling, waar het doel is om een model F te "leren" dat waarden van de vorm y ^ = F ( x ) voorspelt door de mean squared error te minimaliseren.

gradient boosting eenvoudige versie
Bron: Gradient Boosting Part1–Visual Conceptualization
lr = LinearRegression()
dtr = DecisionTreeRegressor()
rfr = RandomForestRegressor()
gbr = GradientBoostingRegressor()
fit1 = lr.fit(X_train,y_train)#Here we fit training data to linear regressor
fit2 = dtr.fit(X_train,y_train)#Here we fit training data to Decision Tree Regressor
fit3 = rfr.fit(X_train,y_train)#Here we fit training data to Random Forest Regressor
fit4 = gbr.fit(X_train,y_train)#Here we fit training data to Gradient Boosting Regressor

Tot nu toe heb je fit en fit_transform gezien, maar nog niet begrepen wat ze zijn? Laten we het nu leren.

fit(): wordt gebruikt om modelparameters te leren uit trainingsdata

transform(): parameters die zijn gegenereerd met fit(), toegepast op het model om een getransformeerde dataset te maken.

fit_transform(): een combinatie van fit() en transform() API op dezelfde dataset

print("Accuracy Score of Linear regression on train set",fit1.score(X_train,y_train)*100)
print("Accuracy Score of Decision Tree on train set",fit2.score(X_train,y_train)*100)
print("Accuracy Score of Random Forests on train set",fit3.score(X_train,y_train)*100)
print("Accuracy Score of Gradient Boosting on train set",fit4.score(X_train,y_train)*100)
Accuracy Score of Linear regression on train set 11.829233894211866
Accuracy Score of Decision Tree on train set 100.0
Accuracy Score of Random Forests on train set 94.207451077798
Accuracy Score of Gradient Boosting on train set 65.49517152859553
print("Accuracy Score of Linear regression on test set",fit1.score(X_test,y_test)*100)
print("Accuracy Score of Decision Tree on test set",fit2.score(X_test,y_test)*100)
print("Accuracy Score of Random Forests on test set",fit3.score(X_test,y_test)*100)
print("Accuracy Score of Gradient Boosting on testset",fit4.score(X_test,y_test)*100)
Accuracy Score of Linear regression on test set 36.8210287243639
Accuracy Score of Decision Tree on test set 57.61911563230391
Accuracy Score of Random Forests on test set 74.71675935214292
Accuracy Score of Gradient Boosting on testset 72.43849411693184

Conclusie

Deze tutorial geeft je snel inzicht in hoe je null-waarden opvult. Ik schreef hierover omdat echte data meestal rommeliger is: je hebt nulls, foute waarden en allerlei troep die je moet opschonen. Hoera! Je hebt deze tutorial voltooid. Als je vragen of gedachten hebt over de tutorial, laat het dan weten in de reacties hieronder.

Wil je meer leren over Machine Learning in Python? Bekijk DataCamp's tutorial Introduction to Machine Learning in Python en de cursus Preprocessing for Machine Learning in Python.

Onderwerpen