الخطوة 2: استكشاف بياناتك

لا يمثّل إنشاء نموذج وتدريبه سوى جزءًا واحدًا من سير العمل. يتيح لك فهم خصائص بياناتك مسبقًا إنشاء نموذج أفضل. ويعني ذلك ببساطة الحصول على دقة أعلى. وقد يعني ذلك أيضًا الحاجة إلى بيانات أقل للتدريب أو موارد أقل حسابية.

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

لنبدأ أولاً بتحميل مجموعة البيانات إلى Python.

def load_imdb_sentiment_analysis_dataset(data_path, seed=123):
    """Loads the IMDb movie reviews sentiment analysis dataset.

    # Arguments
        data_path: string, path to the data directory.
        seed: int, seed for randomizer.

    # Returns
        A tuple of training and validation data.
        Number of training samples: 25000
        Number of test samples: 25000
        Number of categories: 2 (0 - negative, 1 - positive)

    # References
        Mass et al., http://www.aclweb.org/anthology/P11-1015

        Download and uncompress archive from:
        http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
    """
    imdb_data_path = os.path.join(data_path, 'aclImdb')

    # Load the training data
    train_texts = []
    train_labels = []
    for category in ['pos', 'neg']:
        train_path = os.path.join(imdb_data_path, 'train', category)
        for fname in sorted(os.listdir(train_path)):
            if fname.endswith('.txt'):
                with open(os.path.join(train_path, fname)) as f:
                    train_texts.append(f.read())
                train_labels.append(0 if category == 'neg' else 1)

    # Load the validation data.
    test_texts = []
    test_labels = []
    for category in ['pos', 'neg']:
        test_path = os.path.join(imdb_data_path, 'test', category)
        for fname in sorted(os.listdir(test_path)):
            if fname.endswith('.txt'):
                with open(os.path.join(test_path, fname)) as f:
                    test_texts.append(f.read())
                test_labels.append(0 if category == 'neg' else 1)

    # Shuffle the training data and labels.
    random.seed(seed)
    random.shuffle(train_texts)
    random.seed(seed)
    random.shuffle(train_labels)

    return ((train_texts, np.array(train_labels)),
            (test_texts, np.array(test_labels)))

التحقق من البيانات

بعد تحميل البيانات، من المفيد إجراء بعض عمليات التحقّق عليها: اختَر عيّنات قليلة ثم تحقّق يدويًا مما إذا كانت تتوافق مع توقعاتك. على سبيل المثال، اطبع بعض النماذج العشوائية لمعرفة ما إذا كان تصنيف الآراء متوافقًا مع آراء المراجعة. في ما يلي مراجعة اخترناها عشوائيًا من مجموعة بيانات IMDb: "تم مدّة القصة التي تصل مدتها إلى عشر دقائق لتشمل الجزء الأفضل من ساعتين. وعندما لا يكون هناك أي أهمية في هذا الشأن عند منتصف الطريق الذي كان من المفترض أن أغادره"، يتطابق العواطف المتوقعة (السالب) مع تصنيف العيّنة.

جمع المقاييس الرئيسية

بعد التحقق من البيانات، اجمع المقاييس المهمة التالية التي يمكن أن تساعد في تحديد مشكلة تصنيف النص:

  1. عدد العيّنات: إجمالي عدد الأمثلة لديك في البيانات.

  2. عدد الصفوف: إجمالي عدد المواضيع أو الفئات في البيانات.

  3. عدد العيّنات في كل صف: عدد العيّنات في كل صف (الموضوع/الفئة). في مجموعة بيانات متوازنة، ستحتوي جميع الفئات على عدد مماثل من النماذج. في مجموعة بيانات غير متوازنة، سيختلف عدد العيّنات في كل فئة على نطاق واسع.

  4. عدد الكلمات لكل عيّنة: متوسط عدد الكلمات في عيّنة واحدة.

  5. توزيع معدّل تكرار الكلمات: التوزيع الذي يُظهر معدل تكرار (عدد التكرارات) لكل كلمة في مجموعة البيانات.

  6. توزيع طول العيّنة: توزيع يوضّح عدد الكلمات لكل عيّنة في مجموعة البيانات.

لنتعرّف على قيم هذه المقاييس لمجموعة بيانات المراجعات على IMDb (يُرجى الاطّلاع على الشكلين 3 و4 لمخططات توزيع مرات تكرار الكلمات وأخذ طول العينة).

اسم المقياس قيمة المقياس
عدد العيّنات 25000
عدد الصفوف 2
عدد العيّنات في كل صف 12500
عدد الكلمات لكل عيّنة 174

الجدول 1: مراجعات IMDb لمقاييس مجموعة البيانات

explore_data.py تتضمّن دوالًا لحساب هذه المقاييس وتحليلها. مثلاً،

import numpy as np
import matplotlib.pyplot as plt

def get_num_words_per_sample(sample_texts):
    """Returns the median number of words per sample given corpus.

    # Arguments
        sample_texts: list, sample texts.

    # Returns
        int, median number of words per sample.
    """
    num_words = [len(s.split()) for s in sample_texts]
    return np.median(num_words)

def plot_sample_length_distribution(sample_texts):
    """Plots the sample length distribution.

    # Arguments
        samples_texts: list, sample texts.
    """
    plt.hist([len(s) for s in sample_texts], 50)
    plt.xlabel('Length of a sample')
    plt.ylabel('Number of samples')
    plt.title('Sample length distribution')
    plt.show()

توزيع تكرار الكلمات على IMDb

الشكل 3: توزيع تكرار الكلمات على IMDb

توزيع مدة العينة على IMDb

الشكل 4: توزيع عيّنة من طول مدة IMDb