Yazar: Rachael Tatman
Çeviri: Liang Fuqi
Bu makalenin uzunluğu 1600 kelime , Okumanız tavsiye edilir 4 dakika
Tokenizasyon, doğal dil işlemede yaygın bir görevdir. Bu makale, metindeki tek bir işaretin (tek kelime) sıklığını saymak için R'yi nasıl kullanacağınızı ve bu işlemi yeniden kullanılabilir bir işlev olarak nasıl yazacağınızı öğretir.
Doğal dil işlemede yaygın bir görev, belirteçleştirmedir. Genel olarak konuşursak, İngilizce gibi diller için, simge haline getirme tek bir sözcükken belirteçleştirme, bir makalenin veya bir dizi makalenin tek tek kelimelere bölünmesidir. Bu etiketler daha sonra gramer analizi gibi diğer analiz türleri veya görevler için girdi olarak kullanılacaktır (kelimeler arasındaki dilbilgisi ilişkisini otomatik olarak işaretler).
Bu eğitimde aşağıdakilerin nasıl yapılacağını öğreneceksiniz:
Metni R'ye oku
Birkaç satır metin seçin
Metni belirtmek için düzenli metin paketi kullanın
İşaretçilerin sıklığını hesaplayın (her bir işaretleyicinin veri kümesinde ne sıklıkta göründüğünü)
Yukarıdakileri yapmak için yeniden kullanılabilir işlevler yazarak işi daha verimli hale getirin
Bu eğitimde, iki dilli çocukların diyalog transkripsiyonlarından oluşan bir külliyat kullanacağız. Daha fazla bilgi bulabilir ve buradan indirebilirsiniz (https://www.kaggle.com/rtatman/corpus-of-bilingual-childrens-speech).
Bu dosyalar CLAN ( kullanılarak oluşturulur, bu nedenle format biraz tuhaftır. Ancak az miktarda metin işleme ile bunları düz metin dosyaları gibi kullanabiliriz.
Şimdi, çocukların İngilizceye maruz kaldıkları zaman ile konuşma dilini ne sıklıkla kullandıkları (örneğin, "um" ve "er") arasındaki ilişkiyi bulalım.
İhtiyacımız olan kütüphanelerde # yük
library (tidyverse) #keepin 'things düzenli
library (tidytext) # düzenli metin analizi için paket (Julia Silge'in harika kitabına bakın!)
kitaplık (tutkal) # dizeleri yapıştırmak için
library (data.table) #for rbindlist, daha hızlı bir rbind sürümü
# şimdi bazı verileri okuyalım ve bir tibble (özel bir tür düzenli veri çerçevesi)
file_info < -as_data_frame (read.csv ("../ input / guide_to_files.csv"))
kafa (file_info)
Bu harika görünüyor. Şimdi bu csv dosyasından dosya adını alalım ve dosyalardan birini R'ye okuyalım.
# dosyanın yolunu ve bilgi dosyasındaki 1. dosya adını birbirine yapıştırın
dosya adı < -glue ("../ input /", as.character (dosya_bilgisi $ dosya_adı), sep = "")
# arkadaki gizli boşluklardan kurtulun
dosya adı < -trimws (dosyaAdı)
# yeni dosyada oku
fileText < -paste (readLines (fileName))
# ve bir göz atın!
kafa (fileText)
# yapı nedir?
str (fileText)
Oh, ne dağınıklık! Metni bir vektör biçiminde okuruz ve her satır ayrı bir öğe olarak ele alınır; bu, ilgilendiğimiz sözcük sayısı için ideal bir işleme biçimi değildir. Küçük bir numara kullanabiliriz, çünkü sadece çocukların diyaloğuyla ilgileniyoruz ve deneycinin sözleri alakasızdır, bu yüzden kelimeleri yalnızca "* CHI: Çocuk Konuşuyor" ile başlayabiliriz. Dizenin bu kısmını elde etmek için aşağıdaki normal ifadeyi kullanıyoruz:
# "grep", vektörde tam olarak * CHI: dizesini içeren öğeleri bulur.
# (Çift eğik çizgiyi kullanmanız gerekir çünkü aslında karakteri eşleştirmek istiyorum
# * ve genellikle bu "herhangi bir karakterle eşleş" anlamına gelir). Daha sonra bu dizinleri
# "fileText" vektörü.
ChildsSpeech < -as_data_frame (fileText)
kafa (childsSpeech)
Tamam, şimdi çocukların söylediklerini aldık. Ancak bu, yanıtlamayı umduğumuz sorudan uzaktır: "Çocuklar kaç kez" hım "dedi.
Verilerimizi daha düzenli hale getirelim. Tidy verileri aşağıdaki üç özelliğe sahiptir (https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html):
Bir değişken bir sütunu kaplar.
Bir gözlem, bir satırda yer alır.
Tek tip gözlemler bir tablo oluşturur.
Neyse ki sıfırdan başlamamız gerekmiyor, tidytext paketini kullanabiliriz!
# "alt" öğesinin "değer" sütunundaki kelimeleri almak için unnest_tokens işlevini kullanın
childsTokens < -childsSpeech% > % unnest_tokens (kelime, değer)
kafa (childsTokens)
Ah, çok daha iyi! Unnest_tokens işlevinin ön işleme çalışmalarının çoğunu yaptığını fark edeceksiniz. Noktalama işaretleri işlendi ve tüm harfler küçük harflerle yazılmıştır. Belki bunu her seferinde yapmanız gerekmiyor, ama bu sefer "ağaçlar" ile "Ağaçlar" arasında ayrım yapmak istemiyoruz.
Şimdi kelime frekansına veya kelimenin ne kadar yaygın olduğuna bakalım.
# sıralanmış kelime frekanslarının sadece başına bakın
childsTokens% > % sayım (kelime, sıralama = T)% > % kafa
Hemen bir problem keşfettik, aslında en sık kullanılan kelime çocukların söylediği kelimelerden değil, "chi" notundan geliyordu, yani bu cümlenin çocuklar tarafından söylendiği anlamına geliyordu. Bu nedenle, onu kaldırmak için dplyr paketinin anti_join işlevini kullanmalıyız.
# anti_join, her iki veri çerçevesindeki tüm satırları kaldırır, böylece bir data_frame oluştururum
"word" sütununda "chi" içeren 1 satırın # sayısı.
sıralanmışTokens < -childsSpeech% > % unnest_tokens (kelime, değer)% > % anti_join (data_frame (word = "chi"))% > %
say (kelime, sıralama = T)
kafa (sıralanmışTokens)
harika! Bu tam olarak istediğimiz şey. Ama sadece dosyalardan birinin sonucu. Farklı dosyaları karşılaştırmak istiyoruz. Şimdi onu düzene sokalım (bu, bu işlemi daha sonra kopyalamayı kolaylaştıracaktır). Artık bir fonksiyonumuz var, onu çalıştıralım ve çalışıp çalışmadığını görelim.
# Bir dosyayı alan ve az önce yaptığımız şeyi tam olarak kopyalayan bir işlev yapalım
fileToTokens < -function (dosya adı) {
# veride oku
fileText < -paste (readLines (dosya adı))
# çocuğun konuşmasını alın
ChildsSpeech < -as_data_frame (fileText)
Sıklığa göre sıralanmış # simge
sıralanmışTokens < -childsSpeech% > % unnest_tokens (kelime, değer)% > %
anti_join (data_frame (kelime = "chi"))% > %
say (kelime, sıralama = T)
# ve bunu kullanıcıya geri ver
dönüş (sıralanmışTokens)
}
İşlev yazılır, onu dosyalardan birini işlemek için kullanırız.
# eğitimin başında atadığımız bu fileName değişkenine hala sahibiz
dosya adı
# öyleyse onu kullanalım ...
head (fileToTokens (dosyaAdı))
# ve bunu adım adım analiz ettiğimiz verilerle karşılaştırın
kafa (sıralanmışTokens)
Peki! Bu fonksiyonun çıktısı, önceki analizimizin sonucuyla tamamen aynı! Şimdi onu tüm dosya setini işlemek için kullanabiliriz.
Bir şey daha, hangi çocuğun hangi kelimeleri söylediğini belirtmemiz gerekiyor. Bu durumda çıktıya bir sütun eklemeliyiz.
# Dosya adlarını temizlemek için başka bir işlev yazalım. (Önleyebilirsek
# muhtemelen yapmamız gereken aynı kodu yazma / kopyalama yapıştırma)
prepFileName < -fonksiyon adı){
# dosya adını al
dosya adı < -glue ("../ input /", as.character (ad), sep = "")
# arkadaki gizli boşluklardan kurtulun
dosya adı < -trimws (dosyaAdı)
# dosya adımızı iade etmeyi unutamam!
return (dosyaAdı)
}
# sonuçlarımızı depolamak için boş bir veri kümesi yapın
tokenFreqByChild < -BOŞ
# çünkü bu çok büyük bir veri kümesi değil, for döngüsü kullanmamız iyi olur
# (bunlar gerçekten büyük veri kümeleri için yavaş olabilir)
for (file_info $ dosya_adı içindeki isim) {
# belirli bir çocuğun adını alın
çocuk < -name
# Az önce yaptığımız özel işlevleri kullanın!
jetonlar < -prepFileName (alt)% > % fileToTokens ()
# ve mevcut çocuğun adını ekleyin
tokensCurrentChild < -cbind (belirteçler, alt öğe)
# mevcut çocuğun verilerini geri kalanına ekle
# Burada rbindlist kullanıyorum çünkü çok daha verimli (hafıza açısından
# kullanım) rbind'den
tokenFreqByChild < -rbindlist (list (tokensCurrentChild, tokenFreqByChild))
}
# Ortaya çıkan veri çerçevemizin makul göründüğünden emin olun
özet (tokenFreqByChild)
head (tokenFreqByChild)
Artık tüm veriler aynı tablodadır. Hayal edelim!
# Her seferinde kaç kelimenin kullanıldığını çizelim
ggplot (tokenFreqByChild, aes (n)) + geom_histogram ()
Bu tablo bize kelimelerin çoğunun yalnızca bir kez kullanıldığını ve sıklık ne kadar yüksek olursa o kadar az kelime kullanıldığını söylüyor. Bu, Zipf yasası olarak adlandırılan bir insan dili yasasıdır (https://nlp.stanford.edu/IR-book/html/htmledition/zipfs-law-modeling-the-distribution-of-terms-1.html) .
Asıl soruya dönelim: Çocukların "um" kelimesini kullanma sıklığı ile çocukların dili öğrenme süreleri arasında bir ilişki var mı?
# ilk olarak, veri çerçevemizde yalnızca "um" kelimesinin olduğu satırlara bakalım
ums < -tokenFreqByChild
# şimdi ums veri çerçevemizi bilgi dosyamızla birleştirelim
umsWithInfo < -merge (ums, file_info, by.y = "dosya_adı", by.x = "çocuk")
kafa (umsWithInfo)
harika görünüyor. Bakalım çocukların "um" kullanma sayısı, dili öğrendikleri ay sayısıyla ilişkili mi?
# önemli bir korelasyon olup olmadığına bakın
cor.test (umsWithInfo $ n, umsWithInfo $ months_of_english)
# ve konuyu kontrol et
ggplot (umsWithInfo, aes (x = n, y = month_of_english)) + geom_point () +
geom_smooth (yöntem = "lm")
Kesinlikle hayır". Bu külliyattaki materyaller, çocukların "um" deme sayısının İngilizceye maruz kaldıkları sürenin uzunluğuyla hiçbir ilgisi olmadığını göstermektedir.
Analiz sürecini daha eksiksiz hale getirebilecek bazı şeyler de var:
Göreli sıklığa, yani sıklığından ziyade çocuklar tarafından konuşulan kelimelerdeki "um" oranına odaklanın
Tek bir "um" yerine tüm modal parçacıklara odaklanın
Anlaşılması zor kelimelere dikkat edin ("xxx")
Sizlere eski bir ders kitabı gibi bir soru bırakıyorum okuyucular. Yazının başında söz verdiğim her şeyi öğrettim ve bunu yapabilirsiniz:
Metni R'ye oku
Birkaç satırlık metin seçin
Metni belirtmek için derli toplu metin paketi kullanın
İşaretçilerin sıklığını hesaplayın (her bir işaretçinin veri kümesinde ne sıklıkta göründüğünü)
Yukarıdakileri yapmak için yeniden kullanılabilir işlevler yazarak işi daha verimli hale getirin
Simgeleştirmenin temellerini öğrendiğinize göre, becerilerinizi geliştirmek için kullanabileceğiniz diğer bazı yapılar şunlardır:
Ironic Corpus (https://www.kaggle.com/rtatman/ironic-corpus)
Stanford Natural Language Inference Corpus (https://www.kaggle.com/sohier/stanford-natural-language-inference-corpus)
İsimli Varlık Tanıma için Açıklamalı Kitap (https://www.kaggle.com/abhinavwalia95/entity-annotated-corpus)
Sahte E-posta Corpus (https://www.kaggle.com/rtatman/fraudulent-email-corpus)
iyi şanslar! Mutlu belirteçler!
Orjinal başlık:
Veri Bilimi 101 (NLP'ye başlarken): Tokenizasyon eğitimi
Orijinal bağlantı: