In [0]:
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
%pylab inline
import matplotlib.pyplot as plt
plt.xkcd()
Out[0]:
In [0]:
!curl -O https://raw.githubusercontent.com/DJCordhose/deep-learning-crash-course-notebooks/master/data/insurance-customers-1500.csv
In [0]:
import pandas as pd
df = pd.read_csv('./insurance-customers-1500.csv', sep=';')
In [0]:
df.head()
Out[0]:
In [0]:
df.describe()
Out[0]:
In [0]:
import seaborn as sns
sample_df = df.sample(n=120, random_state=42)
sns.pairplot(sample_df,
hue="group", palette={0: '#AA4444', 1: '#006000', 2: '#EEEE44'},
kind='reg',
diag_kind='kde', vars=['age', 'speed', 'miles'])
Out[0]:
In [0]:
# we deliberately decide this is going to be our label, it is often called lower case y
y=df['group']
In [0]:
# since 'group' is now the label we want to predict, we need to remove it from the training data
df.drop('group', axis='columns', inplace=True)
In [0]:
# input data often is named upper case X, the upper case indicates, that each row is a vector
X = df.as_matrix()
In [0]:
# ignore this, it is just technical code to plot decision boundaries
# Adapted from:
# http://scikit-learn.org/stable/auto_examples/neighbors/plot_classification.html
# http://jponttuset.cat/xkcd-deep-learning/
from matplotlib.colors import ListedColormap
cmap_print = ListedColormap(['#AA8888', '#004000', '#FFFFDD'])
cmap_bold = ListedColormap(['#AA4444', '#006000', '#EEEE44'])
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#FFFFDD'])
font_size=25
title_font_size=40
def meshGrid(x_data, y_data):
h = 1 # step size in the mesh
x_min, x_max = x_data.min() - 1, x_data.max() + 1
y_min, y_max = y_data.min() - 1, y_data.max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
return (xx,yy)
def plotPrediction(clf, x_data, y_data, x_label, y_label, ground_truth, title="",
mesh=True, fname=None, size=(15, 8)):
xx,yy = meshGrid(x_data, y_data)
fig, ax = plt.subplots(figsize=size)
if clf and mesh:
Z = clf.predict(np.c_[yy.ravel(), xx.ravel()])
# Put the result into a color plot
Z = Z.reshape(xx.shape)
ax.pcolormesh(xx, yy, Z, cmap=cmap_light)
ax.set_xlim(xx.min(), xx.max())
ax.set_ylim(yy.min(), yy.max())
ax.scatter(x_data, y_data, c=ground_truth, cmap=cmap_bold, s=100, marker='o', edgecolors='k')
ax.set_xlabel(x_label, fontsize=font_size)
ax.set_ylabel(y_label, fontsize=font_size)
ax.set_title(title, fontsize=title_font_size)
def plot_keras_prediction(clf, x_data, y_data, x_label, y_label, ground_truth, title="",
mesh=True, fixed=None, fname=None, size=(15, 8)):
xx,yy = meshGrid(x_data, y_data)
fig, ax = plt.subplots(figsize=size)
if clf and mesh:
grid_X = np.array(np.c_[yy.ravel(), xx.ravel()])
if fixed:
fill_values = np.full((len(grid_X), 1), fixed)
grid_X = np.append(grid_X, fill_values, axis=1)
Z = clf.predict(grid_X)
Z = np.argmax(Z, axis=1)
Z = Z.reshape(xx.shape)
ax.pcolormesh(xx, yy, Z, cmap=cmap_light)
ax.set_xlim(xx.min(), xx.max())
ax.set_ylim(yy.min(), yy.max())
ax.scatter(x_data, y_data, c=ground_truth, cmap=cmap_bold, s=100, marker='o', edgecolors='k')
ax.set_xlabel(x_label, fontsize=font_size)
ax.set_ylabel(y_label, fontsize=font_size)
ax.set_title(title, fontsize=title_font_size)
def plot_history(history, samples=100, init_phase_samples=None, plot_line=False):
epochs = history.params['epochs']
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
every_sample = int(epochs / samples)
acc = pd.DataFrame(acc).iloc[::every_sample, :]
val_acc = pd.DataFrame(val_acc).iloc[::every_sample, :]
loss = pd.DataFrame(loss).iloc[::every_sample, :]
val_loss = pd.DataFrame(val_loss).iloc[::every_sample, :]
if init_phase_samples:
acc = acc.loc[init_phase_samples:]
val_acc = val_acc.loc[init_phase_samples:]
loss = loss.loc[init_phase_samples:]
val_loss = val_loss.loc[init_phase_samples:]
fig, ax = plt.subplots(nrows=2, figsize=(15, 8))
ax[0].plot(acc, 'bo', label='Training acc')
ax[0].plot(val_acc, 'b', label='Validation acc')
ax[0].set_title('Training and validation accuracy')
ax[0].legend()
if plot_line:
x, y, _ = linear_regression(acc)
ax[0].plot(x, y, 'bo', color='red')
x, y, _ = linear_regression(val_acc)
ax[0].plot(x, y, 'b', color='red')
ax[1].plot(loss, 'bo', label='Training loss')
ax[1].plot(val_loss, 'b', label='Validation loss')
ax[1].set_title('Training and validation loss')
ax[1].legend()
if plot_line:
x, y, _ = linear_regression(loss)
ax[1].plot(x, y, 'bo', color='red')
x, y, _ = linear_regression(val_loss)
ax[1].plot(x, y, 'b', color='red')
from sklearn import linear_model
def linear_regression(data):
x = np.array(data.index).reshape(-1, 1)
y = data.values.reshape(-1, 1)
regr = linear_model.LinearRegression()
regr.fit(x, y)
y_pred = regr.predict(x)
return x, y_pred, regr.coef_
In [0]:
plotPrediction(None, X[:, 1], X[:, 0],
'Age', 'Max Speed', y, mesh=False,
title="All Data",
fname='all.png')
In [0]:
from sklearn.model_selection import train_test_split
In [0]:
# using stratefy we get a balanced number of samples per category (important!)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42, stratify=y)
In [0]:
X_train.shape, y_train.shape, X_test.shape, y_test.shape
Out[0]:
In [0]:
np.unique(y_train, return_counts=True)
Out[0]:
In [0]:
np.unique(y_test, return_counts=True)
Out[0]:
In [0]:
X_train_2_dim = X_train[:, :2]
X_test_2_dim = X_test[:, :2]
In [0]:
plotPrediction(None, X_train_2_dim[:, 1], X_train_2_dim[:, 0],
'Age', 'Max Speed', y_train, mesh=False,
title="Train Data",
fname='train.png')
In [0]:
plotPrediction(None, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test, mesh=False,
title="Test Data",
fname='test.png')
Interactive introduction to KNN: https://beta.observablehq.com/@djcordhose/how-to-build-a-teachable-machine-with-tensorflow-js#knndataset
In [0]:
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(1)
In [0]:
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_train_2_dim[:, 1], X_train_2_dim[:, 0],
'Age', 'Max Speed', y_train,
title="Train Data, KNN, k=1",
fname='knn1-train.png')
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, KNN, k=1",
fname='knn1-test.png')
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
In [0]:
# http://scikit-learn.org/stable/modules/cross_validation.html
from sklearn.model_selection import cross_val_score
In [0]:
# cross_val_score?
Cross Validation splits the train data in different ways and performs a number of training runs (3 in this case)
In [0]:
scores = cross_val_score(clf, X_train_2_dim, y_train, n_jobs=-1)
scores
Out[0]:
In [0]:
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
We can try what is the best number of numbers manually, but grid search does the same thing, only with less manual effort. This one tries the number of neighbors between 1 and 50
In [0]:
# KNeighborsClassifier?
In [0]:
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_neighbors': list(range(1, 50)),
'weights': ['uniform', 'distance'] # are points that are nearer more important?
}
clf = GridSearchCV(KNeighborsClassifier(), param_grid, n_jobs=-1)
%time clf.fit(X_train_2_dim, y_train)
clf.best_params_
Out[0]:
In [0]:
clf = KNeighborsClassifier(n_neighbors=39, weights='uniform')
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_train_2_dim[:, 1], X_train_2_dim[:, 0],
'Age', 'Max Speed', y_train,
title="Train Data, KNN, k=39")
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, KNN, k=39")
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
In [0]:
scores = cross_val_score(clf, X_train_2_dim, y_train, n_jobs=-1)
scores
Out[0]:
In [0]:
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
In [0]:
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_train_2_dim[:, 1], X_train_2_dim[:, 0],
'Age', 'Max Speed', y_train,
title="Train Data, Logistic Regression")
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
scores = cross_val_score(clf, X_train_2_dim, y_train, n_jobs=-1)
scores
Out[0]:
In [0]:
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, Logistic Regression")
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
In [0]:
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
We are using the CART algorithm:
http://scikit-learn.org/stable/modules/tree.html#tree-algorithms-id3-c4-5-c5-0-and-cart
https://machinelearningmastery.com/classification-and-regression-trees-for-machine-learning/
In [0]:
# we perform at most 20 splits of our data until we make a decision where the data point belongs
clf.tree_.max_depth
Out[0]:
In [0]:
plotPrediction(clf, X_train_2_dim[:, 1], X_train_2_dim[:, 0],
'Age', 'Max Speed', y_train,
title="Train Data, Decision Tree",
fname='dt-overfit-train.png')
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
scores = cross_val_score(clf, X_train_2_dim, y_train, n_jobs=-1)
scores
Out[0]:
In [0]:
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, Decision Tree",
fname='dt-overfit-test.png')
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
We overfit heavily and need to change the relevant parameters of our tree
In [0]:
param_grid = {
'max_depth': list(range(2, 25)),
'min_samples_split': list(range(2, 11)),
'min_samples_leaf': list(range(1, 11))
}
clf = GridSearchCV(DecisionTreeClassifier(), param_grid, n_jobs=-1)
%time clf.fit(X_train_2_dim, y_train)
clf.best_params_
Out[0]:
In [0]:
clf = DecisionTreeClassifier(max_depth=6,
min_samples_leaf=3,
min_samples_split=2)
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
clf.tree_.max_depth
Out[0]:
In [0]:
plotPrediction(clf, X_train_2_dim[:, 1], X_train_2_dim[:, 0],
'Age', 'Max Speed', y_train,
title="Train Data, Regularized Decision Tree",
fname='dt-sweet-train.png')
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
scores = cross_val_score(clf, X_train_2_dim, y_train, n_jobs=-1)
scores
Out[0]:
In [0]:
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, Regularized Decision Tree",
fname='dt-sweet-test.png')
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
In [0]:
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_jobs=-1)
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, Random Forest",
fname='rf-overfit-train.png')
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
In [0]:
# brute force grid search is far too expensive
param_grid = {
'n_estimators': list(range(3,20)),
'max_depth': list(range(2, 25)),
'min_samples_split': list(range(2, 11)),
'min_samples_leaf': list(range(1, 11))
}
clf = GridSearchCV(RandomForestClassifier(), param_grid, n_jobs=-1)
# %time clf.fit(X_train_2_dim, y_train)
# clf.best_params_
Unfortunately, training random forest classifiers is more expensive than decision trees by the number of estimators it uses (10 in our case). This makes using a deterministic grid search over all parameters prohibitively expensive. We instead use a randomized search, that tries 100 different values and we hope to find the best here.
In [0]:
# http://scikit-learn.org/stable/modules/grid_search.html#randomized-parameter-search
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint
param_dist = {
'n_estimators': randint(3,20),
"max_depth": randint(2, 25),
"min_samples_split": randint(2, 11),
"min_samples_leaf": randint(1, 11)
}
clf = RandomizedSearchCV(RandomForestClassifier(), param_dist, n_iter=1000, n_jobs=-1)
%time clf.fit(X_train_2_dim, y_train)
clf.best_params_
Out[0]:
In [0]:
# parameters might vary a bit with each run, because it is a random search
clf = RandomForestClassifier(max_depth=5, min_samples_leaf=3, min_samples_split=7, n_estimators=12, n_jobs=-1)
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, Regularized Random Forest",
fname='rf-sweet-test.png')
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
Interactive Introduction: https://dash-gallery.plotly.host/dash-svm
In its base version SVMs can only use lines as decision boundaries. Let's see how well this works.
In [0]:
from sklearn.svm import SVC
clf = SVC(kernel='linear')
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, SVM linear Kernel",
fname='svm-underfit-linear-train.png')
In [0]:
from sklearn.svm import SVC
clf = SVC()
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, SVM rbf Kernel",
fname='svm-overfit-test.png')
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
In [0]:
# SVC?
Again we strongly overfit and need to regularize our model. The two important parameters are
Interactively experiment with C and Gamma: https://dash-gallery.plotly.host/dash-svm
http://scikit-learn.org/stable/auto_examples/svm/plot_rbf_parameters.html
In [0]:
param_grid = {
'C': list(np.append(np.arange(0.1, 1.0, 0.1), np.arange(2, 10, 1))),
'gamma': list(np.append(np.arange(0.001, 0.1, 0.0005), np.arange(.02, 1.0, 0.1))),
}
clf = GridSearchCV(SVC(), param_grid, n_jobs=-1)
%time clf.fit(X_train_2_dim, y_train)
clf.best_params_
Out[0]:
In [0]:
clf = SVC(C=9, gamma=0.001)
%time clf.fit(X_train_2_dim, y_train)
Out[0]:
In [0]:
clf.score(X_train_2_dim, y_train)
Out[0]:
In [0]:
plotPrediction(clf, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, SVM Regularized rbf Kernel",
fname='svm-reg-test.png')
In [0]:
clf.score(X_test_2_dim, y_test)
Out[0]:
In [0]:
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)
print(tf.__version__)
In [0]:
# let's see what compute devices we have available, hopefully a GPU
sess = tf.Session()
devices = sess.list_devices()
for d in devices:
print(d.name)
hello = tf.constant('Hello TF!')
print(sess.run(hello))
In [0]:
from tensorflow import keras
print(keras.__version__)
A neuron takes a number of numerical inputs, multiplies each with a weight, sums up all weighted input and adds bias (constant) to that sum. From this it creates a single numerical output. For one input (one dimension) this would be a description of a line. For more dimensions this describes a hyper plane that can serve as a decision boundary. Typically, this output is transformed using an activation function which compresses the output to a value between 0 and 1 (sigmoid), or between -1 and 1 (tanh) or sets all negative values to zero (relu).
It is not really important to understand the details of a neural network. Practically how you configure them to form something more powerful is much more important. This, however, is still a very experimental domain, so there really is no conscise explanation and understanding how they work.
We start with two hidden layers each having 500 neurons
In [0]:
# tf.keras.layers.Dense?
In [0]:
from tensorflow.keras.layers import Dense
model = keras.Sequential()
model.add(Dense(units=500, name='hidden1', activation='tanh', input_dim=2))
model.add(Dense(units=500, name='hidden2', activation='tanh'))
model.add(Dense(3, name='softmax', activation='softmax'))
model.summary()
If you do not train for too long, even without any further regularization this network will not overfit by too much, but look at how strange the decision boundaries look like
In [0]:
BATCH_SIZE=1000
EPOCHS = 2000
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=100, verbose=1)
# checkpoint = tf.keras.callbacks.ModelCheckpoint('keras-model.epoch-{epoch:02d}-val_loss-{val_loss:.2f}.hdf5',
# verbose = 1, save_best_only=True)
checkpoint = tf.keras.callbacks.ModelCheckpoint('keras-model.hdf5', verbose = 1, save_best_only=True)
# %time model.fit(X_train_2_dim, y_train_categorical, epochs=EPOCHS, batch_size=BATCH_SIZE, validation_split=0.2, callbacks=[checkpoint, early_stopping])
%time history = model.fit(X_train_2_dim, y_train, epochs=EPOCHS, batch_size=BATCH_SIZE, validation_split=0.2, verbose=0)
In [0]:
train_loss, train_accuracy = model.evaluate(X_train_2_dim, y_train, batch_size=BATCH_SIZE)
train_accuracy
Out[0]:
In [0]:
test_loss, test_accuracy = model.evaluate(X_test_2_dim, y_test, batch_size=BATCH_SIZE)
test_accuracy
Out[0]:
In [0]:
plot_history(history)
In [0]:
plot_keras_prediction(model, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, NN")
Even though scores do not look too bad, decision boundaries tell us, this is not a good result. We have several means of regularization for neural networks and we use a combination of them as described below.
In [0]:
from tensorflow.keras.layers import Dense, Activation, BatchNormalization, Dropout
# https://stackoverflow.com/questions/34716454/where-do-i-call-the-batchnormalization-function-in-keras
# regularisation:
# - dropout
# - batch normalization
# - reduce capacity of model
dropout = 0.6
model = keras.Sequential()
model.add(Dense(100, name='hidden1', input_dim=2))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(dropout))
model.add(Dense(100, name='hidden2'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(dropout))
model.add(Dense(3, name='softmax', activation='softmax'))
model.summary()
In [0]:
BATCH_SIZE=1000
EPOCHS = 3000
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=500, verbose=1)
%time history = model.fit(X_train_2_dim, y_train, epochs=EPOCHS, batch_size=BATCH_SIZE, validation_split=0.2, callbacks=[early_stopping], verbose=0)
In [0]:
# use the best model
# from keras.models import load_model
# model = load_model('keras-model.hdf5')
In [0]:
train_loss, train_accuracy = model.evaluate(X_train_2_dim, y_train, batch_size=BATCH_SIZE)
train_accuracy
Out[0]:
In [0]:
test_loss, test_accuracy = model.evaluate(X_test_2_dim, y_test, batch_size=BATCH_SIZE)
test_accuracy
Out[0]:
In [0]:
plot_history(history)
In [0]:
plot_history(history, init_phase_samples=250, plot_line=True)
In [0]:
plot_keras_prediction(model, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
title="Test Data, Dropout, BachNormalization, Reduced Cap NN",
fname='nn-reg-test.png')
In [0]:
def meshGrid(x_data, y_data, xlim=None, ylim=None):
h = 1 # step size in the mesh
if xlim == None:
xlim = x_data.min(), x_data.max()
if ylim == None:
ylim = y_data.min(), y_data.max()
x_min, x_max = xlim
y_min, y_max = ylim
xx, yy = np.meshgrid(np.arange(x_min - 1, x_max + 1, h),
np.arange(y_min - 1, y_max + 1, h))
return xx, yy, xlim, ylim
def ext_plot_keras_prediction(clf, x_data, y_data, x_label, y_label, ground_truth, title="",
size=(15, 8),
xlim=(16, 90), ylim=(70, 170)):
xx,yy, xlim, ylim = meshGrid(x_data, y_data, xlim, ylim)
fig, ax = plt.subplots(figsize=size)
if clf:
grid_X = np.array(np.c_[yy.ravel(), xx.ravel()])
Z = clf.predict(grid_X)
Z = np.argmax(Z, axis=1)
Z = Z.reshape(xx.shape)
ax.pcolormesh(xx, yy, Z, cmap=cmap_light)
ax.set_xlim(xlim)
ax.set_ylim(ylim)
ax.scatter(x_data, y_data, c=ground_truth, cmap=cmap_bold, s=100, marker='o', edgecolors='k')
ax.set_xlabel(x_label, fontsize=font_size)
ax.set_ylabel(y_label, fontsize=font_size)
ax.set_title(title, fontsize=title_font_size)
In [0]:
ext_plot_keras_prediction(model, X_test_2_dim[:, 1], X_test_2_dim[:, 0],
'Age', 'Max Speed', y_test,
xlim=(6, 400), ylim=(10, 250),
title="Extended Area - Simulating Production")
In [0]:
# red makes sense here
age = 100
speed = 100
model.predict(np.array([[speed, age]]))
Out[0]:
In [0]:
# does not make any sense, but has 1.0 score for yellow
age = 200
speed = 200
model.predict(np.array([[speed, age]]))
Out[0]:
In [0]:
# there could be such a customer, but it should not be yellow, but red
age = 85
speed = 200
model.predict(np.array([[speed, age]]))
Out[0]:
In [0]: