# تصنيف النصوص

تصنيف النصوص هو مهمة شائعة في معالجة اللغة الطبيعية تُسند بها تسمية أو فئة إلى النص. تشغّل بعض أكبر الشركات تصنيف النصوص في بيئات الإنتاج لمجموعة واسعة من التطبيقات العملية. من أكثر أشكال تصنيف النصوص شيوعاً تحليل المشاعر، الذي يُسند تسمية مثل 🙂 إيجابي، أو 🙁 سلبي، أو 😐 محايد إلى تسلسل من النصوص.

ستُظهر لك هذه الدليل كيفية:

1. قم بتدريب [DistilBERT](https://huggingface.co/distilbert/distilbert-base-uncased) على مجموعة بيانات [IMDb](https://huggingface.co/datasets/stanfordnlp/imdb) لتحديد ما إذا كان تقييم فيلم إيجابياً أم سلبياً.
2. استخدم النموذج المُحسَّن لديك للاستدلال.

للاطلاع على جميع البنى المعمارية ونقاط التفتيش المتوافقة مع هذه المهمة، ننصح بالاطلاع على [صفحة المهمة](https://huggingface.co/tasks/text-classification).

قبل أن تبدأ، تأكد من تثبيت جميع المكتبات اللازمة:

```bash
pip install transformers datasets evaluate accelerate
```

ننصحك بتسجيل الدخول إلى حسابك على Hugging Face حتى تتمكن من رفع نموذجك ومشاركته مع المجتمع. عند الطلب، أدخل رمزك (token) لتسجيل الدخول:

```py
>>> from huggingface_hub import notebook_login

>>> notebook_login()
```

## تحميل مجموعة بيانات IMDb

ابدأ بتحميل مجموعة بيانات IMDb من مكتبة 🤗 Datasets:

```py
>>> from datasets import load_dataset

>>> imdb = load_dataset("stanfordnlp/imdb")
```

ثم اطّلع على مثال:

```py
>>> imdb["test"][0]
{
    "label": 0,
    "text": "I love sci-fi and am willing to put up with a lot. Sci-fi movies/TV are usually underfunded, under-appreciated and misunderstood. I tried to like this, I really did, but it is to good TV sci-fi as Babylon 5 is to Star Trek (the original). Silly prosthetics, cheap cardboard sets, stilted dialogues, CG that doesn't match the background, and painfully one-dimensional characters cannot be overcome with a 'sci-fi' setting. (I'm sure there are those of you out there who think Babylon 5 is good sci-fi TV. It's not. It's clichéd and uninspiring.) While US viewers might like emotion and character development, sci-fi is a genre that does not take itself seriously (cf. Star Trek). It may treat important issues, yet not as a serious philosophy. It's really difficult to care about the characters here as they are not simply foolish, just missing a spark of life. Their actions and reactions are wooden and predictable, often painful to watch. The makers of Earth KNOW it's rubbish as they have to always say \"Gene Roddenberry's Earth...\" otherwise people would not continue watching. Roddenberry's ashes must be turning in their orbit as this dull, cheap, poorly edited (watching it without advert breaks really brings this home) trudging Trabant of a show lumbers into space. Spoiler. So, kill off a main character. And then bring him back as another actor. Jeeez! Dallas all over again.",
}
```

يوجد حقلان في هذا مجموعة البيانات:

- `text`: نص تقييم الفيلم.
- `label`: قيمة تكون إما `0` لمراجعة سلبية أو `1` لمراجعة إيجابية.

## المعالجة المسبقة

الخطوة التالية هي تحميل مُجزِّئ DistilBERT لمعالجة حقل `text` مسبقاً:

```py
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")
```

أنشئ دالةً للمعالجة المسبقة لتجزئة `text` وقصّ التسلسلات بحيث لا تتجاوز الحد الأقصى لطول الإدخال في DistilBERT:

```py
>>> def preprocess_function(examples):
...     return tokenizer(examples["text"], truncation=True)
```

لتطبيق دالة المعالجة المسبقة على مجموعة البيانات بأكملها، استخدم دالة [map](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.map) في 🤗 Datasets. يمكنك تسريع `map` عن طريق تعيين `batched=True` لمعالجة عدة عناصر من مجموعة البيانات في وقت واحد:

```py
tokenized_imdb = imdb.map(preprocess_function, batched=True)
```

الآن أنشئ دفعة من الأمثلة باستخدام [DataCollatorWithPadding](/docs/transformers/main/ar/main_classes/data_collator#transformers.DataCollatorWithPadding). من الكفاءة أن *نملأ الجمل ديناميكيًا* حتى أطول طول في الدفعة أثناء التجميع، بدلاً من ملء مجموعة البيانات بأكملها حتى الطول الأقصى.

```py
>>> from transformers import DataCollatorWithPadding

>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
```

## تقييم

غالباً ما يكون تضمين مقياس أثناء التدريب مفيداً لتقييم أداء نموذجك. يمكنك تحميل طريقة تقييم بسرعة باستخدام مكتبة 🤗 [Evaluate](https://huggingface.co/docs/evaluate/index). لهذه المهمة، حمّل مقياس [accuracy](https://huggingface.co/spaces/evaluate-metric/accuracy) (راجع [quick tour](https://huggingface.co/docs/evaluate/a_quick_tour) الخاص بـ 🤗 Evaluate لمعرفة المزيد حول كيفية تحميل مقياس وحسابه):

```py
>>> import evaluate

>>> accuracy = evaluate.load("accuracy")
```

ثم أنشئ دالة تمرّر تنبؤاتك والتسميات إلى [compute](https://huggingface.co/docs/evaluate/main/en/package_reference/main_classes#evaluate.EvaluationModule.compute) لحساب الدقة:

```py
>>> import numpy as np

>>> def compute_metrics(eval_pred):
...     predictions, labels = eval_pred
...     predictions = np.argmax(predictions, axis=1)
...     return accuracy.compute(predictions=predictions, references=labels)
```

دالة `compute_metrics` الخاصة بك جاهزة الآن، وستعود إليها عند إعداد التدريب.

## تدريب

قبل أن تبدأ في تدريب نموذجك، أنشئ خريطة للـ ids المتوقعة إلى تسمياتها باستخدام `id2label` و`label2id`:

```py
>>> id2label = {0: "NEGATIVE", 1: "POSITIVE"}
>>> label2id = {"NEGATIVE": 0, "POSITIVE": 1}
```

إذا لم تكن على دراية بضبط نموذج باستخدام [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer)، فاطّلع على الدرس الأساسي [هنا](../training)!

أنت مستعد الآن لبدء تدريب نموذجك! حمّل DistilBERT باستخدام [AutoModelForSequenceClassification](/docs/transformers/main/ar/model_doc/auto#transformers.AutoModelForSequenceClassification) مع عدد التسميات المتوقعة، وتعيينات التسميات:

```py
>>> from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer

>>> model = AutoModelForSequenceClassification.from_pretrained(
...     "distilbert/distilbert-base-uncased", num_labels=2, id2label=id2label, label2id=label2id
... )
```

في هذه المرحلة، تبقى ثلاث خطوات فقط:

1. حدّد معاملات التدريب الفائقة في [TrainingArguments](/docs/transformers/main/ar/main_classes/trainer#transformers.TrainingArguments). المعامل الوحيد الإلزامي هو `output_dir` الذي يحدد مكان حفظ النموذج. ستقوم بدفع هذا النموذج إلى Hub من خلال تعيين `push_to_hub=True` (يتعين عليك تسجيل الدخول إلى Hugging Face لرفع النموذج). في نهاية كل حقبة، سيقوم [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) بتقييم الدقة وحفظ نقطة الفحص للتدريب.
2. مرّر حُجج التدريب إلى [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) مع النموذج، ومجموعة البيانات، ومُجزّئ الرموز، ومُجمِّع البيانات، ودالة `compute_metrics`.
3. استدعِ [train()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.train) لضبط نموذجك.

```py
>>> training_args = TrainingArguments(
...     output_dir="my_awesome_model",
...     learning_rate=2e-5,
...     per_device_train_batch_size=16,
...     per_device_eval_batch_size=16,
...     num_train_epochs=2,
...     weight_decay=0.01,
...     eval_strategy="epoch",
...     save_strategy="epoch",
...     load_best_model_at_end=True,
...     push_to_hub=True,
... )

>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     train_dataset=tokenized_imdb["train"],
...     eval_dataset=tokenized_imdb["test"],
...     processing_class=tokenizer,
...     data_collator=data_collator,
...     compute_metrics=compute_metrics,
... )

>>> trainer.train()
```

يطبّق [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) الحشو الديناميكي افتراضياً عند تمرير `tokenizer` إليه. في هذه الحالة، لا حاجة إلى تحديد مُجمِّع بيانات (data collator) بشكل صريح.

بمجرد اكتمال التدريب، شارك نموذجك على Hub باستخدام طريقة [push_to_hub()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.push_to_hub) ليتمكن الجميع من استخدام نموذجك:

```py
>>> trainer.push_to_hub()
```

لمثال أكثر تفصيلاً حول كيفية ضبط نموذج لتصنيف النصوص، راجع [دفتر PyTorch](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/text_classification.ipynb) المقابل.

## الاستدلال

ممتاز، والآن بعد أن قمت بضبط نموذج، يمكنك استخدامه للاستدلال!

احصل على بعض النص الذي تريد تشغيل الاستدلال عليه:

```py
>>> text = "This was a masterpiece. Not completely faithful to the books, but enthralling from beginning to end. Might be my favorite of the three."
```

أبسط طريقة لتجربة نموذجك المُحسَّن للاستدلال هي استخدامه في [pipeline()](/docs/transformers/main/ar/main_classes/pipelines#transformers.pipeline). قم بإنشاء `pipeline` لتحليل المشاعر باستخدام نموذجك، ومرر النص إليه:

```py
>>> from transformers import pipeline

>>> classifier = pipeline("sentiment-analysis", model="stevhliu/my_awesome_model")
>>> classifier(text)
[{'label': 'POSITIVE', 'score': 0.9994940757751465}]
```

يمكنك أيضًا إعادة إنتاج نتائج `pipeline` يدويًا إذا رغبت في ذلك:

قم بتجزئة النص وإرجاع متجهات PyTorch:

```py
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_model")
>>> inputs = tokenizer(text, return_tensors="pt")
```

مرّر مدخلاتك إلى النموذج وأعد `logits`:

```py
>>> import torch
>>> from transformers import AutoModelForSequenceClassification

>>> model = AutoModelForSequenceClassification.from_pretrained("stevhliu/my_awesome_model")
>>> with torch.no_grad():
...     logits = model(**inputs).logits
```

احصل على الفئة ذات أعلى احتمال، واستخدم خرائط `id2label` الخاصة بالنموذج لتحويلها إلى تسمية نصية:

```py
>>> predicted_class_id = logits.argmax().item()
>>> model.config.id2label[predicted_class_id]
'POSITIVE'
```

