دسته‌بندی با استفاده از embeddings

دسته‌بندی با استفاده از embeddings

embeddings, classification
preview

دسته‌بندی با استفاده از embeddings #

راه‌های زیادی برای دسته‌بندی متن وجود دارد. این نوت‌بوک مثالی از دسته‌بندی متن با استفاده از embeddings را نمایش می‌دهد.

در این نوت‌بوک امتیاز بررسی غذایی (از ۱ تا ۵) بر اساس embedding متن بررسی و پیش‌بینی می‌شود. ما دیتاست را به مجموعه‌های آموزشی و آزمایشی تقسیم می‌کنیم تا بتوانیم عملکرد مدل را بر روی داده‌های دیده نشده به طور واقعی ارزیابی کنیم.

جمع آوری داده ها #

مجموعه داده‌ای که در این مثال استفاده شده است، نظرات کاربران در مورد غذاهای مختلف در آمازون می‌باشد. این مجموعه داده شامل 568,454 نظر در مورد غذاهای مختلف است که تا اکتبر 2012 توسط کاربران آمازون ثبت شده‌اند. ما از یک زیرمجموعه از این داده‌ها که شامل 1,000 نظر جدیدتر می‌باشد برای مقاصد آموزشی استفاده خواهیم کرد. این نظرات به زبان انگلیسی نوشته شده‌اند و به طور کلی یا مثبت هستند یا منفی. هر نظر شامل ProductId، UserId، امتیاز (Score)، عنوان نظر (Summary) و متن نظر (Text) می‌باشد.

ما عنوان نظر و متن نظر را به یک متن ترکیبی واحد تبدیل خواهیم کرد. مدل این متن ترکیبی را encode کرده و یک وکتور تکی تولید خواهد کرد.

برای اجرای این نوت‌بوک، نیاز به نصب پکیج‌های زیر دارید: pandas، openai، transformers، plotly، matplotlib، scikit-learn، torch (وابسته به transformerstorchvision، و scipy.

 1import pandas as pd
 2import tiktoken
 3
 4# load & inspect dataset
 5input_datapath = "data/fine_food_reviews_1k.csv"  # to save space, we provide a pre-filtered dataset
 6df = pd.read_csv(input_datapath, index_col=0)
 7df = df[["Time", "ProductId", "UserId", "Score", "Summary", "Text"]]
 8df = df.dropna()
 9df["combined"] = (
10    "Title: " + df.Summary.str.strip() + "; Content: " + df.Text.str.strip()
11)
12df.head(2)

نمایش:

TimeProductIdUserIdScoreSummaryTextcombined
01351123200B003XPF9BOA3R7JR3FMEBXQB5where does one start...and stop... with a tre...Wanted to save some to bring to my Chicago fam...Title: where does one start...and stop... wit...
11351123200B003JK537SA3JBPC3WFUT5ZP1Arrived in piecesNot pleased at all. When I opened the box, mos...Title: Arrived in pieces; Content: Not pleased...
 1
 2embedding_model = "text-embedding-3-small"
 3max_tokens = 8000  # the maximum for text-embedding-3-small is 8191
 4embedding_encoding = "cl100k_base"
 5
 6# subsample to 1k most recent reviews and remove samples that are too long
 7top_n = 1000
 8df = df.sort_values("Time").tail(top_n * 2)  # first cut to first 2k entries, assuming less than half will be filtered out
 9df.drop("Time", axis=1, inplace=True)
10
11encoding = tiktoken.get_encoding(embedding_encoding)
12
13# omit reviews that are too long to embed
14df["n_tokens"] = df.combined.apply(lambda x: len(encoding.encode(x)))
15df = df[df.n_tokens <= max_tokens].tail(top_n)

حال از Gilas API برای تولید امبدینگ ها استفاده می‌کنیم.

برای اجرای کدهای زیر ابتدا باید یک کلید API را از طریق پنل کاربری گیلاس تولید کنید. برای این کار ابتدا یک حساب کاربری جدید بسازید یا اگر صاحب حساب کاربری هستید وارد پنل کاربری خود شوید. سپس، به صفحه کلید API بروید و با کلیک روی دکمه “ساخت کلید API” یک کلید جدید برای دسترسی به Gilas API بسازید.
 1
 2from openai import OpenAI # for calling the OpenAI API
 3import os
 4
 5client = OpenAI(
 6    api_key=os.environ.get(("GILAS_API_KEY", "<کلید API خود را اینجا بسازید https://dashboard.gilas.io/apiKey>")), 
 7    base_url="https://api.gilas.io/v1/" # Gilas APIs
 8)
 9
10def get_embedding(query)
11    query_embedding_response = client.embeddings.create(
12        model=embedding_model,
13        input=query,
14    )
15    return query_embedding_response.data[0].embedding
16
17
18# This may take a few minutes
19df["embedding"] = df.combined.apply(lambda x: get_embedding(x))
20df.to_csv("data/fine_food_reviews_with_embeddings_1k.csv")

حال که بردار امبدینگ‌ها را برای تمام نظرات تولید کردیم نگاهی به نحوه استفاده از آنها می‌کنیم.

 1import pandas as pd
 2import numpy as np
 3from ast import literal_eval
 4
 5from sklearn.ensemble import RandomForestClassifier
 6from sklearn.model_selection import train_test_split
 7from sklearn.metrics import classification_report, accuracy_score
 8
 9datafile_path = "data/fine_food_reviews_with_embeddings_1k.csv"
10
11df = pd.read_csv(datafile_path)
12df["embedding"] = df.embedding.apply(literal_eval).apply(np.array)  # convert string to array
13
14# split data into train and test
15X_train, X_test, y_train, y_test = train_test_split(
16    list(df.embedding.values), df.Score, test_size=0.2, random_state=42
17)
18
19# train random forest classifier
20clf = RandomForestClassifier(n_estimators=100)
21clf.fit(X_train, y_train)
22preds = clf.predict(X_test)
23probas = clf.predict_proba(X_test)
24
25report = classification_report(y_test, preds)
26print(report)
              precision    recall  f1-score   support

           1       0.90      0.45      0.60        20
           2       1.00      0.38      0.55         8
           3       1.00      0.18      0.31        11
           4       0.88      0.26      0.40        27
           5       0.76      1.00      0.86       134

    accuracy                           0.78       200
   macro avg       0.91      0.45      0.54       200
weighted avg       0.81      0.78      0.73       200

می‌توانیم ببینیم که مدل به خوبی توانسته است بین دسته‌ها تمایز قائل شود. نظرات ۵ ستاره بهترین عملکرد را نشان می‌دهند و این امر تعجب‌آور نیست، زیرا این نظرات در دیتاست بیشترین تعداد را دارند.

1from utils.embeddings_utils import plot_multiclass_precision_recall
2
3plot_multiclass_precision_recall(probas, y_test, [1, 2, 3, 4, 5], clf)
RandomForestClassifier() - Average precision score over all classes: 0.90
random forest classifier

تعجب‌آور نیست که پیش‌بینی نظرات ۵ ستاره و ۱ ستاره آسان‌تر است. شاید با داده‌های بیشتر، تفاوت‌های بین ۲ تا ۴ ستاره بهتر پیش‌بینی شود.