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])