¿Puedo usar CountVectorizer en scikit-learn to count frequency of documents that were not used to extract the tokens?


He estado trabajando con la clase CountVectorizer en scikit-learn.

Entiendo que si se usa de la manera que se muestra a continuación, la salida final consistirá en una matriz que contenga recuentos de entidades o tokens.

Estos tokens se extraen de un conjunto de palabras clave, es decir,

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

El siguiente paso es:

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

Donde llegamos

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

Esto está bien, pero mi situación es un poco diferente.

Quiero extraer las características de la misma manera que arriba, pero no quiero que las filas en data sean los mismos documentos de los que se extrajeron las características.

En otras palabras, ¿cómo puedo obtener recuentos de otro conjunto de documentos, digamos,

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

Y obtener:

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

He leído la documentación de la clase CountVectorizer, y me encontré con el argumento vocabulary, que es una asignación de términos a índices de características. Sin embargo, no puedo conseguir que este argumento me ayude.

Cualquier consejo es apreciado.
PS: todo el crédito debido a El Blog de Matthias Friedrich para el ejemplo que usé arriba.

Author: stensootla, 2014-04-07

3 answers

Tienes razón en que vocabulary es lo que quieres. Funciona así:

>>> 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)

Así que le pasa un dict con sus características deseadas como las claves.

Si usó CountVectorizer en un conjunto de documentos y luego desea usar el conjunto de características de esos documentos para un nuevo conjunto, use el atributo vocabulary_ de su CountVectorizer original y páselo al nuevo. Así que en su ejemplo, usted podría hacer

newVec = CountVectorizer(vocabulary=vec.vocabulary_)

Para crear un nuevo tokenizador usando el vocabulario del primero.

 43
Author: BrenBarn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-07 19:25:05

Debe llamar a fit_transform o simplemente fit en su fuente de vocabulario original para que el vectorizador aprenda un vocabulario.

Entonces puede usar este fit vectorizador en cualquier nueva fuente de datos a través del método transform().

Puede obtener el vocabulario producido por el ajuste (es decir, mapeo de palabra a ID de token) a través de vectorizer.vocabulary_ (suponiendo que nombre su CountVectorizer el nombre vectorizer.

 8
Author: Dhruv Ghulati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-05 14:15:10
>>> 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]])

Para verificar que CountVectorizer está utilizando el vocabulario aprendido de tags en new_docs: imprimir vect.vocabulary_ de nuevo o comparar la salida de new_docs.toarray() con la de tags.toarray()

 2
Author: user2476665,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-24 15:39:59