Machine Learning – 17 – Natural Language Toolkit

இதுவரை நாம் கண்ட வெக்டர் உருவாக்கம் அனைத்திலும் ஏதேனும் ஓரிரண்டு வார்த்தைகள் மட்டுமே இடம்பெற்றிருந்தாலும் கூட, இடம் பெறாத வார்த்தைகளுக்கான 0’s ஐ அது கொண்டிருக்கும். இதனால் அந்த வெக்டருடைய அளவு அதிகரிக்கிறது. இதுபோன்ற அதிக அளவிலான 0’s -ஐப் பெற்று விளங்கும் வெக்டர்தான் sparse vector என்று அழைக்கப்படுகிறது. உதாரணத்துக்கு ஒரு கோப்பினுள் அரசியல், சினிமா, விளையாட்டு போன்ற பல்வேறு துறைகளுக்கான வாக்கியங்கள் உள்ளதெனில், அவற்றையெல்லாம் ஒரு வெக்டராக மாற்றும் போது அரசியலுக்கான வரியில் சினிமாவுக்கான வார்த்தை இடம்பெற்றிருக்காது, அதேபோல் சினிமாவுக்கான வரியில் விளையாட்டுக்கான வார்த்தை இடம்பெற்றிருக்காது. இதேபோல் பார்த்தால் ஒவ்வொரு வரியிலும் தேவையில்லாத பல 0’s நிறைந்திருக்கும். இதனால் 2 முக்கியப் பிரச்சனைகள் எழுகின்றன.

முதலாவதாக அதிக அளவு memory & space வீணாகிறது. Numpy என்பது 0’s அல்லாதவற்றை மட்டும் குறிப்பிடுவதற்காக ஒருசில சிறப்பு வகை தரவு வகைகளை வழங்குகின்றன. அடுத்ததாக dimensionality-ன் அளவு அதிகரிக்க அதிகரிக்க அந்த அளவுக்குப் பயிற்சி அளிக்கத் தேவையான தரவுகளின் எண்ணிக்கையும் அதிகரிக்கிறது. இல்லையெனில் overfit ஆவதற்கான அபாயம் உள்ளது. இதுவே ‘curse of dimensionality’ அல்லது ‘Hughes effect’ என்றழைக்கப்படுகிறது. இதை எவ்வாறு குறைப்பது எனப் பேசுவதே dimensionality reduction ஆகும்.

நமது வெக்டர் உருவாக்கத்தின்போது stop_words=’english’ எனக் கொடுத்தோமானால் is,was,are போன்ற ஆங்கிலத்தில் வருகின்ற துணைச் சொற்களை எல்லாம் தவிர்த்து மீதமுள்ள சொற்களுக்கு மட்டும் dictionary உருவாக்கப்படும். இதனால் அதன் dimensionality குறைகிறது.

அவ்வாறே NLTK எனும் கருவி ஒன்று உள்ளது. அதிலுள்ள stemmer, lemmatizer ஆகியவற்றைப் பயன்படுத்துவதன் மூலம் வெக்டரின் dimensionality இன்னும் குறைக்கப்படுவதைக் காணலாம்.


"""
import nltk
nltk.download()
"""
from sklearn.feature_extraction.text import CountVectorizer
from nltk import word_tokenize
from nltk.stem import PorterStemmer
from nltk.stem.wordnet import WordNetLemmatizer
from nltk import pos_tag
def lemmatize(token, tag):
if tag[0].lower() in ['n', 'v']:
return WordNetLemmatizer().lemmatize(token, tag[0].lower())
return token
corpus = ['Bird is a Peacock Bird','Peacock dances very well','It eats variety of seeds','Cumin seed was eaten by it once']
print (CountVectorizer().fit_transform(corpus).todense())
print (CountVectorizer(stop_words='english').fit_transform(corpus).todense())
print (PorterStemmer().stem('seeds'))
print (WordNetLemmatizer().lemmatize('gathering', 'v'))
print (WordNetLemmatizer().lemmatize('gathering', 'n'))
s_lines=[]
for document in corpus:
s_words=[]
for token in word_tokenize(document):
s_words.append(PorterStemmer().stem(token))
s_lines.append(s_words)
print ('Stemmed:',s_lines)
tagged_corpus=[]
for document in corpus:
tagged_corpus.append(pos_tag(word_tokenize(document)))
l_lines=[]
for document in tagged_corpus:
l_words=[]
for token, tag in document:
l_words.append(lemmatize(token, tag))
l_lines.append(l_words)
print ('Lemmatized:',l_lines)

இதனை பின்வருமாறு பதிவிறக்கம் செய்து பயன்படுத்தலாம்.

import nltk
nltk.download()



'Bird is a Peacock Bird','Peacock dances very well','It eats variety of seeds',
'Cumin seed was eaten by it once'

1. மேற்கண்ட வாக்கியங்களுக்கான CountVectorizer() என்பது பின்வருமாறு ஒரு வெக்டரை உருவாக்கும்(4*17). 
print (CountVectorizer().fit_transform(corpus).todense())
[[2 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1]
 [0 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 0]
 [0 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0]]

மேற்கண்ட அதே வாக்கியங்களுக்கு stop_words=’english’ எனக் கொடுத்து வெக்டர் உருவாக்கும்போது,
is, very, well, it, of, was, by, once ஆகிய வார்த்தைகள் நீக்கப்படுவதால் dimensionality
குறைந்து இருப்பதைக் காணலாம்(4*9).

print (CountVectorizer(stop_words='english').fit_transform(corpus).todense())
[[2 0 0 0 0 1 0 0 0]
 [0 0 1 0 0 1 0 0 0]
 [0 0 0 0 1 0 0 1 1]
 [0 1 0 1 0 0 1 0 0]]

2. stop_words=’english’ பயன்படுத்தினாலும் கூட, seeds, seed ஆகிய இரண்டும் இரண்டு தனித்தனி வார்த்தைகளாக சேமிக்கப்படுகின்றன. இதைத் தவிர்ப்பதற்காக வந்ததே PorterStemmer() ஆகும். இது ஒரு ஆங்கிலச் சொல்லின் வேர்சொல்லை கண்டறிந்து அதை மட்டும் சேமிக்கும். அதைத் தழுவி வருகின்ற இன்ன பிற சொற்களையெல்லாம் சேமிக்காது.

print (PorterStemmer().stem('seeds'))
seed 

3. WordNetLemmatizer() என்பது ஒரு ஆங்கிலச் சொல்லை அதன் பொருளறிந்து பிரித்து சேமிக்கும். அதாவது ஒரே ஒரு சொல் ஓரிடத்தில் பெயர்ச்சொல்லாகவும் மற்றொரு இடத்தில் வினைசொல்லாகவும் பயன்படுத்தப்பட்டிருப்பின் அவை இரண்டையும் இரண்டு தனித்தனி சொற்களாகச் சேமிக்கும். உதாரணத்துக்கு  ‘I am gathering foods for birds’, ‘seeds are stored in the gathering place’ என்பதில் gathering, gather என்பது இரண்டு தனித்தனி வார்த்தைகளாக சேமிக்கப்படும்.

print (WordNetLemmatizer().lemmatize('gathering', 'v'))
gather

print (WordNetLemmatizer().lemmatize('gathering', 'n'))
gathering

4. நம்முடைய corpus-ஐ NLTK கொண்டு அணுகும்போது, அது பின்வருமாறு வெளிப்படுத்தும்.

print ('Stemmed:',s_lines)
Stemmed: [['bird', 'is', 'a', 'peacock', 'bird'], ['peacock', 'danc', 'veri', 'w
ell'], ['It', 'eat', 'varieti', 'of', 'seed'], ['cumin', 'seed', 'wa', 'eaten',
'by', 'it', 'onc']]

print ('Lemmatized:',l_lines)
Lemmatized: [['Bird', 'be', 'a', 'Peacock', 'Bird'], ['Peacock', 'dance', 'very', 'well'], 
['It', 'eat', 'variety', 'of', 'seed'], ['Cumin', 'seed', 'be', 'eat', 'by', 'it', 'once']]

%d bloggers like this: