web-dev-qa-db-fra.com

Puis-je utiliser CountVectorizer dans scikit-learn pour compter la fréquence des documents non utilisés pour extraire les jetons?

J'ai travaillé avec la classe CountVectorizer dans scikit-learn.

Je comprends que si utilisé de la manière indiquée ci-dessous, la sortie finale consistera en un tableau contenant le nombre d'entités, ou jetons.

Ces jetons sont extraits d’un ensemble de mots-clés, c.-à-d.

tags = [
  "python, tools",
  "linux, tools, ubuntu",
  "distributed systems, linux, networking, tools",
]

La prochaine étape est:

from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(tokenizer=tokenize)
data = vec.fit_transform(tags).toarray()
print data

Où nous obtenons

[[0 0 0 1 1 0]
 [0 1 0 0 1 1]
 [1 1 1 0 1 0]]

C'est bien, mais ma situation est un peu différente.

Je souhaite extraire les fonctionnalités de la même manière que ci-dessus, mais je ne souhaite pas que les lignes de data soient les mêmes documents à partir desquels les fonctionnalités ont été extraites.

En d'autres termes, comment puis-je obtenir le décompte d'un autre ensemble de documents, par exemple,

list_of_new_documents = [
  ["python, chicken"],
  ["linux, cow, ubuntu"],
  ["machine learning, bird, fish, pig"]
]

Et obtenir:

[[0 0 0 1 0 0]
 [0 1 0 0 0 1]
 [0 0 0 0 0 0]]

J'ai lu la documentation de la classe CountVectorizer et suis tombé sur l'argument vocabulary, qui est un mappage de termes en indices de caractéristiques. Je n'arrive pas à obtenir cet argument pour m'aider, cependant.

Tout conseil est apprécié.
PS: tout crédit dû à Blog de Matthias Friedrich pour l'exemple que j'ai utilisé ci-dessus.

39
Matt O'Brien

Vous avez raison, vocabulary est ce que vous voulez. Cela fonctionne comme ceci:

>>> cv = sklearn.feature_extraction.text.CountVectorizer(vocabulary=['hot', 'cold', 'old'])
>>> cv.fit_transform(['pease porridge hot', 'pease porridge cold', 'pease porridge in the pot', 'nine days old']).toarray()
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 0],
       [0, 0, 1]], dtype=int64)

Donc, vous passez un dict avec vos fonctionnalités souhaitées comme les clés.

Si vous avez utilisé CountVectorizer sur un ensemble de documents et que vous souhaitez ensuite utiliser l'ensemble des fonctionnalités de ces documents pour un nouvel ensemble, utilisez la commande vocabulary_ attribut de votre CountVectorizer d’origine et transmettez-le au nouveau. Donc, dans votre exemple, vous pourriez faire

newVec = CountVectorizer(vocabulary=vec.vocabulary_)

créer un nouveau tokenizer en utilisant le vocabulaire de votre premier.

50
BrenBarn

Vous devez appeler fit_transform Ou simplement fit sur votre source de vocabulaire d'origine pour que le vectoriseur apprenne un vocabulaire.

Ensuite, vous pouvez utiliser ce vectoriseur fit sur n'importe quelle nouvelle source de données via la méthode transform().

Vous pouvez obtenir le vocabulaire produit par l'ajustement (c'est-à-dire le mappage de Word à l'identificateur de jeton) via vectorizer.vocabulary_ (En supposant que vous nommez votre CountVectorizer le nom vectorizer.

8
Dhruv Ghulati
>>> tags = [
  "python, tools",
  "linux, tools, ubuntu",
  "distributed systems, linux, networking, tools",
]

>>> list_of_new_documents = [
  ["python, chicken"],
  ["linux, cow, ubuntu"],
  ["machine learning, bird, fish, pig"]

]

>>> from sklearn.feature_extraction.text import CountVectorizer
>>> vect = CountVectorizer()
>>> tags = vect.fit_transform(tags)

# vocabulary learned by CountVectorizer (vect)
>>> print(vect.vocabulary_)
{'python': 3, 'tools': 5, 'linux': 1, 'ubuntu': 6, 'distributed': 0, 'systems': 4, 'networking': 2}

# counts for tags
>>> tags.toarray()
array([[0, 0, 0, 1, 0, 1, 0],
       [0, 1, 0, 0, 0, 1, 1],
       [1, 1, 1, 0, 1, 1, 0]], dtype=int64)

# to use `transform`, `list_of_new_documents` should be a list of strings 
# `itertools.chain` flattens shallow lists more efficiently than list comprehensions

>>> from itertools import chain
>>> new_docs = list(chain.from_iterable(list_of_new_documents)
>>> new_docs = vect.transform(new_docs)

# finally, counts for new_docs!
>>> new_docs.toarray()
array([[0, 0, 0, 1, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0, 0, 0]])

Pour vérifier que CountVectorizer utilise le vocabulaire appris de tags sur new_docs: Print vect.vocabulary_ À nouveau ou comparez la sortie de new_docs.toarray() à celle de tags.toarray()

2
user2476665