TensorFlow ile NLP — Giriş 1

Furkan Gulsen
10 min readAug 28, 2021

Bu öğrenim serisinde TensorFlow, derin öğrenme (deep learning) ve makine öğrenmesi (machine learning) ile ilgili detaylı anlatımlar ve projeler yer almaktadır. Bu sayfanın daha fazla kişiye ulaşması için sayfayı yıldızlarsanız çok seviniriz.

İçerik

Doğal dil işlemenin (NLP) temel amacı, doğal dilden bilgi elde etmektir. Doğal dil geniş bir terimdir ancak aşağıdakilerden herhangi birini kapsadığını düşünebilirsiniz:

  • Metin (bir e-postada, blog gönderisinde, kitapta, Tweette bulunanlar gibi)
  • Konuşma (bir doktorla yaptığınız konuşma, telefonuna verdiğiniz sesli komutlar)

Metin ve konuşma şemsiyesi altında yapmak isteyebileceğiniz birçok farklı şey var. Bir e-posta uygulaması oluşturuyorsanız, spam olup olmadıklarını (sınıflandırma) görmek için gelen e-postaları taramak isteyebilirsiniz.

Müşteri geri bildirim şikayetlerini analiz etmeye çalışıyorsanız, bunların işletmenizin hangi bölümü için olduğunu keşfetmek isteyebilirsiniz.

🔑 Not: Bu tür verilerin her ikisine de genellikle diziler denir (bir cümle, bir sözcük dizisidir). Bu nedenle, NLP problemlerinde karşılaşacağınız yaygın bir terime seq2seq denir, başka bir deyişle, bir dizideki bilgiyi başka bir dizi oluşturmak için bulmaktır (örneğin, bir konuşma komutunu metin tabanlı adımlar dizisine dönüştürmek).

TensorFlow’da NLP ile pratik yapmak için daha önce kullandığımız adımları bu sefer metin verileriyle uygulayacağız:

Metin -> sayılara dönüştürün -> bir model oluşturun -> modeli kalıpları bulmak için eğitin -> kalıpları kullanın (tahminlerde bulunun)

İçerik:

  • Bir metin veri kümesini indirme
  • Metin verilerini görselleştirme
  • Tokenization kullanarak metni sayılara dönüştürme
  • Belirtilmiş metnimizi bir gömmeye dönüştürmek
  • Bir metin veri kümesini modelleme
    Temel ile başlama (TF-IDF)
    Birkaç derin öğrenme metin modeli oluşturma
    LSTM, GRU, Conv1D, Transfer Learning
  • Her bir modelimizin performansını karşılaştırma
  • Modellerimizi bir toplulukta birleştirmek
  • Eğitilmiş bir modeli kaydetme ve yükleme
  • En yanlış tahminleri bulunma

Eğitime başlamadan önce gerekli fonksiyonları oluşturalım.

Veri Kümesini İndirme

Bir metin veri kümesi indirerek başlayalım. Real or Not’u kullanacağız. Doğal afetler hakkında metin tabanlı Tweetler içeren Kaggle sitesinde bulunan veri seti.

Gerçek Tweetler aslında felaketlerle ilgilidir, örneğin:

Jetstar and Virgin forced to cancel Bali flights again because of ash from Mount Raung volcano

Gerçek Olmayan Tweetler, felaketlerle ilgili olmayan Tweetlerdir (her konuda olabilir), örneğin:

'Education is the most powerful weapon which you can use to change the world.' Nelson #Mandela #quote
--2021-08-22 07:09:20--  https://storage.googleapis.com/ztm_tf_course/nlp_getting_started.zip
Resolving storage.googleapis.com (storage.googleapis.com)... 74.125.204.128, 64.233.188.128, 64.233.189.128, ...
Connecting to storage.googleapis.com (storage.googleapis.com)|74.125.204.128|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 607343 (593K) [application/zip]
Saving to: ‘nlp_getting_started.zip’
nlp_getting_started 100%[===================>] 593.11K --.-KB/s in 0.007s2021-08-22 07:09:20 (87.6 MB/s) - ‘nlp_getting_started.zip’ saved [607343/607343]

nlp_getting_started.zip dosyasında 3 farklı csv belgesi vardır: Bunlar:

  • sample_submission.csv Modelinizin tahminlerini içeren Kaggle yarışmasına göndereceğiniz dosyanın bir örneği.
  • train.csv Gerçek ve gerçek olmayan felaket Tweetlerinin eğitim örnekleri.
  • test.csv Gerçek ve gerçek olmayan felaket Tweet örneklerinin test edilmesi için örnekler.

Bir Metin Veri Kümesini Görselleştirme

Çalışmak için yeni bir veri kümesi edindikten sonra, önce ne yapmalısınız? Keşfetmek mi? Kontrol etmek mi? Doğrulak mı? Hepsi doğru :)

Sloganı hatırlayın: görselleştirin, görselleştirin, görselleştirin.

Şu anda metin veri örneklerimiz .csv dosyaları biçimindedir. Onları görsel hale getirmenin kolay bir yolu için onları pandas DataFrame'e çevirelim.

📖 Okuma: Birçok farklı formatta metin veri setleriyle karşılaşabilirsiniz. CSV dosyalarının (üzerinde çalıştığımız şey) yanı sıra, muhtemelen .txt dosyaları ve .json dosyalarıyla da karşılaşacaksınız. Bu tür dosyalarla çalışmak için RealPython'un aşağıdaki iki makalesini okumanızı tavsiye ederim:

İndirdiğimiz eğitim verileri muhtemelen zaten karıştırılmıştır. Ama emin olmak için tekrar karıştıralım.

Eğitim verilerinin nasıl bir "target" sütunu olduğuna dikkat edin.

"target" sütununun değerini tahmin etmek için eğitim veri kümesinin "text" sütununda kalıpları (örneğin farklı kelime kombinasyonları) bulmak için kod yazacağız. Test veri kümesinin bir "target" sütunu yok.

Inputs (text column) -> Machine Learning Algorithm -> Outputs (target column)

Her hedeften kaç tane örneğimiz olduğunu kontrol edelim.

0    4342
1 3271
Name: target, dtype: int64

İki sınıf değeri olduğundan, binary_classification problemiyle uğraşacağız gibi duruyor. Veri setimizi incelediğimizde dengeli bir dağılım görüyoruz. %60 olumsuz, %40 olumlu sınıf içeriyor.

  • 1: gerçek bir felaket twet’i
  • 0: gerçek olmayan bir felaket twet’i

Peki elimizde ki toplam örnek sayısı kaç?

Total training samples: 7613
Total test samples: 3263
Total samples: 10876

Pekala, yeterli miktarda eğitim ve test verisine sahibiz gibi görünüyor. Görselleştirme zamanı, hadi rastgele metin örneklerini görselleştirmek için bazı kodlar yazalım.

🤔 Soru: Rastgele örnekleri neden görselleştirelim? Örnekleri sırayla görselleştirebilirsiniz, ancak bu yalnızca belirli bir veri alt kümesini görmenize neden olabilir. Üzerinde çalıştığınız farklı veri türleri hakkında bir fikir edinmek için önemli miktarda (100+) rastgele örneği görselleştirmek daha iyidir. Makine öğreniminde rastgeleliğin gücünü asla hafife almayın.

Target: 0 (not real disaster)
Text:
@QuotesTTG Save the panicking for when you get to Helios. ;)
---Target: 0 (not real disaster)
Text:
Patience Jonathan On The Move To Hijack APC In BayelsaåÊState http://t.co/Vh8QtbyPZt
---Target: 0 (not real disaster)
Text:
Ali you flew planes and ran into burning buildings why are you making soup for that man child?! #BooRadleyVanCullen
---Target: 0 (not real disaster)
Text:
@ACOUSTICMALOLEY no he was blazing it
---Target: 1 (real disaster)
Text:
National Briefing | West: California: Spring Oil Spill Estimate Grows: Documents released on Wednesday d... http://t.co/hTxAi05y7B (NYT)
---

Verileri Eğitim ve Doğrulama Kümelerine Ayırın

Test setinde etiket olmadığından ve eğitilmiş modellerimizi değerlendirmek için bir yola ihtiyacımız olduğundan, eğitim verilerinden bazılarını ayıracağız ve bir doğrulama seti oluşturacağız.

Modelimiz eğitildiğinde (Tweet örneklerindeki kalıpları denediğinde), yalnızca eğitim kümesindeki verileri görür ve doğrulama kümesini kullanarak görünmeyen veriler üzerinde nasıl performans gösterdiğini görebiliriz.

Pandas Series veri türlerinden bölmelerimizi daha sonra kullanım kolaylığı için string listelerine (metin için) ve ints listelerine (etiketler için) dönüştüreceğiz.

Eğitim veri setimizi bölmek ve bir doğrulama veri seti oluşturmak için Scikit-Learn’in train_test_split() yöntemini kullanacağız ve eğitim örneklerinin %10'unu doğrulama setine ayıracağız.

(6851, 6851, 762, 762)
(array(['@mogacola @zamtriossu i screamed after hitting tweet',
'Imagine getting flattened by Kurt Zouma',
'@Gurmeetramrahim #MSGDoing111WelfareWorks Green S welfare force ke appx 65000 members har time disaster victim ki help ke liye tyar hai....',
"@shakjn @C7 @Magnums im shaking in fear he's gonna hack the planet",
'Somehow find you and I collide http://t.co/Ee8RpOahPk',
'@EvaHanderek @MarleyKnysh great times until the bus driver held us hostage in the mall parking lot lmfao',
'destroy the free fandom honestly',
'Weapons stolen from National Guard Armory in New Albany still missing #Gunsense http://t.co/lKNU8902JE',
'@wfaaweather Pete when will the heat wave pass? Is it really going to be mid month? Frisco Boy Scouts have a canoe trip in Okla.',
'Patient-reported outcomes in long-term survivors of metastatic colorectal cancer - British Journal of Surgery http://t.co/5Yl4DC1Tqt'],
dtype=object), array([0, 0, 1, 0, 0, 1, 1, 0, 1, 1]))

Metni Sayılara dönüştürme

Tweetler ve etiketler içeren bir eğitim setimiz ve bir doğrulama setimiz var. Etiketlerimiz sayısal (0 ve 1) biçimindedir, ancak Tweetlerimiz dize biçimindedir.

🤔 Soru: Metin verilerimizle bir makine öğrenmesi algoritması kullanabilmemiz için sizce ne yapmamız gerekiyor?

“Sayıya çevir” gibi bir cevap verdiyseniz, haklısınız. Bir makine öğrenimi algoritması, girdilerinin sayısal biçimde olmasını gerektirir.

NLP’de metni sayılara dönüştürmek için iki ana kavram vardır:

  • Tokenization
    Kelimeden veya karakterden veya alt kelimeden sayısal bir değere düz bir eşleme. Üç ana tokenizasyon seviyesi vardır:
  1. Kelime düzeyinde simgeleştirmeyi “I love TensorFlow” cümlesiyle kullanmak, “I”nin 0, “love” 1 ve “TensorFlow”un 2 olmasına neden olabilir. Bu durumda, bir dizideki her sözcük tek bir simge olarak kabul edilir.
  2. A-Z harflerini 1–26 değerlerine dönüştürmek gibi karakter düzeyinde simgeleştirme. Bu durumda, bir dizideki her karakter tek bir simge olarak kabul edilir.
  3. Alt sözcük belirleme, sözcük düzeyinde ve karakter düzeyinde simgeleştirme arasındadır. Tek tek kelimeleri daha küçük parçalara ayırmayı ve ardından bu daha küçük parçaları sayılara dönüştürmeyi içerir. Örneğin, “my favorite food is pineapple pizza”, “my, favor, rite, fo, oo, od, is, pin, ine, app, le, piz, za” olabilir. Bunu yaptıktan sonra, bu alt kelimeler daha sonra sayısal bir değere eşlenir. Bu durumda, her kelime birden fazla belirteç olarak kabul edilebilir.
  • Embedding
    Embed, öğrenilebilen doğal dilin bir temsilidir. Temsil, bir özellik vektörü şeklinde gelir. Örneğin, “dance” kelimesi 5 boyutlu vektör [-0.8547, 0.4559, -0.3332, 0.9877, 0.1112] ile temsil edilebilir. Burada not etmek önemlidir, özellik vektörünün boyutu ayarlanabilir. Embed kullanmanın iki yolu vardır:
  1. Kendi embed işleminizi oluşturun — Metniniz sayılara dönüştürüldüğünde (embed için gereklidir), onları bir embed katmanına (tf.keras.layers.Embedding gibi) koyabilirsiniz ve model eğitimi sırasında bir embed gösterimi öğrenilecektir.
  2. Önceden öğrenilmiş bir yerleştirmeyi yeniden kullanın — Çevrimiçi olarak önceden eğitilmiş birçok yerleştirme mevcuttur. Bu önceden eğitilmiş yerleştirmeler genellikle büyük metin kütlelerinde (tüm Wikipedia’da olduğu gibi) öğrenilmiştir ve bu nedenle doğal dilin iyi bir temel temsiline sahiptir. Modelinizi başlatmak ve kendi özel görevinize göre ince ayar yapmak için önceden eğitilmiş bir yerleştirme kullanabilirsiniz.

Soru: Hangi düzeyde belirteç kullanmalıyım? Hangi embedi seçmeliyim?

Sorununuza bağlı. Karakter düzeyinde tokenization/embed ve sözcük düzeyinde word-level-tokenization/embed deneyebilir ve hangisinin en iyi performansı gösterdiğini görebilirsiniz. Bunları istiflemeyi bile deneyebilirsiniz (örneğin, embed katmanlarınızın çıktılarını tf.keras.layers.concatenate kullanarak birleştirmek).

Önceden eğitilmiş sözcük yerleştirmeleri arıyorsanız, Word2vec yerleştirmeleri, GloVe yerleştirmeleri ve TensorFlow Hub’da bulunan seçeneklerin çoğu, başlamak için harika yerlerdir.

🔑 Not: Önceden eğitilmiş bir bilgisayarlı görü modelini aramaya benzer şekilde, probleminiz için kullanmak üzere önceden eğitilmiş sözcük yerleştirmelerini arayabilirsiniz. “TensorFlow’da önceden eğitilmiş kelime yerleştirmelerini kullan” gibi bir şey aramayı deneyin.

Metin Vektörleştirme

İlk önce tokenizasyon (kelimelerimizi sayılarla eşleştirme) alıştırması yapacağız. Sözlerimizi simgeleştirmek için, yararlı önişleme katmanı tf.keras.layers.experimental.preprocessing.TextVectorization kullanacağız.

TextVectorization katmanı aşağıdaki parametreleri alır:

  • max_tokens
    Kelime dağarcığınızdaki maksimum kelime sayısı (örneğin, metninizdeki 20000 veya benzersiz kelime sayısı), OOV (kelime dışı) belirteçleri için bir değer içerir.
  • standardize
    Metni standartlaştırma yöntemi. Varsayılan, metni alçaltan ve tüm noktalama işaretlerini kaldıran “lower_and_strip_punctuation"dır.
  • split
    Metin nasıl bölünür, varsayılan olarak boşluklara bölünen “split”tir.
  • ngrams
    Belirteç başına kaç sözcük içerecek, örneğin, ngrams=2 belirteçleri 2'lik sürekli dizilere böler.
  • output_mode
    Belirteçler nasıl çıkarılır, “int” (tamsayı eşleme), “binary” (tek-sıcak kodlama), “count” veya “tf-idf” olabilir.
  • output_sequence_length
    Çıktı için belirtilmiş dizinin uzunluğu. Örneğin, çıktı_dizi_uzunluk=150 ise, tüm belirteçli diziler 150 belirteç uzunluğunda olacaktır.
  • pad_to_max_tokens
    True (varsayılan) ise, sözlükteki benzersiz jeton sayısı max_tokens’den az olsa bile çıktı özelliği ekseni max_tokens olarak doldurulur.

Bir TextVectorization nesnesini varsayılan ayarlarla başlattık, ancak bunu kendi kullanım durumumuz için biraz özelleştirelim. Özellikle max_tokens ve output_sequence_length için değerler belirleyelim.

max_tokens (kelimelerdeki kelime sayısı) için 10.000'in katları (10.000, 20.000, 30.000) veya metninizdeki tam benzersiz kelime sayısı (ör. 32.179) ortak değerlerdir. Kullanım durumumuz için 10.000 kullanacağız.

Ve output_sequence_length için, eğitim setindeki Tweet başına ortalama jeton sayısını kullanacağız. Ama önce onu bulmamız gerekecek.

15

Şimdi özel parametrelerimizi kullanarak başka bir TextVectorization nesnesi oluşturalım.

Güzel! TextVectorization örneğimizi text_vectorizer verilerimizle eşleştirmek için, eğitim metnimizi iletirken adapt() yöntemini çağırabiliriz.

Eğitim verileri eşlendi! Text_vectorizer’ımızı özel bir cümle üzerinde deneyelim (eğitim verilerinde görebileceğinize benzer bir cümle).

<tf.Tensor: shape=(1, 15), dtype=int64, numpy=
array([[264, 3, 232, 4, 13, 698, 0, 0, 0, 0, 0, 0, 0, 0, 0]])>

Harika, görünüşe göre metnimizi sayılara dönüştürmenin bir yolu var (bu durumda, kelime düzeyinde simgeleştirme). Döndürülen tensörün sonundaki 0'lara dikkat edin, bunun nedeni output_sequence_length=15 olarak ayarlamış olmamızdır, yani text_vectorizer’a ilettiğimiz dizinin boyutu ne olursa olsun, her zaman 15 uzunluğunda bir dizi döndürür.

Birkaç rastgele cümle üzerinde text_vectorizer’ımızı denemeye ne dersiniz?

Original text:
Quirk Injury Law's News is out! http://t.co/HxVIhDuShP Stories via @dantmatrafajlo
Vectorized version:<tf.Tensor: shape=(1, 15), dtype=int64, numpy=
array([[9416, 345, 2068, 58, 9, 36, 1, 1172, 49, 1, 0, 0, 0, 0, 0]])>

İyi görünüyor! Son olarak, get_vocabulary() yöntemini kullanarak sözlüğümüzdeki benzersiz belirteçleri kontrol edebiliriz.

Number of words in vocab: 10000
Top 5 most common words: ['', '[UNK]', 'the', 'a', 'in']
Bottom 5 least common words: ['pages', 'paeds', 'pads', 'padres', 'paddytomlinson1']

Gömme Katmanı Kullanarak Gömme Oluşturma Metnimizi sayılarla eşleştirmenin bir yolu var. Bir adım daha ileri gidip bu sayıları bir gömme haline getirmeye ne dersiniz?

Bir gömmenin güçlü yanı, eğitim sırasında öğrenilebilmesidir. Bu, yalnızca statik olmaktan ziyade (örneğin 1 = I, 2 = love, 3 = TensorFlow), bir kelimenin sayısal gösteriminin, bir model veri örneklerinden geçerken geliştirilebileceği anlamına gelir.

tf.keras.layers.Embedding katmanını kullanarak bir kelimenin gömülmesinin nasıl göründüğünü görebiliriz.

Burada ilgilendiğimiz ana parametreler şunlardır:

  • input_dim
    Sözlüğün boyutu
  • output_dim
    Çıktı gömme vektörünün boyutu, örneğin 100 değeri, her kelime için 100 boyutunda bir özellik vektörü verir.
  • embeddings_initializer
    Gömme matrisi nasıl başlatılır, varsayılan değer, tek tip dağılımla gömme matrisini rastgele başlatan “tek biçimli”dir. Bu, önceden öğrenilmiş yerleştirmeleri kullanmak için değiştirilebilir.
  • input_length
    Gömme katmanına geçirilen dizilerin uzunluğu.

Bunları bilerek bir gömme katmanı yapalım.

<keras.layers.embeddings.Embedding at 0x7f5bf062d050>

Mükemmel, TensoFlow katmanının nasıl gömüldüğünü fark ettiniz mi? Bu önemlidir çünkü onu bir modelin parçası olarak kullanabiliriz, yani parametreleri (kelime temsilleri) model öğrendikçe güncellenebilir ve geliştirilebilir.

Örnek bir cümle üzerinde deneyelim mi?

<tf.Tensor: shape=(1, 15, 128), dtype=float32, numpy=
array([[[-2.67661568e-02, 3.09980996e-02, 9.19399410e-03, ...,
-1.61751285e-02, 2.21572071e-03, -7.00148195e-03],
[-4.41038385e-02, -4.84013557e-03, 2.72500776e-02, ...,
-1.73950568e-02, -2.18516830e-02, -9.85272974e-03],
[-1.61503777e-02, -3.82886529e-02, 2.60415785e-02, ...,
-3.55404019e-02, 8.02986324e-05, -7.18279928e-03],
...,
[-3.36676128e-02, -6.04265928e-03, -5.23805618e-04, ...,
-4.41053882e-02, 1.10260025e-02, 1.55389644e-02],
[-3.36676128e-02, -6.04265928e-03, -5.23805618e-04, ...,
-4.41053882e-02, 1.10260025e-02, 1.55389644e-02],
[-3.36676128e-02, -6.04265928e-03, -5.23805618e-04, ...,
-4.41053882e-02, 1.10260025e-02, 1.55389644e-02]]],
dtype=float32)>

Cümledeki her belirteç, 128 uzunlukta bir özellik vektörüne dönüştürülür.

<tf.Tensor: shape=(128,), dtype=float32, numpy=
array([-2.6766157e-02, 3.0998100e-02, 9.1939941e-03, 1.1298049e-02, 1.9281853e-02,
...
...
...
1.0297049e-02, 3.5892416e-02, -2.7472233e-02, -2.4868632e-02, -1.6175129e-02, 2.2157207e-03, -7.0014820e-03], dtype=float32)>

🔑 Not: Önceki iki kavram (tokenization ve embedding) birçok NLP görevinin temelidir. Bu nedenle, herhangi bir şeyden emin değilseniz, anlayışınıza daha fazla yardımcı olmak için kendi deneylerinizi araştırdığınızdan ve yürüttüğünüzden emin olun.

… devamı TensorFlow ile NLP — Giriş 2 yazımda.

--

--

Furkan Gulsen
Furkan Gulsen

Written by Furkan Gulsen

🧑‍💻 As a software engineer, I write about software, artificial intelligence, productivity, and everything I know

No responses yet