Это определенно первое: каждое слово idf
(обратная частота документов) рассчитывается только на основе учебных документов. Это имеет смысл, поскольку именно эти значения рассчитываются при вызове fit
в векторизаторе. Если бы второй вариант, который вы описали, был верным, мы бы каждый раз по существу заменяли векторизатор, и мы также вызывали бы information leak
, поскольку idf из набора тестов использовались бы во время оценки модели.
Помимо этих чисто концептуальных объяснений, вы также можете запустить следующий код, чтобы убедить себя:
from sklearn.feature_extraction.text import TfidfVectorizer
vect = TfidfVectorizer()
x_train = ["We love apples", "We really love bananas"]
vect.fit(x_train)
print(vect.get_feature_names())
>>> ['apples', 'bananas', 'love', 'really', 'we']
x_test = ["We really love pears"]
vectorized = vect.transform(x_test)
print(vectorized.toarray())
>>> array([[0. , 0. , 0.50154891, 0.70490949, 0.50154891]])
Следуя рассуждениям о том, как работает методика подбора, вы можете самостоятельно пересчитать эти значения tfidf:
«яблоки» и «бананы», очевидно, имеют значение tfidf, равное 0, потому что они не появляются в x_test
. «груши», с другой стороны, не существуют в x_train
и поэтому даже не появятся при векторизации. Следовательно, только «любовь», «действительно» и «мы» будут иметь значение tfidf.
Scikit-learn реализует tfidf как log ((1 + n) / (1 + df) + 1) * f, где n - количество документов в обучающем наборе (2 для нас), df количество документов в какое слово появляется только в обучающем наборе , а f - счетчик частоты слова в тестовом наборе. Следовательно:
tfidf_love = (np.log((1+2)/(1+2))+1)*1
tfidf_really = (np.log((1+2)/(1+1))+1)*1
tfidf_we = (np.log((1+2)/(1+2))+1)*1
Затем вам нужно масштабировать эти значения tfidf на расстояние L2 вашего документа:
tfidf_non_scaled = np.array([tfidf_love,tfidf_really,tfidf_we])
tfidf_list = tfidf_non_scaled/sum(tfidf_non_scaled**2)**0.5
print(tfidf_list)
>>> [0.50154891 0.70490949 0.50154891]
Вы можете видеть, что на самом деле мы получаем одинаковые значения, что подтверждает то, как scikit-learn
реализовал эту методологию.