import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.model_selection import learning_curve def do_Kfold(model, X, y, k, scaler=None, random_state=146): from sklearn.model_selection import KFold kf = KFold(n_splits=k, random_state = random_state, shuffle=True) train_scores = [] test_scores = [] for idxTrain, idxTest in kf.split(X): Xtrain = X[idxTrain, :] Xtest = X[idxTest, :] ytrain = y[idxTrain] ytest = y[idxTest] if scaler != None: Xtrain = scaler.fit_transform(Xtrain) Xtest = scaler.transform(Xtest) model.fit(Xtrain,ytrain) train_scores.append(model.score(Xtrain,ytrain)) test_scores.append(model.score(Xtest,ytest)) return train_scores,test_scores #functions courtesy of Prof. Smith def plot_groups(points, groups, colors, ec='black', ax=None,s=30, alpha=1, figsize=(6,6), labels = ['x','y'], legend_text = None): '''Creates a scatter plot, given: Input: points (2D array) groups (1D array containing an integer label for each point) colors (one for each group) s (size for points) alpha (transparency) legend_text (a list of labels for the legend) Output: handle to the ax object (the current axes/plot) ''' if ax is None: fig,ax = plt.subplots(figsize=figsize) else: fig = plt.gcf() for yi in np.unique(groups): idx = groups == yi plt.scatter(points[idx,0], points[idx,1],color = colors[int(yi)], alpha = alpha, s = s, ec = 'k') plt.xlabel(labels[0], fontsize = 14) plt.ylabel(labels[1], fontsize = 14) if legend_text: plt.legend(legend_text) return fig,ax def compare_classes(actual, predicted, names=None): '''Function returns a confusion matrix, and overall accuracy given: Input: actual - a list of actual classifications predicted - a list of predicted classifications names (optional) - a list of class names ''' accuracy = sum(actual==predicted)/actual.shape[0] classes = pd.DataFrame(columns = ['Actual', 'Predicted']) classes['Actual'] = actual classes['Predicted'] = predicted conf_mat = pd.crosstab(classes['Actual'], classes['Predicted']) if type(names) != type(None): conf_mat.index = names conf_mat.index.name = 'Actual' conf_mat.columns = names conf_mat.columns.name = 'Predicted' print('Test accuracy = ' + format(accuracy, '.2f')) return conf_mat, accuracy def get_colors(N, map_name='rainbow'): '''Returns a list of N colors from a matplotlib colormap Input: N = number of colors, and map_name = name of a matplotlib colormap For a list of available colormaps: https://matplotlib.org/3.1.1/gallery/color/colormap_reference.html ''' import matplotlib cmap = matplotlib.cm.get_cmap(name=map_name) n = np.linspace(0,1,N) colors = cmap(n) return colors def make_grid(x_range,y_range): '''Function will take a list of x values and a list of y values, and return a list of points in a grid defined by the two ranges''' import numpy as np xx,yy = np.meshgrid(x_range,y_range) points = np.vstack([xx.ravel(), yy.ravel()]).T return points def plot_decision_boundaries(X, y, model_class, **model_params): # credits: T. Sarkar, # https://towardsdatascience.com/easily-visualize-scikit-learn-models-decision-boundaries-dd0fb3747508 """ Function to plot the decision boundaries of a classification model. This uses just the first two columns of the data for fitting the model as we need to find the predicted value for every point in scatter plot. Arguments: X: Feature data as a NumPy-type array. y: Label data as a NumPy-type array. model_class: A Scikit-learn ML estimator class e.g. GaussianNB (imported from sklearn.naive_bayes) or LogisticRegression (imported from sklearn.linear_model) **model_params: Model parameters to be passed on to the ML estimator Typical code example: e.g., plt.figure() plt.title("KNN decision boundary with neighbros: 5",fontsize=16) plot_decision_boundaries(X_train,y_train,KNeighborsClassifier,n_neighbors=5) plt.xlabel("PCA-1",fontsize=15) plt.ylabel("PCA-2",fontsize=15) plt.show() """ try: X = np.array(X) y = np.array(y).flatten() except: print("Coercing input data to NumPy arrays failed") # Reduces to the first two columns of data reduced_data = X[:, :2] # Instantiate the model object model = model_class(**model_params) # Fits the model with the reduced data model.fit(reduced_data, y) # Step size of the mesh. Decrease to increase the quality of the VQ. h = .02 # point in the mesh [x_min, m_max]x[y_min, y_max]. # Plot the decision boundary. For that, we will assign a color to each x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1 y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1 # Meshgrid creation xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) # Obtain labels for each point in mesh using the model. Z = model.predict(np.c_[xx.ravel(), yy.ravel()]) x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1), np.arange(y_min, y_max, 0.1)) # Predictions to obtain the classification results Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape) # Plotting plt.contourf(xx, yy, Z, alpha=0.4) plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8) plt.xticks(fontsize=14) plt.yticks(fontsize=14) return plt from matplotlib import pyplot from math import cos, sin, atan class Neuron(): def __init__(self, x, y): self.x = x self.y = y def draw(self, neuron_radius): circle = pyplot.Circle((self.x, self.y), radius=neuron_radius, fill=False) pyplot.gca().add_patch(circle) class Layer(): def __init__(self, network, number_of_neurons, number_of_neurons_in_widest_layer): self.vertical_distance_between_layers = 6 self.horizontal_distance_between_neurons = 2 self.neuron_radius = 0.5 self.number_of_neurons_in_widest_layer = number_of_neurons_in_widest_layer self.previous_layer = self.__get_previous_layer(network) self.y = self.__calculate_layer_y_position() self.neurons = self.__intialise_neurons(number_of_neurons) def __intialise_neurons(self, number_of_neurons): neurons = [] x = self.__calculate_left_margin_so_layer_is_centered(number_of_neurons) for iteration in range(number_of_neurons): neuron = Neuron(x, self.y) neurons.append(neuron) x += self.horizontal_distance_between_neurons return neurons def __calculate_left_margin_so_layer_is_centered(self, number_of_neurons): return self.horizontal_distance_between_neurons * (self.number_of_neurons_in_widest_layer - number_of_neurons) / 2 def __calculate_layer_y_position(self): if self.previous_layer: return self.previous_layer.y + self.vertical_distance_between_layers else: return 0 def __get_previous_layer(self, network): if len(network.layers) > 0: return network.layers[-1] else: return None def __line_between_two_neurons(self, neuron1, neuron2): angle = atan((neuron2.x - neuron1.x) / float(neuron2.y - neuron1.y)) x_adjustment = self.neuron_radius * sin(angle) y_adjustment = self.neuron_radius * cos(angle) line = pyplot.Line2D((neuron1.x - x_adjustment, neuron2.x + x_adjustment), (neuron1.y - y_adjustment, neuron2.y + y_adjustment)) pyplot.gca().add_line(line) def draw(self, layerType=0): for neuron in self.neurons: neuron.draw( self.neuron_radius ) if self.previous_layer: for previous_layer_neuron in self.previous_layer.neurons: self.__line_between_two_neurons(neuron, previous_layer_neuron) # write Text x_text = self.number_of_neurons_in_widest_layer * self.horizontal_distance_between_neurons if layerType == 0: pyplot.text(x_text, self.y, 'Input Layer', fontsize = 12) elif layerType == -1: pyplot.text(x_text, self.y, 'Output Layer', fontsize = 12) else: pyplot.text(x_text, self.y, 'Hidden Layer '+str(layerType), fontsize = 12) class NeuralNetwork(): def __init__(self, number_of_neurons_in_widest_layer): self.number_of_neurons_in_widest_layer = number_of_neurons_in_widest_layer self.layers = [] self.layertype = 0 def add_layer(self, number_of_neurons ): layer = Layer(self, number_of_neurons, self.number_of_neurons_in_widest_layer) self.layers.append(layer) def draw(self): pyplot.figure() for i in range( len(self.layers) ): layer = self.layers[i] if i == len(self.layers)-1: i = -1 layer.draw( i ) pyplot.axis('scaled') pyplot.axis('off') pyplot.title( 'Neural Network architecture', fontsize=15 ) pyplot.show() class DrawNN(): def __init__( self, neural_network ): self.neural_network = neural_network def draw( self ): widest_layer = max( self.neural_network ) network = NeuralNetwork( widest_layer ) for l in self.neural_network: network.add_layer(l) network.draw()