ml nlp - ghdrako/doc_snipets GitHub Wiki

"Worek słów"

Model "worek słów" (ang. Bag of Words - BoW) jest jedna z podstawowych, najprostszych i najpopularniejszych technik inżynierii cech, umożliwiając przekształcenie tekstu w wektor numeryczny. Działa dwuetapowo: najpierw pobiera słowa z wokabularza, a następnie zlicza ich obecność lub częstość występowania w tekście. Nie są brane pod uwagę struktura dokumentu ani informacje kontekstowe.

Metoda TD-IDF

Skrót TD-IDF rozwija się jako Term Frequency - Inverse Document Frequency. Technika ta zawiera dwie składowe, TF czyli warzenie częstością termów oraz IDF czyli obliczanie odwrotnej częstości słów w dokumencie. Składowa TF określa jedynie występowanie słów w danym dokumencie. Jest ona równoważna "workowi słów". Nie uwzględnia kontekstu słow i jest obciążona błędem systematycznym w kierunku dłuższych dokumentów. Z kolei ze składowa IDF oblicza wartość określajace ilosc informacji przechowywane przez poszczególne słowo:

Metoda TD-IDF stanowi iloczyn skalarny obydwu członów TD i IDF. Normalizuje omna wagi dokumentów. Wyższa wartość TD-IDF danego słowa oznacza wieksza częstośc wystepowania tego słowa w dokumencie.

BM25

BM25 (dokładniej Okapi BM25) jest to udoskonalona wersja starszej metody TF-IDF i opiera się na trzech głównych mechanizmach:

  • Częstotliwość słowa (Term Frequency - TF): Im częściej szukane słowo pojawia się w dokumencie, tym wyższa jego ocena. BM25 wprowadza tu jednak tzw. "krzywą nasycenia". Oznacza to, że skok z 1 do 3 wystąpień słowa drastycznie podnosi trafność, ale różnica między 100 a 105 wystąpieniami jest już traktowana jako nieistotna.
  • Rzadkość słowa (Inverse Document Frequency - IDF): Algorytm analizuje, jak popularne jest dane słowo we wszystkich dokumentach w bazie. Pospolite słowa (np. "oraz", "aplikacja", "dane") dostają bardzo niską wagę punktową. Słowa rzadkie i wysoce specyficzne (np. "defibrylator", "XDEEP") punktują najwyżej.
  • Kompensacja długości dokumentu (Document Length Normalization): BM25 "karze" długie ściany tekstu, aby nie wygrywały z krótkimi statystycznie. Jeśli szukane słowo występuje 3 razy w krótkim, 5-zdaniowym akapicie oraz 3 razy w 500-stronicowej książce, algorytm uzna, że krótki akapit jest znacznie bardziej skupiony na szukanym temacie i umieści go wyżej w wynikach.

BM25 to algorytm rankingowy używany w wyszukiwarkach tekstowych (takich jak Elasticsearch, Apache Lucene czy Solr).

Text Cleaning and Feature Extraction

# Converting Text to Lowercase
text = "This Product Is Amazing"
print(text.lower())

# Removing Punctuation
import re
text = "Amazing product!!! Highly recommended."
clean_text = re.sub(
    r"[^\w\s]",
    "",
    text
)
print(clean_text)

# Removing Numbers
text = "The battery lasted 12 hours."
clean_text = re.sub(
r"\d+",
    "",
    text
)
print(clean_text)

# Removing Extra Spaces
text = "This     product      works"
clean_text = re.sub(
    r"\s+",
    " ",
    text
).strip()
print(clean_text)


# Removing Stop Words
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
words = [
"this",
    "product",
    "is",
    "excellent"
]
filtered = [
    word
    for word in words
    if word not in ENGLISH_STOP_WORDS
]
print(filtered)

Tokenizing Text

text = "Machine learning improves customer analytics."
tokens = text.split()
print(tokens)

Bag-of-Words Representation

from sklearn.feature_extraction.text import CountVectorizer
documents = [
    "good product",
    "excellent product",
    "bad quality"
]
vectorizer = CountVectorizer()
features = vectorizer.fit_transform(
    documents
)
print(
    vectorizer.get_feature_names_out()
)
print(features.toarray())

TF-IDF Representation

from sklearn.feature_extraction.text import TfidfVectorizer
documents = [
    "good product",
    "excellent product",
    "bad quality"
]
vectorizer = TfidfVectorizer()
features = vectorizer.fit_transform(
    documents
)
print(
    vectorizer.get_feature_names_out()
)
print(features.toarray())

Pipline

from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import TfidfVectorizer
pipeline = Pipeline([
    (
        "tfidf",
        TfidfVectorizer(
            stop_words="english",
            max_features=5000
        )
    ),
    (
        "classifier",
        LogisticRegression(
            max_iter=1000
        )
    )
])
pipeline.fit(
    X_train,
    y_train
)
predictions = pipeline.predict(
    X_test
)
print(predictions[:10])