3. Adım: Verilerinizi Hazırlayın

Verilerimizin bir modele aktarılabilmesi için öncelikle modelin anlayabileceği bir biçime dönüştürülmesi gerekir.

Öncelikle, topladığımız veri örnekleri belirli bir sırada olabilir. Örneklerin sıralamasıyla ilişkili hiçbir bilginin metinlerle etiketler arasındaki ilişkiyi etkilemesini istemeyiz. Örneğin, bir veri kümesi sınıfa göre sıralanır ve ardından eğitim/doğrulama kümelerine bölünürse bu gruplar verilerin genel olarak dağıtımını temsil etmez.

Modelin veri düzeninden etkilenmemesini sağlamak için basit bir en iyi uygulama, başka bir şey yapmadan önce verileri her zaman karıştırmaktır. Verileriniz eğitim ve doğrulama kümelerine bölünmüşse doğrulama verilerinizi, eğitim verilerinizi dönüştürdüğünüz şekilde dönüştürdüğünüzden emin olun. Ayrı eğitim ve doğrulama kümeleriniz yoksa karıştırdıktan sonra örnekleri örnekleyebilirsiniz. Eğitim için örneklerin% 80'ini ve doğrulama için% 20'sini kullanın.

İkinci olarak, makine öğrenimi algoritmaları girdileri sayı olarak alır. Bu, metinleri sayısal vektörlere dönüştürmemiz gerektiği anlamına geliyor. Bu işlem iki adımdan oluşur:

  1. Jetona dönüştürme: Metinleri kelimelere veya daha küçük alt metinlere bölerek metinler ile etiketler arasındaki ilişkinin iyi bir şekilde genelleştirilmesini sağlayabilirsiniz. Bu, veri kümesinin "sözlüğünü" (verilerde bulunan benzersiz jetonlar grubu) belirler.

  2. Vektörleme: Bu metinlerin tanımlanması için iyi bir sayısal ölçüm tanımlayın.

Şimdi, bu iki adımı hem n-gram vektörleri hem de dizi vektörleri için nasıl gerçekleştireceğimize ve özellik seçim ve normalleştirme tekniklerini kullanarak vektör temsillerini nasıl optimize edeceğinize bakalım.

N-gram vektörleri [Option A]

Sonraki paragraflarda, n-gram modelleri için jetonlaştırma ve vektörleştirmenin nasıl yapılacağını göreceğiz. Özellik seçimi ve normalleştirme tekniklerini kullanarak n-gram temsilini nasıl optimize edebileceğimize de değineceğiz.

n-gram vektör olarak, metin benzersiz n-gram koleksiyonu olarak temsil edilir: n Yakın bitişik jeton grupları (genellikle kelimeler). The mouse ran up the clock metnini kullanmayı düşünün. Burada unigramlar (n = 1) ['the', 'mouse', 'ran', 'up', 'clock'], bigram (no = 2) kelimesi ise ['the mouse', 'mouse ran', 'ran up', 'up the', 'the clock'] şeklindedir.

Jetonlama

Kelime ünigramları ve bigram'lar arasında şifrelemenin daha az işlem süresi sağlarken iyi bir doğruluk sağladığını tespit ettik.

Vektörleştirme

Metin örneklerimizi n-gramlara böldükten sonra, bu n-gramları makine öğrenimi modellerimizin işleyebildiği sayısal vektörlere dönüştürmemiz gerekir. Aşağıdaki örnekte, iki metin için oluşturulan unigram'lara ve bigram'lara atanan dizinler gösterilmektedir.

Texts: 'The mouse ran up the clock' and 'The mouse ran down'
Index assigned for every token: {'the': 7, 'mouse': 2, 'ran': 4, 'up': 10,
  'clock': 0, 'the mouse': 9, 'mouse ran': 3, 'ran up': 6, 'up the': 11, 'the
clock': 8, 'down': 1, 'ran down': 5}

Dizinler n-gramlara atandıktan sonra, aşağıdaki seçeneklerden birini kullanarak genellikle vektör uygularız.

Tek seferlik kodlama: Her örnek metin, metinde bir jetonun var olduğunu veya mevcut olmadığını gösteren bir vektör olarak gösterilir.

'The mouse ran up the clock' = [1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1]

Sayım kodlaması: Her örnek metin, metindeki bir jetonun sayısını belirten bir vektör olarak gösterilir. Metinde "the" kelimesi iki kez göründüğü için, unigram 'the' (aşağıda kalın harflerle yazılmış) öğesine karşılık gelen öğenin artık 2 olarak gösterildiğini unutmayın.

'The mouse ran up the clock' = [1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1]

Tf-idf kodlaması: Yukarıdaki iki yaklaşımdan kaynaklanan sorun, tüm dokümanlarda benzer sıklıkta görülen yaygın kelimelerin (yani veri kümesindeki metin örneklerine özel olmayan kelimelerin) cezalandırılmamasıdır. Örneğin, "a" gibi kelimeler tüm metinlerde çok sık kullanılır. Bu nedenle, "the" için daha anlamlı başka kelimeler kullanmaktan daha yüksek bir jeton sayısı çok faydalı değildir.

'The mouse ran up the clock' = [0.33, 0, 0.23, 0.23, 0.23, 0, 0.33, 0.47, 0.33,
0.23, 0.33, 0.33] (See Scikit-learn TfidfTransformer)

Birçok farklı vektör temsili mevcuttur ancak yukarıdaki en yaygın üç yöntem kullanılır.

tf-idf kodlamasının doğruluk açısından diğer ikisine göre marjinal olarak daha iyi olduğunu (ortalama: %0,25-15 daha yüksek) gözlemledik.n-gramları vektörleştirmek için bu yöntemi kullanmanızı öneririz. Ancak, kayan nokta gösterimini kullandığı için daha fazla bellek kapladığını ve özellikle büyük veri kümelerinde hesaplamanın daha uzun sürdüğünü (bazı durumlarda iki kat daha uzun sürebilir) unutmayın.

Özellik seçimi

Bir veri kümesindeki tüm metinleri kelime uni+gramı jetonlarına dönüştürdüğümüzde on binlerce jeton üretebiliriz. Bu jetonların/özelliklerin tümü, etiket tahminine katkıda bulunmaz. Bu nedenle, veri kümesinde nadiren meydana gelen jetonlar gibi belirli jetonları bırakabiliriz. Ayrıca, özelliğin önemini de ölçebiliriz (her bir jetonun etiket tahminlerine ne kadar katkıda bulunduğu) ve yalnızca en bilgilendirici jetonları dahil ederiz.

Özellikleri ve ilgili etiketleri alıp özellik önem puanını oluşturan birçok istatistiksel işlev vardır. Sık kullanılan iki işlev: f_classif ve chi2. Yaptığımız denemelerde, bu işlevlerin her ikisinin de eşit düzeyde iyi performans gösterdiğini gördük.

Daha da önemlisi, doğruluğun çoğu veri kümesi için yaklaşık 20.000 özellik zirvesine ulaştığını gördük (bkz. 6. Şekil). Bu eşiğin üzerine daha fazla özellik eklemek, çok az katkı sağlar, hatta bazen aşırı uyuma neden olarak performansı düşürür.

İlk K ve Doğruluk karşılaştırması

Şekil 6: En çok kullanılan K özellikleri ile Doğruluk karşılaştırması. Veri kümeleri genelinde, en iyi 20.000 özellikte doğruluk platoları.

Normalleştirme

Normalleştirme, tüm özellik/örnek değerlerini küçük ve benzer değerlere dönüştürür. Bu, öğrenim algoritmalarında gradyan iniş dönüşümünü basitleştirir. Gördüğümüz kadarıyla veri işleme sırasında normalleştirme, metin sınıflandırma sorunlarına fazla değer katmıyor gibi görünüyor. Bu adımı atlamanızı öneririz.

Aşağıdaki kod, yukarıdaki adımların tamamını bir araya getirir:

  • Metin örneklerini kelime uni+gramları halinde şifreleyin.
  • Tf-idf kodlamasını kullanarak vektör oynayın,
  • 2'den az kez gösterilen jetonları silip özelliklerin önemini hesaplamak için f_classif öğesini kullanarak yalnızca jeton vektörünün en iyi 20.000 özelliğini seçin.
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif

# Vectorization parameters
# Range (inclusive) of n-gram sizes for tokenizing text.
NGRAM_RANGE = (1, 2)

# Limit on the number of features. We use the top 20K features.
TOP_K = 20000

# Whether text should be split into word or character n-grams.
# One of 'word', 'char'.
TOKEN_MODE = 'word'

# Minimum document/corpus frequency below which a token will be discarded.
MIN_DOCUMENT_FREQUENCY = 2

def ngram_vectorize(train_texts, train_labels, val_texts):
    """Vectorizes texts as n-gram vectors.

    1 text = 1 tf-idf vector the length of vocabulary of unigrams + bigrams.

    # Arguments
        train_texts: list, training text strings.
        train_labels: np.ndarray, training labels.
        val_texts: list, validation text strings.

    # Returns
        x_train, x_val: vectorized training and validation texts
    """
    # Create keyword arguments to pass to the 'tf-idf' vectorizer.
    kwargs = {
            'ngram_range': NGRAM_RANGE,  # Use 1-grams + 2-grams.
            'dtype': 'int32',
            'strip_accents': 'unicode',
            'decode_error': 'replace',
            'analyzer': TOKEN_MODE,  # Split text into word tokens.
            'min_df': MIN_DOCUMENT_FREQUENCY,
    }
    vectorizer = TfidfVectorizer(**kwargs)

    # Learn vocabulary from training texts and vectorize training texts.
    x_train = vectorizer.fit_transform(train_texts)

    # Vectorize validation texts.
    x_val = vectorizer.transform(val_texts)

    # Select top 'k' of the vectorized features.
    selector = SelectKBest(f_classif, k=min(TOP_K, x_train.shape[1]))
    selector.fit(x_train, train_labels)
    x_train = selector.transform(x_train).astype('float32')
    x_val = selector.transform(x_val).astype('float32')
    return x_train, x_val

n-gram vektör temsili ile kelime sırası ve dil bilgisi ile ilgili pek çok bilgiyi atıyoruz (en iyisi n ve gt; 1 olduğunda bazı kısmi sıralama bilgilerini saklayabiliriz). Buna paket kelime yaklaşımı denir. Bu temsil, lojistik regresyon, çok katmanlı algılamalar, gradyan güçlendirme makineleri, destek vektör makineleri gibi sıralamayı hesaba katmayan modellerle birlikte kullanılır.

Adım Vektörleri [Option B]

Sonraki paragraflarda, dizi modelleri için jetonlaştırma ve vektörleştirmenin nasıl yapılacağını göreceğiz. Özellik seçimi ve normalleştirme tekniklerini kullanarak dizi temsilini nasıl optimize edeceğimizi de ele alacağız.

Bazı metin örneklerinde kelime sırası, metnin anlamı açısından son derece önemlidir. Örneğin, "İşe gidip gelirken nefret ediyordum. Yeni bisikletim tamamen değişti." Sırasıyla okunduğunda da bu durum anlaşılabilir. CNN/RNN gibi modeller, örnekteki kelimelerin sıralamasından anlam çıkarabilir. Bu modellerde, metni bir dizi dizi halinde temsil edip sırayı korur.

Jetonlama

Metin, bir karakter dizisi veya bir kelime dizisi olarak gösterilebilir. Kelime düzeyinde temsili kullanmanın karakter jetonlarından daha iyi performans gösterdiğini tespit ettik. Bu, sektörde de kullanılan genel bir normdur. Karakter jetonları kullanmak yalnızca metinlerde çok sayıda yazım hatası varsa mantıklıdır. Normalde böyle bir durum söz konusu değildir.

Vektörleştirme

Metin örneklerimizi kelime dizilerine dönüştürdükten sonra bu dizileri sayısal vektörlere dönüştürmemiz gerekir. Aşağıdaki örnekte iki metin için oluşturulan unigramlara atanan dizinler ve ilk metnin dönüştürüldüğü jeton dizinleri dizisi gösterilmektedir.

Texts: 'The mouse ran up the clock' and 'The mouse ran down'
Index assigned for every token: {'clock': 5, 'ran': 3, 'up': 4, 'down': 6, 'the': 1, 'mouse': 2}.
NOTE: 'the' occurs most frequently, so the index value of 1 is assigned to it.
Some libraries reserve index 0 for unknown tokens, as is the case here.
Sequence of token indexes: 'The mouse ran up the clock' = [1, 2, 3, 4, 1, 5]

Jeton dizilerini vektöre dönüştürmek için iki seçenek vardır:

Tek sıcak kodlama: Diziler, n = sözlüğün boyutu olan n boyutlu alanda kelime vektörleri kullanılarak gösterilir. Bu temsil, karakterler olarak jeton hale getirdiğimizde ve bu nedenle sözlük küçük olduğunda işe yarar. Kelime olarak jetona dönüştürdüğümüzde, sözlük genellikle on binlerce jetona sahip olur ve bu durumda, yüksek görüntüler içeren vektörler çok seyrek ve verimsiz olur. Örnek:

'The mouse ran up the clock' = [
  [0, 1, 0, 0, 0, 0, 0],
  [0, 0, 1, 0, 0, 0, 0],
  [0, 0, 0, 1, 0, 0, 0],
  [0, 0, 0, 0, 1, 0, 0],
  [0, 1, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 1, 0]
]

Kelime yerleştirme: Kelimelerle ilişkilendirilmiş anlamları vardır. Bunun sonucunda, yoğun bir vektör alanına (yaklaşık birkaç yüz gerçek sayı) ait kelime jetonlarını gösterebiliyoruz. Burada kelimeler arasındaki yer ve mesafe, anlam açısından ne kadar benzer olduklarını gösterir (bkz. 7. Şekil). Bu temsile kelime yerleştirme denir.

Kelime Yerleştirme

Şekil 7: Kelime yerleştirme

Dizi modellerinin genellikle ilk katmanı olarak böyle bir yerleştirme katmanı vardır. Bu katman, eğitim sürecinde kelime dizini dizilerini kelime yerleştirme vektörlerine dönüştürmeyi öğrenir. Böylece her kelime dizini, semantik boşlukta ilgili kelimenin konumunu temsil eden yoğun değerlerden oluşan yoğun bir vektörle eşleştirilir (bkz. Şekil 8).

Katıştırma Katmanı

Şekil 8: Katman yerleştirme

Özellik seçimi

Verilerimizdeki tüm kelimeler etiket tahminlerine katkıda bulunmaz. Ender veya alakasız kelimeleri sözlüğümüzden kaldırarak öğrenme sürecimizi optimize edebiliriz. Gerçekte, en sık kullanılan 20.000 özelliğin kullanılmasının genellikle yeterli olduğu gözlemlenmektedir. Bu, n-gram modeller için de geçerlidir (bkz. Şekil 6).

Dizi vektörelleştirmede yukarıdaki adımların tümünü bir araya getirelim. Aşağıdaki kod, bu görevleri gerçekleştirir:

  • Metinleri kelimelere çevirir
  • İlk 20.000 jetonu kullanarak bir sözlük oluşturur
  • Jetonları dizi vektörlerine dönüştürür
  • Adım sıralarını sabit bir dizi uzunluğuna geçirir
from tensorflow.python.keras.preprocessing import sequence
from tensorflow.python.keras.preprocessing import text

# Vectorization parameters
# Limit on the number of features. We use the top 20K features.
TOP_K = 20000

# Limit on the length of text sequences. Sequences longer than this
# will be truncated.
MAX_SEQUENCE_LENGTH = 500

def sequence_vectorize(train_texts, val_texts):
    """Vectorizes texts as sequence vectors.

    1 text = 1 sequence vector with fixed length.

    # Arguments
        train_texts: list, training text strings.
        val_texts: list, validation text strings.

    # Returns
        x_train, x_val, word_index: vectorized training and validation
            texts and word index dictionary.
    """
    # Create vocabulary with training texts.
    tokenizer = text.Tokenizer(num_words=TOP_K)
    tokenizer.fit_on_texts(train_texts)

    # Vectorize training and validation texts.
    x_train = tokenizer.texts_to_sequences(train_texts)
    x_val = tokenizer.texts_to_sequences(val_texts)

    # Get max sequence length.
    max_length = len(max(x_train, key=len))
    if max_length > MAX_SEQUENCE_LENGTH:
        max_length = MAX_SEQUENCE_LENGTH

    # Fix sequence length to max value. Sequences shorter than the length are
    # padded in the beginning and sequences longer are truncated
    # at the beginning.
    x_train = sequence.pad_sequences(x_train, maxlen=max_length)
    x_val = sequence.pad_sequences(x_val, maxlen=max_length)
    return x_train, x_val, tokenizer.word_index

Etiket vektörü

Örnek metin verilerini sayısal vektörlere nasıl dönüştüreceğimizi gördük. Etiketlere benzer bir işlem uygulanmalıdır. Etiketleri [0, num_classes - 1] aralığındaki değerlere dönüştürebiliriz. Örneğin, 3 sınıf varsa bunları temsil etmek için yalnızca 0, 1 ve 2 değerlerini kullanabiliriz. Dahili olarak ağ, bu değerleri temsil eden bir "vektör" vektörünü kullanır (etiketler arasında yanlış bir ilişki olduğunu ortaya çıkarmamak için). Bu temsil, kayıp işlevine ve nöral ağımızda kullandığımız son katman etkinleştirme işlevine bağlıdır. Sonraki bölümde bunlar hakkında daha fazla bilgi edineceğiz.