Як обробляти текстові дані за допомогою TF-IDF в Python

Комп’ютери добре працюють з цифрами, але не настільки з текстовими даними. Одним з найбільш широко використовуваних методів обробки текстових даних є TF-IDF. У цій статті ми дізнаємося, як це працює та які його особливості.

З нашої інтуїції ми думаємо, що слова, які з’являються частіше, повинні мати більшу вагу при аналізі текстових даних, але це не завжди так. Такі слова, як „the”, „will” та „you” - так звані стоп-слова - з’являються найбільше в корпусі тексту, але мають дуже незначне значення. Натомість рідкісні слова, які насправді допомагають розрізнити дані та мають більшу вагу.

Вступ до TF-IDF

TF-IDF розшифровується як "Термінова частота - зворотна частота даних". Спочатку ми дізнаємось, що математично означає цей термін.

Термін частоти (tf) : дає нам частоту слів у кожному документі корпусу. Це відношення кількості випадків появи слова в документі порівняно із загальною кількістю слів у цьому документі. Він збільшується із збільшенням кількості зустрічань цього слова в документі. Кожен документ має свій власний tf.

Частота зворотних даних (idf): використовується для обчислення ваги рідкісних слів у всіх документах корпусу. Слова, які рідко трапляються в корпусі, мають високий бал IDF. Це дається рівнянням нижче.

Поєднуючи ці два, ми отримуємо оцінку TF-IDF (w) для слова в документі в корпусі. Це продукт tf та idf:

Візьмемо приклад, щоб отримати більш чітке розуміння.

Речення 1: Автомобіль їде по дорозі.

Речення 2: Вантажівка їде по шосе.

У цьому прикладі кожне речення є окремим документом.

Тепер ми розрахуємо TF-IDF для вищезазначених двох документів, які представляють наш корпус.

З наведеної таблиці ми бачимо, що TF-IDF загальних слів дорівнював нулю, що свідчить про те, що вони не є значущими. З іншого боку, TF-IDF для "автомобіля", "вантажівки", "дороги" та "шосе" є ненульовим. Ці слова мають більше значення.

Використання Python для обчислення TF-IDF

Давайте тепер кодуємо TF-IDF у Python з нуля. Після цього ми побачимо, як ми можемо використовувати sklearn для автоматизації процесу.

Функція computeTFобчислює оцінку TF для кожного слова в корпусі за документом.

Функція computeIDFобчислює оцінку IDF кожного слова в корпусі.

Функція computeTFIDFнижче обчислює оцінку TF-IDF для кожного слова, помножуючи оцінки TF і IDF.

Вихідні дані, наведені вищевказаним кодом для набору документів D1 і D2, є такими ж, як і те, що ми вручну обчислили вище в таблиці.

Повне посилання можна отримати за цим посиланням.

sklearn

Тепер ми побачимо, як ми можемо реалізувати це за допомогою sklearn у Python.

Спочатку ми імпортуємо TfidfVectorizerз sklearn.feature_extraction.text:

Тепер ми ініціалізуємо, vectorizerа потім викличемо fit та перетворимо на нього, щоб обчислити оцінку TF-IDF для тексту.

Під капотом sklearn fit_transform виконує наступні функції fit та transformфункції. Їх можна знайти в офіційній бібліотеці sklearn на GitHub.

 def fit(self, X, y=None): """Learn the idf vector (global term weights) Parameters ---------- X : sparse matrix, [n_samples, n_features] a matrix of term/token counts """ if not sp.issparse(X): X = sp.csc_matrix(X) if self.use_idf: n_samples, n_features = X.shape df = _document_frequency(X) # perform idf smoothing if required df += int(self.smooth_idf) n_samples += int(self.smooth_idf) # log+1 instead of log makes sure terms with zero idf don't get # suppressed entirely. idf = np.log(float(n_samples) / df) + 1.0 self._idf_diag = sp.spdiags(idf, diags=0, m=n_features, n=n_features, format="csr") return self def transform(self, X, copy=True): """Transform a count matrix to a tf or tf-idf representation Parameters ---------- X : sparse matrix, [n_samples, n_features] a matrix of term/token counts copy : boolean, default True Whether to copy X and operate on the copy or perform in-place operations. Returns ------- vectors : sparse matrix, [n_samples, n_features] """ if hasattr(X, 'dtype') and np.issubdtype(X.dtype, np.floating): # preserve float family dtype X = sp.csr_matrix(X, copy=copy) else: # convert counts or binary occurrences to floats X = sp.csr_matrix(X, dtype=np.float64, copy=copy) n_samples, n_features = X.shape if self.sublinear_tf: np.log(X.data, X.data) X.data += 1 if self.use_idf: check_is_fitted(self, '_idf_diag', 'idf vector is not fitted') expected_n_features = self._idf_diag.shape[0] if n_features != expected_n_features: raise ValueError("Input has n_features=%d while the model" " has been trained with n_features=%d" % ( n_features, expected_n_features)) # *= doesn't work X = X * self._idf_diag if self.norm: X = normalize(X, norm=self.norm, copy=False) return X

Одне, на що слід звернути увагу у наведеному вище коді, це те, що замість просто журналу n_samples до n_samples додано 1 для обчислення балу IDF. Це гарантує, що слова з нульовим балом IDF не будуть повністю придушені.

Отриманий результат має форму косої матриці, яка нормується, щоб отримати наступний результат.

Таким чином ми побачили, як ми можемо легко кодувати TF-IDF всього за 4 рядки за допомогою sklearn. Тепер ми розуміємо, наскільки потужним є TF-IDF як інструмент для обробки текстових даних з корпусу. Щоб дізнатись більше про sklearn TF-IDF, ви можете скористатися цим посиланням.

Щасливого кодування!

Дякуємо, що прочитали цю статтю. Обов’язково поділіться нею, якщо вважаєте це корисним.

Щоб дізнатися більше про програмування, ви можете піти за мною, щоб отримувати сповіщення щоразу, коли я вигадую нову публікацію.

На здоров’я!

Крім того, давайте підключатись у Twitter , Linkedin , Github та Facebook .