Recherche de site Web

Comment créer un harnais de test d'algorithme à partir de zéro avec Python


Nous ne pouvons pas savoir quel algorithme sera le meilleur pour un problème donné.

Par conséquent, nous devons concevoir un harnais de test que nous pouvons utiliser pour évaluer différents algorithmes d’apprentissage automatique.

Dans ce didacticiel, vous découvrirez comment développer un harnais de test d'algorithme d'apprentissage automatique à partir de zéro en Python.

Après avoir terminé ce tutoriel, vous saurez :

  • Comment mettre en œuvre un harnais de test d'algorithme de test de train.
  • Comment implémenter un harnais de test d'algorithme de validation croisée k-fold.

Démarrez votre projet avec mon nouveau livre Machine Learning Algorithms From Scratch, comprenant des tutoriels pas à pas et les fichiers code source Python pour tous les exemples.

Commençons.

  • Mise à jour janvier 2017 : modification du calcul de Fold_size dans cross_validation_split() pour qu'il soit toujours un nombre entier. Résout les problèmes avec Python 3.
  • Mise à jour de mars 2018 : ajout d'un lien alternatif pour télécharger l'ensemble de données, car l'original semble avoir été supprimé.
  • Mise à jour d'août 2018 : testée et mise à jour pour fonctionner avec Python 3.6.

Description

Un harnais de test fournit un moyen cohérent d’évaluer les algorithmes d’apprentissage automatique sur un ensemble de données.

Cela implique 3 éléments :

  1. La méthode de rééchantillonnage pour diviser l’ensemble de données.
  2. L'algorithme d'apprentissage automatique à évaluer.
  3. Mesure de performance permettant d'évaluer les prédictions.

Le chargement et la préparation d’un jeu de données sont une étape préalable qui doit avoir été complétée avant d’utiliser le harnais de test.

Le harnais de test doit permettre d'évaluer différents algorithmes d'apprentissage automatique, tandis que l'ensemble de données, la méthode de rééchantillonnage et les mesures de performances restent constants.

Dans ce tutoriel, nous allons démontrer les harnais de test avec un jeu de données réel.

L'ensemble de données utilisé est l'ensemble de données sur le diabète des Indiens Pima. Il contient 768 lignes et 9 colonnes. Toutes les valeurs du fichier sont numériques, en particulier des valeurs à virgule flottante.

  • Fichier d'ensemble de données.
  • Détails de l'ensemble de données.

L'algorithme Zero Rule sera évalué dans le cadre du didacticiel. L'algorithme Zero Rule prédit toujours la classe qui contient le plus d'observations dans l'ensemble de données d'entraînement.

Tutoriel

Ce tutoriel est divisé en deux sections principales :

  1. Harnais de test d’algorithme de test de train.
  2. Harnais de test d’algorithme de validation croisée.

Ces harnais de tests vous donneront les bases dont vous avez besoin pour évaluer une suite d'algorithmes d'apprentissage automatique sur un problème de modélisation prédictive donné.

1. Harnais de test d’algorithme de test de train

La répartition train-test est une méthode de rééchantillonnage simple qui peut être utilisée pour évaluer un algorithme d'apprentissage automatique.

En tant que tel, il constitue un bon point de départ pour développer un harnais de test.

Nous pouvons supposer le développement préalable d'une fonction pour diviser un ensemble de données en ensembles d'entraînement et de test et d'une fonction pour évaluer l'exactitude d'un ensemble de prédictions.

Nous avons besoin d'une fonction capable de prendre un ensemble de données et un algorithme et de renvoyer un score de performance.

Vous trouverez ci-dessous une fonction nommée evaluate_algorithm() qui permet d'y parvenir. Il faut 3 arguments fixes, dont l'ensemble de données, la fonction d'algorithme et le pourcentage de répartition pour la répartition train-test.

Tout d’abord, l’ensemble de données est divisé en éléments d’entraînement et de test. Ensuite, une copie de l'ensemble de test est effectuée et chaque valeur de sortie est effacée en la définissant sur la valeur Aucun, pour empêcher l'algorithme de tricher accidentellement.

L'algorithme fourni en paramètre est une fonction qui attend les ensembles de données d'entraînement et de test sur lesquels préparer puis faire des prédictions. L'algorithme peut nécessiter des paramètres de configuration supplémentaires. Ceci est géré en utilisant les arguments variables *args dans la fonction evaluate_algorithm() et en les transmettant à la fonction d'algorithme.

La fonction d'algorithme devrait renvoyer une liste de prédictions, une pour chaque ligne de l'ensemble de données d'entraînement. Celles-ci sont comparées aux valeurs de sortie réelles de l'ensemble de données de test non modifié par la fonction accuracy_metric().

Enfin, la précision est renvoyée.

# Evaluate an algorithm using a train/test split
def evaluate_algorithm(dataset, algorithm, split, *args):
	train, test = train_test_split(dataset, split)
	test_set = list()
	for row in test:
		row_copy = list(row)
		row_copy[-1] = None
		test_set.append(row_copy)
	predicted = algorithm(train, test_set, *args)
	actual = [row[-1] for row in test]
	accuracy = accuracy_metric(actual, predicted)
	return accuracy

La fonction d'évaluation repose sur des hypothèses fortes, mais celles-ci peuvent facilement être modifiées si nécessaire.

Plus précisément, il suppose que la dernière ligne de l'ensemble de données est toujours la valeur de sortie. Une autre colonne pourrait être utilisée. L'utilisation de accuracy_metric() suppose que le problème est un problème de classification, mais cela pourrait être modifié en erreur quadratique moyenne pour les problèmes de régression.

Rassemblons cela avec un exemple concret.

Nous utiliserons l'ensemble de données sur le diabète des Indiens Pima et évaluerons l'algorithme Zero Rule.

# Train-Test Test Harness
from random import seed
from random import randrange
from csv import reader

# Load a CSV file
def load_csv(filename):
	file = open(filename, "rb")
	lines = reader(file)
	dataset = list(lines)
	return dataset

# Convert string column to float
def str_column_to_float(dataset, column):
	for row in dataset:
		row[column] = float(row[column].strip())

# Split a dataset into a train and test set
def train_test_split(dataset, split):
	train = list()
	train_size = split * len(dataset)
	dataset_copy = list(dataset)
	while len(train) < train_size:
		index = randrange(len(dataset_copy))
		train.append(dataset_copy.pop(index))
	return train, dataset_copy

# Calculate accuracy percentage
def accuracy_metric(actual, predicted):
	correct = 0
	for i in range(len(actual)):
		if actual[i] == predicted[i]:
			correct += 1
	return correct / float(len(actual)) * 100.0

# Evaluate an algorithm using a train/test split
def evaluate_algorithm(dataset, algorithm, split, *args):
	train, test = train_test_split(dataset, split)
	test_set = list()
	for row in test:
		row_copy = list(row)
		row_copy[-1] = None
		test_set.append(row_copy)
	predicted = algorithm(train, test_set, *args)
	actual = [row[-1] for row in test]
	accuracy = accuracy_metric(actual, predicted)
	return accuracy

# zero rule algorithm for classification
def zero_rule_algorithm_classification(train, test):
	output_values = [row[-1] for row in train]
	prediction = max(set(output_values), key=output_values.count)
	predicted = [prediction for i in range(len(test))]
	return predicted

# Test the zero rule algorithm on the diabetes dataset
seed(1)
# load and prepare data
filename = 'pima-indians-diabetes.csv'
dataset = load_csv(filename)
for i in range(len(dataset[0])):
	str_column_to_float(dataset, i)
# evaluate algorithm
split = 0.6
accuracy = evaluate_algorithm(dataset, zero_rule_algorithm_classification, split)
print('Accuracy: %.3f%%' % (accuracy))

L'ensemble de données a été divisé en 60 % pour l'entraînement du modèle et 40 % pour son évaluation.

Remarquez comment le nom de l'algorithme Zero Rule zero_rule_algorithm_classification a été transmis comme argument à la fonction evaluate_algorithm(). Vous pouvez voir comment ce harnais de test peut être utilisé encore et encore avec différents algorithmes.

L'exécution de l'exemple ci-dessus imprime la précision du modèle.

Accuracy: 67.427%

2. Harnais de test d’algorithme de validation croisée

La validation croisée est une technique de rééchantillonnage qui fournit des estimations plus fiables des performances de l'algorithme sur des données invisibles.

Cela nécessite la création et l’évaluation de k modèles sur différents sous-ensembles de vos données, ce qui coûte plus cher en termes de calcul. Néanmoins, il s’agit de la référence en matière d’évaluation des algorithmes d’apprentissage automatique.

Comme dans la section précédente, nous devons créer une fonction qui relie la méthode de rééchantillonnage, l'évaluation de l'algorithme sur l'ensemble de données et la méthode de calcul des performances.

Contrairement à ci-dessus, l’algorithme doit être évalué plusieurs fois sur différents sous-ensembles de l’ensemble de données. Cela signifie que nous avons besoin de boucles supplémentaires dans notre fonction evaluate_algorithm().

Vous trouverez ci-dessous une fonction qui implémente l'évaluation d'algorithmes avec validation croisée.

Tout d'abord, l'ensemble de données est divisé en groupes n_folds appelés plis.

Ensuite, nous effectuons une boucle donnant à chaque pli la possibilité d'être exclu de la formation et utilisé pour évaluer l'algorithme. Une copie de la liste des plis est créée et le pli retenu est supprimé de cette liste. Ensuite, la liste des plis est aplatie en une longue liste de lignes pour correspondre aux attentes des algorithmes d'un ensemble de données d'entraînement. Cela se fait à l'aide de la fonction sum().

Une fois l'ensemble de données de formation préparé, le reste de la fonction au sein de cette boucle est comme ci-dessus. Une copie de l'ensemble de données de test (le pli) est effectuée et les valeurs de sortie sont effacées pour éviter toute tricherie accidentelle par les algorithmes. L'algorithme est préparé sur l'ensemble de données du train et effectue des prédictions sur l'ensemble de données de test. Les prédictions sont évaluées et stockées dans une liste.

Contrairement au faisceau de tests de l'algorithme de test d'entraînement, une liste de scores est renvoyée, un pour chaque pli de validation croisée.

# Evaluate an algorithm using a cross validation split
def evaluate_algorithm(dataset, algorithm, n_folds, *args):
	folds = cross_validation_split(dataset, n_folds)
	scores = list()
	for fold in folds:
		train_set = list(folds)
		train_set.remove(fold)
		train_set = sum(train_set, [])
		test_set = list()
		for row in fold:
			row_copy = list(row)
			test_set.append(row_copy)
			row_copy[-1] = None
		predicted = algorithm(train_set, test_set, *args)
		actual = [row[-1] for row in fold]
		accuracy = accuracy_metric(actual, predicted)
		scores.append(accuracy)
	return scores

Bien que son code soit légèrement plus complexe et plus lent à exécuter, cette fonction fournit une estimation plus robuste des performances de l'algorithme.

Nous pouvons relier tout cela avec un exemple complet sur l’ensemble de données sur le diabète avec l’algorithme Zero Rule.

# Cross Validation Test Harness
from random import seed
from random import randrange
from csv import reader

# Load a CSV file
def load_csv(filename):
	file = open(filename, "rb")
	lines = reader(file)
	dataset = list(lines)
	return dataset

# Convert string column to float
def str_column_to_float(dataset, column):
	for row in dataset:
		row[column] = float(row[column].strip())

# Split a dataset into k folds
def cross_validation_split(dataset, n_folds):
	dataset_split = list()
	dataset_copy = list(dataset)
	fold_size = int(len(dataset) / n_folds)
	for i in range(n_folds):
		fold = list()
		while len(fold) < fold_size:
			index = randrange(len(dataset_copy))
			fold.append(dataset_copy.pop(index))
		dataset_split.append(fold)
	return dataset_split

# Calculate accuracy percentage
def accuracy_metric(actual, predicted):
	correct = 0
	for i in range(len(actual)):
		if actual[i] == predicted[i]:
			correct += 1
	return correct / float(len(actual)) * 100.0

# Evaluate an algorithm using a cross validation split
def evaluate_algorithm(dataset, algorithm, n_folds, *args):
	folds = cross_validation_split(dataset, n_folds)
	scores = list()
	for fold in folds:
		train_set = list(folds)
		train_set.remove(fold)
		train_set = sum(train_set, [])
		test_set = list()
		for row in fold:
			row_copy = list(row)
			test_set.append(row_copy)
			row_copy[-1] = None
		predicted = algorithm(train_set, test_set, *args)
		actual = [row[-1] for row in fold]
		accuracy = accuracy_metric(actual, predicted)
		scores.append(accuracy)
	return scores

# zero rule algorithm for classification
def zero_rule_algorithm_classification(train, test):
	output_values = [row[-1] for row in train]
	prediction = max(set(output_values), key=output_values.count)
	predicted = [prediction for i in range(len(test))]
	return predicted

# Test the zero rule algorithm on the diabetes dataset
seed(1)
# load and prepare data
filename = 'pima-indians-diabetes.csv'
dataset = load_csv(filename)
for i in range(len(dataset[0])):
	str_column_to_float(dataset, i)
# evaluate algorithm
n_folds = 5
scores = evaluate_algorithm(dataset, zero_rule_algorithm_classification, n_folds)
print('Scores: %s' % scores)
print('Mean Accuracy: %.3f%%' % (sum(scores)/len(scores)))

Au total, 5 plis de validation croisée ont été utilisés pour évaluer l'algorithme de la règle zéro. Ainsi, 5 scores ont été renvoyés par l'algorithme evaluate_algorithm().

L'exécution de cet exemple imprime à la fois la liste des scores calculés et le score moyen.

Scores: [62.091503267973856, 64.70588235294117, 64.70588235294117, 64.70588235294117, 69.28104575163398]
Mean Accuracy: 65.098%

Vous disposez désormais de deux harnais de test différents que vous pouvez utiliser pour évaluer vos propres algorithmes d'apprentissage automatique.

Rallonges

Cette section répertorie les extensions de ce didacticiel que vous souhaiterez peut-être envisager.

  • Évaluation paramétrée. Transmettez la fonction utilisée pour évaluer les prédictions, vous permettant de travailler de manière transparente avec des problèmes de régression.
  • Rééchantillonnage paramétré. Transmettez la fonction utilisée pour calculer les fractionnements de rééchantillonnage, vous permettant de basculer facilement entre les méthodes de test d'entraînement et de validation croisée.
  • Scores d'écart type. Calculez l'écart type pour avoir une idée de la répartition des scores lors de l'évaluation d'algorithmes à l'aide de la validation croisée.

Avez-vous essayé l'une de ces extensions ?
Partagez vos expériences dans les commentaires ci-dessous.

Revoir

Dans ce didacticiel, vous avez découvert comment créer un harnais de test à partir de zéro pour évaluer vos algorithmes d'apprentissage automatique.

Concrètement, vous savez désormais :

  • Comment mettre en œuvre et utiliser un harnais de test d'algorithme de test de train.
  • Comment implémenter et utiliser un harnais de test d'algorithme de validation croisée.

Avez-vous des questions ?
Posez vos questions dans les commentaires ci-dessous et je ferai de mon mieux pour y répondre.

Articles connexes