שלב 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