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, metinler ve etiketler arasındaki ilişkiyi etkilemesini istemeyiz. Örneğin, bir veri kümesi sınıfa göre sıralanır ve daha sonra eğitim/doğrulama kümelerine ayrılırsa bu kümeler, verilerin genel dağılımını temsil etmez.

Modelin veri sırasından etkilenmemesini sağlamak için basit bir en iyi uygulama, başka bir şey yapmadan önce her zaman verileri karıştırmaktır. Verileriniz zaten 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 örnekleri karıştırdıktan sonra bölebilirsiniz. Genellikle örneklerin% 80'ini eğitim ve% 20'sini doğrulama için kullanmak normaldir.

İkinci olarak, makine öğrenimi algoritmaları sayıları giriş olarak alır. Bu, metinleri sayısal vektörlere dönüştürmemiz gerektiği anlamına gelir. Bu süreç iki adımdan oluşur:

  1. Jetona dönüştürme: Metinleri kelimelere veya daha küçük alt metinlere bölün. Bu işlem, metinler ve etiketler arasındaki ilişkinin iyi bir şekilde genelleştirilmesini sağlar. Bu, veri kümesinin "kelime bilgisini" (verilerde bulunan benzersiz jeton kümesi) belirler.

  2. Vektörleştirme: Bu metinleri nitelemek için iyi bir sayısal ölçü tanımlayın.

Şimdi bu iki adımın hem n-gram vektörleri hem de dizi vektörleri için nasıl uygulanacağına ve özellik seçimi ve normalleştirme teknikleri kullanılarak vektör temsillerinin nasıl optimize edileceğine bakalım.

N-gram vektörleri [Seçenek A]

Sonraki paragraflarda, n-gram modelleri için tokenizasyon ve vektörleştirmenin nasıl yapılacağını göreceğiz. Ayrıca, özellik seçimi ve normalleştirme tekniklerini kullanarak n-gram gösterimini nasıl optimize edebileceğimizi ele alacağız.

Bir n-gram vektöründe, metin benzersiz n-gram'ların, yani bitişik n adet simgeden (genellikle, kelimeler) oluşan bir grup olarak temsil edilir. The mouse ran up the clock metnini düşünün. Burada:

  • Ünigramlar (n = 1) ['the', 'mouse', 'ran', 'up', 'clock'].
  • Bigrams kelimesi (n = 2) ['the mouse', 'mouse ran', 'ran up', 'up the', 'the clock']
  • Örnekler çoğaltılabilir.

Tokenizasyon

Kelime unigram ve büyük ram'lere jeton ayırmanın, daha az işlem süresi alırken 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şleyebileceği sayısal vektörlere dönüştürmemiz gerekir. Aşağıdaki örnekte, iki metin için oluşturulan unigram 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 genellikle aşağıdaki seçeneklerden birini kullanarak vektörize ederiz.

Tek kullanımlık kodlama: Her örnek metin, metinde bir jetonun bulunup bulunmadığını gösteren bir vektör olarak temsil edilir.

'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ı gösteren bir vektör olarak temsil edilir. "the" kelimesi metinde iki kez geçtiği için "the" unigramına karşılık gelen öğenin artık 2 olarak temsil edildiğ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şımdaki sorun, tüm belgelerde benzer sıklıkta yer alan yaygın kelimelerin (veri kümesindeki metin örneklerine özel olmayan kelimeler) cezalandırılmamasıdır. Örneğin "a" gibi kelimeler tüm metinlerde çok sık geçilir. Bu nedenle, “the” için daha yüksek bir jeton sayısının diğer anlamlı kelimelere göre çok faydası yoktur.

'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]

(bkz. Scikit-learn TfidfTransformer)

Daha pek çok vektör gösterimi vardır ancak önceki üçü, en sık kullanılanlardır.

tf-idf kodlamasının doğruluk açısından diğer ikisinden marjinal şekilde daha iyi olduğunu gözlemledik (ortalama% 0,25-15 daha yüksek). n-gramları vektörleştirmek için bu yöntemi kullanmanızı öneriyoruz. Bununla birlikte, bu komutun daha fazla bellek kapladığını (kayan nokta temsilini kullandığından) ve özellikle büyük veri kümelerinde daha fazla işlem gerektirdiğini (bazı durumlarda iki kat daha uzun sürebilir) unutmayın.

Özellik seçimi

Bir veri kümesindeki tüm metinleri kelime uni+bigram belirteçlerine dönüştürdüğümüzde elimizde on binlerce simge olabilir. Bu jetonların/özelliklerin tümü etiket tahminine katkıda bulunmaz. Dolayısıyla, örneğin veri kümesinde son derece nadiren gerçekleşenler gibi belirli jetonları bırakabiliriz. Özellik önemini de ölçebilir (her jetonun etiket tahminlerine ne kadar katkıda bulunduğu) ve yalnızca en bilgilendirici jetonları dahil edebiliriz.

Özellikleri ve karşılık gelen etiketleri alıp özellik önem puanını veren birçok istatistiksel işlev vardır. Yaygın olarak kullanılan iki işlev f_classif ve chi2'dir. Denemelerimiz, bu işlevlerin ikisinin de eşit derecede iyi performans gösterdiğini ortaya koydu.

Daha da önemlisi, doğruluğun birçok veri kümesi için 20.000 özellik civarında zirveye ulaştığını gördük (bkz. Şekil 6). Bu eşiğin üzerinde daha fazla özellik eklenmesi çok az katkıda bulunur, hatta bazen aşırı uyuma yol açar ve performansı düşürür.

Top K ve Doğruluk

Şekil 6: En İyi K özellikleri ile Doğruluk. Veri kümelerinde en iyi 20.000 özellikteki 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, öğrenme algoritmalarında gradyan azalma yakınsaklığını basitleştirir. Gördüğümüz kadarıyla veri ön işlemesi sırasında normalleştirme, metin sınıflandırma sorunları için pek değer sağlamaz. Bu adımı atlamanızı öneririz.

Aşağıdaki kod yukarıdaki adımların tümünü bir araya getirir:

  • Metin örneklerini kelime uni+bigram olarak şifreleyerek
  • tf-idf kodlamasını kullanarak vektörleştirin,
  • 2'den daha az görünen jetonları çıkararak ve özellik önemini hesaplamak için f_classif parametresini kullanarak jeton vektöründen yalnızca ilk 20.000 özelliği 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 gösterimiyle, kelime sırası ve dil bilgisi ile ilgili birçok bilgiyi atıyoruz (en iyisi, n > 1 olduğunda bazı kısmi sıralama bilgilerini koruyabiliriz). Buna kısa kelime yaklaşımı adı verilir. Bu gösterim, sıralamayı hesaba katmayan mantıksal regresyon, çok katmanlı algılayıcılar, gradyan artırma makineleri ve destek vektör makineleri gibi modellerle birlikte kullanılır.

Sıra Vektörleri [Seçenek B]

Sonraki paragraflarda, dizi modelleri için tokenizasyon ve vektörleştirmenin nasıl yapılacağını göreceğiz. Ayrıca, özellik seçimi ve normalleştirme tekniklerini kullanarak dizilimin nasıl optimize edileceğini de ele alacağız.

Bazı metin örneklerinde kelime sırası, metnin anlamı açısından kritik öneme sahiptir. Örneğin, "İşe gidip gelme rotamdan nefret ediyordum. Yeni bisikletim bu kadar değişti." mesajı yalnızca sırayla okunduğunda anlaşılabilir. CNN'ler/RNN'ler gibi modeller, bir örneklemdeki kelimelerin sırasından anlam çıkarımını yapabilir. Bu modellerde metni, düzeni koruyan bir simge dizisi olarak sunarız.

Tokenizasyon

Metin, bir karakter dizisi veya kelime dizisi olarak temsil edilebilir. Kelime düzeyinde temsil kullanmanın, karakter jetonlarına göre daha iyi performans sağladığını tespit ettik. Bu aynı zamanda sanayinin takip ettiği genel bir normdur. Karakter simgelerini kullanmak, yalnızca metinlerde çok fazla yazım hatası olduğunda mantıklıdır, bu durum normalde 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 ardından ilk metnin dönüştürüldüğü jeton dizinleri dizisi gösterilmektedir.

Texts: 'The mouse ran up the clock' and 'The mouse ran down'

Her jetona atanan dizin:

{'clock': 5, 'ran': 3, 'up': 4, 'down': 6, 'the': 1, 'mouse': 2}

NOT: "the" kelimesi en sık geçtiği için dizin değeri 1'e atanır. Burada olduğu gibi bazı kitaplıklar, bilinmeyen jetonlar için dizin 0'ı ayırır.

Jeton dizinlerinin sırası:

'The mouse ran up the clock' = [1, 2, 3, 4, 1, 5]

Jeton sıralarını vektörleştirmek için kullanılabilecek iki seçenek vardır:

Tek sıcak kodlama: Sıralar, kelime vektörleri kullanılarak n boyutlu alanda temsil edilir. Burada n = sözlük boyutu bulunur. Bu temsil, karakterler olarak jetona dönüştüğümüzde çok işe yarar ve dolayısıyla kelime dağarcığımız dardır. Kelime olarak belirtdiğimizde, sözlükte genellikle on binlerce belirteç olur. Bu da tek seferlik vektörlerin çok az ve verimsiz olmasına yol açar. Ö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şkili anlamlar vardır. Sonuç olarak, kelime simgelerini yoğun bir vektör alanında (yaklaşık birkaç yüz gerçek sayı) temsil edebiliriz. Burada, kelimeler arasındaki konum ve mesafe, anlam açısından ne kadar benzer olduklarını gösterir (bkz. Şekil 7). Bu gösterime kelime yerleştirme adı verilir.

Kelime Yerleştirme

Şekil 7: Kelime yerleştirme

Dizi modellerinin ilk katmanları genellikle böyle bir yerleştirme katmanına sahiptir. Bu katman, eğitim işlemi sırasında kelime dizini dizilerini kelime yerleştirme vektörlerine dönüştürmeyi öğrenir. Böylece, her kelime dizini, kelimenin anlamsal boşluktaki konumunu temsil eden gerçek değerlerin yoğun bir vektörüyle eşlenir (bkz. Şekil 8).

Katıştırma Katmanı

Şekil 8: Katman yerleştirme

Özellik seçimi

Verilerimizdeki tüm kelimeler etiket tahminlerine katkıda bulunmaz. Nadir ya da alakasız kelimeleri kelime dağarcığımızdan çıkararak öğrenme sürecimizi optimize edebiliriz. Aslında, en sık 20.000 özelliği kullanmanın genellikle yeterli olduğunu gözlemliyoruz. Bu, n-gram modelleri için de geçerlidir (bkz. Şekil 6).

Yukarıdaki tüm adımları dizi vektörlendirmede bir araya getirelim. Aşağıdaki kod, şu görevleri yerine getirir:

  • Metinleri kelimelere dönüştürerek
  • En iyi 20.000 jetonu kullanarak sözlük oluşturur
  • Jetonları dizi vektörlerine dönüştürür
  • Dizileri sabit bir dizi uzunluğuna doldurur
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örleştirme

Örnek metin verilerini sayısal vektörlere nasıl dönüştüreceğimizi gördük. Etiketlere de benzer bir süreç 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 etmek için tek sıcak vektörler kullanır (etiketler arasında yanlış bir ilişki çıkarmayı önlemek amacıyla). Bu gösterim, kayıp işlevine ve nöral ağımızda kullandığımız son katman aktivasyon işlevine bağlıdır. Bir sonraki bölümde bu konu hakkında daha fazla bilgi edineceğiz.