[PYTHON] [Chapitre 6] Introduction à scicit-learn avec 100 coups de traitement du langage

Dans cet article, j'expliquerai scikit-learn en utilisant 100 Language Processing Knock Chapitre 6.

Tout d'abord, faisons pip install scikit-learn.

50. Obtention et mise en forme des données

Téléchargez l'ensemble de données News Aggregator et créez les données d'entraînement (train.txt), les données de vérification (valid.txt) et les données d'évaluation (test.txt) comme suit.

Décompressez le fichier zip téléchargé et lisez l'explication de readme.txt. Seuls les cas (articles) où la source d'information (éditeur) est «Reuters», «Huffington Post», «Businessweek», «Contactmusic.com», «Daily Mail» sont extraits. Triez au hasard les cas extraits. Divisez 80% des observations extraites en données d'entraînement et les 10% restants en données de vérification et en données d'évaluation, et enregistrez-les respectivement sous les noms de fichier train.txt, valid.txt et test.txt. Écrivez un cas par ligne dans le fichier et utilisez le format délimité par des tabulations du nom de la catégorie et de l'en-tête de l'article (ce fichier sera réutilisé plus tard dans le problème 70).

Après avoir créé les données d'entraînement et les données d'évaluation, vérifiez le nombre de cas dans chaque catégorie.

Ce problème n'a rien à voir avec scicit-learn, vous pouvez donc le résoudre comme vous le souhaitez. Tout d'abord, téléchargez le fichier et lisez readme.txt.

!wget https://archive.ics.uci.edu/ml/machine-learning-databases/00359/NewsAggregatorDataset.zip
!unzip -c NewsAggregatorDataset.zip readme.txt

Readme est très bien, mais je veux gérer les fichiers compressés sans les décompresser autant que possible. Le fichier zip du corps de données doit être géré par le module zipfile. N'importe quelle méthode peut être utilisée pour la lecture, mais dans ce cas, Use pandas est facile. Laissez sklearn.model_selection.train_test_split () faire le fractionnement. Il mélange également.

En guise d'histoire rudimentaire, le nom de la bibliothèque est scikit-learn, mais le nom du module lors de l'importation est sklearn.

import csv
import zipfile

import pandas as pd
from sklearn.model_selection import train_test_split


with zipfile.ZipFile("NewsAggregatorDataset.zip") as z:
    with z.open("newsCorpora.csv") as f:
        names = ('ID','TITLE','URL','PUBLISHER','CATEGORY','STORY','HOSTNAME','TIMESTAMP')
        df = pd.read_table(f, names=names, quoting=csv.QUOTE_NONE)

publisher_set = {"Reuters", "Huffington Post", "Businessweek", "Contactmusic.com", "Daily Mail"}
df = df[df['PUBLISHER'].isin(publisher_set)]
df, valid_test_df = train_test_split(df, train_size=0.8, random_state=0)
df.to_csv('train.txt', columns=('CATEGORY','TITLE'), sep='\t', header=False, index=False)
valid_df, test_df = train_test_split(valid_test_df, test_size=0.5, random_state=0)
valid_df.to_csv('valid.txt', columns=('CATEGORY','TITLE'), sep='\t', header=False, index=False)
test_df.to_csv('test.txt', columns=('CATEGORY','TITLE'), sep='\t', header=False, index=False)

pandas.read_table () lit un fichier TSV et crée un objet de type DataFrame. names définit le nom de la colonne. quoting = csv.QUOTE_NONE est un paramètre permettant de traiter le guillemet comme une chaîne de caractères. csv.QUOTE_NONE est le même même si vous écrivez 3.

(J'ai entendu dire que read_table () était obsolète, vous pouvez donc utiliser read_csv (sep = '\ t'), mais il semble qu'il ne soit plus obsolète car il n'y a pas d'avertissement.)

La partie df ['PUBLISHER'] est une opération d'extraction de colonnes, et la valeur de retour sera de type Series. Le type de pandas «DataFrame» représentait la structure de la table entière, et chaque colonne était représentée par le type «Série». Sa méthode ʻisin () retourne la Series de la valeur de vérité de l'opération ʻin pour chaque élément. Et si vous le passez comme s'il s'agissait d'une clé df, il retournera un DataFrame qui extrait uniquement les lignes True.

names = ('CATEGORY','TITLE')
df = pd.read_table('train.txt', names=names, quoting=csv.QUOTE_NONE)
df['CATEGORY'].value_counts()
b    4503
e    4254
t    1210
m     717
Name: CATEGORY, dtype: int64
df = pd.read_table('test.txt', names=names, quoting=csv.QUOTE_NONE)
df['CATEGORY'].value_counts()
b    565
e    518
t    163
m     90
Name: CATEGORY, dtype: int64

51. Extraction d'entités

Extrayez les fonctionnalités des données d'entraînement, des données de vérification et des données d'évaluation, et enregistrez-les respectivement sous les noms de fichier train.feature.txt, valid.feature.txt et test.feature.txt. N'hésitez pas à concevoir les fonctionnalités susceptibles d'être utiles pour la catégorisation. La ligne de base minimale serait un titre d'article converti en une chaîne de mots.

Dans ce problème, il n'est pas dit que les caractéristiques extraites doivent être converties en un vecteur (matrice). Il semble qu'il soit nécessaire d'enregistrer le montant de la fonction dans un format lisible par l'homme afin de l'utiliser ultérieurement pour l'analyse des erreurs.

(Si vous utilisez Count vectorizer de scikit-learn, l'extraction de caractéristiques et la vectorisation seront effectuées comme un ensemble, ce qui n'est pas familier avec ce problème.)

Par conséquent, extrayez les fonctionnalités par vous-même, créez un objet dictionnaire, enregistrez-le et utilisez Dictvectorizer dans le problème suivant. Nous allons le résoudre avec la politique de vectorisation en utilisant. La clé du dictionnaire est le nom de la quantité de caractéristiques et la valeur est 1,0. C'est une nature binaire. Création d'un dictionnaire à partir de quantités d'entités Ce processus est également requis pour l'inférence, alors faites-en une fonction.

Le format de stockage de la quantité de fonctionnalités n'est pas spécifié, mais je pense que le format jsonl est meilleur du point de vue de la lisibilité.

Je veux séparer les virgules et les guillemets des mots. Peu importe comment vous le faites. SpaCy est célèbre en tant que tokenizer, mais je pense que le tokenizer de Count vectorizer est également efficace dans ce problème.

q51.py


import argparse
import json


from sklearn.feature_extraction.text import CountVectorizer


def ngram_gen(seq, n):
    return zip(*(seq[i:] for i in range(n)))


nlp = CountVectorizer().build_tokenizer()

def make_feats_dict(title):
    words = nlp(title)
    
    feats = {}
    for token in words:
        feats[token] = 1.0
    for bigram in ngram_gen(words, 2):
        feats[' '.join(bigram)] = 1.0
    for trigram in ngram_gen(words, 3):
        feats[' '.join(trigram)] = 1.0
    return feats


def dump_features(input_file, output_file):
    with open(input_file) as fi, open(output_file, 'w') as fo:
        for line in fi:
            vals = line.rstrip().split('\t')
            label, title = vals
            feats = {'**LABEL**': label}
            feats.update(make_feats_dict(title))
            print(json.dumps(feats), file=fo)

            
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('input_file')
    parser.add_argument('output_file')
    args = vars(parser.parse_args())
    dump_features(**args)
    
            
if __name__ == '__main__':
    main()

Overwriting q51.py
!python q51.py test.txt test.feature.txt
!python q51.py valid.txt valid.feature.txt
!python q51.py train.txt train.feature.txt

ngram_gen () fait ngram. Pour le bigramme, transposez [[I, am, an, NLPer], [am, an, NLPer]] (selon le plus court)! Je le fais de manière élégante.

(L'étiquette n'est pas une quantité de caractéristiques, mais je l'écris car elle atténuera le problème suivant)

Je fais quelque chose d'étrange avec la fonction principale, mais cela est également utilisé dans le chapitre 4 [Déballer la liste des arguments](https://docs.python.org/ja/3/tutorial/controlflow.html#unpacking- J'essaie de passer des arguments de mots clés dans un dictionnaire par des listes d'arguments) Puisque la valeur de retour de parse_args () est un objet d'espace de noms, elle est convertie en objet dictionnaire par vars () (comme mentionné au chapitre 5).

52. Apprentissage

Apprenez le modèle de régression logistique à l'aide des données d'entraînement construites en> 51.

Commencez par créer une liste «X» constituée d'un dictionnaire représentant la quantité de caractéristiques du fichier créé en 51. Pour l'entrer dans le modèle d'apprentissage automatique, nous avons besoin d'un vecteur qui répertorie les valeurs de toutes les fonctionnalités. Utilisez donc DictVectorizer (). La méthode fit (X) du DictVectorizer récupère le mappage du nom de la fonction-index du X et le stocke dans une variable à l'intérieur de l'instance. Ensuite, utilisez transform (X) pour transformer X en une matrice numpy. Fit_transform (X) fait tout cela en même temps.

Utilisez ensuite LogisticRegression (). Instanciez simplement et appelez la méthode fit (X, y) pour apprendre le vecteur de poids à l'intérieur de l'instance. Hypara est défini lors de l'instanciation. «X» est comme une matrice, «y» est comme une liste, et ce n'est pas grave si les longueurs correspondent.

Enregistrez le modèle entraîné en vous référant à Persistance du modèle. Lors de l'utilisation de joblib.dump (), un grand nombre de fichiers sera généré à moins que l'argument optionnel «compress» ne soit spécifié. Donc sois prudent.

À ce stade, si vous n'enregistrez pas le mappage entre le nom de la quantité d'entités et l'index, vous serez en difficulté au moment de l'inférence. Jetons chaque instance de DictVectorizer.

q52.py


import argparse
import json


import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.linear_model import LogisticRegression
import joblib


def argparse_imf():
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--input')
    parser.add_argument('-m', '--model')
    parser.add_argument('-f', '--feats')
    args = parser.parse_args()
    return args


def load_xy(filename):
    X = []
    y = []
    with open(filename) as f:
        for line in f:
            dic = json.loads(line)
            y.append(dic.pop('**LABEL**'))
            X.append(dic)
    return X, y


def main():
    args = argparse_imf()
    X_train, y_train = load_xy(args.input)
    
    vectorizer = DictVectorizer()
    X_train = vectorizer.fit_transform(X_train)
    y_train = np.array(y_train)
    clf = LogisticRegression(random_state=0, max_iter=1000, verbose=1)
    clf.fit(X_train, y_train)
    
    joblib.dump(clf, args.model, compress=3)
    joblib.dump(vectorizer, args.feats, compress=3)

    
if __name__ == '__main__':
    main()

Overwriting q52.py
!python q52.py -i train.feature.txt -m train.logistic.model -f train.feature.joblib

53. Prévisions

Utilisez le modèle de régression logistique appris en> 52 et implémentez un programme qui calcule la catégorie et sa probabilité de prédiction à partir de l'en-tête d'article donné.

Je pense que le "titre d'article donné" dans cette question ne fait pas référence aux données de test créées ci-dessus, mais plutôt à faire des prédictions à partir de n'importe quel titre d'article.

Si vous chargez le modèle sauvegardé et appelez predict (X), l'étiquette sortira, et si vous appelezpredict_proba (X), la probabilité de prédiction sortira. Ce X peut être obtenu en créant un dictionnaire de caractéristiques à partir de l'entrée et en le convertissant avec le Dictvectorizer () enregistré dans 52.

Si vous entrez deux titres et appliquez predict_proba (), vous obtiendrez un numpy.ndarray comme celui-ci.

>>> y_proba
array([[0.24339871, 0.54111814, 0.10059608, 0.11488707],
       [0.19745579, 0.69644375, 0.04204659, 0.06405386]])

Les probabilités de prédiction pour toutes les étiquettes sortent, mais je pense que vous ne voulez que la valeur maximale. que devrais-je faire? Il semble que ndarray ait une méthode max () ...

>>> y_proba.max()
0.6964437549683299
>>> y_proba.max(axis=0)
array([0.24339871, 0.69644375, 0.10059608, 0.11488707])

Faisons de notre mieux. Voici un exemple de réponse.

q53.py


import argparse
import json
import sys


import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.linear_model import LogisticRegression
import joblib


from q51 import make_feats_dict
from q52 import argparse_imf, load_xy


def predict_label_proba(X, vectorizer, clf):
    X = vectorizer.transform(X)
    y_proba = clf.predict_proba(X)    
    y_pred = clf.classes_[y_proba.argmax(axis=1)]
    y_proba_max = y_proba.max(axis=1)
    return y_pred, y_proba_max


def main():
    args = argparse_imf()
    vectorizer = joblib.load(args.feats)
    clf = joblib.load(args.model)
    X = list(map(make_feats_dict, sys.stdin))
    y_pred, y_proba = predict_label_proba(X, vectorizer, clf)
    for label, proba in zip(y_pred, y_proba):
        print('%s\t%.4f' % (label, proba))

    
if __name__ == '__main__':
    main()

Overwriting q53.py
!echo 'I have a dog.' | python q53.py -m train.logistic.model -f train.feature.joblib
e	0.5441

54. Mesure du taux de réponse correcte

Mesurez le taux de réponse correct du modèle de régression logistique appris en> 52 sur les données d'entraînement et les données d'évaluation.

Vous pouvez l'implémenter à la main, mais je vais le laisser à sklearn.metrics.accuracy_score ().

La chose la plus importante dans l'apprentissage de «scikit-learn» est le flux jusqu'à présent.

  1. Extraire les fonctionnalités et les convertir en type «dict» (liste avec éléments)
  2. Convertissez en une matrice avec Dictvectorizer.fit_transform ()
  3. Sélectionnez et instanciez un modèle d'apprentissage automatique tel que LogisticRegression
  4. Apprenez avec fit (X_train, y_train)
  5. Inférer avec prédire (X_test)
  6. Évaluer d'une manière ou d'une autre

Tenons cela fermement.

q54.py


import argparse
import json


import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import joblib


from q52 import argparse_imf, load_xy


def predict(args):
    X_test, y_true = load_xy(args.input)
    
    vectorizer = joblib.load(args.feats)
    X_test = vectorizer.transform(X_test)
    y_true = np.array(y_true)
    
    clf = joblib.load(args.model)
    y_pred = clf.predict(X_test)
    
    return y_true, y_pred


def main():
    args = argparse_imf()
    y_true, y_pred = predict(args)
    accuracy = accuracy_score(y_true, y_pred) * 100
    print('Accuracy: %.3f' % accuracy)

    
if __name__ == '__main__':
    main()

Overwriting q54.py
!python q54.py -i train.feature.txt -m train.logistic.model -f train.feature.joblib
Accuracy: 99.897
!python q54.py -i test.feature.txt -m train.logistic.model -f train.feature.joblib
Accuracy: 87.275

55. Création d'une matrice de confusion

Créer une matrice de confusion du modèle de régression logistique appris en> 52 sur les données d'entraînement et les données d'évaluation.

Laissez-le à sklearn.metrics.confusion_matrix ().

q55.py


from sklearn.metrics import confusion_matrix

from q52 import argparse_imf
from q54 import predict


def main():
    args = argparse_imf()
    y_true, y_pred = predict(args)
    labels = ('b', 'e', 't', 'm')
    matrix = confusion_matrix(y_true, y_pred, labels=labels)
    print(labels)
    print(matrix)

    
if __name__ == '__main__':
    main()
Overwriting q55.py
!python q55.py -i train.feature.txt -m train.logistic.model -f train.feature.joblib
('b', 'e', 't', 'm')
[[4499    1    3    0]
 [   2 4252    0    0]
 [   3    1 1206    0]
 [   0    1    0  716]]
!python q55.py -i test.feature.txt -m train.logistic.model -f train.feature.joblib
('b', 'e', 't', 'm')
[[529  26  10   0]
 [ 13 503   2   0]
 [ 37  36  89   1]
 [ 19  26   0  45]]

56. Mesure de la précision, du rappel et du score F1

Mesurer la précision, le rappel et le score F1 du modèle de régression logistique appris en> 52 sur les données d'évaluation. Obtenez le taux de précision, le taux de rappel et le score F1 pour chaque catégorie, et intégrez les performances de chaque catégorie avec une micro-moyenne et une macro-moyenne.

Laissez-le à sklearn.metrics.classification_report (). Dans la classification multi-classes (étiquette unique), la micro-moyenne de toutes les classes correspond au taux de réponse correct (Référence).

q56.py


from sklearn.metrics import classification_report

from q52 import argparse_imf
from q54 import predict


def main():
    args = argparse_imf()
    y_true, y_pred = predict(args)
    print(classification_report(y_true, y_pred, digits=4))

    
if __name__ == '__main__':
    main()
Overwriting q56.py
!python q56.py -i test.feature.txt -m train.logistic.model -f train.feature.joblib
              precision    recall  f1-score   support

           b     0.8846    0.9363    0.9097       565
           e     0.8511    0.9710    0.9071       518
           m     0.9783    0.5000    0.6618        90
           t     0.8812    0.5460    0.6742       163

    accuracy                         0.8728      1336
   macro avg     0.8988    0.7383    0.7882      1336
weighted avg     0.8775    0.8728    0.8633      1336

57. Confirmation du poids caractéristique

Vérifiez les 10 principales fonctionnalités avec des poids élevés et les 10 principales caractéristiques avec des poids faibles dans le modèle de régression logistique appris en> 52.

L'attribut coef_ a un poids, mais comme il s'agit d'une classification multi-classes, le poids est égal au nombre de classes x le nombre d'étiquettes d'entités. Les 4 classes seront-elles générées?

q57.py


import joblib
import numpy as np


from q52 import argparse_imf


def get_topk_indices(array, k=10):
    unsorted_max_indices = np.argpartition(-array, k)[:k]
    max_weights = array[unsorted_max_indices]
    max_indices = np.argsort(-max_weights)
    return unsorted_max_indices[max_indices]

def show_weights(args):
    vectorizer = joblib.load(args.feats)
    feature_nemes = np.array(vectorizer.get_feature_names())
    
    clf = joblib.load(args.model)
    coefs = clf.coef_
    y_labels = clf.classes_
    for coef, y_label in zip(coefs, y_labels):
        max_k_indices = get_topk_indices(coef)
        print(y_label)
        for name, weight in zip(feature_nemes[max_k_indices],  coef[max_k_indices]):
            print(name, weight, sep='\t')
        print('...')
        min_k_indices = get_topk_indices(-coef)
        for name, weight in zip(feature_nemes[min_k_indices],  coef[min_k_indices]):
            print(name, weight, sep='\t')
        print()

def main():
    args = argparse_imf()
    show_weights(args)

    
if __name__ == '__main__':
    main()
Overwriting q57.py
!python q57.py -i test.feature.txt -m train.logistic.model -f train.feature.joblib

C'est une façon détournée comme celle-ci, car je ne veux que les niveaux supérieur et inférieur au lieu de trier le coef_entier. C'est parce qu'il n'y a pas de fonction de typetopk ()dans numpy, et il n'y a pas d'autre choix que d'obtenir l'index supérieur qui n'est pas trié par ʻargpartition ().

58. Modifier les paramètres de régularisation

Lors de l'entraînement d'un modèle de régression logistique, le degré de surajustement pendant l'entraînement peut être contrôlé en ajustant les paramètres de régularisation. Apprenez le modèle de régression logistique avec différents paramètres de régularisation et trouvez le taux de réponse correct sur les données d'entraînement, les données de validation et les données d'évaluation. Résumez les résultats de l'expérience dans un graphique avec les paramètres de régularisation sur l'axe horizontal et le taux de précision sur l'axe vertical.

import argparse
import json


import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import joblib
import matplotlib.pyplot as plt
from tqdm import tqdm


from q52 import load_xy


def get_accuracy(clf, X, y_true):
    y_pred = clf.predict(X)
    return accuracy_score(y_true, y_pred)


X_train, y_train = load_xy('train.feature.txt')
X_valid, y_valid = load_xy('valid.feature.txt')
X_test, y_test = load_xy('test.feature.txt')

vectorizer = DictVectorizer()
X_train = vectorizer.fit_transform(X_train)
X_valid = vectorizer.transform(X_valid)
X_test = vectorizer.transform(X_test)

train_accuracies = []
valid_accuracies = []
test_accuracies = []

for exp in tqdm(range(10)):
    clf = LogisticRegression(random_state=0, max_iter=1000, C=2**exp)
    clf.fit(X_train, y_train)
    train_accuracies.append(get_accuracy(clf, X_train, y_train))
    valid_accuracies.append(get_accuracy(clf, X_valid, y_valid))
    test_accuracies.append(get_accuracy(clf, X_test, y_test))


cs = [2**c for c in range(10)]
plt.plot(cs, train_accuracies, label='train')
plt.plot(cs, valid_accuracies, label='valid')
plt.plot(cs, test_accuracies, label='test')
plt.legend()
plt.show()

59. Recherche d'hyper paramètres

Apprenez le modèle de catégorisation tout en modifiant l'algorithme d'apprentissage et les paramètres d'apprentissage. Trouvez le paramètre d'algorithme d'apprentissage qui donne le taux de précision le plus élevé sur les données de vérification. Trouvez également le taux de réponse correct sur les données d'évaluation lorsque l'algorithme d'apprentissage et les paramètres sont utilisés.

La sélection de l'algorithme high-para doit être effectuée sur les données de vérification et non sur le réglage de l'ensemble de test. Mais cette fois, je n'ai pas fait grand chose et j'ai fini par utiliser sklearn.ensemble.GradientBoostingClassifier comme il convenait ... J'avais l'intention d'y mettre fin.

from sklearn.ensemble import GradientBoostingClassifier


clf = GradientBoostingClassifier(random_state=0, min_samples_split=0.01,
                                 min_samples_leaf=5, max_depth=10, 
                                 max_features='sqrt', n_estimators=500, 
                                 subsample=0.8)
clf.fit(X_train, y_train)
valid_acc = get_accuracy(clf, X_valid, y_valid) * 100
print('Validation Accuracy: %.3f' % valid_acc)
test_acc = get_accuracy(clf, X_test, y_test) * 100
print('Test Accuracy: %.3f' % test_acc)
Validation Accuracy: 88.997
Test Accuracy: 88.548

C'est un GBDT à la mode! Je l'ai essayé, mais c'était difficile car les performances changeaient considérablement avec un para élevé. Si j'avais le temps, je ferais sérieusement une recherche dans la grille ...

Quoi qu'il en soit, en ce qui concerne l'apprentissage automatique en Python, je pense que c'est un chapitre où vous pouvez apprendre scikit-learn.

Recommended Posts

[Chapitre 6] Introduction à scicit-learn avec 100 coups de traitement du langage
[Chapitre 5] Introduction à Python avec 100 coups de traitement du langage
[Chapitre 3] Introduction à Python avec 100 coups de traitement du langage
[Chapitre 2] Introduction à Python avec 100 coups de traitement du langage
[Chapitre 4] Introduction à Python avec 100 coups de traitement du langage
100 coups de traitement du langage ~ Chapitre 1
Le traitement de 100 langues frappe le chapitre 2 (10 ~ 19)
Traitement parallèle avec Parallel de scikit-learn
J'ai essayé de résoudre la version 2020 de 100 problèmes de traitement du langage [Chapitre 3: Expressions régulières 20 à 24]
J'ai essayé de résoudre la version 2020 de 100 coups de traitement de langue [Chapitre 1: Mouvement préparatoire 00-04]
J'ai essayé de résoudre la version 2020 de 100 traitements linguistiques [Chapitre 1: Mouvement préparatoire 05-09]
[Traitement du langage 100 coups 2020] Chapitre 3: Expressions régulières
100 traitements du langage naturel frappent le chapitre 4 Commentaire
[Traitement du langage 100 coups 2020] Chapitre 6: Machine learning
100 traitements de langage avec Python
100 coups de traitement du langage 2020: Chapitre 4 (analyse morphologique)
[Traitement du langage 100 coups 2020] Chapitre 5: Analyse des dépendances
100 traitements de langage avec Python (chapitre 3)
[Traitement du langage 100 coups 2020] Chapitre 1: Mouvement préparatoire
[Traitement du langage 100 coups 2020] Chapitre 7: Vecteur Word
100 Language Processing Knock 2020: Chapitre 3 (expression régulière)
[Traitement du langage 100 coups 2020] Chapitre 8: Réseau neuronal
[Traitement du langage 100 coups 2020] Chapitre 2: Commandes UNIX
[Traitement du langage 100 coups 2020] Chapitre 9: RNN, CNN
[Traitement du langage 100 coups 2020] Chapitre 4: Analyse morphologique
Traitement du langage 100 knocks-48: Extraction du chemin du nez à la racine
100 traitements linguistiques frappent 03 ~ 05
100 coups de traitement linguistique (2020): 40
100 coups de traitement linguistique (2020): 32
Résumé du chapitre 2 de l'introduction aux modèles de conception appris en langage Java
100 coups de traitement linguistique (2020): 35
100 coups de traitement linguistique (2020): 47
100 coups de traitement linguistique (2020): 39
Chapitre 4 Résumé de l'introduction aux modèles de conception appris en langage Java
100 coups de traitement linguistique (2020): 22
100 coups de traitement linguistique (2020): 42
Traitement du langage 100 coups Chapitre 4: Analyse morphologique 31. Verbes
100 coups de traitement linguistique (2020): 29
100 coups de traitement linguistique (2020): 49
100 traitements de langage avec Python (chapitre 2, partie 2)
100 coups de traitement linguistique (2020): 45
100 coups de traitement linguistique (2020): 10-19
100 coups de traitement linguistique (2020): 30
100 coups de traitement linguistique (2020): 00-09
100 traitements de langage avec Python (chapitre 2, partie 1)
100 coups de traitement linguistique (2020): 31
100 coups de traitement linguistique (2020): 48
100 coups de traitement linguistique (2020): 44
100 coups de traitement linguistique (2020): 41
100 coups de traitement linguistique (2020): 37
100 coups de traitement linguistique (2020): 25
100 coups de traitement linguistique (2020): 23
100 coups de traitement linguistique (2020): 33
100 coups de traitement linguistique (2020): 20
100 coups de traitement linguistique (2020): 27
100 coups de traitement linguistique (2020): 46
100 coups de traitement linguistique (2020): 21
100 coups de traitement linguistique (2020): 36
J'ai essayé de résoudre 100 traitements linguistiques Knock version 2020 [Chapitre 3: Expressions régulières 25-29]
Réhabilitation des compétences Python et PNL à partir de "100 Language Processing Knock 2015" (Chapitre 1)
Démarrer avec Python avec 100 coups sur le traitement du langage