چیتشیت
پردازش متن کلاسیک و TF-IDF
Classic Text Processing and TF-IDF
توکنسازی، ریشهیابی، لماتیزهسازی، شمارش، وزندهی با TF-IDF، طبقهبندی احساسات و موضوعیابی با LDA یا BERTopic.
فهرست مطالب
پایپلاین متن کلاسیک
گامبهگام- توکنسازیتقسیم رشته به توکنهای کلمه. علائم نگارشی را به عنوان توکنهای مجزا نگه دارید.
- ریشهیابی یا لماتیزهسازیریشهیابی برای سرعت. لماتیزهسازی با برچسب نقش دستوری زمانی که معنا مهم است.
- دامنه نفیافزودن پیشوند
NOT_به توکنهای پس از کلمه منفی تا رسیدن به علامت نگارشی. - شمارشکیسه کلمات (BoW). یک سطر به ازای هر سند، یک ستون به ازای هر کلمه واژگان.
- وزندهیTF-IDF اثر کلمات پرتکرار را کم میکند. سطرهای L2 کسینوس را به ضرب داخلی تبدیل میکنند.
- طبقهبندیبیز ساده برای خط مبنا، رگرسیون لجستیک برای محیط عملیاتی.
- ارزیابیدقت و بازخوانی به ازای هر کلاس، امتیاز Macro-F1، ماتریس درهمریختگی.
وظایف در قالب کد
کار و کد| وظیفه | کد |
|---|---|
| توکنسازی، ریشهیابی و لماتیزهسازی | preprocess(text, pos_tagger=demo_pos_tagger) |
| گام 1a الگوریتم Porter | stem_step_1a(word) |
| لماتایزر جدولی با طرح پشتیبان | lemmatize(word, pos) |
| ماتریس شمارش | bag_of_words(docs, build_vocab(docs)) |
| سطرهای TF-IDF روی کره واحد | l2_normalize(tfidf(bow)) |
| دامنه نفی | apply_negation(tokens) |
| خط مبنای بیز ساده | train_nb(docs_by_class, vocab, alpha=1.0) |
| الگوریتم LDA با نمونهبرداری گیبس ادغامشده | collapsed_gibbs_lda(docs, n_topics=3, n_iters=300, seed=42) |
NLTK: توکنها، ریشهها، لمها
کدpython
nltk.download("punkt_tab")
nltk.download("wordnet")
nltk.download("averaged_perceptron_tagger_eng")
tokens = word_tokenize(text) # مخففها، Unicode
stems = [PorterStemmer().stem(t) for t in tokens] # all five phases
tagged = pos_tag(tokens) # برچسبهای Penn Treebank
lemmatizer = WordNetLemmatizer()
lemmas = [lemmatizer.lemmatize(t, nltk_pos_to_wordnet(tag)) for t, tag in tagged] # V>v J>a R>r در غیر این صورت n
خط مبنای احساسات در scikit-learn
کدpython
pipe = Pipeline([
("tfidf", TfidfVectorizer(
ngram_range=(1, 2), # دوتاییها (bigrams)، تا not_good یک ویژگی باشد
min_df=2,
sublinear_tf=True, # تکرار کلمات را تعدیل میکند
stop_words=None)), # کلمات منفیساز را نگه میدارد
("clf", LogisticRegression(C=1.0, max_iter=1000)),
])
pipe.fit(X_train, y_train)
print(pipe.score(X_test, y_test)) # 75٪ تا 85٪ روی SST-2 با 3 فلگ
تنظیمات Vectorizer
دستورها| دستور | کارکرد |
|---|---|
CountVectorizer() | توکنسازی، واژگان و BoW در یک فراخوانی |
TfidfVectorizer() | افزودن وزندهی IDF و نرمالسازی L2 |
ngram_range=(1, 2) | شامل دوتاییها. معمولاً طبقهبندی را ارتقا میدهد |
min_df=2 | حذف کلمات در کمتر از 2 سند |
max_df=0.95 | حذف کلمات در بیش از 95٪ اسناد |
stop_words="english" | لیست ایستواژههای درونبرنامهای. مناسب تحلیل احساسات نیست |
sublinear_tf=True | استفاده از 1 + log(tf) به جای tf خام |
get_feature_names_out() | فهرست واژگان به ترتیب ستونها |
مدلهای موضوعی
کدpython
cv = CountVectorizer(max_features=max_features, stop_words="english",
min_df=2, max_df=0.9) # الگوریتم LDA به شمارش خام نیاز دارد
X = cv.fit_transform(documents)
lda = LatentDirichletAllocation(n_components=n_topics, random_state=42,
max_iter=50, learning_method="online")
doc_topic = lda.fit_transform(X) # (n_docs, n_topics)، مجموع هر سطر 1 است
topic_model = BERTopic(
embedding_model="sentence-transformers/all-MiniLM-L6-v2",
min_topic_size=15) # پیشفرض کتابخانه 10 است
topics, probs = topic_model.fit_transform(documents)
info = topic_model.get_topic_info() # موضوع 1- سطل دادههای پرت است
فرمولها
مفهومها- TF-IDF
- $\frac{\mathrm{count}(w \text{ in } d)}{|d|} \cdot \log\frac{N}{\mathrm{df}(w)}$
- هموارسازی IDF
- $\log\frac{n + 1}{d + 1} + 1$. کلمهای در همه اسناد IDF برابر 1 میگیرد.
- سطر L2
- تقسیم هر سطر بر نرم آن. اسناد طولانی اثر غالب پیدا نمیکنند.
- بیز ساده
- لگاریتم پیشین بهعلاوه مجموع لگاریتم $P(\text{word} \mid \text{class})$. مقدار ماکزیمم را بردارید.
- لاپلاس
- $(\mathrm{count} + \alpha) / (\mathrm{total} + \alpha |V|)$. بدون احتمال صفر.
- رگرسیون لجستیک
- سیگموئید $Xw + b$. پیشبینی 1 در 0.5 یا بیشتر.
- امتیاز Macro-F1
- میانگین F1 هر کلاس با وزن یکسان.
- انسجام c_v
- همبستگی NPMI جفت کلمات برتر، مقایسه با کسینوس. بالاتر بهتر است.
پیشفرضها
پیشفرضها| تنظیم | پیشفرض | نکته |
|---|---|---|
NB `alpha` | 1.0 | پیشفرض آموزشی. در عمل 0.01 رایج است |
LR `l2` | 0.01 | از اینجا شروع و تیون کنید. ویژگیهای تنک دچار بیشبرازش میشوند |
LR `epochs`, `lr` | 500 | نرخ یادگیری 0.05 |
LR `C` | 1.0 | با max_iter=1000 در scikit-learn |
BERTopic `min_topic_size` | 10 | استفاده از 50 یا 100 برای بیش از 10,000 سند |
Gibbs `alpha`, `beta` | 0.1 | بتا 0.01 است. هر دو باید مثبت باشند |
Gibbs `n_iters` | 200 | نسخه دمو 300 را اجرا میکند |
Topic count | max(5, round(sqrt(n_docs))) | محدود کردن به 200 برای زیر 40,000 سند |
عیبیابی
عیبیابیافت دقت پس از استقرار
- علت
- تفاوت پیشپردازش آموزش و استنتاج
- راهحل
- ارائه یک تابع پیشپردازش واحد در مدل
تغییر توکنها پس از ارتقا
- علت
- دریفت نسخه کتابخانه
- راهحل
- تثبیت نسخهها. فریز کردن 20 جمله نمونه
poniesبهponiریشهیابی میشود- علت
- فقط قانون
iesگام 1a اعمال شده - راهحل
- استفاده از Porter کامل با گام 1b
watchedبه صورتwatchedباقی میماند- علت
- جدول لماتایزر قانون
edندارد - راهحل
- استفاده از WordNet یا spaCy
"not good" مثبت خوانده میشود
- علت
- لیست ایستواژهها کلمات منفی را حذف میکند
- راهحل
stop_words=Noneبه همراه bigrams
امتیاز بالا، عملکرد ضعیف کلاس اقلیت
- علت
- Micro-F1 یا دقت روی دادههای نامتوازن
- راهحل
- گزارش امتیاز Macro-F1، معیار AUPRC بالای 95-5
موضوعات زائد LDA
- علت
- ایستواژهها و اصطلاحات مکرر
- راهحل
- تنظیم
min_dfوmax_df
اسناد زیاد در موضوع 1-
- علت
- سطل دادههای پرت HDBSCAN
- راهحل
- بررسی
min_topic_size، خواندن اسناد 1-
چه زمانی از چه روشی استفاده کنیم؟
پرسش و پاسخ- ریشهیابی یا لماتیزهسازی؟
- ریشهیابی برای نمایهسازی جستجو. لماتیزهسازی برای متنی که کاربر میخواند.
- NLTK یا spaCy؟
- NLTK برای آموزش و جابجایی اجزا. spaCy برای سرعت محیط عملیاتی.
- TF-IDF یا امبدینگها؟
- TF-IDF برای اسپم، لاگها، دادههای کم و مدلهای تفسیرپذیر.
- چه زمانی ترنسفورمر؟
- طعنه، جنبهها، تغییر لحن احساسات و زبانهای کممنبع.
- LDA یا BERTopic؟
- LDA برای اسناد طولانی با ترکیب موضوعات. BERTopic برای متون کوتاه.
- بدون GPU؟
- استفاده از LDA یا NMF.
نکات
نکتهها- تنک بمانید. TF-IDF چگال برای 100 هزار سند در حافظه جا نمیشود.
- قبل از اعتماد به یک سنجه، 5 پیشبینی غلط در هر کلاس را بخوانید.
- خط مبنا را روی پایپلاین خودتان بازتولید کنید، نه بر اساس عدد مقاله.