This dataset is well studied and is a good problem for practicing on ANN because of the four input variables and neumaric and have same scale in centimeters. Each instance describes the properites of an observed flower measurements and the output variable is specific iris species.
Therefore, it's a multi-class problem, meaning that there are more than two classes to be predicted, in fact there are three flower species. This is an important type of problem on which to practice with ANN because the three class values require specilized handling.
Goal: Model accuracy of 95%-97%
It is a Python library for deep learning that wraps the efficeint numerical libraries Theano and TensorFlow.
import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
Using TensorFlow backend.
Initialize random number generator to constant value, which is 7. This is important to ensure that the result we achieve from model can be achieved again precisely. It ensures that the stochastic process of training an ANN model can be reproduced.
# fix random seed for reproducibility
seed_value = 7
np.random.seed(seed_value)
# load dataset
dataframe = pd.read_csv('datasets/Multi-class_Classification/Iris/iris.data.txt')
dataframe.head()
5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa | |
---|---|---|---|---|---|
0 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
1 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
2 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
3 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
4 | 5.4 | 3.9 | 1.7 | 0.4 | Iris-setosa |
dataset = dataframe.values
X = dataset[:,0:4].astype(float)
Y = dataset[:,4]
Due to Y's nature, we need to create dummy variables from a categorical variable.
# encode class values as integers
label_encoder = LabelEncoder()
#creating the dummy varibales
Y = label_encoder.fit_transform(Y)
# convert integers to dummy variables (i.e. one hot encoded)
dummy_y = np_utils.to_categorical(Y)
# Avoiding dummy variable trap
# have to remove one dummy variable away, you don't need all three types
dummy_y = dummy_y[:, 1:]
dummy_y
array([[ 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.], [ 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., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 1., 0.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.], [ 0., 1.]])
# Splitting the dataset into the Training set and Test set
# X_train, X_test, y_train, y_test = train_test_split(X, dummy_y, test_size = 0.2, random_state = 0)
# sc = StandardScaler()
# X_train = sc.fit_transform(X_train)
# X_test = sc.transform(X_test)
def baseline_model():
# Initialising the ANN
# 4 inputs -> [8 hidden nodes] -> 3 outputs
classifier = Sequential()
# Adding the input layer and the first hidden layer
classifier.add(Dense(units = 8, kernel_initializer = 'uniform', activation = 'relu', input_dim = 4))
# Adding the output layer
classifier.add(Dense(units = 2, kernel_initializer = 'uniform', activation = 'softmax'))
# Compiling the ANN
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
return classifier
estimator = KerasClassifier(build_fn=baseline_model, epochs=200, batch_size=5, verbose=0)
The gold standard for evaluating machine learning models is k-fold cross validation. Evaluating the model only takes approximately 10 seconds and returns an object that describes the evaluation of the 10 constructed models for each of the splits of the dataset. The results are less biased with this method and it is great for smaller models.
kfold = KFold(n_splits=10, shuffle=True, random_state=seed_value)
results = cross_val_score(estimator, X, dummy_y, cv=kfold)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Baseline: 96.62% (5.41%)
By doing this project I learned: