web-dev-qa-db-fra.com

Comment utiliser la validation croisée a-k dans scikit avec un classificateur bayésien naïf et NLTK

J'ai un petit corpus et je veux calculer la précision du classificateur naïf de Bayes en utilisant la validation croisée 10 fois, comment le faire.

28
user2284345

Vos options sont de le configurer vous-même ou d'utiliser quelque chose comme NLTK-Trainer puisque NLTK ne prend pas directement en charge la validation croisée pour les algorithmes d'apprentissage automatique .

Je recommanderais probablement d'utiliser un autre module pour le faire pour vous, mais si vous voulez vraiment écrire votre propre code, vous pouvez faire quelque chose comme ceci.

Supposons que vous souhaitiez décupler , vous devez partitionner votre ensemble d'entraînement en 10 sous-ensembles, entraînez-vous sur 9/10, testez les 1/10, et procédez ainsi pour chaque combinaison de sous-ensembles (10).

En supposant que votre ensemble d'entraînement se trouve dans une liste nommée training, un moyen simple d'y parvenir serait,

num_folds = 10
subset_size = len(training)/num_folds
for i in range(num_folds):
    testing_this_round = training[i*subset_size:][:subset_size]
    training_this_round = training[:i*subset_size] + training[(i+1)*subset_size:]
    # train using training_this_round
    # evaluate against testing_this_round
    # save accuracy

# find mean accuracy over all rounds
26
Jared

En fait, il n'y a pas besoin d'itérations à boucle longue fournies dans la réponse la plus votée. De plus, le choix du classificateur n'est pas pertinent (il peut s'agir de n'importe quel classificateur).

Scikit fournit cross_val_score , qui fait toutes les boucles sous le capot.

from sklearn.cross_validation import KFold, cross_val_score
k_fold = KFold(len(y), n_folds=10, shuffle=True, random_state=0)
clf = <any classifier>
print cross_val_score(clf, X, y, cv=k_fold, n_jobs=1)
21
Salvador Dali

J'ai utilisé les bibliothèques et NLTK pour naivebayes sklearn pour la validation croisée comme suit:

import nltk
from sklearn import cross_validation
training_set = nltk.classify.apply_features(extract_features, documents)
cv = cross_validation.KFold(len(training_set), n_folds=10, indices=True, shuffle=False, random_state=None, k=None)

for traincv, testcv in cv:
    classifier = nltk.NaiveBayesClassifier.train(training_set[traincv[0]:traincv[len(traincv)-1]])
    print 'accuracy:', nltk.classify.util.accuracy(classifier, training_set[testcv[0]:testcv[len(testcv)-1]])

et à la fin j'ai calculé la précision moyenne

14
user2284345

Inspiré de réponse de Jared , voici une version utilisant un générateur:

def k_fold_generator(X, y, k_fold):
    subset_size = len(X) / k_fold  # Cast to int if using Python 3
    for k in range(k_fold):
        X_train = X[:k * subset_size] + X[(k + 1) * subset_size:]
        X_valid = X[k * subset_size:][:subset_size]
        y_train = y[:k * subset_size] + y[(k + 1) * subset_size:]
        y_valid = y[k * subset_size:][:subset_size]

        yield X_train, y_train, X_valid, y_valid

Je suppose que votre ensemble de données X a N points de données (= 4 dans l'exemple) et D fonctionnalités (= 2 dans l'exemple). Les N étiquettes associées sont stockées dans y.

X = [[ 1, 2], [3, 4], [5, 6], [7, 8]]
y = [0, 0, 1, 1]
k_fold = 2

for X_train, y_train, X_valid, y_valid in k_fold_generator(X, y, k_fold):
    # Train using X_train and y_train
    # Evaluate using X_valid and y_valid
1
Victor

Modification de la deuxième réponse:

cv = cross_validation.KFold(len(training_set), n_folds=10, shuffle=True, random_state=None)
1
user3236650