2017-02-06 18 views
1

Я работаю над корпусом ~ 100 тыс. Исследовательских работ. Я рассматриваю три поля:TfIdfVectorizer: Как векторный инструмент с фиксированным вокалом обрабатывает новые слова?

  1. открытого текста
  2. название
  3. аннотация

Я использовал TfIdfVectorizer, чтобы получить представление TfIdf в незашифрованном поле и кормить таким образом, возникла Vocab обратно в Векторизаторы названия и абстрактные, чтобы гарантировать, что все три представления работают над одним и тем же vocab. Моя идея заключалась в том, что, поскольку поле открытого текста намного больше, чем два других, это, скорее всего, словар будет охватывать все слова в других полях. Но как бы TfIdfVectorizer имел дело с новыми словами/токенами, если это не так?

Вот пример моего кода:

vectorizer = TfidfVectorizer(min_df=2) 
plaintexts_tfidf = vectorizer.fit_transform(plaintexts) 
vocab = vectorizer.vocabulary_ 
# later in an another script after loading the vocab from disk 
vectorizer = TfidfVectorizer(min_df=2, vocabulary=vocab) 
titles_tfidf = vectorizer.fit_transform(titles) 

Vocab имеет ~ 900K слов.

Во время векторизации я не столкнулся каких-либо проблем, но позже, когда я хотел, чтобы сравнить сходство векторизованных названий с использованием sklearn.metrics.pairwise.cosine_similarity я столкнулся с этой ошибкой:

>> titles_sim = cosine_similarity(titles_tfidf) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-237-5aa86fe892da> in <module>() 
----> 1 titles_sim = cosine_similarity(titles) 

/usr/local/lib/python3.5/dist-packages/sklearn/metrics/pairwise.py in cosine_similarity(X, Y, dense_output) 
    916   Y_normalized = normalize(Y, copy=True) 
    917 
--> 918  K = safe_sparse_dot(X_normalized, Y_normalized.T, dense_output=dense_output) 
    919 
    920  return K 

/usr/local/lib/python3.5/dist-packages/sklearn/utils/extmath.py in safe_sparse_dot(a, b, dense_output) 
    184   ret = a * b 
    185   if dense_output and hasattr(ret, "toarray"): 
--> 186    ret = ret.toarray() 
    187   return ret 
    188  else: 

/usr/local/lib/python3.5/dist-packages/scipy/sparse/compressed.py in toarray(self, order, out) 
    918  def toarray(self, order=None, out=None): 
    919   """See the docstring for `spmatrix.toarray`.""" 
--> 920   return self.tocoo(copy=False).toarray(order=order, out=out) 
    921 
    922  ############################################################## 

/usr/local/lib/python3.5/dist-packages/scipy/sparse/coo.py in toarray(self, order, out) 
    256   M,N = self.shape 
    257   coo_todense(M, N, self.nnz, self.row, self.col, self.data, 
--> 258      B.ravel('A'), fortran) 
    259   return B 
    260 

ValueError: could not convert integer scalar 

Я Я не уверен, что это связано, но я не могу понять, что здесь происходит. Также потому, что я не сталкиваюсь с ошибкой при вычислении сходств на векторах открытого текста.

Я что-то пропустил? Есть ли лучший способ использовать Vectorizer?

Edit:

Формы разреженных csr_matrices равны.

>> titles_tfidf.shape 
(96582, 852885) 
>> plaintexts_tfidf.shape 
(96582, 852885) 
+0

Это была моя первая мысль, как хорошо, но размеры разреженных csr_matrices равны: plaintexts_tfidf.shape (96582, 852885) titles_tfidf (96582, 852885) – nadre

ответ

1

Я боюсь, что матрица может быть слишком большой. Это будет 96582 * 96582 = 9328082724 клеток. Попытайтесь немного нарезать titles_tfidf и проверить.

Источник: http://scipy-user.10969.n7.nabble.com/SciPy-User-strange-error-when-creating-csr-matrix-td20129.html

EDT: Если вы используете старую версию SciPy/Numpy вы можете обновить: https://github.com/scipy/scipy/pull/4678

EDT2: Кроме того, если вы используете 32-битную питон, переход на 64-битный может помочь (Я полагаю)

EDT3: Отвечая на ваш первоначальный вопрос. Когда вы используете словарь от plaintexts и появятся новые слова в titles, они будут игнорироваться, но не влияют на значение tfidf. Надеюсь, что этот фрагмент может сделать его более понятным:

from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.metrics.pairwise import cosine_similarity 

plaintexts =["They are", "plain texts texts amoersand here"] 
titles = ["And here", "titles ", "wolf dog eagle", "But here plain"] 

vectorizer = TfidfVectorizer() 
plaintexts_tfidf = vectorizer.fit_transform(plaintexts) 
vocab = vectorizer.vocabulary_ 
vectorizer = TfidfVectorizer(vocabulary=vocab) 
titles_tfidf = vectorizer.fit_transform(titles) 
print('values using vocabulary') 
print(titles_tfidf) 
print(vectorizer.get_feature_names()) 
print('Brand new vectorizer') 
vectorizer = TfidfVectorizer() 
titles_tfidf = vectorizer.fit_transform(titles) 
print(titles_tfidf) 
print(vectorizer.get_feature_names()) 

Результат:

values using vocabulary 
    (0, 2)  1.0 
    (3, 3)  0.78528827571 
    (3, 2)  0.61913029649 
['amoersand', 'are', 'here', 'plain', 'texts', 'they'] 
Brand new vectorizer 
    (0, 0)  0.78528827571 
    (0, 4)  0.61913029649 
    (1, 6)  1.0 
    (2, 7)  0.57735026919 
    (2, 2)  0.57735026919 
    (2, 3)  0.57735026919 
    (3, 4)  0.486934264074 
    (3, 1)  0.617614370976 
    (3, 5)  0.617614370976 
['and', 'but', 'dog', 'eagle', 'here', 'plain', 'titles', 'wolf'] 

Обратите внимание, что это не то же самое, как я бы удалить слова, которые не встречаются в открытых текстов из названий.

+0

Спасибо! Преобразование разреженной к плотной матрице, похоже, также является обходным решением. К счастью, у меня много памяти. Есть ли у вас какое-либо представление о моем первом вопросе, как векторизатор имеет дело с неизвестными словами в первом случае? – nadre

+0

@ nadre Я обновил ответ, надеюсь, что это поможет. – Xevaquor

+0

Помогает, спасибо. – nadre