Natural Language Processing

Kategori: Machine Learning , 20 Aralık 2019 , JanFranco


Natural Language Processing yani Doğal Dil İşleme alanında metin bazlı veriler ile çalışacağız. Bu prensipte genel olarak preprocessing ve feature extraction kısımlarına bakacağız. Metin, resim bazlı verilerde ve benzerlerinde genellikle şu adımlar izlenir: Preprocessing yani ön işleme, feature extraction yani özellik çıkarımı ve sonrasında makine öğrenmesi. Makine öğrenmesi algoritmalarını daha önce gördük farklı bir şey yapmayacağız. Dediğim gibi bu tarz verilerde önemli olan kısım, işin yoğun olduğu kısım ön işleme ve feature extraction. Python ile örneğe geçmeden önce belirtmek isterim, bu yazıyı makine öğrenmesi için hazırladım. NLP için ayrı bir bölüm açıp, NLP hakkında daha detaylı yazılar paylaşacağım. Kütüphaneleri ve verileri alalım:


import re
import nltk
import pandas as pd
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer

nltk.download('stopwords')
df = pd.read_csv('Restaurant_Reviews.csv')
print(df)

>>

                                                Review  Liked
0                             Wow... Loved this place.      1
1                                   Crust is not good.      0
2            Not tasty and the texture was just nasty.      0
3    Stopped by during the late May bank holiday of...      1
4    The selection on the menu was great and so wer...      1
5       Now I am getting angry and I want my damn pho.      0
6                Honeslty it didn't taste THAT fresh.)      0
7    The potatoes were like rubber and you could te...      0
8                            The fries were great too.      1
9                                       A great touch.      1
10                            Service was very prompt.      1
11                                  Would not go back.      0
12   The cashier had no care what so ever on what I...      0
13   I tried the Cape Cod ravoli, chicken, with cra...      1
14   I was disgusted because I was pretty sure that...      0
15   I was shocked because no signs indicate cash o...      0
16                                 Highly recommended.      1
17              Waitress was a little slow in service.      0
18   This place is not worth your time, let alone V...      0
19                                did not like at all.      0
20                                 The Burrittos Blah!      0
21                                  The food, amazing.      1
22                               Service is also cute.      1
23   I could care less... The interior is just beau...      1
24                                  So they performed.      1
25   That's right....the red velvet cake.....ohhh t...      1
26                                              #NAME?      0
27   This hole in the wall has great Mexican street...      1
28   Took an hour to get our food only 4 tables in ...      0
29                   The worst was the salmon sashimi.      0
..                                                 ...    ...
970  I immediately said I wanted to talk to the man...      0
971                    The ambiance isn't much better.      0
972  Unfortunately, it only set us up for disapppoi...      0
973                              The food wasn't good.      0
974  Your servers suck, wait, correction, our serve...      0
975      What happened next was pretty....off putting.      0
976  too bad cause I know it's family owned, I real...      0
977               Overpriced for what you are getting.      0
978               I vomited in the bathroom mid lunch.      0
979  I kept looking at the time and it had soon bec...      0
980  I have been to very few places to eat that und...      0
981  We started with the tuna sashimi which was bro...      0
982                            Food was below average.      0
983  It sure does beat the nachos at the movies but...      0
984       All in all, Ha Long Bay was a bit of a flop.      0
985  The problem I have is that they charge $11.99 ...      0
986  Shrimp- When I unwrapped it (I live only 1/2 a...      0
987     It lacked flavor, seemed undercooked, and dry.      0
988  It really is impressive that the place hasn't ...      0
989  I would avoid this place if you are staying in...      0
990  The refried beans that came with my meal were ...      0
991         Spend your money and time some place else.      0
992  A lady at the table next to us found a live gr...      0
993            the presentation of the food was awful.      0
994           I can't tell you how disappointed I was.      0
995  I think food should have flavor and texture an...      0
996                           Appetite instantly gone.      0
997  Overall I was not impressed and would not go b...      0
998  The whole experience was underwhelming, and I ...      0
999  Then, as if I hadn't wasted enough of my life ...      0
Verikümesi gördüğünüz gibi iki sütundan oluşuyor. Bir cümlenin olumlu anlam taşıyıp taşımadığını belirtlen Likes sütunu ve cümlenin kendisi. Cümlelerdeki kelime sayıları farklı. Noktalama işaretleri var. Büyük-küçük harfler var. Bunların hepsi birer problemdir. Daha derin problemlerden, kelimelerin ekleri var vs. Hepsine bakacağız. ntlk doğal dil işleme için oluşturulmuş bir kütüphanedir. stopwords şeklinde bir dosya indirdik. İngilizcede the, if, and gibi kelimeler stopword'dür. Yani tek başına anlamı olmayan kelimelerdir. Bunları da temizleyeceğiz. İlk olarak noktalama işaretlerini temizleyerek başlayalım:


comment0 = re.sub('[^a-zA-Z]', ' ', df['Review'][0])
print(comment0)
Burada ilk satırı aldık ve re.sub methodu ile noktalama işaretlerini temizledik. Temizlemekten kastım, a-z arası harfler dışında olan tüm karakterler yerine boşluk karakteri koyduk. Cümlemiz 'Wow... Loved this place.' idi. Şimdi 'Wow Loved this place' olmuş oldu. Büyük harfleri küçük harfe dönüştürelim:


comment0 = comment0.lower()
print(comment0)
Cümlemiz 'Wow Loved this place' idi. 'wow loved this place ' cümlesine dönüştü. Cümleyi boşluklara göre parçalayıp, kelimeleri almalıyız:


comment0 = comment0.split()
print(comment0)

>>

['wow', 'loved', 'this', 'place']
Şimdi bu kelimeleri işleyebilmemiz için stopword kelimeleri atacağız ve kelimelerin köklerini temizleyeceğiz:


ps = PorterStemmer()
comment0 = [ps.stem(word) for word in comment0 if word not in set(stopwords.words('english'))]
print(comment0)

>>

['wow', 'love', 'place']
PorterStemmer sınıfından bir obje ürettik. Bu obje ile köklerden arındırdık. Bunu da şu şekilde yaptık, comment0 listesindeki kelimelerde gezindik. Eğer bir kelime stopwords dosyasındaki bir kelimeye dahilse alma, dahil değilse köklerinden arındır. Listeyi stringe çevirmemiz gerekli:


comment0 = ' '.join(comment0)
print(comment0)
İlk satır 'Wow... Loved this place.' idi. Son hali 'wow love place' oldu. Bunu tüm satırlar için yapalım:


clearReviews = []
for i in range(1000):
    comment = re.sub('[^a-zA-Z]', ' ', df['Review'][i]).lower().split()
    comment = [ps.stem(word) for word in comment if word not in set(stopwords.words('english'))]
    comment = ' '.join(comment)
    clearReviews.append(comment)
Doğal dil işlemede metin bazlı çalışıyoruz ve metinlerin en büyük problemi kelime sayılarının eşit olmaması. Deep Learning bölümünde görmüştük, resimleri resize edip modele gönderebiliyorduk fakat burada böyle bir şansımız yok. Burada işin içine kelime vektörü giriyor. CountVectorizer sınıfından bir obje oluşturacağız. Bu obje ile tüm veri kümesini okuyacağız ve unique yani eşsiz kelimeleri alacağız. Örneğin tek bir verimiz olduğunu düşünelim. 'python ile makine öğrenmesi'. Burada 4 kelime mevcut. 'ile' kelimesini atarsak 3 kelime mevcut. Bu durumda 3 sütun oluşacak:


	0 1 2
0	1 1 1
Tek verimiz olduğu için sadece 0 satırı mevcut. 3 kelimemiz var. 3 sütun oluştu. 3 kelime de 0. satırda geçiyor bu sebeple 1, 1, 1 değerlerini almış oldu. Bunu tüm veri kümesi için yaparsak ki 1000 satır mevcut, binlerce sütunluk bir veri kümesi elde edebiliriz. CountVectorizer sınıfının bir özelliği mevcut, max_features parametresi ile sadece en çok geçen kelimeleri alabiliriz. Yani max_features değerini 2000 belirlersek, en çok geçen 2000 kelimeyi bizler için alacak:


cv = CountVectorizer(max_features=2000)
clearReviews = cv.fit_transform(clearReviews).toarray()
İlk veri kümesindeki likeları alalıp, clearReviews ve likeları train_test_split methoduna gönderelim, bizim için verileri ayırsın. Daha sonra makine öğrenmesi uygulayalım:


likes = df.iloc[:, [1]].values
x_train, x_test, y_train, y_test = train_test_split(clearReviews, likes, test_size=.33)
gnb = GaussianNB()
gnb.fit(x_train, y_train.ravel())
res = gnb.predict(x_test)

cfm = confusion_matrix(y_test, res)
print(cfm)

>>

[[ 78  84]
 [ 32 136]]
Basit bir NLP uygulaması yaptık. Dediğim gibi NLP ile ilgili bir bölüm açıp, daha ayrıntılı yazılar yazacağım. Bu bir giriş yazısı olarak kalabilir :).


Sonraki Yazı: Neural Networks
Yorumlar

Henüz bir yorum bulunmuyor.