Il y a un exemple dans nltk.org livre (chapitre 6) où ils utilisent un algorithme NaiveBayesian pour classer un symbole de ponctuation comme finissant une phrase ou ne la finissant pas...
C'est ce qu'ils font : Tout d'abord, ils prennent un corpus et utilisent la méthode .sent pour obtenir les phrases et construire à partir de celles-ci un index de l'endroit où se trouvent les symboles de ponctuation qui les séparent (les boundaries
) sont.
Ensuite, ils "tokenisent" le texte (le convertissent en liste de mots et de symboles de ponctuation) et appliquent l'algorithme/fonction suivant à chaque token afin d'obtenir une liste de caractéristiques qui sont retournés dans un dictionnaire :
def punct_features(tokens, i):
return {'nextWordCapitalized': tokens[i+1][0].isupper(),
'prevWord': tokens[i-1].lower(),
'punct': tokens[i],
'prevWordis1Char': len(tokens[i-1]) == 1}
Ces caractéristiques seront utilisées par l'algorithme ML pour classer le symbole de ponctuation comme terminant ou non une phrase (c'est-à-dire comme un token de frontière).
Avec ce fn et l'index 'boundaries', ils sélectionnent tous les tokens de ponctuation, chacun avec ses caractéristiques, et les étiquettent en tant que True
la frontière, ou False
un, créant ainsi une liste de ensembles de caractéristiques étiquetées :
featuresets1 = [(punct_features(tokens, i), (i in boundaries)) for i in range(1, len(tokens)-1)
if tokens[i] in '.?!;']
print(featuresets1[:4])
C'est un exemple de la surcharge que nous pourrions avoir en imprimant les quatre premières séries :
[({'nextWordCapitalized': False, 'prevWord': 'nov', 'punct': '.', 'prevWordis1Char': False}, False),
({'nextWordCapitalized': True, 'prevWord': '29', 'punct': '.', 'prevWordis1Char': False}, True),
({'nextWordCapitalized': True, 'prevWord': 'mr', 'punct': '.', 'prevWordis1Char': False}, False),
({'nextWordCapitalized': True, 'prevWord': 'n', 'punct': '.', 'prevWordis1Char': True}, False)]
Avec cela, ils entraînent et évaluent le classificateur de ponctuation :
size = int(len(featuresets) * 0.1)
train_set, test_set = featuresets[size:], featuresets[:size]
classifier = nltk.NaiveBayesClassifier.train(train_set)
nltk.classify.accuracy(classifier, test_set)
Maintenant, (1) comment et que pourrait améliorer un tel algorithme ML ? Je n'arrive pas à comprendre comment il pourrait améliorer le premier algorithme simple qui vérifie simplement si le jeton suivant du symbole de ponctuation est en majuscule et le précédent en minuscule. En effet, cet algorithme est pris pour valider qu'un symbole est une limite... ! Et s'il ne l'améliore pas, à quoi pourrait-il bien servir ?
Et en relation avec cela : (2) est-ce que l'un de ces deux algorithmes est la façon dont nlpk sépare réellement les phrases ? Je veux dire, surtout si le meilleur est le premier algorithme simple, est-ce que nltk comprend que les phrases sont juste un texte entre deux symboles de ponctuation qui sont suivis par un mot avec le premier graphique en majuscule et le mot précédent en minuscule ? Est-ce ce que fait la méthode .sent ? Remarquez que c'est loin de la façon dont la linguistique, ou mieux, le dictionnaire Oxford, définit une phrase :
"Un ensemble de mots qui est complet en lui-même, contenant typiquement un sujet et un prédicat, véhiculant une déclaration, une question, une exclamation ou un ordre, d'exclamation ou de commandement, et composé d'une clause principale et parfois d'une ou plusieurs clauses subordonnées".
Ou (3) les textes bruts du corpus comme treebank
ou brown
déjà divisé par des phrases manuellement ? - dans ce cas, quel est le critère pour les sélectionner ?