2016-01-17 1 views
5

Я довольно новичок в sckit-learn и смущен, потому что TfidVectorizer иногда возвращает другой вектор для того же документа.scikit TfidfVectorizer.transform() возвращает переменные результаты для того же документа

В моем корпусе содержится> 100 документов.

Я бегу:

vectorizer = TfidfVectorizer(ngram_range=(1, 2), token_pattern=r'\b\w+\b', min_df=1) 

X = vectorizer.fit_transform(corpus) 

инициализировать TfidVectorizer и приспосабливать его к документам в корпусе. corpus - это список текстовых строк.

Затем, если я:

test = list(vectorizer.transform([corpus[0]]).toarray()[0]) 

test == list(X.toarray()[0]) 

В результате False.

Если я напечатаю первые 20 предметов list(X.toarray()[0]) и test, соответственно, вы можете видеть, что они отключены на долю, когда я ожидаю, что они будут одинаковыми.

[0.16971458376720741, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] 

против

[0.16971458376720716, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] 

Но если я:

test_1 = list(vectorizer.transform([corpus[0]).toarray()[0]) 
test_2 = list(vectorizer.transform([corpus[0]).toarray()[0]) 
test_1 == test_2 

В результате True. Выше, я по сути делаю вычисление вектора дважды, что, как я думал, я делал в первом примере (поскольку X содержит векторы, возвращаемые во время fit_transform).

Почему в моем первом примере векторы разные? Я здесь что-то не так?

+2

Не совсем уверен, что происходит, может быть, какая-то ошибка округления, я думаю, что это, вероятно, не стоит беспокоиться. – maxymoo

+0

Хм нормально. Да, я просто беспокоил меня. Спасибо за ответ. – deef

ответ

0

Как упоминалось в комментарии, это, скорее всего, ошибка округления, и это, вероятно, не стоит беспокоиться о.

Однако я думаю, что стоит попытаться понять явление.

Что, вероятно, происходит, это ошибка округления. Иногда эти ошибки случаются, потому что числа на вашем компьютере не имеют бесконечной точности: типичный numpy float будет храниться на 64 бит.

Тот факт, что они имеют конечную точность, означает, что дополнение больше не ассоциативно: a + (b + c) не всегда точно (a + b) + c.

Попытаемся показать это поведение в действии:

import numpy as np 

a = np.random.random(size=1000000) 
print(a.dtype) 
print("%.15f" % a.sum()) 
b = np.random.permutation(a) 
print("%.15f" % b.sum()) 

Выход:

float64 
500399.674621732032392 
500399.674621731741354 

Теперь, если мы расширим выше сценарий, чтобы попытаться с поплавками на 32 бита:

a = a.astype(np.float32) 
print(a.dtype) 
print("%.15f" % a.sum()) 
b = np.random.permutation(a) 
print("%.15f" % b.sum()) 

Мы получаем:

float64 
500214.871674167399760 
500214.871674167283345 
float32 
500214.937500000000000 
500215.000000000000000 

Вы можете видеть, что ошибка намного выше: это потому, что поплавки на 32 бита менее точны, чем поплавки на 64 бита.

Теперь, если вы думаете, что это удивительное, и вы хотите знать больше, NumPy дает подробную информацию о хранении поплавков через функцию np.finfo:

In [10]: np.finfo(np.float32) 
Out[10]: finfo(resolution=1e-06, min=-3.4028235e+38, max=3.4028235e+38, dtype=float32) 

Жаль, что я не ответил на ваш вопрос;). Может быть, причина ошибки в вашем случае не совсем то, что я объяснил, я пишу это, потому что, думаю, если бы вы были знакомы с этими тезисами, вы бы не задали этот вопрос в первую очередь.

Надеюсь, это поможет в любом случае!

+0

Спасибо за это. Поскольку это, вероятно, полезно для других, сталкивающихся с этим вопросом, поэтому я принимаю это как ответ. – deef

Смежные вопросы