תחי ישראל - אין לנו ארץ אחרת

תחי ישראל -אין לנו ארץ אחרת

שימוש ב-word embedding שאומן מראש במודל Keras לסיווג טקסטים

 

מחבר:
בתאריך:

בעיה מרכזית שהמחשב צריך לפתור כדי לעשות למידת מכונה מטקסטים NLP היא שהתהליך דורש ביצוע פעולות חשבוניות על וקטורים. לכן, אחד הדברים הראשונים שנעשה, כהכנה ללימוד שפה, הוא להמיר את המילים מהם מורכב הטקסט לוקטורים (וקטוריזציה). בתהליך שבו נוצר מילון שממפה מילים לוקטורים.

בניגוד למילונים רגילים בהם הולכת לאיבוד המשמעות הסמנטית של מילים, טכנולוגיה של word embedding משמרת את משמעות המילים כאשר מילים בעלות משמעות דומה ימצאו בסמיכות במרחב הגיאומטרי שהטכנולוגיה יוצרת. לדוגמה, המילים "צרפת" ו-"הודו" יהיו קרובות יותר מאשר "צרפת" ו-"בוהן".

אתה יכול לקרוא על טכנולוגית word embedding במדריך מבוא לעיבוד שפה באמצעות Gensim ו-Word2Vec.

במדריך זה נשתמש ב-word embedding שעשו בשבילנו באמצעות אלגוריתם GloVe שאומן מראש על וויקיפדיה האנגלית.

את הקוד המלא של המדריך כדאי להוריד מהקישור: keras_glove_embedding.py בגלל שלא פרטתי במדריך את כל השלבים.

 

שיטות

מסד הנתונים במדריך הוא 20 news group שייבאתי לפי הפרוטוקול שתארתי במדריך למידת מכונה - סיווג טקסטים באמצעות sklearn.

בהכנת מסד הנתונים ושכבת ה-embedding השתמשתי בגישה המתוארת ב-Using pre-trained word embeddings in a Keras model עם התאמות קלות.

 

הכנת מסד הנתונים

מסד הנתונים 20 news group שהורדנו בשלב קודם מורכב מקבצים שבכל אחד מהם נמצא אחד הטקסטים. הקבצים מסודרים בתיקיות. לצורך המדריך, לקחתי 4 קטגוריות מתוך ה-20.

 

# second, prepare text samples and their labels
print('Processing text dataset')
 
dir_list = os.listdir(TEXT_DATA_DIR)
 
texts = []  # list of text samples
labels_index = {}  # dictionary mapping label name to numeric id
labels = []  # list of label ids
categories = ['rec.autos','sci.med','comp.os.ms-windows.misc','comp.windows.x']
 
for name in sorted(dir_list):
    path = os.path.join(TEXT_DATA_DIR, name)
    # print(path)
    if os.path.isdir(path) and name in categories:
        label_id = len(labels_index)
        labels_index[name] = label_id
        for fname in sorted(os.listdir(path)):
            if fname.isdigit():
                fpath = os.path.join(path, fname)
                args = {}
                with open(fpath, encoding='latin-1') as f:
                    t = f.read()
                    i = t.find('\n\n')  # skip header
                    if 0 < i:
                        t = t[i:]
                    texts.append(t)
                labels.append(label_id)
 
print('Found %s texts.' % len(texts))

הפיכת הטקסטים לווקטורים:

# vectorize the text samples into a 2D integer tensor
tokenizer = Tokenizer(num_words=MAX_NUM_WORDS)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
 
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))
 
data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)
 
labels = to_categorical(np.asarray(labels))
print('Shape of data tensor:', data.shape)
print('Shape of label tensor:', labels.shape)

נחלק את הדוגמאות בין קבוצת אימון ובקרה:

VALIDATION_SPLIT = 0.2

# split the data into a training set and a validation set
indices = np.arange(data.shape[0])
np.random.shuffle(indices)
data = data[indices]
labels = labels[indices]
num_validation_samples = int(VALIDATION_SPLIT * data.shape[0])
 
x_train = data[:-num_validation_samples]
y_train = labels[:-num_validation_samples]
x_val = data[-num_validation_samples:]
y_val = labels[-num_validation_samples:]

 

הכנת שכבת ה-embedding

קיבלנו את המילים והווקטורים שמקורם באימון אלגוריתם GloVe על וויקיפדיה:

# first, build index mapping words in the embeddings set
# to their embedding vector
 
print('Indexing word vectors.')
 
embeddings_index = {}
with open(os.path.join(GLOVE_DIR,'glove.6B.100d.txt')) as f:
    for line in f:
        word, coefs = line.split(maxsplit=1)
        coefs = np.fromstring(coefs, 'f', sep=' ')
        embeddings_index[word] = coefs
 
print('Found %s word vectors.' % len(embeddings_index))

בשלב זה נתרגם את הטקסטים שלנו לוקטורים שמספק GloVe. התוצאה של השלב הזה היא embedding matrix שאותו נזין לרשת הנוירונית.

# prepare embedding matrix
num_words = min(MAX_NUM_WORDS, len(word_index) + 1)
embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
for word, i in word_index.items():
    if i >= MAX_NUM_WORDS:
        continue
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        # words not found in embedding index will be all-zeros.
        embedding_matrix[i] = embedding_vector

 

הרשת הנוירונית

המודל לסיווג הטקסטים מבוסס על RNN, כפי שהסברתי במדריך פיתוח מודל לאנליזת סנטימנט באמצעות למידת מכונה ו-keras.

בניסוי ראשוני שערכתי המודל סבל מ-overfitting שהתבטא בדיוק התאמה גבוה יותר לדוגמאות קבוצת האימון לעומת קבוצת הבקרה. כדי להתגבר על הבעיה ערכתי שלושה שינויים מבניים במודל:

  • הורדתי את מספר שכבות ה-RNN מ-3 ל-2
  • הוספתי רגולריזציה מסוג l2
  • הוספתי dropout 

שלוש השיטות מיועדות למנוע overfitting כפי שהסברתי במדריך כיצד להתגבר על overfitting במודלים מבוססי Keras?

בניית המודל:

EPOCHS = 22
BATCH_SIZE = 32
NUM_CLASSES = 4

model = Sequential()
model.add(Embedding(MAX_NUM_WORDS, 
                    128, 
                    embeddings_initializer=Constant(embedding_matrix),
                    input_length=MAX_SEQUENCE_LENGTH,
                    trainable=False))
model.add(Bidirectional(GRU(units=64, dropout=0.2, recurrent_dropout=0.2, activation='sigmoid', return_sequences=True)))
model.add(Bidirectional(GRU(units=4, dropout=0.2, recurrent_dropout=0.2, activation='sigmoid', return_sequences=False)))
model.add(Dense(NUM_CLASSES, activation='softmax'))
model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

אימון המודל:

# set the conditions for early stopping
from tensorflow.keras.callbacks import EarlyStopping
es = EarlyStopping(patience = 2, monitor='val_loss')
 
 
model.fit(x_train, y_train,
          batch_size=BATCH_SIZE,
          epochs=EPOCHS,
          validation_data=(x_val, y_val), 
          callbacks=[es])

 

הערכת המודל

loss, accuracy = model.evaluate(x_val, y_val, verbose=1)
print('Accuracy: %0.2f' % (accuracy*100))

דיוק של 78.78% בסיווג דוגמאות קבוצת הבקרה.

 

השוואה לביצועי מודל sklearn

במדריך למידת מכונה - סיווג טקסטים באמצעות sklearn הגעתי למידת דיוק של 99% בדוגמאות הבקרה כשהשתמשתי לסיווג במודל MultinomialNB. תוצאה שהיא גבוהה משמעותית מ-79% שאליו הגיע המודל מבוסס ה-Keras. לא זו בלבד, גם זמן האימון היה ארוך משמעותית יותר כשהשתמשתי ב-Keras. בתחילה, חשבתי שמודל אחר של Keras עשוי להשתוות לתוצאות של sklearn. בהתאם, ניסיתי מודל מבוסס קונבולציה, שאפרסם את תוצאותיו בעתיד. רק שגם הוא לא הצליח להתקרב לתוצאות של sklearn. נראה שהמודלים שאני בונה עם Keras הם לא מספיק מוצלחים, וייתכן שמה שתורם לכך הוא מספר הדוגמאות היחסית קטן שבו השתמשתי לאימון כי רשתות נוירוניות דורשות מספר גדול מאוד של דוגמאות. בכל מקרה, הניסיון שלי מלמד אותי שכדאי להעדיף את sklearn לצורך סיווג טקסט לקטגוריות בפרט כשמספר הדוגמאות והטוקנים אינו גדול מספיק.

 

מקורות מידע

  1. מבוא לעיבוד שפה באמצעות Gensim ו-Word2Vec
  2. למידת מכונה - סיווג טקסטים באמצעות sklearn
  3. Using pre-trained embedding model in Keras
  4. פיתוח מודל לאנליזת סנטימנט באמצעות למידת מכונה ו-keras
  5. כיצד להתגבר על overfitting במודלים מבוססי Keras

 

לכל המדריכים בנושא של למידת מכונה

 

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.

למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.

שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.

המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

הוסף תגובה חדשה

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

מהם שלוש רשויות השלטון בישראל?