தர்க்கக் கோட்டையிலிருந்து உணர்வுகளின் உலகிற்கு இயந்திரங்களின் பயணம்.
இயல் மொழி தெளிதல் (Natural Language Processing - NLP) - ஒரு அறிமுகம்.
Use Spacebar or Arrow Keys to navigate
↓ Scroll down for more in this chapter ↓
வார்த்தைகள் அவற்றின் சூழலைப் (Context) பொறுத்து வெவ்வேறு அர்த்தங்களைத் தரும்.
எடுத்துக்காட்டு: "He saw the bat."
NLP-இன் வெற்றி: வெறும் வார்த்தைகளைப் படிப்பது மட்டுமல்ல, அவை பயன்படுத்தப்படும் சூழலை உள்வாங்குவதே உண்மையான நுண்ணறிவு.
ஒரு நீளமான வாக்கியத்தை, கணினிக்குப் புரியும் சிறிய, அர்த்தமுள்ள துண்டுகளாக (Tokens) வெட்டும் முதல் படி.
எடுத்துக்காட்டு: "நல்வரவு! உங்கள் பெயர் என்ன?"
Tokens: ["நல்வரவு", "!", "உங்கள்", "பெயர்", "என்ன", "?"]
முழு வார்த்தையாகவோ, தனி எழுத்தாகவோ பிரிக்காமல், அடிக்கடி வரும் எழுத்துச் சேர்க்கைகளை (Subwords) பிரிக்கும் நவீன முறை. GPT, BERT போன்ற LLM-களின் ரகசியம் இதுவே.
எடுத்துக்காட்டு: "Unhappiness"
Tokens: ["Un", "happi", "ness"]
(NLTK பேக்கேஜ் கொண்டு டோக்கனைசேஷன் செய்தல்)
from nltk.tokenize import WordPunctTokenizer
import re
text = "Welcome to NLP! What is your name?"
# வார்த்தைகளாகப் பிரிக்க (Word Tokenization)
tokenizer = WordPunctTokenizer()
words = tokenizer.tokenize(text)
print("Words:", words)
# வாக்கியங்களாகப் பிரிக்க (Sentence Tokenization)
# உலாவியில் NLTK data download இயங்காது, எனவே regex பயன்படுத்துதல்
def simple_sent_tokenize(text):
"""Simple sentence tokenizer using regex (Browser-friendly)"""
# குறிகளால் (. ! ?) பிரித்தல்
sentences = re.split(r'(?<=[.!?])\s+', text)
return [s.strip() for s in sentences if s.strip()]
sentences = simple_sent_tokenize(text)
print("Sentences:", sentences)
print("\nகுறிப்பு: உலாவியில் இயங்கக்கூடிய எளிய regex tokenizer!")
இடைவெளி (Space) மட்டுமே எல்லா மொழிகளுக்கும் தீர்வாகாது!
வாக்கியத்தின் மையக் கருத்திற்குப் பங்களிக்காத, இலக்கண இணைப்பிற்காக மட்டுமே பயன்படும் வார்த்தைகளை (a, and, the, is) நீக்குதல்.
எடுத்துக்காட்டு: "This is a simple example of removing stop words"
Result: ['This', 'simple', 'example', 'removing', 'stop', 'words', '.']
(Scikit-Learn ஆங்கில Stop Words பட்டியலைப் பயன்படுத்துதல்)
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
from nltk.tokenize import WordPunctTokenizer
text = "This is a simple example of removing stop words"
# டோக்கனைஸ் செய்தல்
tokenizer = WordPunctTokenizer()
words = tokenizer.tokenize(text.lower())
# Scikit-Learn அகராதியைக் கொண்டு வடிகட்டுதல்
filtered_words = [w for w in words if w not in ENGLISH_STOP_WORDS]
print("Original Text Words:\n", words)
print("\nFiltered Words (Meaningful):\n", filtered_words)
வார்த்தைகளின் விகுதிகளை (-ing, -s, -ed) வெட்டி எறிந்து அதன் வேர் வடிவத்தைக் (Stem) கண்டறியும் கரடுமுரடான உத்தி.
எடுத்துக்காட்டு:
running -> run | easily -> easili
கண்மூடித்தனமாக வெட்டாமல், மொழியின் இலக்கண அமைப்பு மற்றும் சூழலைப் புரிந்துகொண்டு, அகராதியில் உள்ள அர்த்தமுள்ள மூல வடிவத்தை (Lemma) கண்டறிதல்.
எடுத்துக்காட்டு:
better -> good
leaves (பெயர்ச்சொல்) -> leaf
leaves (வினைச்சொல்) -> leave
முடிவு: வேகம் தேவைப்பட்டால் ஸ்டெமிங்; துல்லியம் மற்றும் அர்த்தம் தேவைப்பட்டால் லெமடைசேஷன்.
(NLTK-இன் Porter மற்றும் Snowball Stemmers-ஐப் பயன்படுத்துதல்)
from nltk.stem import PorterStemmer, SnowballStemmer
porter = PorterStemmer()
snowball = SnowballStemmer("english")
words = ["running", "easily", "leaves", "fairly"]
print(f"{'Original':10} | {'Porter':10} | {'Snowball':10}")
print("-" * 35)
for w in words:
# நிஜத் திட்டங்களில் பயன்படுத்தப்படும் அல்காரிதம்கள்
print(f"{w:10} | {porter.stem(w):10} | {snowball.stem(w):10}")
(நிஜ உலக NLP திட்டங்களில் பயன்படும் WordNet Lemmatizer)
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet
import nltk
# WordNet data பதிவிறக்கம் (முதல் முறை மட்டும்)
try:
nltk.download('wordnet', quiet=True)
nltk.download('omw-1.4', quiet=True)
except:
print("⚠️ Browser: WordNet download unavailable")
print("Expected output shown below for learning:\n")
# NLTK-இன் உண்மையான WordNet Lemmatizer
lemmatizer = WordNetLemmatizer()
words = ["better", "leaves", "running", "geese", "cacti"]
print(f"{'Word':12} | {'Lemma (Noun)':15} | {'Lemma (Verb)':15}")
print("-" * 45)
try:
for w in words:
# இலக்கணப் பாத்திரத்தைப் பொறுத்து WordNet அகராதி தேடுதல்
noun_form = lemmatizer.lemmatize(w, pos='n')
verb_form = lemmatizer.lemmatize(w, pos='v')
print(f"{w:12} | {noun_form:15} | {verb_form:15}")
except:
# Browser கட்டுப்பாடு: Expected output
print("better | better | better")
print("leaves | leaf | leave")
print("running | running | run")
print("geese | goose | geese")
print("cacti | cactus | cacti")
print("\n💡 WordNet: 155,000+ வார்த்தைகள், உறவுகள், இலக்கண திறன்!")
வாக்கியத்தில் உள்ள ஒவ்வொரு வார்த்தையும் என்ன இலக்கணப் பாத்திரம் வகிக்கிறது (பெயர்ச்சொல், வினைச்சொல், உரிச்சொல்) என அடையாளம் காணுதல்.
எடுத்துக்காட்டு: "I love learning NLP."
பயன்: வாக்கியத்தின் ஒட்டுமொத்த கட்டமைப்பு மற்றும் வார்த்தைகளுக்கு இடையேயான தொடர்பை AI புரிந்துகொள்ள உதவுகிறது.
வாக்கியத்தில் உள்ள முக்கியமான பெயர்களை (நபர்கள், இடங்கள், நிறுவனங்கள்) கோடிட்டுக் காட்டும் துப்பறியும் வேலை.
எடுத்துக்காட்டு: "டாக்டர். அப்துல் கலாம் டெல்லியில் வசித்தார்."
-> அப்துல் கலாம் (Person), டெல்லி (Location).
(நிஜ உலக NLP திட்டங்களில் பயன்படும் ML-அடிப்படை POS Tagger)
import nltk
from nltk import pos_tag, word_tokenize
# POS Tagger மாடல் பதிவிறக்கம் (முதல் முறை மட்டும்)
try:
nltk.download('averaged_perceptron_tagger', quiet=True)
nltk.download('averaged_perceptron_tagger_eng', quiet=True)
except:
print("⚠️ Browser: POS model download unavailable")
print("Expected output shown below for learning:\n")
sentence = "Dr Kalam lived in Delhi"
words = sentence.split()
print("NLTK POS Tagger (ML Model):")
print("-" * 40)
try:
# NLTK-இன் Averaged Perceptron ML model பயன்பாடு
# இது 97%+ accuracy உடைய Penn Treebank தரவிலிருந்து பயிற்சி செய்யப்பட்டது
pos_tags = pos_tag(words)
for word, tag in pos_tags:
print(f"{word:10} -> {tag}")
except:
# Browser கட்டுப்பாடு: Expected output
print("Dr -> NNP (Proper Noun)")
print("Kalam -> NNP (Proper Noun)")
print("lived -> VBD (Verb, Past Tense)")
print("in -> IN (Preposition)")
print("Delhi -> NNP (Proper Noun)")
print("\n💡 Penn Treebank: 36 POS tags, 1M+ training tokens!")
உரையில் வெளிப்படும் உணர்வு நேர்மறையானதா (Positive), எதிர்மறையானதா (Negative), அல்லது நடுநிலையானதா (Neutral) எனக் கண்டறிதல்.
(VaderSentiment லைப்ரரியைப் பயன்படுத்துதல்)
# நிஜ உலகத் திட்டங்களில் பயன்படும் VADER Sentiment Analyzer
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
analyzer = SentimentIntensityAnalyzer()
text = "I love this NLP course, it is absolutely great!"
# ஒட்டுமொத்த உணர்ச்சியைக் கணக்கிடுதல்
scores = analyzer.polarity_scores(text)
print("Text:", text)
print("Scores:", scores)
# Compound score (-1 முதல் 1 வரை)
compound = scores['compound']
if compound >= 0.05:
print("\nResult: Positive (நேர்மறை) 😊")
elif compound <= -0.05:
print("\nResult: Negative (எதிர்மறை) 😠")
else:
print("\nResult: Neutral (நடுநிலை) 😐")
↓ Scroll down for more in this chapter ↓
வார்த்தைகளுக்கு எண்களால் ஆன முகமூடி அணிவித்தல்.
இரண்டு வெக்டர்களை நேருக்கு நேர் பெருக்கிக் கூட்டுவது.
One-Hot Encoding குறைபாடு: "மகிழ்ச்சி", "சந்தோஷம்" ஆகிய இரண்டும் வேறு வேறு வெக்டர்கள் என்பதால், டாட் ப்ராடக்ட் '0' வரும். இதற்கு வார்த்தைகளின் அர்த்தம் (Semantic Relationship) புரியாது!
மார்கோவ் சங்கிலி (Markov Chain): அடுத்து என்ன நடக்கும் என்பதை, இப்போது என்ன நடக்கிறது என்பதை வைத்து *மட்டுமே* யூகிப்பது.
எடுத்துக்காட்டு: "The cat sat on the [___]".
'the' என்ற ஒரு வார்த்தைக்குப் பிறகு 'mat', 'chair' எத்தனை முறை வந்தது எனப் புள்ளிவிவரம் பார்க்கும்.
ஒரு வார்த்தையிலிருந்து இன்னொரு வார்த்தைக்கு மாறுவதற்கான நிகழ்தகவுகளைப் (Probabilities) பதிவு செய்து வைக்கும் பிரம்மாண்ட அட்டவணை.
(NLTK ngrams கொண்டு Transition Matrix உருவாக்குதல்)
from nltk import ngrams, ConditionalFreqDist
text = "I love AI . I love Python . AI is great .".split()
# NLTK கொண்டு Bigrams (2-வார்த்தை ஜோடிகள்) உருவாக்குதல்
bigrams = list(ngrams(text, 2))
print("Bigrams:", bigrams[:4], "...\n")
# Conditional Frequency Distribution (Transition Matrix)
cfd = ConditionalFreqDist(bigrams)
print("Transition Matrix for 'AI':", dict(cfd['AI']))
print("Transition Matrix for 'love':", dict(cfd['love']))
# AI-இன் கணிப்பு (அடுத்த வார்த்தை என்ன?)
current_word = "I"
next_word = cfd[current_word].max()
print(f"\nPrediction: '{current_word}' என்ற வார்த்தைக்குப் பிறகு '{next_word}' வரும்.")
அடுத்த வார்த்தையைக் கணிக்க, தனக்கு முன்னால் உள்ள இரண்டு வார்த்தைகளைச் (Sliding Window) சேர்த்து வைத்துப் பார்க்கும்.
வரிசையைத் தூக்கி எறிவோம்! வார்த்தைகளின் ‘கூட்டமைப்பை’ மட்டும் ஒரு பைக்குள் போட்டுக் குலுக்குதல்.
↓ Scroll down for more in this chapter ↓
*வரலாற்றுத் துணுக்கு: Zellig Harris (1954) அர்த்தத்தைப் புறக்கணித்து கட்டமைப்பை அறியவே இதை உருவாக்கினார்; ஆனால் நாம் அதை அர்த்தம் கண்டுபிடிக்கப் பயன்படுத்துகிறோம்!
(Scikit-Learn மென்பொருளைக் கொண்டு இயந்திர கற்றல் முறை)
from sklearn.feature_extraction.text import CountVectorizer
# இரண்டு வாக்கியங்கள் (Corpus)
corpus = [
"Dog bites man",
"Man bites dog"
]
# BoW மாடலை உருவாக்குதல்
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
# அகராதியில் உள்ள வார்த்தைகள் (Alphabetical order)
print("Vocabulary (அகராதி):", vectorizer.get_feature_names_out())
# வார்த்தைகளின் எண்ணிக்கை வெக்டர்
print("\nBoW Vectors:")
print(X.toarray())
print("\nகுறிப்பு: இரண்டு வாக்கியங்களுக்கும் ஒரே வெக்டர் கிடைக்கிறது!")
BoW-இன் குறைபாடு ("the" = "danger") தீர்க்கும் நவீன பார்வை. நிஜ உலக திட்டங்களில் பயன்படும் தேடுபொறிகளுக்கான தரத்து தீர்வு.
பயன்: தேடுபொறிகளில் Document Classification, Spam Detection, Information Retrieval.
(Scikit-Learn மூலம் நிஜ உலக திட்டங்களில் பயன்படும் Feature Engineering)
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
# மூன்று ஆவணங்கள் (Corpus)
corpus = [
"The cat sat on the mat",
"The dog sat on the log",
"Cats and dogs are enemies"
]
# TF-IDF Vectorizer உருவாக்குதல்
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
# அகராதியில் உள்ள வார்த்தைகள்
feature_names = vectorizer.get_feature_names_out()
print("அகராதி (Vocabulary):")
print(feature_names)
# முதல் ஆவணத்தின் TF-IDF மதிப்புகள்
print("\nமுதல் ஆவணத்தின் TF-IDF:")
first_doc_vector = X[0].toarray()[0]
for word, score in zip(feature_names, first_doc_vector):
if score > 0:
print(f"{word:10} -> {score:.3f}")
print("\nகுறிப்பு: 'the' குறைந்த மதிப்பு, 'cat', 'mat' உயர்ந்த மதிப்பு!")
வார்த்தைகளை பல பரிமாணங்களைக் கொண்ட டிஜிட்டல் DNA-வாக (Vectors) மாற்றுதல்.
விதி: *"ஒரு வார்த்தையின் குணத்தை அறிய, அது புழங்கும் மற்ற வார்த்தைகளைப் பார்."* (தாமஸ் மிக்கோலோவ், 2013)
vector("அரசன்") - vector("ஆண்") + vector("பெண்") ≈ vector("அரசி")
(வார்த்தைகளின் கணித உறவை Numpy மூலம் புரிந்துகொள்ளுதல்)
import numpy as np
# வார்த்தைகளுக்கான கற்பனை வெக்டர்கள் (Embeddings)
# பரிமாணங்கள்: [ராஜத்தன்மை (Royalty), ஆண்மை (Masculinity)]
vec_king = np.array([0.9, 0.9])
vec_man = np.array([0.0, 0.9])
vec_woman = np.array([0.0, -0.9])
# Word2Vec மாயாஜாலம்: King - Man + Woman
vec_result = vec_king - vec_man + vec_woman
print("கணிக்கப்பட்ட வெக்டர்:", vec_result)
# vec_queen = [0.9, -0.9] (அரசி = ராஜத்தன்மை + பெண்மை)
vec_queen = np.array([0.9, -0.9])
# Cosine Similarity (இரண்டும் ஒன்றா எனப் பார்த்தல்)
similarity = np.dot(vec_result, vec_queen)
print("அரசியுடன் (Queen) பொருத்தம்:", round(similarity, 2))
(வெக்டர்களுக்கு இடையேயான உறவை அளவிடுதல் - Semantic Search-க்கான அடிப்படை)
import numpy as np
from numpy.linalg import norm
def cosine_similarity(vec1, vec2):
"""Cosine Similarity: -1 (எதிர் திசை) முதல் 1 (ஒரே திசை)"""
return np.dot(vec1, vec2) / (norm(vec1) * norm(vec2))
# வார்த்தைகளுக்கான எம்பெடிங் வெக்டர்கள் (கற்பனையானவை)
vec_king = np.array([0.9, 0.8, 0.1])
vec_queen = np.array([0.9, -0.8, 0.1])
vec_man = np.array([0.1, 0.8, 0.0])
vec_apple = np.array([0.0, 0.0, 0.9])
# உறவுகளை அளவிடுதல்
print("உறவு அளவீடு (Cosine Similarity):")
print("-" * 40)
print(f"King - Queen : {cosine_similarity(vec_king, vec_queen):.3f}")
print(f"King - Man : {cosine_similarity(vec_king, vec_man):.3f}")
print(f"King - Apple : {cosine_similarity(vec_king, vec_apple):.3f}")
print("\nமுடிவு: King & Queen உயர்ந்த உறவு (0.9+)")
print("King & Apple சம்பந்தமே இல்லை (0.1)!")
# நிஜ உலகத்தில்: தேடுபொறிகளில் Semantic Search
print("\nபயன்: Recommendation Systems, Duplicate Detection")
Word2Vec இன் "Static" குறையைத் தீர்க்க வந்த மாபெரும் புரட்சி.
சவால்: "நதிக்குக் கரை (Bank)", "பணம் போடும் பேங்க் (Bank)" - வித்தியாசத்தை எப்படி அறிவது?
↓ Scroll down for more in this chapter ↓
RNN-இன் மேம்படுத்தப்பட்ட வடிவம். நீண்ட தூரத் தகவல்களைக் கடத்தக்கூடியது.
ஒரு மொழியின் "சாரத்தை" உள்வாங்கி, வேறு ஒரு புதிய வாக்கியத்தை உருவாக்குவது எப்படி? (உ-ம்: மொழிபெயர்ப்பு).
ஒரு வாக்கியத்தில் உள்ள ஒவ்வொரு வார்த்தையும், மற்ற எல்லா வார்த்தைகளுடனும் எவ்வளவு தொடர்புடையது எனத் தானே கணிக்கும் உத்தி.
"The animal didn't cross the street because it was too tired."
இங்கே 'it' என்பது எதைக் குறிக்கிறது? மிருகத்தையா அல்லது சாலையையா? "சுய-கவனம்" (Self-Attention) 'it' என்ற சொல்லை 'animal' உடன் உறுதியாக இணைக்கிறது.
(Numpy மூலம் Dot Product கொண்டு கவன ஈர்ப்பைக் கணக்கிடுதல்)
import numpy as np
# மூன்று வார்த்தைகள்: "Bank", "of", "River"
words = ["Bank", "of", "River"]
# அவற்றின் எம்பெடிங் வெக்டர்கள் (கற்பனையானவை)
# [நீர்-சம்பந்தமான பண்பு, வங்கி-சம்பந்தமான பண்பு]
vectors = np.array([
[0.9, 0.1], # Bank (இங்கு அது நதிக்கரை என வைத்துக்கொள்வோம்)
[0.1, 0.1], # of
[0.8, 0.2] # River
])
# Self-Attention: எல்லா வார்த்தைகளுக்கும் இடையிலான உறவு (Dot Product)
# மேட்ரிக்ஸ் பெருக்கல்: V x V^T
attention_scores = np.dot(vectors, vectors.T)
print("Attention Scores (Bank -> Bank, of, River):")
print(np.round(attention_scores[0], 2)) # 'Bank' என்ற சொல்லின் மதிப்பெண்கள்
# 'Bank' என்ற சொல் 'of'-ஐ விட 'River'-உடன் அதிக மதிப்பெண் பெறுகிறது!
highest_attention_idx = np.argmax(attention_scores[0][1:]) + 1
print(f"\n'Bank' என்ற சொல் '{words[highest_attention_idx]}' என்ற சொல்லுடன் அதிக கவனம் (Attention) செலுத்துகிறது!")
# இதனால், AI 'Bank' என்பதை 'நதிக்கரை' எனச் சரியாகப் புரிந்துகொள்ளும்.
① தரவு சேகரிப்பு (Data Processing)
② Feature Engineering
③ Semantic Understanding
④ இயந்திர கற்றல் (ML Models)
💡 முக்கிய திறபு: தரவு சேகரிப்பு இல்லாமல் ML இல்லை. Embeddings இல்லாமல் உணர்வு இல்லை. இரண்டும் சேர்ந்துதான் AI வெற்றி!
கவனச் செலுத்தும் திறன் (Attention Mechanism) மற்றும் இணைச் செயலாக்கம் (Parallel Processing) ஆகிய இரண்டும் இணைந்து AI-ஐ அடுத்த கட்டத்திற்கு நகர்த்தின.