nlpkit14 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
nlpkit14/__init__.py ADDED
@@ -0,0 +1,70 @@
1
+ """Run the fourteen supplied NLP practicals, with source available separately."""
2
+ from importlib.resources import files
3
+ import json
4
+ import os
5
+
6
+ __version__ = "0.3.0"
7
+
8
+ def _resource(number):
9
+ if number not in range(1, 15):
10
+ raise ValueError("Choose a question from 1 to 14")
11
+ return files(__package__).joinpath("programs", f"q{number}.py")
12
+
13
+ def _configure():
14
+ path = os.path.expanduser(os.environ.get("NLPKIT14_DATA", "~/.nlpkit14"))
15
+ data = os.path.join(path, "nltk_data")
16
+ os.environ.setdefault("HF_HOME", os.path.join(path, "huggingface"))
17
+ try:
18
+ import nltk
19
+ except ModuleNotFoundError:
20
+ return
21
+ if data not in nltk.data.path:
22
+ nltk.data.path.insert(0, data)
23
+
24
+ def source(number):
25
+ """Print runnable source, including the commented question and expected output."""
26
+ print(_resource(number).read_text(encoding="utf-8"), end="")
27
+
28
+ def questions():
29
+ for row in json.loads(files(__package__).joinpath("questions.json").read_text(encoding="utf-8")):
30
+ print(f"q{row['number']}(): {row['question']}")
31
+
32
+ def _run(number):
33
+ _configure()
34
+ resource = _resource(number)
35
+ namespace = {"__name__": f"nlpkit14.question{number}"}
36
+ exec(compile(resource.read_text(encoding="utf-8"), str(resource), "exec"), namespace)
37
+
38
+ def _make(number):
39
+ def question():
40
+ _run(number)
41
+ question.__name__ = f"q{number}"
42
+ question.__qualname__ = question.__name__
43
+ question.__doc__ = f"Execute question {number}. Use source({number}) to see code and comments."
44
+ return question
45
+
46
+ for _number in range(1, 15):
47
+ globals()[f"q{_number}"] = _make(_number)
48
+
49
+ def setup(models=False):
50
+ """Explicit online preparation. models=True also downloads large parsing/BERT models."""
51
+ _configure()
52
+ import nltk
53
+ import subprocess
54
+ import sys
55
+ directory = os.path.join(os.path.expanduser(os.environ.get("NLPKIT14_DATA", "~/.nlpkit14")), "nltk_data")
56
+ os.makedirs(directory, exist_ok=True)
57
+ for name in ("punkt_tab", "stopwords", "averaged_perceptron_tagger_eng", "wordnet", "omw-1.4"):
58
+ if not nltk.download(name, download_dir=directory, quiet=True):
59
+ raise RuntimeError(f"Could not download {name}; check internet connectivity")
60
+ subprocess.run([sys.executable, "-m", "spacy", "download", "en_core_web_sm"], check=True)
61
+ if models:
62
+ subprocess.run([sys.executable, "-m", "spacy", "download", "en_core_web_md"], check=True)
63
+ import benepar
64
+ if not benepar.download("benepar_en3", download_dir=directory):
65
+ raise RuntimeError("Could not download benepar_en3; check internet connectivity")
66
+ from transformers import BertTokenizer, BertModel
67
+ BertTokenizer.from_pretrained("bert-base-uncased")
68
+ BertModel.from_pretrained("bert-base-uncased")
69
+
70
+ __all__ = ["questions", "source", "setup"] + [f"q{i}" for i in range(1, 15)]
@@ -0,0 +1,30 @@
1
+ # Question 1 (B1): Tokenization and Stop-word Removal using NLTK
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Sentences: ['This is a simple example demonstrating stopword removal in NLP.', 'NLP is interesting.']
5
+ # Words: ['This', 'is', 'a', 'simple', 'example', 'demonstrating', 'stopword', 'removal', 'in', 'NLP', '.', 'NLP', 'is', 'interesting', '.']
6
+ # Filtered Tokens: ['simple', 'example', 'demonstrating', 'stopword', 'removal', 'NLP', 'NLP', 'interesting']
7
+
8
+ import nltk
9
+ from nltk.tokenize import word_tokenize, sent_tokenize
10
+ from nltk.corpus import stopwords
11
+
12
+ # Download required resources
13
+ # Resource download moved to n.setup().
14
+ # Resource download moved to n.setup().
15
+ # Input text
16
+ text = "This is a simple example demonstrating stopword removal in NLP. NLP is interesting."
17
+
18
+ # Sentence tokenization
19
+ sentences = sent_tokenize(text)
20
+
21
+ # Word tokenization
22
+ words = word_tokenize(text)
23
+
24
+ # Stop-word removal
25
+ stop_words = set(stopwords.words('english'))
26
+ filtered = [w for w in words if w.lower() not in stop_words and w.isalnum()]
27
+
28
+ print("Sentences:", sentences)
29
+ print("Words:", words)
30
+ print("Filtered Tokens:", filtered)
@@ -0,0 +1,41 @@
1
+ # Question 10 (C3): Add-One (Laplace) Smoothing for an N-gram Model
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # P(i|<s>) = 0.272727
5
+ # P(like|i) = 0.300000
6
+ # P(apples|like) = 0.200000
7
+ # P(</s>|apples) = 0.300000
8
+ # Vocabulary Size = 8
9
+ # Add-One Sentence Probability = 0.00490909
10
+
11
+ from collections import Counter
12
+
13
+ corpus = [
14
+ ['i', 'like', 'apples'],
15
+ ['i', 'like', 'bananas'],
16
+ ['you', 'eat', 'apples']
17
+ ]
18
+
19
+ unigrams = Counter()
20
+ bigrams = Counter()
21
+
22
+ for sentence in corpus:
23
+ tokens = ['<s>'] + sentence + ['</s>']
24
+ unigrams.update(tokens)
25
+ bigrams.update(zip(tokens[:-1], tokens[1:]))
26
+
27
+ V = len(unigrams) # vocabulary size including boundary tokens
28
+
29
+ def add_one(w1, w2):
30
+ return (bigrams[(w1, w2)] + 1) / (unigrams[w1] + V)
31
+
32
+ test = ['<s>', 'i', 'like', 'apples', '</s>']
33
+ probability = 1.0
34
+
35
+ for w1, w2 in zip(test[:-1], test[1:]):
36
+ p = add_one(w1, w2)
37
+ probability *= p
38
+ print(f"P({w2}|{w1}) = {p:.6f}")
39
+
40
+ print("Vocabulary Size =", V)
41
+ print("Add-One Sentence Probability =", round(probability, 8))
@@ -0,0 +1,39 @@
1
+ # Question 11 (C4): Calculate Good-Turing Frequency
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Raw Good-Turing adjusted frequencies only; this is not a normalized probability model.
4
+ # Expected output:
5
+ # r C*(r)
6
+ # -------------
7
+ # 0 0.0
8
+ # 1 1.3333
9
+ # 2 1.5
10
+ # 3 0.0
11
+
12
+ from collections import Counter
13
+
14
+ def good_turing(counts):
15
+ # counts contains observed frequencies of different events
16
+ freq_of_freq = Counter(counts)
17
+ max_r = max(freq_of_freq.keys())
18
+ adjusted_counts = {}
19
+
20
+ for r in range(0, max_r + 1):
21
+ Nr = freq_of_freq.get(r, 0)
22
+ Nr_plus_1 = freq_of_freq.get(r + 1, 0)
23
+
24
+ if Nr > 0:
25
+ c_star = (r + 1) * (Nr_plus_1 / Nr)
26
+ adjusted_counts[r] = round(c_star, 4)
27
+ else:
28
+ adjusted_counts[r] = 0.0
29
+
30
+ return adjusted_counts
31
+
32
+ # 3 events occur once, 2 events occur twice, 1 event occurs 3 times
33
+ sample_counts = [1, 1, 1, 2, 2, 3]
34
+ result = good_turing(sample_counts)
35
+
36
+ print(f"{'r':<5}{'C*(r)':<10}")
37
+ print("-" * 13)
38
+ for r in sorted(result):
39
+ print(f"{r:<5}{result[r]:<10}")
@@ -0,0 +1,50 @@
1
+ # Question 12 (C5): Text Classification
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Preserves the document example; fit the vectorizer on training data only for unbiased evaluation.
4
+ # Expected output:
5
+ # precision recall f1-score support
6
+ #
7
+ # sports 0.00 0.00 0.00 2
8
+ # technology 0.33 1.00 0.50 1
9
+ #
10
+ # accuracy 0.33 3
11
+ # macro avg 0.17 0.50 0.25 3
12
+ # weighted avg 0.11 0.33 0.17 3
13
+
14
+ from sklearn.feature_extraction.text import CountVectorizer
15
+ from sklearn.model_selection import train_test_split
16
+ from sklearn.linear_model import LogisticRegression
17
+ from sklearn.metrics import classification_report
18
+
19
+ texts = [
20
+ "The CPU and memory are important in a computer",
21
+ "Basketball is a popular sport",
22
+ "Python and Java are programming languages",
23
+ "Football players need strength and speed",
24
+ "Hard disk and RAM are types of hardware",
25
+ "Tennis is played with a racket",
26
+ "Motherboard connects all components",
27
+ "He scored a goal in the last minute"
28
+ ]
29
+
30
+ labels = [
31
+ "technology", "sports", "technology", "sports",
32
+ "technology", "sports", "technology", "sports"
33
+ ]
34
+
35
+ # Convert text into Bag-of-Words vectors
36
+ vectorizer = CountVectorizer()
37
+ X = vectorizer.fit_transform(texts)
38
+
39
+ # Train-test split
40
+ X_train, X_test, y_train, y_test = train_test_split(
41
+ X, labels, test_size=0.3, random_state=42
42
+ )
43
+
44
+ # Train classifier
45
+ clf = LogisticRegression()
46
+ clf.fit(X_train, y_train)
47
+
48
+ # Predict and evaluate
49
+ y_pred = clf.predict(X_test)
50
+ print(classification_report(y_test, y_pred, zero_division=0))
@@ -0,0 +1,25 @@
1
+ # Question 13 (C6): Calculate Vector Similarity in Semantic Space
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Semantic similarity between:
5
+ # "Apples are tasty" and "Bananas are delicious" = 0.8661
6
+
7
+ import spacy
8
+ from sklearn.metrics.pairwise import cosine_similarity
9
+
10
+ # Medium model contains pretrained vectors
11
+ nlp = spacy.load("en_core_web_md")
12
+
13
+ text1 = "Apples are tasty"
14
+ text2 = "Bananas are delicious"
15
+
16
+ doc1 = nlp(text1)
17
+ doc2 = nlp(text2)
18
+
19
+ vec1 = doc1.vector.reshape(1, -1)
20
+ vec2 = doc2.vector.reshape(1, -1)
21
+
22
+ similarity = cosine_similarity(vec1, vec2)[0][0]
23
+
24
+ print(f'Semantic similarity between:')
25
+ print(f'"{text1}" and "{text2}" = {similarity:.4f}')
@@ -0,0 +1,40 @@
1
+ # Question 14 (C7): Identify Context of Ambiguous Words using BERT
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Sentence 1: He sat on the river bank and watched the water flow.
5
+ # Sentence 2: She went to the bank to deposit some money.
6
+ # Contextual similarity of 'bank': 0.4972
7
+
8
+ from transformers import BertTokenizer, BertModel
9
+ import torch
10
+ from sklearn.metrics.pairwise import cosine_similarity
11
+
12
+ # Load pretrained BERT
13
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', local_files_only=True)
14
+ model = BertModel.from_pretrained('bert-base-uncased', local_files_only=True)
15
+ model.eval()
16
+
17
+ sent1 = "He sat on the river bank and watched the water flow."
18
+ sent2 = "She went to the bank to deposit some money."
19
+
20
+ def get_word_embedding(sentence, target_word):
21
+ inputs = tokenizer(sentence, return_tensors='pt')
22
+
23
+ with torch.no_grad():
24
+ outputs = model(**inputs)
25
+
26
+ tokens = tokenizer.convert_ids_to_tokens(inputs['input_ids'][0])
27
+ embeddings = outputs.last_hidden_state.squeeze(0)
28
+
29
+ # Find token position
30
+ idx = tokens.index(target_word)
31
+ return embeddings[idx].numpy()
32
+
33
+ embedding1 = get_word_embedding(sent1, "bank")
34
+ embedding2 = get_word_embedding(sent2, "bank")
35
+
36
+ similarity = cosine_similarity([embedding1], [embedding2])[0][0]
37
+
38
+ print("Sentence 1:", sent1)
39
+ print("Sentence 2:", sent2)
40
+ print("Contextual similarity of 'bank':", round(similarity, 4))
@@ -0,0 +1,33 @@
1
+ # Question 2 (B2): Tokenization and Stop-word Removal using spaCy
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Sentences: ['This is an example sentence, demonstrating tokenization and stop word removal.']
5
+ # Tokens: ['This', 'is', 'an', 'example', 'sentence', ',', 'demonstrating', 'tokenization', 'and', 'stop', 'word', 'removal', '.']
6
+ # Filtered Tokens: ['example', 'sentence', 'demonstrating', 'tokenization', 'stop', 'word', 'removal']
7
+
8
+ import spacy
9
+
10
+ # Load spaCy English model
11
+ nlp = spacy.load("en_core_web_sm")
12
+
13
+ # Sample text
14
+ text = "This is an example sentence, demonstrating tokenization and stop word removal."
15
+
16
+ # Process text
17
+ Doc = nlp(text)
18
+
19
+ # Sentence tokenization
20
+ sentences = [sent.text for sent in Doc.sents]
21
+
22
+ # Word tokenization
23
+ tokens = [token.text for token in Doc]
24
+
25
+ # Remove stop words and punctuation
26
+ filtered_tokens = [
27
+ token.text for token in Doc
28
+ if not token.is_stop and not token.is_punct
29
+ ]
30
+
31
+ print("Sentences:", sentences)
32
+ print("Tokens:", tokens)
33
+ print("Filtered Tokens:", filtered_tokens)
@@ -0,0 +1,29 @@
1
+ # Question 3 (B3): Stemming and Lemmatization using spaCy
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Original Words : ['Studies', 'studying', 'cries', 'cried', 'flying', 'flies']
5
+ # Lemmatized Words : ['study', 'study', 'cry', 'cry', 'fly', 'fly']
6
+ # Stemmed Words : ['studi', 'studi', 'cri', 'cri', 'fli', 'fli']
7
+
8
+ import spacy
9
+ from nltk.stem import PorterStemmer
10
+
11
+ # Load spaCy model and create stemmer
12
+ nlp = spacy.load("en_core_web_sm")
13
+ stemmer = PorterStemmer()
14
+
15
+ sentence = "Studies studying cries cried flying flies"
16
+ doc = nlp(sentence)
17
+
18
+ # Original tokens
19
+ original_words = [token.text for token in doc]
20
+
21
+ # Lemmatization using spaCy
22
+ lemmatized_words = [token.lemma_ for token in doc]
23
+
24
+ # Stemming on spaCy tokens
25
+ stemmed_words = [stemmer.stem(token.text) for token in doc]
26
+
27
+ print("Original Words :", original_words)
28
+ print("Lemmatized Words :", lemmatized_words)
29
+ print("Stemmed Words :", stemmed_words)
@@ -0,0 +1,44 @@
1
+ # Question 4 (B4): Stemming and Lemmatization using NLTK
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Original Words: ['Studies', 'studying', 'cries', 'cried', 'flying', 'flies']
5
+ # Stemmed Words : ['studi', 'studi', 'cri', 'cri', 'fli', 'fli']
6
+ # Lemmatized Words: ['Studies', 'study', 'cry', 'cry', 'fly', 'fly']
7
+
8
+ import nltk
9
+ from nltk.tokenize import word_tokenize
10
+ from nltk.stem import PorterStemmer, WordNetLemmatizer
11
+ from nltk.corpus import wordnet
12
+
13
+ # Resource download moved to n.setup().
14
+ # Resource download moved to n.setup().
15
+ # Resource download moved to n.setup().
16
+ # Resource download moved to n.setup().
17
+ stemmer = PorterStemmer()
18
+ lemmatizer = WordNetLemmatizer()
19
+
20
+ # Map Treebank POS tag to WordNet POS
21
+ def get_wordnet_pos(tag):
22
+ if tag.startswith('J'):
23
+ return wordnet.ADJ
24
+ elif tag.startswith('V'):
25
+ return wordnet.VERB
26
+ elif tag.startswith('N'):
27
+ return wordnet.NOUN
28
+ elif tag.startswith('R'):
29
+ return wordnet.ADV
30
+ return wordnet.NOUN
31
+
32
+ text = "Studies studying cries cried flying flies"
33
+ tokens = word_tokenize(text)
34
+ tagged = nltk.pos_tag(tokens)
35
+
36
+ stems = [stemmer.stem(word) for word in tokens]
37
+ lemmas = [
38
+ lemmatizer.lemmatize(word, get_wordnet_pos(tag))
39
+ for word, tag in tagged
40
+ ]
41
+
42
+ print("Original Words:", tokens)
43
+ print("Stemmed Words :", stems)
44
+ print("Lemmatized Words:", lemmas)
@@ -0,0 +1,33 @@
1
+ # Question 5 (B5): Design a Python Program to Illustrate Corpus
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # --- Document 1 ---
5
+ # Tokens: ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog', '.']
6
+ # POS Tags: [('The', 'DET'), ('quick', 'ADJ'), ('brown', 'ADJ'), ('fox', 'NOUN'), ('jumps', 'VERB'), ('over', 'ADP'), ('the', 'DET'), ('lazy', 'ADJ'), ('dog', 'NOUN'), ('.', 'PUNCT')]
7
+ #
8
+ # --- Document 2 ---
9
+ # Tokens: ['SpaCy', 'is', 'a', 'popular', 'NLP', 'library', 'in', 'Python', '.']
10
+ #
11
+ # --- Document 3 ---
12
+ # Tokens: ['Natural', 'Language', 'Processing', 'enables', 'machines', 'to', 'understand', 'human', 'language', '.']
13
+
14
+ import spacy
15
+
16
+ nlp = spacy.load("en_core_web_sm")
17
+
18
+ # A small corpus: collection of documents
19
+ corpus = [
20
+ "The quick brown fox jumps over the lazy dog.",
21
+ "SpaCy is a popular NLP library in Python.",
22
+ "Natural Language Processing enables machines to understand human language."
23
+ ]
24
+
25
+ for i, text in enumerate(corpus, start=1):
26
+ print(f"\n--- Document {i} ---")
27
+ doc = nlp(text)
28
+
29
+ tokens = [token.text for token in doc]
30
+ pos_tags = [(token.text, token.pos_) for token in doc]
31
+
32
+ print("Tokens:", tokens)
33
+ print("POS Tags:", pos_tags)
@@ -0,0 +1,43 @@
1
+ # Question 6 (B6): Generate a Constituency Parse Tree
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Parse String:
5
+ # (S (NP (DT The) (JJ quick) (JJ brown) (NN fox))
6
+ # (VP (VBZ jumps)
7
+ # (PP (IN over) (NP (DT the) (JJ lazy) (NN dog))))
8
+ # (. .))
9
+ #
10
+ # Pretty Tree:
11
+ # S
12
+ # _______________|__________________________
13
+ # | VP |
14
+ # | _________|___ |
15
+ # NP | PP |
16
+ # ____|__________ | ________|___ |
17
+ # DT JJ JJ NN VBZ IN DT JJ NN .
18
+ # The quick brown fox jumps over the lazy dog .
19
+
20
+ # Run once if required:
21
+ # !pip install spacy benepar
22
+ # !python -m spacy download en_core_web_sm
23
+
24
+ import spacy
25
+ import benepar
26
+ import nltk
27
+
28
+ # Model download moved to n.setup(models=True).
29
+ nlp = spacy.load("en_core_web_sm")
30
+
31
+ if not nlp.has_pipe("benepar"):
32
+ nlp.add_pipe("benepar", config={"model": "benepar_en3"})
33
+
34
+ sentence = "The quick brown fox jumps over the lazy dog."
35
+ doc = nlp(sentence)
36
+
37
+ for sent in doc.sents:
38
+ parse_string = sent._.parse_string
39
+ print("Parse String:\n", parse_string)
40
+
41
+ tree = nltk.Tree.fromstring(parse_string)
42
+ print("\nPretty Tree:")
43
+ tree.pretty_print()
@@ -0,0 +1,31 @@
1
+ # Question 7 (B7): Generate a Dependency Parse Tree
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # Word: The POS: DET Head: team Dep: det
5
+ # Word: cricket POS: NOUN Head: team Dep: compound
6
+ # Word: team POS: NOUN Head: won Dep: nsubj
7
+ # Word: won POS: VERB Head: won Dep: ROOT
8
+ # Word: the POS: DET Head: match Dep: det
9
+ # Word: match POS: NOUN Head: won Dep: dobj
10
+ # Word: in POS: ADP Head: won Dep: prep
11
+ # Word: Mumbai POS: PROPN Head: in Dep: pobj
12
+ # Word: . POS: PUNCT Head: won Dep: punct
13
+
14
+ import spacy
15
+ from spacy import displacy
16
+
17
+ nlp = spacy.load("en_core_web_sm")
18
+ sentence = "The cricket team won the match in Mumbai."
19
+ doc = nlp(sentence)
20
+
21
+ # Print dependency information
22
+ for token in doc:
23
+ print(
24
+ f"Word: {token.text:8} "
25
+ f"POS: {token.pos_:6} "
26
+ f"Head: {token.head.text:8} "
27
+ f"Dep: {token.dep_}"
28
+ )
29
+
30
+ # In Jupyter / Colab
31
+ # displacy.render(doc, style="dep", jupyter=True)
@@ -0,0 +1,39 @@
1
+ # Question 8 (C1): POS Tagging on Text Scraped from a Website
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # POS Tags (sample):
5
+ # [('B.N.M', 'NNP'), ('Institute', 'NNP'), ('of', 'IN'),
6
+ # ('Technology', 'NNP'), ('is', 'VBZ'), ('one', 'CD'),
7
+ # ('of', 'IN'), ('the', 'DT'), ('top', 'JJ'),
8
+ # ('engineering', 'NN'), ('colleges', 'NNS'), ...]
9
+
10
+ import requests
11
+ from bs4 import BeautifulSoup
12
+ import nltk
13
+
14
+ # Resource download moved to n.setup().
15
+ # Resource download moved to n.setup().
16
+ def scrape_text(url):
17
+ response = requests.get(url, timeout=10)
18
+ response.raise_for_status()
19
+ soup = BeautifulSoup(response.content, 'html.parser')
20
+
21
+ # Remove scripts and styles
22
+ for item in soup(['script', 'style']):
23
+ item.extract()
24
+
25
+ return soup.get_text(separator=' ')
26
+
27
+ def pos_tag_text(text):
28
+ tokens = nltk.word_tokenize(text)
29
+ return nltk.pos_tag(tokens)
30
+
31
+ url = "https://www.bnmit.org/"
32
+ scraped_text = scrape_text(url)
33
+ pos_tags = pos_tag_text(scraped_text)
34
+
35
+ print("Scraped Text (first 300 characters):")
36
+ print(scraped_text[:300])
37
+
38
+ print("\nPOS Tags (first 30 tokens):")
39
+ print(pos_tags[:30])
@@ -0,0 +1,36 @@
1
+ # Question 9 (C2): Implement a Bigram Model and Calculate Test-Sentence Probability
2
+ # Output below is the document example; actual model and website results may differ.
3
+ # Expected output:
4
+ # P(i|<s>) = 2/3 = 0.666667
5
+ # P(like|i) = 2/2 = 1.000000
6
+ # P(apples|like) = 1/2 = 0.500000
7
+ # P(</s>|apples) = 2/2 = 1.000000
8
+ # Sentence Probability = 0.33333333
9
+
10
+ from collections import Counter
11
+
12
+ # Training corpus
13
+ corpus = [
14
+ ['i', 'like', 'apples'],
15
+ ['i', 'like', 'bananas'],
16
+ ['you', 'eat', 'apples']
17
+ ]
18
+
19
+ unigrams = Counter()
20
+ bigrams = Counter()
21
+
22
+ for sentence in corpus:
23
+ tokens = ['<s>'] + sentence + ['</s>']
24
+ unigrams.update(tokens)
25
+ bigrams.update(zip(tokens[:-1], tokens[1:]))
26
+
27
+ # Test sentence
28
+ test = ['<s>', 'i', 'like', 'apples', '</s>']
29
+ probability = 1.0
30
+
31
+ for w1, w2 in zip(test[:-1], test[1:]):
32
+ p = bigrams[(w1, w2)] / unigrams[w1]
33
+ probability *= p
34
+ print(f"P({w2}|{w1}) = {bigrams[(w1,w2)]}/{unigrams[w1]} = {p:.6f}")
35
+
36
+ print("Sentence Probability =", round(probability, 8))
@@ -0,0 +1,72 @@
1
+ [
2
+ {
3
+ "number": 1,
4
+ "label": "B1",
5
+ "question": "Tokenization and Stop-word Removal using NLTK"
6
+ },
7
+ {
8
+ "number": 2,
9
+ "label": "B2",
10
+ "question": "Tokenization and Stop-word Removal using spaCy"
11
+ },
12
+ {
13
+ "number": 3,
14
+ "label": "B3",
15
+ "question": "Stemming and Lemmatization using spaCy"
16
+ },
17
+ {
18
+ "number": 4,
19
+ "label": "B4",
20
+ "question": "Stemming and Lemmatization using NLTK"
21
+ },
22
+ {
23
+ "number": 5,
24
+ "label": "B5",
25
+ "question": "Design a Python Program to Illustrate Corpus"
26
+ },
27
+ {
28
+ "number": 6,
29
+ "label": "B6",
30
+ "question": "Generate a Constituency Parse Tree"
31
+ },
32
+ {
33
+ "number": 7,
34
+ "label": "B7",
35
+ "question": "Generate a Dependency Parse Tree"
36
+ },
37
+ {
38
+ "number": 8,
39
+ "label": "C1",
40
+ "question": "POS Tagging on Text Scraped from a Website"
41
+ },
42
+ {
43
+ "number": 9,
44
+ "label": "C2",
45
+ "question": "Implement a Bigram Model and Calculate Test-Sentence Probability"
46
+ },
47
+ {
48
+ "number": 10,
49
+ "label": "C3",
50
+ "question": "Add-One (Laplace) Smoothing for an N-gram Model"
51
+ },
52
+ {
53
+ "number": 11,
54
+ "label": "C4",
55
+ "question": "Calculate Good-Turing Frequency"
56
+ },
57
+ {
58
+ "number": 12,
59
+ "label": "C5",
60
+ "question": "Text Classification"
61
+ },
62
+ {
63
+ "number": 13,
64
+ "label": "C6",
65
+ "question": "Calculate Vector Similarity in Semantic Space"
66
+ },
67
+ {
68
+ "number": 14,
69
+ "label": "C7",
70
+ "question": "Identify Context of Ambiguous Words using BERT"
71
+ }
72
+ ]
@@ -0,0 +1,71 @@
1
+ Metadata-Version: 2.4
2
+ Name: nlpkit14
3
+ Version: 0.3.0
4
+ Summary: Execute fourteen NLP practical programs with commented source and expected outputs
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: nltk<4,>=3.9
8
+ Requires-Dist: spacy<4,>=3.8
9
+ Requires-Dist: scikit-learn<2,>=1.5
10
+ Requires-Dist: requests<3,>=2.32
11
+ Requires-Dist: beautifulsoup4<5,>=4.12
12
+ Provides-Extra: models
13
+ Requires-Dist: torch<3,>=2.4; extra == "models"
14
+ Requires-Dist: transformers<5,>=4.45; extra == "models"
15
+ Requires-Dist: benepar<0.3,>=0.2.0; extra == "models"
16
+ Requires-Dist: sentencepiece<1,>=0.2; extra == "models"
17
+
18
+ # nlpkit14 0.3.0
19
+
20
+ Run the fourteen programs from the supplied IA1 question/code/output document.
21
+
22
+ ```python
23
+ import nlpkit14 as n
24
+ n.q1() # Actually runs question 1 and prints computed output
25
+ n.source(1) # Shows the code, question and expected output as comments
26
+ n.questions()
27
+ ```
28
+
29
+ Question numbers 1–7 are B1–B7. Numbers 8–14 are C1–C7. The question, expected output, and extra notes are comments in each bundled standalone Python program. Exercise calls print only the program's output. No expected-output text is substituted for model computation.
30
+
31
+ ## Install and prepare online once
32
+
33
+ Install the shared wheel, then prepare the basic data and spaCy model:
34
+
35
+ ```sh
36
+ python -m pip install ./nlpkit14-0.3.0-py3-none-any.whl
37
+ python -c "import nlpkit14 as n; n.setup()"
38
+ ```
39
+
40
+ For all exercises, install the model extra and run the complete setup (large downloads):
41
+
42
+ ```sh
43
+ python -m pip install './nlpkit14-0.3.0-py3-none-any.whl[models]'
44
+ python -c "import nlpkit14 as n; n.setup(models=True)"
45
+ ```
46
+
47
+ This is a local release of the new nlpkit14 project, not yet uploaded to PyPI. Do not use pip install nlpkit14 until publication succeeds.
48
+
49
+ ## Offline installation
50
+
51
+ On an internet-connected machine with the SAME OS, architecture and Python version as the offline machine, download the wheel and dependencies:
52
+
53
+ ```sh
54
+ python -m pip download --dest wheelhouse './nlpkit14-0.3.0-py3-none-any.whl[models]'
55
+ ```
56
+
57
+ Install and run setup online on that matching machine. Copy the wheelhouse, both installed spaCy model packages (or their installation wheels), and the full data/cache folder to the offline machine. Model data defaults to ~/.nlpkit14; set NLPKIT14_DATA before setup/import to choose a portable folder. Copying the entire prepared Python environment is platform specific; do not copy a Mac environment to Windows.
58
+
59
+ On the offline computer:
60
+
61
+ ```sh
62
+ python -m pip install --no-index --find-links=wheelhouse nlpkit14==0.3.0
63
+ ```
64
+
65
+ Install the spaCy model wheels from local storage too. Keep the copied data folder at ~/.nlpkit14 or point NLPKIT14_DATA to it. Model and dependency archives are not included in this small library wheel.
66
+
67
+ q8 fetches https://www.bnmit.org/ and requires internet even after setup. Other exercises can run without internet after all their requirements are installed. No downloads run implicitly from q1–q14. Missing packages/data raise their real installation errors rather than producing fake results.
68
+
69
+ ## Output fidelity
70
+
71
+ The original algorithms and sample input are preserved. Downloads are moved to explicit setup. HTTP errors are checked. BERT uses evaluation mode and local cached model files. The raw Good–Turing demonstration is not a normalized probability estimator. The document's classifier fits its vocabulary before splitting and is an educational example, not an unbiased evaluation pipeline. Model outputs, parse trees, POS tags and similarity values can differ from the commented reference output. The document's B5 reference omits POS lines that the code actually prints. Read TEST_RESULTS.md for exactly which programs were executed.
@@ -0,0 +1,20 @@
1
+ nlpkit14/__init__.py,sha256=2EHXNbGUKxx4Ye2c9TZadt7fsOQarGe_GPX0gb5QToQ,2869
2
+ nlpkit14/questions.json,sha256=CVPEhmk-O3BZHxDaaZrna7XHzea7R6RzknIH_7Guozk,1473
3
+ nlpkit14/programs/q1.py,sha256=ahswJa7pL7JWeAqtc5RGZte_oZLlcZflAa-j_ieVHfA,1183
4
+ nlpkit14/programs/q10.py,sha256=tWRjvc7hD0zLTFvLvjIHdVb5wXRqmttd_-3SWCElrWU,1086
5
+ nlpkit14/programs/q11.py,sha256=BfLYiyaxQWRQo19vZ7PUJX5sLTonacctVH3noalhWC8,1105
6
+ nlpkit14/programs/q12.py,sha256=RZws0e4PfZ7rtiLXTCX317ghaAEBcDpcuz6qHGlMHI4,1694
7
+ nlpkit14/programs/q13.py,sha256=1ERbF9xHdwOfb37lBjwZhSfVR-ibNtMaqmbyseykGIo,716
8
+ nlpkit14/programs/q14.py,sha256=vvkdMsJDpdfkenX1qNef_e7t53hy-1BDxvY8Chktx6c,1443
9
+ nlpkit14/programs/q2.py,sha256=9bLonO1zS8TIeGCKxPy6eJ1mLY-wlResFXz2EjAAew8,1082
10
+ nlpkit14/programs/q3.py,sha256=AH0krQLuUe0yI5y5YN7ps0qAJsC2nK3A8D47fCbS3ik,974
11
+ nlpkit14/programs/q4.py,sha256=xu6Jow4Fqn7vpMSOTeJ3qOlaZQEkFzcuWQdUWr31mdM,1406
12
+ nlpkit14/programs/q5.py,sha256=98wjuG9qh-zP2_9c8YuAHTrEFqA_aJJDk00v6bpMIs4,1261
13
+ nlpkit14/programs/q6.py,sha256=we8-i04A-H48UGQE7TKdqPhLqwSSWbHmmnD2clC6H4s,1330
14
+ nlpkit14/programs/q7.py,sha256=1f6olq4RaJmygdkpesVXMNRb6tFq0Kq4fQrO_ohXf_Y,1069
15
+ nlpkit14/programs/q8.py,sha256=PZWqzAkHKx84PcLhx6zIRi50Xvk8_yCYqVQKPlKi0dw,1167
16
+ nlpkit14/programs/q9.py,sha256=DjlgwamtvDwvfZzDSRy4vnJazY41-5r7b7wH4Nsjq_Y,1002
17
+ nlpkit14-0.3.0.dist-info/METADATA,sha256=izsROo-CFlx30m35clCpACTZzEuE-HkClFg7AhpqvAQ,3701
18
+ nlpkit14-0.3.0.dist-info/WHEEL,sha256=16fc_9Rp854SLcdhaDEjr0u65p0e3FhZxihNgcnCE98,91
19
+ nlpkit14-0.3.0.dist-info/top_level.txt,sha256=DDWqq9h6vlXFiGvftng11Hx_I1Nfge5RFEqR2HfxNVE,9
20
+ nlpkit14-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ nlpkit14