practical08 0.4.0__tar.gz → 0.5.0__tar.gz
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.
- practical08-0.5.0/PKG-INFO +53 -0
- practical08-0.5.0/README.md +39 -0
- {practical08-0.4.0 → practical08-0.5.0}/pyproject.toml +6 -2
- practical08-0.5.0/src/practical08/__init__.py +168 -0
- practical08-0.5.0/src/practical08.egg-info/PKG-INFO +53 -0
- {practical08-0.4.0 → practical08-0.5.0}/tests/test_package.py +9 -2
- practical08-0.4.0/PKG-INFO +0 -51
- practical08-0.4.0/README.md +0 -37
- practical08-0.4.0/src/practical08/__init__.py +0 -165
- practical08-0.4.0/src/practical08.egg-info/PKG-INFO +0 -51
- {practical08-0.4.0 → practical08-0.5.0}/LICENSE +0 -0
- {practical08-0.4.0 → practical08-0.5.0}/setup.cfg +0 -0
- {practical08-0.4.0 → practical08-0.5.0}/src/practical08.egg-info/SOURCES.txt +0 -0
- {practical08-0.4.0 → practical08-0.5.0}/src/practical08.egg-info/dependency_links.txt +0 -0
- {practical08-0.4.0 → practical08-0.5.0}/src/practical08.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: practical08
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: AIML practical programs with interactive inputs and viva Q&A
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Keywords: education,machine-learning,practicals,jupyter
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Topic :: Education
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Practical08 v0.5.0
|
|
16
|
+
|
|
17
|
+
A small Python package for finding AIML practical programs by natural-language questions. The `ask()` function prints the complete code, required libraries, and viva questions with answers. The displayed code prompts for relevant inputs where appropriate.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m pip install --upgrade practical08==0.5.0
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Use from Python or terminal
|
|
26
|
+
|
|
27
|
+
Create `main.py`:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from practical08 import ask
|
|
31
|
+
ask("Write a program for DBSCAN clustering")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run it:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python main.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or directly from terminal:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
python -c "from practical08 import ask; ask('Write a program for DBSCAN clustering')"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Copy the displayed program into a separate `.py` file to execute it; install the listed third-party libraries if they are not already installed. For example, clustering/classification programs use `numpy` and/or `scikit-learn`; the XGBoost practical additionally needs `xgboost`.
|
|
47
|
+
|
|
48
|
+
## Notes
|
|
49
|
+
|
|
50
|
+
- Contains 30 practical programs across Units IV, V, and VI.
|
|
51
|
+
- Includes viva questions and short answers for each practical.
|
|
52
|
+
- Uses sample datasets for model-training demonstrations and asks for configurable values; data-driven examples prompt for user input.
|
|
53
|
+
- The library prints code; it does not execute arbitrary returned code automatically.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Practical08 v0.5.0
|
|
2
|
+
|
|
3
|
+
A small Python package for finding AIML practical programs by natural-language questions. The `ask()` function prints the complete code, required libraries, and viva questions with answers. The displayed code prompts for relevant inputs where appropriate.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
python -m pip install --upgrade practical08==0.5.0
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Use from Python or terminal
|
|
12
|
+
|
|
13
|
+
Create `main.py`:
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from practical08 import ask
|
|
17
|
+
ask("Write a program for DBSCAN clustering")
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Run it:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python main.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or directly from terminal:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
python -c "from practical08 import ask; ask('Write a program for DBSCAN clustering')"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Copy the displayed program into a separate `.py` file to execute it; install the listed third-party libraries if they are not already installed. For example, clustering/classification programs use `numpy` and/or `scikit-learn`; the XGBoost practical additionally needs `xgboost`.
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
|
|
36
|
+
- Contains 30 practical programs across Units IV, V, and VI.
|
|
37
|
+
- Includes viva questions and short answers for each practical.
|
|
38
|
+
- Uses sample datasets for model-training demonstrations and asks for configurable values; data-driven examples prompt for user input.
|
|
39
|
+
- The library prints code; it does not execute arbitrary returned code automatically.
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "practical08"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.5.0"
|
|
8
|
+
description = "AIML practical programs with interactive inputs and viva Q&A"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
11
11
|
license = "MIT"
|
|
@@ -21,3 +21,7 @@ package-dir = {"" = "src"}
|
|
|
21
21
|
|
|
22
22
|
[tool.setuptools.packages.find]
|
|
23
23
|
where = ["src"]
|
|
24
|
+
|
|
25
|
+
[tool.pytest.ini_options]
|
|
26
|
+
pythonpath = ["src"]
|
|
27
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""PracticalPrep: retrieve stored practical programs by natural-language question."""
|
|
2
|
+
from difflib import SequenceMatcher
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
_PROGRAMS = [{'id': 'IV01', 'unit': 'IV', 'topic': 'K-Means clustering', 'statement': 'Apply K-Means clustering to group data points.', 'keywords': ['kmeans', 'clustering', 'partition', 'groups'], 'code': "from sklearn.cluster import KMeans\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nmodel = KMeans(n_clusters=k, random_state=42, n_init=10)\nlabels = model.fit_predict(X)\nprint('Cluster labels:', labels)\nprint('Centroids:\\n', model.cluster_centers_)", 'explanation': 'K-Means assigns each point to one of k clusters and updates cluster centers.', 'libraries': ['scikit-learn', 'numpy'], 'viva': [{'question': 'What is K-Means clustering?', 'answer': 'K-Means assigns each point to one of k clusters and updates cluster centers.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV02', 'unit': 'IV', 'topic': 'Hierarchical clustering', 'statement': 'Perform agglomerative hierarchical clustering.', 'keywords': ['hierarchical', 'agglomerative', 'dendrogram', 'clustering'], 'code': "from sklearn.cluster import AgglomerativeClustering\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nmodel = AgglomerativeClustering(n_clusters=k)\nprint('Cluster labels:', model.fit_predict(X))", 'explanation': 'Agglomerative clustering starts with individual points and repeatedly merges nearby clusters.', 'libraries': ['scikit-learn', 'numpy'], 'viva': [{'question': 'What is Hierarchical clustering?', 'answer': 'Agglomerative clustering starts with individual points and repeatedly merges nearby clusters.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV03', 'unit': 'IV', 'topic': 'Apriori frequent items', 'statement': 'Find frequent single items in a transaction dataset using minimum support.', 'keywords': ['apriori', 'frequent', 'itemsets', 'transactions', 'support'], 'code': "transactions = [\n ['bread', 'milk'], ['bread', 'diaper', 'beer', 'eggs'],\n ['milk', 'diaper', 'beer', 'cola'], ['bread', 'milk', 'diaper', 'beer'],\n ['bread', 'milk', 'diaper', 'cola']\n]\nmin_support = int(input('Minimum support count: '))\ncounts = {}\nfor transaction in transactions:\n for item in set(transaction):\n counts[item] = counts.get(item, 0) + 1\nprint('Frequent items:')\nfor item, count in sorted(counts.items()):\n if count >= min_support:\n print(item, 'support =', count)", 'explanation': 'This compact Apriori-style demonstration counts frequent individual items. Full Apriori also generates and tests item combinations.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Apriori frequent items?', 'answer': 'This compact Apriori-style demonstration counts frequent individual items. Full Apriori also generates and tests item combinations.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV04', 'unit': 'IV', 'topic': 'DBSCAN clustering', 'statement': 'Group data using density-based spatial clustering and identify noise points.', 'keywords': ['dbscan', 'density', 'based', 'clustering', 'noise', 'eps', 'min_samples'], 'code': "from sklearn.cluster import DBSCAN\nimport numpy as np\n\nX = np.array([[1, 2], [2, 2], [2, 3], [8, 7], [8, 8], [25, 80]])\neps = float(input('Enter eps: '))\nmin_samples = int(input('Enter min_samples: '))\nlabels = DBSCAN(eps=eps, min_samples=min_samples).fit_predict(X)\nprint('Cluster labels:', labels)\nprint('-1 represents noise/outliers.')", 'explanation': 'DBSCAN forms dense regions into clusters; points labelled -1 are treated as noise.', 'libraries': ['scikit-learn', 'numpy'], 'viva': [{'question': 'What is DBSCAN clustering?', 'answer': 'DBSCAN forms dense regions into clusters; points labelled -1 are treated as noise.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV05', 'unit': 'IV', 'topic': 'WCSS calculation', 'statement': 'Calculate within-cluster sum of squares for K-Means.', 'keywords': ['wcss', 'inertia', 'within', 'cluster', 'sum', 'squares', 'elbow'], 'code': "from sklearn.cluster import KMeans\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nmodel = KMeans(n_clusters=k, random_state=42, n_init=10).fit(X)\nprint('WCSS:', model.inertia_)", 'explanation': 'WCSS is the sum of squared distances from points to their assigned cluster centers; scikit-learn exposes it as inertia_.', 'libraries': ['scikit-learn', 'numpy'], 'viva': [{'question': 'What is WCSS calculation?', 'answer': 'WCSS is the sum of squared distances from points to their assigned cluster centers; scikit-learn exposes it as inertia_.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV06', 'unit': 'IV', 'topic': 'Silhouette score per point', 'statement': 'Calculate silhouette score for every data point.', 'keywords': ['silhouette', 'samples', 'score', 'each', 'point', 'clustering'], 'code': "from sklearn.cluster import KMeans\nfrom sklearn.metrics import silhouette_samples\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters (2 to n-1): '))\nlabels = KMeans(n_clusters=k, random_state=42, n_init=10).fit_predict(X)\nprint('Silhouette scores:', silhouette_samples(X, labels))", 'explanation': 'Silhouette scores range from -1 to 1; higher values generally indicate better-separated clusters.', 'libraries': ['scikit-learn', 'numpy'], 'viva': [{'question': 'What is Silhouette score per point?', 'answer': 'Silhouette scores range from -1 to 1; higher values generally indicate better-separated clusters.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV07', 'unit': 'IV', 'topic': 'Davies-Bouldin Index', 'statement': 'Evaluate clustering quality using Davies-Bouldin Index.', 'keywords': ['davies', 'bouldin', 'index', 'clustering', 'evaluation'], 'code': "from sklearn.cluster import KMeans\nfrom sklearn.metrics import davies_bouldin_score\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nlabels = KMeans(n_clusters=k, random_state=42, n_init=10).fit_predict(X)\nprint('Davies-Bouldin Index:', davies_bouldin_score(X, labels))", 'explanation': 'Lower Davies-Bouldin Index values generally indicate more compact, better-separated clusters.', 'libraries': ['scikit-learn', 'numpy'], 'viva': [{'question': 'What is Davies-Bouldin Index?', 'answer': 'Lower Davies-Bouldin Index values generally indicate more compact, better-separated clusters.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV08', 'unit': 'IV', 'topic': 'Threshold anomaly detection', 'statement': 'Detect anomalies using a numeric threshold.', 'keywords': ['threshold', 'anomaly', 'outlier', 'detection'], 'code': "values = [10, 12, 11, 13, 80, 9, 12]\nthreshold = float(input('Enter anomaly threshold: '))\nfor i, value in enumerate(values):\n if value > threshold:\n print('Anomaly at index', i, ':', value)", 'explanation': 'A value is flagged when it crosses the chosen threshold. The threshold should suit the data and problem.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Threshold anomaly detection?', 'answer': 'A value is flagged when it crosses the chosen threshold. The threshold should suit the data and problem.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV09', 'unit': 'IV', 'topic': 'Group documents by common words', 'statement': 'Find common words in two documents.', 'keywords': ['documents', 'common', 'words', 'text', 'intersection'], 'code': "doc1 = input('Enter first document: ').strip()\ndoc2 = input('Enter second document: ').strip()\nwords1 = set(doc1.lower().split())\nwords2 = set(doc2.lower().split())\nprint('Common words:', sorted(words1 & words2))", 'explanation': 'Convert document words into sets and use set intersection to find shared words.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Group documents by common words?', 'answer': 'Convert document words into sets and use set intersection to find shared words.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'IV10', 'unit': 'IV', 'topic': 'Retail customer segmentation', 'statement': 'Segment retail customers by annual income and spending score.', 'keywords': ['retail', 'customer', 'segmentation', 'income', 'spending', 'kmeans'], 'code': "from sklearn.cluster import KMeans\nimport numpy as np\n\ncustomers = np.array([[15, 39], [16, 81], [17, 6], [18, 77], [19, 40], [20, 76]]) # income, spending score\nk = int(input('Enter number of segments: '))\nlabels = KMeans(n_clusters=k, random_state=42, n_init=10).fit_predict(customers)\nfor i, label in enumerate(labels, start=1):\n print(f'Customer {i}: Segment {label}')", 'explanation': 'K-Means groups customers with similar income and spending-score patterns.', 'libraries': ['scikit-learn', 'numpy'], 'viva': [{'question': 'What is Retail customer segmentation?', 'answer': 'K-Means groups customers with similar income and spending-score patterns.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V01', 'unit': 'V', 'topic': 'Max voting ensemble', 'statement': 'Combine classifier predictions using majority voting.', 'keywords': ['max', 'voting', 'majority', 'vote', 'ensemble', 'classifier'], 'code': "from collections import Counter\n\nraw = input('Enter classifier predictions separated by commas (e.g. Yes,No,Yes): ')\npredictions = [item.strip() for item in raw.split(',') if item.strip()]\nif not predictions:\n raise ValueError('Enter at least one prediction.')\ncounts = Counter(predictions)\nprint('Vote counts:', counts)\nprint('Final prediction:', counts.most_common(1)[0][0])", 'explanation': 'The class receiving the most votes becomes the ensemble prediction.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Max voting ensemble?', 'answer': 'The class receiving the most votes becomes the ensemble prediction.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V02', 'unit': 'V', 'topic': 'Averaging predictions', 'statement': 'Combine numerical predictions by averaging them.', 'keywords': ['averaging', 'predictions', 'regression', 'ensemble'], 'code': "raw = input('Enter numeric predictions separated by commas (e.g. 120.5,118,123.5): ')\npredictions = [float(item.strip()) for item in raw.split(',') if item.strip()]\nif not predictions:\n raise ValueError('Enter at least one numeric prediction.')\nprint('Average prediction:', sum(predictions) / len(predictions))", 'explanation': 'Averaging is commonly used to combine numeric outputs from multiple regression models.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Averaging predictions?', 'answer': 'Averaging is commonly used to combine numeric outputs from multiple regression models.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V03', 'unit': 'V', 'topic': 'Weighted averaging', 'statement': 'Combine predictions using assigned model weights.', 'keywords': ['weighted', 'average', 'predictions', 'ensemble'], 'code': "predictions = [float(x.strip()) for x in input('Enter numeric predictions separated by commas: ').split(',') if x.strip()]\nweights = [float(x.strip()) for x in input('Enter matching weights separated by commas (must sum to 1): ').split(',') if x.strip()]\nif len(predictions) != len(weights) or abs(sum(weights) - 1.0) > 1e-8:\n raise ValueError('Weights must match predictions and sum to 1.')\nprint('Weighted prediction:', sum(p*w for p, w in zip(predictions, weights)))", 'explanation': 'Models with larger weights contribute more. These example weights sum to one.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Weighted averaging?', 'answer': 'Models with larger weights contribute more. These example weights sum to one.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V04', 'unit': 'V', 'topic': 'Bagging ensemble', 'statement': 'Train a bagging classifier using bootstrap samples.', 'keywords': ['bagging', 'bootstrap', 'aggregation', 'classifier'], 'code': "from sklearn.ensemble import BaggingClassifier\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\ntest_size = float(input('Test set proportion (0.1 to 0.4, default 0.2): ') or 0.2)\nif not 0.1 <= test_size <= 0.4:\n raise ValueError('Test set proportion must be between 0.1 and 0.4.')\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)\nmodel = BaggingClassifier(estimator=DecisionTreeClassifier(), n_estimators=10, random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Bagging trains models on bootstrap samples and aggregates their predictions.', 'libraries': ['scikit-learn'], 'viva': [{'question': 'What is Bagging ensemble?', 'answer': 'Bagging trains models on bootstrap samples and aggregates their predictions.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V05', 'unit': 'V', 'topic': 'AdaBoost classifier', 'statement': 'Train an AdaBoost classifier using decision stumps.', 'keywords': ['adaboost', 'adaptive', 'boosting', 'decision', 'stump'], 'code': "from sklearn.ensemble import AdaBoostClassifier\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\ntest_size = float(input('Test set proportion (0.1 to 0.4, default 0.2): ') or 0.2)\nif not 0.1 <= test_size <= 0.4:\n raise ValueError('Test set proportion must be between 0.1 and 0.4.')\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)\nstump = DecisionTreeClassifier(max_depth=1, random_state=42)\nmodel = AdaBoostClassifier(estimator=stump, n_estimators=50, random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'AdaBoost gives more attention to examples previous weak learners classified incorrectly.', 'libraries': ['scikit-learn'], 'viva': [{'question': 'What is AdaBoost classifier?', 'answer': 'AdaBoost gives more attention to examples previous weak learners classified incorrectly.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V06', 'unit': 'V', 'topic': 'Gradient Boosting classifier', 'statement': 'Train a Gradient Boosting classifier and evaluate accuracy.', 'keywords': ['gradient', 'boosting', 'classifier', 'sequential', 'trees'], 'code': "from sklearn.ensemble import GradientBoostingClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\ntest_size = float(input('Test set proportion (0.1 to 0.4, default 0.2): ') or 0.2)\nif not 0.1 <= test_size <= 0.4:\n raise ValueError('Test set proportion must be between 0.1 and 0.4.')\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)\nmodel = GradientBoostingClassifier(random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Gradient Boosting adds weak learners sequentially to improve on earlier errors.', 'libraries': ['scikit-learn'], 'viva': [{'question': 'What is Gradient Boosting classifier?', 'answer': 'Gradient Boosting adds weak learners sequentially to improve on earlier errors.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V07', 'unit': 'V', 'topic': 'XGBoost classifier', 'statement': 'Train an XGBoost classifier on a sample classification dataset.', 'keywords': ['xgboost', 'classifier', 'extreme', 'gradient', 'boosting'], 'code': "from xgboost import XGBClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\ntest_size = float(input('Test set proportion (0.1 to 0.4, default 0.2): ') or 0.2)\nif not 0.1 <= test_size <= 0.4:\n raise ValueError('Test set proportion must be between 0.1 and 0.4.')\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)\nmodel = XGBClassifier(n_estimators=50, max_depth=3, learning_rate=0.1, eval_metric='mlogloss')\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'XGBoost is an optimized gradient-boosting library. Install it separately with pip install xgboost.', 'libraries': ['xgboost', 'scikit-learn'], 'viva': [{'question': 'What is XGBoost classifier?', 'answer': 'XGBoost is an optimized gradient-boosting library. Install it separately with pip install xgboost.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V08', 'unit': 'V', 'topic': 'Random Forest classifier', 'statement': 'Train and evaluate a Random Forest classifier.', 'keywords': ['random', 'forest', 'classifier', 'ensemble', 'decision', 'trees'], 'code': "from sklearn.ensemble import RandomForestClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\ntest_size = float(input('Test set proportion (0.1 to 0.4, default 0.2): ') or 0.2)\nif not 0.1 <= test_size <= 0.4:\n raise ValueError('Test set proportion must be between 0.1 and 0.4.')\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)\nmodel = RandomForestClassifier(n_estimators=100, random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Random Forest averages/votes across many decision trees trained with randomness.', 'libraries': ['scikit-learn'], 'viva': [{'question': 'What is Random Forest classifier?', 'answer': 'Random Forest averages/votes across many decision trees trained with randomness.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V09', 'unit': 'V', 'topic': 'Stacking ensemble', 'statement': 'Combine multiple base estimators using a meta-classifier.', 'keywords': ['stacking', 'classifier', 'meta', 'learner', 'ensemble'], 'code': "from sklearn.ensemble import StackingClassifier\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\ntest_size = float(input('Test set proportion (0.1 to 0.4, default 0.2): ') or 0.2)\nif not 0.1 <= test_size <= 0.4:\n raise ValueError('Test set proportion must be between 0.1 and 0.4.')\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)\nbase = [('tree', DecisionTreeClassifier(max_depth=3)), ('knn', KNeighborsClassifier(n_neighbors=5))]\nmodel = StackingClassifier(estimators=base, final_estimator=LogisticRegression(max_iter=1000))\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Stacking trains a meta-model to combine predictions from multiple base models.', 'libraries': ['scikit-learn'], 'viva': [{'question': 'What is Stacking ensemble?', 'answer': 'Stacking trains a meta-model to combine predictions from multiple base models.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'V10', 'unit': 'V', 'topic': 'Fraud detection with multiple models', 'statement': 'Compare Logistic Regression and Random Forest for fraud classification.', 'keywords': ['fraud', 'detection', 'multiple', 'models', 'compare'], 'code': "from sklearn.datasets import make_classification\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nn_samples = int(input('Number of synthetic transactions (default 1000): ') or 1000)\nX, y = make_classification(n_samples=n_samples, n_features=12, weights=[0.95, 0.05], random_state=42)\ntest_size = float(input('Test set proportion (0.1 to 0.4, default 0.2): ') or 0.2)\nX_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=test_size, random_state=42)\nmodels = {'Logistic Regression': LogisticRegression(max_iter=1000), 'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42)}\nfor name, model in models.items():\n model.fit(X_train, y_train)\n print(name, 'accuracy:', round(accuracy_score(y_test, model.predict(X_test)), 3))", 'explanation': 'This uses synthetic data to demonstrate model comparison; it is not a production fraud detector.', 'libraries': ['scikit-learn'], 'viva': [{'question': 'What is Fraud detection with multiple models?', 'answer': 'This uses synthetic data to demonstrate model comparison; it is not a production fraud detector.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI01', 'unit': 'VI', 'topic': 'Epsilon-greedy multi-armed bandit', 'statement': 'Choose an arm using epsilon-greedy exploration.', 'keywords': ['multi', 'armed', 'bandit', 'epsilon', 'greedy', 'explore', 'exploit'], 'code': "import random\n\nestimated_values = [0.2, 0.7, 0.5] # estimated reward per arm\nepsilon = float(input('Enter epsilon (0 to 1): '))\nif random.random() < epsilon:\n action = random.randrange(len(estimated_values))\n print('Exploration: selected random arm', action)\nelse:\n action = max(range(len(estimated_values)), key=estimated_values.__getitem__)\n print('Exploitation: selected best estimated arm', action)", 'explanation': 'With probability epsilon, explore a random arm; otherwise exploit the arm with the highest estimated reward.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Epsilon-greedy multi-armed bandit?', 'answer': 'With probability epsilon, explore a random arm; otherwise exploit the arm with the highest estimated reward.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI02', 'unit': 'VI', 'topic': 'Discounted return', 'statement': 'Calculate discounted return from a reward sequence.', 'keywords': ['discounted', 'return', 'gamma', 'rewards', 'reinforcement', 'learning'], 'code': "rewards = [1, 2, 3]\ngamma = float(input('Enter discount factor gamma (0 to 1): '))\nG = 0\nfor reward in reversed(rewards):\n G = reward + gamma * G\nprint('Discounted return:', G)", 'explanation': 'The return is the sum of future rewards discounted by powers of gamma.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Discounted return?', 'answer': 'The return is the sum of future rewards discounted by powers of gamma.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI03', 'unit': 'VI', 'topic': 'State value from rewards', 'statement': 'Estimate a state value from observed rewards.', 'keywords': ['state', 'value', 'mean', 'rewards', 'reinforcement', 'learning'], 'code': "rewards = [float(x.strip()) for x in input('Enter observed rewards separated by commas (e.g. 2,1,4,3,5): ').split(',') if x.strip()]\nif not rewards:\n raise ValueError('Enter at least one reward.')\nvalue = sum(rewards) / len(rewards)\nprint('Estimated state value:', value)", 'explanation': 'This simplified estimate uses the average observed reward. Full RL state values estimate expected long-term return.', 'libraries': ['standard library'], 'viva': [{'question': 'What is State value from rewards?', 'answer': 'This simplified estimate uses the average observed reward. Full RL state values estimate expected long-term return.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI04', 'unit': 'VI', 'topic': 'Bellman state value update', 'statement': 'Update a state value using the Bellman expectation-style equation.', 'keywords': ['bellman', 'equation', 'state', 'value', 'reward', 'next', 'value', 'gamma'], 'code': "reward = float(input('Immediate reward: '))\ngamma = float(input('Discount factor gamma: '))\nnext_value = float(input('Value of next state: '))\nvalue = reward + gamma * next_value\nprint('Updated value:', value)", 'explanation': 'For a deterministic single next state, this simplified update is reward + gamma times next-state value.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Bellman state value update?', 'answer': 'For a deterministic single next state, this simplified update is reward + gamma times next-state value.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI05', 'unit': 'VI', 'topic': 'Q-Learning update', 'statement': 'Update a Q-value using the Q-Learning equation.', 'keywords': ['q', 'learning', 'update', 'alpha', 'gamma', 'max', 'next', 'q'], 'code': "q = float(input('Current Q value: '))\nreward = float(input('Reward: '))\nmax_next_q = float(input('Maximum next-state Q value: '))\nalpha = float(input('Learning rate alpha: '))\ngamma = float(input('Discount factor gamma: '))\nupdated_q = q + alpha * (reward + gamma * max_next_q - q)\nprint('Updated Q value:', updated_q)", 'explanation': 'Q-Learning is off-policy: it uses the maximum next-state Q-value in its update target.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Q-Learning update?', 'answer': 'Q-Learning is off-policy: it uses the maximum next-state Q-value in its update target.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI06', 'unit': 'VI', 'topic': 'SARSA update', 'statement': 'Update a Q-value using the SARSA equation.', 'keywords': ['sarsa', 'update', 'next', 'action', 'q', 'on', 'policy'], 'code': "q = float(input('Current Q value: '))\nreward = float(input('Reward: '))\nnext_q = float(input('Q value for next chosen action: '))\nalpha = float(input('Learning rate alpha: '))\ngamma = float(input('Discount factor gamma: '))\nupdated_q = q + alpha * (reward + gamma * next_q - q)\nprint('Updated Q value:', updated_q)", 'explanation': 'SARSA is on-policy: it uses the Q-value of the next action actually chosen by the policy.', 'libraries': ['standard library'], 'viva': [{'question': 'What is SARSA update?', 'answer': 'SARSA is on-policy: it uses the Q-value of the next action actually chosen by the policy.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI07', 'unit': 'VI', 'topic': 'Epsilon-greedy action selection', 'statement': 'Select an action from Q-values using epsilon-greedy.', 'keywords': ['epsilon', 'greedy', 'action', 'selection', 'q', 'values'], 'code': "import random\n\nq_values = [1.2, 0.5, 2.1]\nepsilon = float(input('Enter epsilon (0 to 1): '))\nif random.random() < epsilon:\n action = random.randrange(len(q_values))\nelse:\n action = max(range(len(q_values)), key=q_values.__getitem__)\nprint('Selected action index:', action)", 'explanation': 'Epsilon controls exploration; with probability 1-epsilon the action with the largest Q-value is selected.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Epsilon-greedy action selection?', 'answer': 'Epsilon controls exploration; with probability 1-epsilon the action with the largest Q-value is selected.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI08', 'unit': 'VI', 'topic': 'Simple Markov Decision Process', 'statement': 'Represent a small MDP using states, actions, and rewards.', 'keywords': ['mdp', 'markov', 'decision', 'process', 'states', 'actions', 'rewards'], 'code': "states = ['Start', 'Goal']\nactions = {'Start': ['move_right', 'stay'], 'Goal': []}\ngoal_reward = float(input('Enter reward for reaching Goal (default example: 10): ') or 10)\nstay_reward = float(input('Enter reward for staying at Start (default example: -1): ') or -1)\nrewards = {('Start', 'move_right', 'Goal'): goal_reward, ('Start', 'stay', 'Start'): stay_reward}\nprint('States:', states)\nprint('Actions:', actions)\nprint('Rewards:')\nfor transition, reward in rewards.items():\n print(transition, '->', reward)", 'explanation': 'An MDP is defined by states, actions, transition probabilities, rewards, and a discount factor. This example illustrates states/actions/rewards only.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Simple Markov Decision Process?', 'answer': 'An MDP is defined by states, actions, transition probabilities, rewards, and a discount factor. This example illustrates states/actions/rewards only.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI09', 'unit': 'VI', 'topic': 'Temporal Difference learning update', 'statement': 'Update a state value using a one-step TD target.', 'keywords': ['temporal', 'difference', 'td', 'learning', 'update'], 'code': "value = float(input('Current state value: '))\nreward = float(input('Observed reward: '))\nnext_value = float(input('Next-state value: '))\nalpha = float(input('Learning rate alpha: '))\ngamma = float(input('Discount factor gamma: '))\nupdated = value + alpha * (reward + gamma * next_value - value)\nprint('Updated state value:', updated)", 'explanation': 'TD learning updates the current estimate toward reward + gamma times the next-state estimate.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Temporal Difference learning update?', 'answer': 'TD learning updates the current estimate toward reward + gamma times the next-state estimate.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}, {'id': 'VI10', 'unit': 'VI', 'topic': 'Robot maze Q-Learning', 'statement': 'Demonstrate Q-Learning for a tiny three-state robot path.', 'keywords': ['robot', 'maze', 'q', 'learning', 'reinforcement', 'learning'], 'code': "import random\n\n# States 0 -> 1 -> 2 (goal); actions: 0=left, 1=right\nQ = [[0.0, 0.0] for _ in range(3)]\nalpha = float(input('Learning rate alpha (0 to 1, default 0.5): ') or 0.5)\ngamma = float(input('Discount factor gamma (0 to 1, default 0.9): ') or 0.9)\nepsilon = float(input('Exploration rate epsilon (0 to 1, default 0.2): ') or 0.2)\nepisodes = int(input('Training episodes (default 200): ') or 200)\nfor episode in range(episodes):\n state = 0\n for _ in range(10):\n if random.random() < epsilon:\n action = random.randrange(2)\n else:\n action = max(range(2), key=lambda a: Q[state][a])\n next_state = max(0, min(2, state + (1 if action == 1 else -1)))\n reward = 10 if next_state == 2 else -1\n best_next = max(Q[next_state]) if next_state != 2 else 0\n Q[state][action] += alpha * (reward + gamma * best_next - Q[state][action])\n state = next_state\n if state == 2:\n break\nprint('Learned Q-table:')\nfor state, values in enumerate(Q):\n print(state, values)", 'explanation': 'The agent explores the tiny maze and updates Q-values to learn actions that lead to the goal.', 'libraries': ['standard library'], 'viva': [{'question': 'What is Robot maze Q-Learning?', 'answer': 'The agent explores the tiny maze and updates Q-values to learn actions that lead to the goal.'}, {'question': 'What is the main input or parameter in this program?', 'answer': 'The program prompts you for the relevant values; where a standard sample dataset is used, it is included so the program runs immediately after copying.'}, {'question': 'How do you interpret the output?', 'answer': 'Read the printed result and relate it to the practical objective. For clustering, labels identify groups; for classifiers, accuracy measures correct predictions; for reinforcement learning, values guide action selection.'}]}]
|
|
6
|
+
|
|
7
|
+
_ALIASES = {
|
|
8
|
+
"IV01": ["kmeans", "k means", "centroid clustering", "partition clustering"],
|
|
9
|
+
"IV02": ["hierarchical clustering", "agglomerative clustering", "bottom up clustering"],
|
|
10
|
+
"IV03": ["apriori", "frequent items", "frequent itemsets", "market basket analysis", "support count"],
|
|
11
|
+
"IV04": ["dbscan", "density based clustering", "density-based clustering", "noise points", "density clustering"],
|
|
12
|
+
"IV05": ["wcss", "within cluster sum of squares", "within-cluster sum of squares", "elbow method"],
|
|
13
|
+
"IV06": ["silhouette", "silhouette score", "silhouette samples", "silhouette score per point"],
|
|
14
|
+
"IV07": ["davies bouldin", "davies-bouldin", "db index", "davies bouldin index"],
|
|
15
|
+
"IV08": ["anomaly detection", "threshold anomaly", "outlier detection"],
|
|
16
|
+
"IV09": ["common words", "document similarity", "words common between documents"],
|
|
17
|
+
"IV10": ["customer segmentation", "retail segmentation", "spending score", "customer clusters"],
|
|
18
|
+
"V01": ["max voting", "majority voting", "majority vote", "hard voting"],
|
|
19
|
+
"V02": ["averaging predictions", "average predictions", "mean ensemble"],
|
|
20
|
+
"V03": ["weighted averaging", "weighted average", "weighted predictions"],
|
|
21
|
+
"V04": ["bagging", "bootstrap aggregation", "bootstrap samples"],
|
|
22
|
+
"V05": ["adaboost", "ada boost", "adaptive boosting"],
|
|
23
|
+
"V06": ["gradient boosting", "gradientboosting"],
|
|
24
|
+
"V07": ["xgboost", "xg boost", "extreme gradient boosting"],
|
|
25
|
+
"V08": ["random forest", "randomforest", "forest classifier"],
|
|
26
|
+
"V09": ["stacking", "stacked ensemble", "meta learner", "meta-model"],
|
|
27
|
+
"V10": ["fraud detection", "fraud classification", "compare models for fraud"],
|
|
28
|
+
"VI01": ["multi armed bandit", "multi-armed bandit", "epsilon greedy bandit"],
|
|
29
|
+
"VI02": ["discounted return", "discounted reward", "return gamma", "cumulative discounted reward"],
|
|
30
|
+
"VI03": ["state value", "value from rewards", "state value from rewards"],
|
|
31
|
+
"VI04": ["bellman", "bellman equation", "bellman update", "state value update"],
|
|
32
|
+
"VI05": ["q learning", "q-learning", "q learning update", "q value update"],
|
|
33
|
+
"VI06": ["sarsa", "sarsa update", "on policy update"],
|
|
34
|
+
"VI07": ["epsilon greedy", "epsilon-greedy", "action selection", "exploration exploitation"],
|
|
35
|
+
"VI08": ["mdp", "markov decision process", "states actions rewards"],
|
|
36
|
+
"VI09": ["temporal difference", "td learning", "td update"],
|
|
37
|
+
"VI10": ["robot maze", "maze q learning", "robot q learning"]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
def _normalize(text):
|
|
41
|
+
text = str(text).lower().replace("-", " ").replace("_", " ")
|
|
42
|
+
text = re.sub(r"[^a-z0-9]+", " ", text)
|
|
43
|
+
return " ".join(text.split())
|
|
44
|
+
|
|
45
|
+
def _tokens(text):
|
|
46
|
+
# Remove generic command words that add little meaning to a practical question.
|
|
47
|
+
ignored = {"write", "program", "code", "implement", "create", "make", "perform",
|
|
48
|
+
"calculate", "find", "using", "use", "for", "the", "a", "an", "to",
|
|
49
|
+
"on", "with", "and", "of", "in", "from", "apply", "develop", "show"}
|
|
50
|
+
return {t for t in _normalize(text).split() if t not in ignored}
|
|
51
|
+
|
|
52
|
+
def _score(query, entry):
|
|
53
|
+
qnorm = _normalize(query)
|
|
54
|
+
qtokens = _tokens(query)
|
|
55
|
+
if not qnorm or not qtokens:
|
|
56
|
+
return 0.0
|
|
57
|
+
|
|
58
|
+
pid = entry.get("id", "")
|
|
59
|
+
topic = _normalize(entry.get("topic", ""))
|
|
60
|
+
statement = _normalize(entry.get("statement", ""))
|
|
61
|
+
keywords = [_normalize(k) for k in entry.get("keywords", [])]
|
|
62
|
+
aliases = [_normalize(a) for a in _ALIASES.get(pid, [])]
|
|
63
|
+
candidates = [topic, statement] + keywords + aliases
|
|
64
|
+
|
|
65
|
+
# Strong exact phrase / known alias match, which fixes ambiguous matches such as DBSCAN.
|
|
66
|
+
best_phrase = max((1.0 if c and (c in qnorm or qnorm in c) else 0.0 for c in candidates), default=0.0)
|
|
67
|
+
if best_phrase:
|
|
68
|
+
return 0.98 if any(a and a in qnorm for a in aliases) else 0.96
|
|
69
|
+
|
|
70
|
+
# Token overlap against the topic and aliases matters more than broad statement overlap.
|
|
71
|
+
topic_tokens = _tokens(topic)
|
|
72
|
+
alias_tokens = set().union(*(_tokens(a) for a in aliases)) if aliases else set()
|
|
73
|
+
keyword_tokens = set().union(*(_tokens(k) for k in keywords)) if keywords else set()
|
|
74
|
+
statement_tokens = _tokens(statement)
|
|
75
|
+
def overlap(target):
|
|
76
|
+
return len(qtokens & target) / max(1, len(qtokens))
|
|
77
|
+
focused = max(overlap(topic_tokens), overlap(alias_tokens), overlap(keyword_tokens))
|
|
78
|
+
broad = overlap(statement_tokens)
|
|
79
|
+
from difflib import SequenceMatcher
|
|
80
|
+
fuzzy = max([SequenceMatcher(None, qnorm, c).ratio() for c in candidates] or [0.0])
|
|
81
|
+
return round(min(0.94, 0.68 * focused + 0.20 * broad + 0.12 * fuzzy), 4)
|
|
82
|
+
|
|
83
|
+
def search_programs(query, limit=5, unit=None):
|
|
84
|
+
"""Return matching program dictionaries ranked by relevance, including a score."""
|
|
85
|
+
results = []
|
|
86
|
+
for p in _PROGRAMS:
|
|
87
|
+
if unit and p["unit"].upper() != str(unit).upper():
|
|
88
|
+
continue
|
|
89
|
+
item = dict(p)
|
|
90
|
+
item["score"] = _score(query, p)
|
|
91
|
+
results.append(item)
|
|
92
|
+
results.sort(key=lambda x: x["score"], reverse=True)
|
|
93
|
+
return results[:max(0, int(limit))]
|
|
94
|
+
|
|
95
|
+
def find_program(query, min_score=0.40, unit=None):
|
|
96
|
+
"""Return the best matching program dictionary, or None for a weak match."""
|
|
97
|
+
results = search_programs(query, limit=1, unit=unit)
|
|
98
|
+
if not results or results[0]["score"] < float(min_score):
|
|
99
|
+
return None
|
|
100
|
+
return results[0]
|
|
101
|
+
|
|
102
|
+
def get_program(program_id):
|
|
103
|
+
"""Get a stored program by ID, such as IV04, V08, or VI05."""
|
|
104
|
+
key = str(program_id).strip().upper()
|
|
105
|
+
for p in _PROGRAMS:
|
|
106
|
+
if p["id"].upper() == key:
|
|
107
|
+
return dict(p)
|
|
108
|
+
raise KeyError(f"Unknown program ID: {program_id!r}")
|
|
109
|
+
|
|
110
|
+
def list_programs(unit=None):
|
|
111
|
+
"""List stored programs; optionally filter by IV, V, or VI."""
|
|
112
|
+
return [dict(p, code=None) for p in _PROGRAMS
|
|
113
|
+
if unit is None or p["unit"].upper() == str(unit).upper()]
|
|
114
|
+
|
|
115
|
+
def search_theory(query, unit=None, limit=5):
|
|
116
|
+
"""Return ranked theory-note dictionaries."""
|
|
117
|
+
results = []
|
|
118
|
+
for note in _THEORY:
|
|
119
|
+
if unit and note["unit"].upper() != str(unit).upper():
|
|
120
|
+
continue
|
|
121
|
+
entry = dict(note, keywords=[])
|
|
122
|
+
entry["score"] = _score(query, entry)
|
|
123
|
+
results.append(entry)
|
|
124
|
+
results.sort(key=lambda x: x["score"], reverse=True)
|
|
125
|
+
return results[:max(0, int(limit))]
|
|
126
|
+
|
|
127
|
+
def list_theory_topics(unit=None):
|
|
128
|
+
"""List theory topics, optionally filtered by unit."""
|
|
129
|
+
return [dict(n) for n in _THEORY
|
|
130
|
+
if unit is None or n["unit"].upper() == str(unit).upper()]
|
|
131
|
+
|
|
132
|
+
def __dir__():
|
|
133
|
+
return sorted(set(globals()) | {"find_program", "search_programs", "get_program",
|
|
134
|
+
"list_programs", "search_theory", "list_theory_topics"})
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def ask(question, unit=None):
|
|
139
|
+
"""Print the best matching practical program. Returns nothing to keep notebooks tidy."""
|
|
140
|
+
result = find_program(question, unit=unit)
|
|
141
|
+
if result is None:
|
|
142
|
+
print("I couldn't confidently match that question.")
|
|
143
|
+
print("Try the topic name or a keyword such as DBSCAN, XGBoost, SARSA, or WCSS.")
|
|
144
|
+
print("You can also use search_programs(question) to inspect possible matches.")
|
|
145
|
+
return
|
|
146
|
+
print(f"[{result['id']}] {result['topic']} (match: {result['score'] * 100:.1f}%)")
|
|
147
|
+
print(result["explanation"])
|
|
148
|
+
print("\n--- COMPLETE CODE ---\n")
|
|
149
|
+
print(result["code"])
|
|
150
|
+
print("\nRequired libraries:", ", ".join(result["libraries"]))
|
|
151
|
+
print("\n--- VIVA QUESTIONS & ANSWERS ---")
|
|
152
|
+
for index, item in enumerate(result.get("viva", []), start=1):
|
|
153
|
+
print(f"Q{index}. {item['question']}")
|
|
154
|
+
print(f" A: {item['answer']}")
|
|
155
|
+
|
|
156
|
+
def run():
|
|
157
|
+
"""Interactive terminal loop: type practical questions, or 'exit' to quit."""
|
|
158
|
+
print("Practical08 — type a practical question (or 'exit' to quit).")
|
|
159
|
+
while True:
|
|
160
|
+
try:
|
|
161
|
+
question = input("\nQuestion: ").strip()
|
|
162
|
+
except (EOFError, KeyboardInterrupt):
|
|
163
|
+
print("\nExiting Practical08.")
|
|
164
|
+
break
|
|
165
|
+
if question.lower() in {"exit", "quit", "q"}:
|
|
166
|
+
break
|
|
167
|
+
if question:
|
|
168
|
+
ask(question)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: practical08
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: AIML practical programs with interactive inputs and viva Q&A
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Keywords: education,machine-learning,practicals,jupyter
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Topic :: Education
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Practical08 v0.5.0
|
|
16
|
+
|
|
17
|
+
A small Python package for finding AIML practical programs by natural-language questions. The `ask()` function prints the complete code, required libraries, and viva questions with answers. The displayed code prompts for relevant inputs where appropriate.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m pip install --upgrade practical08==0.5.0
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Use from Python or terminal
|
|
26
|
+
|
|
27
|
+
Create `main.py`:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from practical08 import ask
|
|
31
|
+
ask("Write a program for DBSCAN clustering")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run it:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python main.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or directly from terminal:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
python -c "from practical08 import ask; ask('Write a program for DBSCAN clustering')"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Copy the displayed program into a separate `.py` file to execute it; install the listed third-party libraries if they are not already installed. For example, clustering/classification programs use `numpy` and/or `scikit-learn`; the XGBoost practical additionally needs `xgboost`.
|
|
47
|
+
|
|
48
|
+
## Notes
|
|
49
|
+
|
|
50
|
+
- Contains 30 practical programs across Units IV, V, and VI.
|
|
51
|
+
- Includes viva questions and short answers for each practical.
|
|
52
|
+
- Uses sample datasets for model-training demonstrations and asks for configurable values; data-driven examples prompt for user input.
|
|
53
|
+
- The library prints code; it does not execute arbitrary returned code automatically.
|
|
@@ -20,9 +20,16 @@ def test_other_known_queries():
|
|
|
20
20
|
def test_weak_query_rejected():
|
|
21
21
|
assert find_program("please do the thing") is None
|
|
22
22
|
|
|
23
|
-
def
|
|
23
|
+
def test_ask_prints_code_and_viva(capsys):
|
|
24
24
|
assert ask("DBSCAN clustering") is None
|
|
25
|
-
|
|
25
|
+
output = capsys.readouterr().out
|
|
26
|
+
assert "[IV04]" in output
|
|
27
|
+
assert "COMPLETE CODE" in output
|
|
28
|
+
assert "VIVA QUESTIONS & ANSWERS" in output
|
|
29
|
+
|
|
30
|
+
def test_inputs_and_viva_present():
|
|
31
|
+
assert "input(" in get_program("V01")["code"]
|
|
32
|
+
assert len(get_program("V01")["viva"]) >= 3
|
|
26
33
|
|
|
27
34
|
def test_exact_lookup():
|
|
28
35
|
assert get_program("VI05")["topic"] == "Q-Learning update"
|
practical08-0.4.0/PKG-INFO
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: practical08
|
|
3
|
-
Version: 0.4.0
|
|
4
|
-
Summary: Searchable AIML practical program library with simple ask interface
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
Keywords: education,machine-learning,practicals,jupyter
|
|
7
|
-
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: Operating System :: OS Independent
|
|
9
|
-
Classifier: Topic :: Education
|
|
10
|
-
Requires-Python: >=3.9
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
License-File: LICENSE
|
|
13
|
-
Dynamic: license-file
|
|
14
|
-
|
|
15
|
-
# Practical08
|
|
16
|
-
|
|
17
|
-
Finalized question-to-code library containing 30 AIML practical programs from Units IV, V and VI.
|
|
18
|
-
|
|
19
|
-
## Simple Jupyter use
|
|
20
|
-
|
|
21
|
-
```python
|
|
22
|
-
%pip install --upgrade practical08
|
|
23
|
-
from practical08 import ask
|
|
24
|
-
|
|
25
|
-
ask("Write a program for DBSCAN clustering")
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
`ask(question)` prints the best matching program, a brief explanation, the complete code and required libraries. It does not print an extra dictionary afterward.
|
|
29
|
-
|
|
30
|
-
## Examples
|
|
31
|
-
|
|
32
|
-
```python
|
|
33
|
-
ask("Implement Random Forest classifier")
|
|
34
|
-
ask("Calculate discounted return using gamma")
|
|
35
|
-
ask("Find frequent items using Apriori")
|
|
36
|
-
ask("Update Q value using Q-Learning")
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Optional exact lookup
|
|
40
|
-
|
|
41
|
-
```python
|
|
42
|
-
from practical08 import get_program
|
|
43
|
-
print(get_program("IV04")["code"])
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Search behavior
|
|
47
|
-
- Recognizes aliases such as DBSCAN / density-based clustering, XGBoost / extreme gradient boosting, and Q-learning / Q value update.
|
|
48
|
-
- Uses topic-focused scoring and rejects weak matches instead of silently selecting unrelated programs.
|
|
49
|
-
- No AI API key is required; matching uses Python's standard library and works offline after installation.
|
|
50
|
-
- Some returned examples need additional packages (e.g. `scikit-learn`, `numpy`, or `xgboost`) to execute.
|
|
51
|
-
- `ask()` prints code but never executes it automatically.
|
practical08-0.4.0/README.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# Practical08
|
|
2
|
-
|
|
3
|
-
Finalized question-to-code library containing 30 AIML practical programs from Units IV, V and VI.
|
|
4
|
-
|
|
5
|
-
## Simple Jupyter use
|
|
6
|
-
|
|
7
|
-
```python
|
|
8
|
-
%pip install --upgrade practical08
|
|
9
|
-
from practical08 import ask
|
|
10
|
-
|
|
11
|
-
ask("Write a program for DBSCAN clustering")
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
`ask(question)` prints the best matching program, a brief explanation, the complete code and required libraries. It does not print an extra dictionary afterward.
|
|
15
|
-
|
|
16
|
-
## Examples
|
|
17
|
-
|
|
18
|
-
```python
|
|
19
|
-
ask("Implement Random Forest classifier")
|
|
20
|
-
ask("Calculate discounted return using gamma")
|
|
21
|
-
ask("Find frequent items using Apriori")
|
|
22
|
-
ask("Update Q value using Q-Learning")
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Optional exact lookup
|
|
26
|
-
|
|
27
|
-
```python
|
|
28
|
-
from practical08 import get_program
|
|
29
|
-
print(get_program("IV04")["code"])
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Search behavior
|
|
33
|
-
- Recognizes aliases such as DBSCAN / density-based clustering, XGBoost / extreme gradient boosting, and Q-learning / Q value update.
|
|
34
|
-
- Uses topic-focused scoring and rejects weak matches instead of silently selecting unrelated programs.
|
|
35
|
-
- No AI API key is required; matching uses Python's standard library and works offline after installation.
|
|
36
|
-
- Some returned examples need additional packages (e.g. `scikit-learn`, `numpy`, or `xgboost`) to execute.
|
|
37
|
-
- `ask()` prints code but never executes it automatically.
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
"""PracticalPrep: retrieve stored practical programs by natural-language question."""
|
|
2
|
-
from difflib import SequenceMatcher
|
|
3
|
-
import re
|
|
4
|
-
|
|
5
|
-
_PROGRAMS = [{'id': 'IV01', 'unit': 'IV', 'topic': 'K-Means clustering', 'statement': 'Apply K-Means clustering to group data points.', 'keywords': ['kmeans', 'clustering', 'partition', 'groups'], 'code': "from sklearn.cluster import KMeans\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nmodel = KMeans(n_clusters=k, random_state=42, n_init=10)\nlabels = model.fit_predict(X)\nprint('Cluster labels:', labels)\nprint('Centroids:\\n', model.cluster_centers_)", 'explanation': 'K-Means assigns each point to one of k clusters and updates cluster centers.', 'libraries': ['scikit-learn', 'numpy']}, {'id': 'IV02', 'unit': 'IV', 'topic': 'Hierarchical clustering', 'statement': 'Perform agglomerative hierarchical clustering.', 'keywords': ['hierarchical', 'agglomerative', 'dendrogram', 'clustering'], 'code': "from sklearn.cluster import AgglomerativeClustering\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nmodel = AgglomerativeClustering(n_clusters=k)\nprint('Cluster labels:', model.fit_predict(X))", 'explanation': 'Agglomerative clustering starts with individual points and repeatedly merges nearby clusters.', 'libraries': ['scikit-learn', 'numpy']}, {'id': 'IV03', 'unit': 'IV', 'topic': 'Apriori frequent items', 'statement': 'Find frequent single items in a transaction dataset using minimum support.', 'keywords': ['apriori', 'frequent', 'itemsets', 'transactions', 'support'], 'code': "transactions = [\n ['bread', 'milk'], ['bread', 'diaper', 'beer', 'eggs'],\n ['milk', 'diaper', 'beer', 'cola'], ['bread', 'milk', 'diaper', 'beer'],\n ['bread', 'milk', 'diaper', 'cola']\n]\nmin_support = int(input('Minimum support count: '))\ncounts = {}\nfor transaction in transactions:\n for item in set(transaction):\n counts[item] = counts.get(item, 0) + 1\nprint('Frequent items:')\nfor item, count in sorted(counts.items()):\n if count >= min_support:\n print(item, 'support =', count)", 'explanation': 'This compact Apriori-style demonstration counts frequent individual items. Full Apriori also generates and tests item combinations.', 'libraries': ['standard library']}, {'id': 'IV04', 'unit': 'IV', 'topic': 'DBSCAN clustering', 'statement': 'Group data using density-based spatial clustering and identify noise points.', 'keywords': ['dbscan', 'density', 'based', 'clustering', 'noise', 'eps', 'min_samples'], 'code': "from sklearn.cluster import DBSCAN\nimport numpy as np\n\nX = np.array([[1, 2], [2, 2], [2, 3], [8, 7], [8, 8], [25, 80]])\neps = float(input('Enter eps: '))\nmin_samples = int(input('Enter min_samples: '))\nlabels = DBSCAN(eps=eps, min_samples=min_samples).fit_predict(X)\nprint('Cluster labels:', labels)\nprint('-1 represents noise/outliers.')", 'explanation': 'DBSCAN forms dense regions into clusters; points labelled -1 are treated as noise.', 'libraries': ['scikit-learn', 'numpy']}, {'id': 'IV05', 'unit': 'IV', 'topic': 'WCSS calculation', 'statement': 'Calculate within-cluster sum of squares for K-Means.', 'keywords': ['wcss', 'inertia', 'within', 'cluster', 'sum', 'squares', 'elbow'], 'code': "from sklearn.cluster import KMeans\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nmodel = KMeans(n_clusters=k, random_state=42, n_init=10).fit(X)\nprint('WCSS:', model.inertia_)", 'explanation': 'WCSS is the sum of squared distances from points to their assigned cluster centers; scikit-learn exposes it as inertia_.', 'libraries': ['scikit-learn', 'numpy']}, {'id': 'IV06', 'unit': 'IV', 'topic': 'Silhouette score per point', 'statement': 'Calculate silhouette score for every data point.', 'keywords': ['silhouette', 'samples', 'score', 'each', 'point', 'clustering'], 'code': "from sklearn.cluster import KMeans\nfrom sklearn.metrics import silhouette_samples\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters (2 to n-1): '))\nlabels = KMeans(n_clusters=k, random_state=42, n_init=10).fit_predict(X)\nprint('Silhouette scores:', silhouette_samples(X, labels))", 'explanation': 'Silhouette scores range from -1 to 1; higher values generally indicate better-separated clusters.', 'libraries': ['scikit-learn', 'numpy']}, {'id': 'IV07', 'unit': 'IV', 'topic': 'Davies-Bouldin Index', 'statement': 'Evaluate clustering quality using Davies-Bouldin Index.', 'keywords': ['davies', 'bouldin', 'index', 'clustering', 'evaluation'], 'code': "from sklearn.cluster import KMeans\nfrom sklearn.metrics import davies_bouldin_score\nimport numpy as np\n\nX = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])\nk = int(input('Enter number of clusters: '))\nlabels = KMeans(n_clusters=k, random_state=42, n_init=10).fit_predict(X)\nprint('Davies-Bouldin Index:', davies_bouldin_score(X, labels))", 'explanation': 'Lower Davies-Bouldin Index values generally indicate more compact, better-separated clusters.', 'libraries': ['scikit-learn', 'numpy']}, {'id': 'IV08', 'unit': 'IV', 'topic': 'Threshold anomaly detection', 'statement': 'Detect anomalies using a numeric threshold.', 'keywords': ['threshold', 'anomaly', 'outlier', 'detection'], 'code': "values = [10, 12, 11, 13, 80, 9, 12]\nthreshold = float(input('Enter anomaly threshold: '))\nfor i, value in enumerate(values):\n if value > threshold:\n print('Anomaly at index', i, ':', value)", 'explanation': 'A value is flagged when it crosses the chosen threshold. The threshold should suit the data and problem.', 'libraries': ['standard library']}, {'id': 'IV09', 'unit': 'IV', 'topic': 'Group documents by common words', 'statement': 'Find common words in two documents.', 'keywords': ['documents', 'common', 'words', 'text', 'intersection'], 'code': "doc1 = 'machine learning helps analyse data'\ndoc2 = 'data science uses machine learning'\nwords1 = set(doc1.lower().split())\nwords2 = set(doc2.lower().split())\nprint('Common words:', sorted(words1 & words2))", 'explanation': 'Convert document words into sets and use set intersection to find shared words.', 'libraries': ['standard library']}, {'id': 'IV10', 'unit': 'IV', 'topic': 'Retail customer segmentation', 'statement': 'Segment retail customers by annual income and spending score.', 'keywords': ['retail', 'customer', 'segmentation', 'income', 'spending', 'kmeans'], 'code': "from sklearn.cluster import KMeans\nimport numpy as np\n\ncustomers = np.array([[15, 39], [16, 81], [17, 6], [18, 77], [19, 40], [20, 76]]) # income, spending score\nk = int(input('Enter number of segments: '))\nlabels = KMeans(n_clusters=k, random_state=42, n_init=10).fit_predict(customers)\nfor i, label in enumerate(labels, start=1):\n print(f'Customer {i}: Segment {label}')", 'explanation': 'K-Means groups customers with similar income and spending-score patterns.', 'libraries': ['scikit-learn', 'numpy']}, {'id': 'V01', 'unit': 'V', 'topic': 'Max voting ensemble', 'statement': 'Combine classifier predictions using majority voting.', 'keywords': ['max', 'voting', 'majority', 'vote', 'ensemble', 'classifier'], 'code': "from collections import Counter\n\npredictions = ['Yes', 'No', 'Yes', 'Yes', 'No']\ncounts = Counter(predictions)\nprint('Vote counts:', counts)\nprint('Final prediction:', counts.most_common(1)[0][0])", 'explanation': 'The class receiving the most votes becomes the ensemble prediction.', 'libraries': ['standard library']}, {'id': 'V02', 'unit': 'V', 'topic': 'Averaging predictions', 'statement': 'Combine numerical predictions by averaging them.', 'keywords': ['averaging', 'predictions', 'regression', 'ensemble'], 'code': "predictions = [120.5, 118.0, 123.5]\nprint('Average prediction:', sum(predictions) / len(predictions))", 'explanation': 'Averaging is commonly used to combine numeric outputs from multiple regression models.', 'libraries': ['standard library']}, {'id': 'V03', 'unit': 'V', 'topic': 'Weighted averaging', 'statement': 'Combine predictions using assigned model weights.', 'keywords': ['weighted', 'average', 'predictions', 'ensemble'], 'code': "predictions = [120.5, 118.0, 123.5]\nweights = [0.5, 0.3, 0.2]\nif len(predictions) != len(weights) or abs(sum(weights) - 1.0) > 1e-8:\n raise ValueError('Weights must match predictions and sum to 1.')\nprint('Weighted prediction:', sum(p*w for p, w in zip(predictions, weights)))", 'explanation': 'Models with larger weights contribute more. These example weights sum to one.', 'libraries': ['standard library']}, {'id': 'V04', 'unit': 'V', 'topic': 'Bagging ensemble', 'statement': 'Train a bagging classifier using bootstrap samples.', 'keywords': ['bagging', 'bootstrap', 'aggregation', 'classifier'], 'code': "from sklearn.ensemble import BaggingClassifier\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\nmodel = BaggingClassifier(estimator=DecisionTreeClassifier(), n_estimators=10, random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Bagging trains models on bootstrap samples and aggregates their predictions.', 'libraries': ['scikit-learn']}, {'id': 'V05', 'unit': 'V', 'topic': 'AdaBoost classifier', 'statement': 'Train an AdaBoost classifier using decision stumps.', 'keywords': ['adaboost', 'adaptive', 'boosting', 'decision', 'stump'], 'code': "from sklearn.ensemble import AdaBoostClassifier\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\nstump = DecisionTreeClassifier(max_depth=1, random_state=42)\nmodel = AdaBoostClassifier(estimator=stump, n_estimators=50, random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'AdaBoost gives more attention to examples previous weak learners classified incorrectly.', 'libraries': ['scikit-learn']}, {'id': 'V06', 'unit': 'V', 'topic': 'Gradient Boosting classifier', 'statement': 'Train a Gradient Boosting classifier and evaluate accuracy.', 'keywords': ['gradient', 'boosting', 'classifier', 'sequential', 'trees'], 'code': "from sklearn.ensemble import GradientBoostingClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\nmodel = GradientBoostingClassifier(random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Gradient Boosting adds weak learners sequentially to improve on earlier errors.', 'libraries': ['scikit-learn']}, {'id': 'V07', 'unit': 'V', 'topic': 'XGBoost classifier', 'statement': 'Train an XGBoost classifier on a sample classification dataset.', 'keywords': ['xgboost', 'classifier', 'extreme', 'gradient', 'boosting'], 'code': "from xgboost import XGBClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\nmodel = XGBClassifier(n_estimators=50, max_depth=3, learning_rate=0.1, eval_metric='mlogloss')\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'XGBoost is an optimized gradient-boosting library. Install it separately with pip install xgboost.', 'libraries': ['xgboost', 'scikit-learn']}, {'id': 'V08', 'unit': 'V', 'topic': 'Random Forest classifier', 'statement': 'Train and evaluate a Random Forest classifier.', 'keywords': ['random', 'forest', 'classifier', 'ensemble', 'decision', 'trees'], 'code': "from sklearn.ensemble import RandomForestClassifier\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\nmodel = RandomForestClassifier(n_estimators=100, random_state=42)\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Random Forest averages/votes across many decision trees trained with randomness.', 'libraries': ['scikit-learn']}, {'id': 'V09', 'unit': 'V', 'topic': 'Stacking ensemble', 'statement': 'Combine multiple base estimators using a meta-classifier.', 'keywords': ['stacking', 'classifier', 'meta', 'learner', 'ensemble'], 'code': "from sklearn.ensemble import StackingClassifier\nfrom sklearn.tree import DecisionTreeClassifier\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.datasets import load_iris\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = load_iris(return_X_y=True)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\nbase = [('tree', DecisionTreeClassifier(max_depth=3)), ('knn', KNeighborsClassifier(n_neighbors=5))]\nmodel = StackingClassifier(estimators=base, final_estimator=LogisticRegression(max_iter=1000))\nmodel.fit(X_train, y_train)\nprint('Accuracy:', accuracy_score(y_test, model.predict(X_test)))", 'explanation': 'Stacking trains a meta-model to combine predictions from multiple base models.', 'libraries': ['scikit-learn']}, {'id': 'V10', 'unit': 'V', 'topic': 'Fraud detection with multiple models', 'statement': 'Compare Logistic Regression and Random Forest for fraud classification.', 'keywords': ['fraud', 'detection', 'multiple', 'models', 'compare'], 'code': "from sklearn.datasets import make_classification\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nX, y = make_classification(n_samples=1000, n_features=12, weights=[0.95, 0.05], random_state=42)\nX_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.2, random_state=42)\nmodels = {'Logistic Regression': LogisticRegression(max_iter=1000), 'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42)}\nfor name, model in models.items():\n model.fit(X_train, y_train)\n print(name, 'accuracy:', round(accuracy_score(y_test, model.predict(X_test)), 3))", 'explanation': 'This uses synthetic data to demonstrate model comparison; it is not a production fraud detector.', 'libraries': ['scikit-learn']}, {'id': 'VI01', 'unit': 'VI', 'topic': 'Epsilon-greedy multi-armed bandit', 'statement': 'Choose an arm using epsilon-greedy exploration.', 'keywords': ['multi', 'armed', 'bandit', 'epsilon', 'greedy', 'explore', 'exploit'], 'code': "import random\n\nestimated_values = [0.2, 0.7, 0.5] # estimated reward per arm\nepsilon = float(input('Enter epsilon (0 to 1): '))\nif random.random() < epsilon:\n action = random.randrange(len(estimated_values))\n print('Exploration: selected random arm', action)\nelse:\n action = max(range(len(estimated_values)), key=estimated_values.__getitem__)\n print('Exploitation: selected best estimated arm', action)", 'explanation': 'With probability epsilon, explore a random arm; otherwise exploit the arm with the highest estimated reward.', 'libraries': ['standard library']}, {'id': 'VI02', 'unit': 'VI', 'topic': 'Discounted return', 'statement': 'Calculate discounted return from a reward sequence.', 'keywords': ['discounted', 'return', 'gamma', 'rewards', 'reinforcement', 'learning'], 'code': "rewards = [1, 2, 3]\ngamma = float(input('Enter discount factor gamma (0 to 1): '))\nG = 0\nfor reward in reversed(rewards):\n G = reward + gamma * G\nprint('Discounted return:', G)", 'explanation': 'The return is the sum of future rewards discounted by powers of gamma.', 'libraries': ['standard library']}, {'id': 'VI03', 'unit': 'VI', 'topic': 'State value from rewards', 'statement': 'Estimate a state value from observed rewards.', 'keywords': ['state', 'value', 'mean', 'rewards', 'reinforcement', 'learning'], 'code': "rewards = [2, 1, 4, 3, 5]\nvalue = sum(rewards) / len(rewards)\nprint('Estimated state value:', value)", 'explanation': 'This simplified estimate uses the average observed reward. Full RL state values estimate expected long-term return.', 'libraries': ['standard library']}, {'id': 'VI04', 'unit': 'VI', 'topic': 'Bellman state value update', 'statement': 'Update a state value using the Bellman expectation-style equation.', 'keywords': ['bellman', 'equation', 'state', 'value', 'reward', 'next', 'value', 'gamma'], 'code': "reward = float(input('Immediate reward: '))\ngamma = float(input('Discount factor gamma: '))\nnext_value = float(input('Value of next state: '))\nvalue = reward + gamma * next_value\nprint('Updated value:', value)", 'explanation': 'For a deterministic single next state, this simplified update is reward + gamma times next-state value.', 'libraries': ['standard library']}, {'id': 'VI05', 'unit': 'VI', 'topic': 'Q-Learning update', 'statement': 'Update a Q-value using the Q-Learning equation.', 'keywords': ['q', 'learning', 'update', 'alpha', 'gamma', 'max', 'next', 'q'], 'code': "q = float(input('Current Q value: '))\nreward = float(input('Reward: '))\nmax_next_q = float(input('Maximum next-state Q value: '))\nalpha = float(input('Learning rate alpha: '))\ngamma = float(input('Discount factor gamma: '))\nupdated_q = q + alpha * (reward + gamma * max_next_q - q)\nprint('Updated Q value:', updated_q)", 'explanation': 'Q-Learning is off-policy: it uses the maximum next-state Q-value in its update target.', 'libraries': ['standard library']}, {'id': 'VI06', 'unit': 'VI', 'topic': 'SARSA update', 'statement': 'Update a Q-value using the SARSA equation.', 'keywords': ['sarsa', 'update', 'next', 'action', 'q', 'on', 'policy'], 'code': "q = float(input('Current Q value: '))\nreward = float(input('Reward: '))\nnext_q = float(input('Q value for next chosen action: '))\nalpha = float(input('Learning rate alpha: '))\ngamma = float(input('Discount factor gamma: '))\nupdated_q = q + alpha * (reward + gamma * next_q - q)\nprint('Updated Q value:', updated_q)", 'explanation': 'SARSA is on-policy: it uses the Q-value of the next action actually chosen by the policy.', 'libraries': ['standard library']}, {'id': 'VI07', 'unit': 'VI', 'topic': 'Epsilon-greedy action selection', 'statement': 'Select an action from Q-values using epsilon-greedy.', 'keywords': ['epsilon', 'greedy', 'action', 'selection', 'q', 'values'], 'code': "import random\n\nq_values = [1.2, 0.5, 2.1]\nepsilon = float(input('Enter epsilon (0 to 1): '))\nif random.random() < epsilon:\n action = random.randrange(len(q_values))\nelse:\n action = max(range(len(q_values)), key=q_values.__getitem__)\nprint('Selected action index:', action)", 'explanation': 'Epsilon controls exploration; with probability 1-epsilon the action with the largest Q-value is selected.', 'libraries': ['standard library']}, {'id': 'VI08', 'unit': 'VI', 'topic': 'Simple Markov Decision Process', 'statement': 'Represent a small MDP using states, actions, and rewards.', 'keywords': ['mdp', 'markov', 'decision', 'process', 'states', 'actions', 'rewards'], 'code': "states = ['Start', 'Goal']\nactions = {'Start': ['move_right', 'stay'], 'Goal': []}\nrewards = {('Start', 'move_right', 'Goal'): 10, ('Start', 'stay', 'Start'): -1}\nprint('States:', states)\nprint('Actions:', actions)\nprint('Rewards:')\nfor transition, reward in rewards.items():\n print(transition, '->', reward)", 'explanation': 'An MDP is defined by states, actions, transition probabilities, rewards, and a discount factor. This example illustrates states/actions/rewards only.', 'libraries': ['standard library']}, {'id': 'VI09', 'unit': 'VI', 'topic': 'Temporal Difference learning update', 'statement': 'Update a state value using a one-step TD target.', 'keywords': ['temporal', 'difference', 'td', 'learning', 'update'], 'code': "value = float(input('Current state value: '))\nreward = float(input('Observed reward: '))\nnext_value = float(input('Next-state value: '))\nalpha = float(input('Learning rate alpha: '))\ngamma = float(input('Discount factor gamma: '))\nupdated = value + alpha * (reward + gamma * next_value - value)\nprint('Updated state value:', updated)", 'explanation': 'TD learning updates the current estimate toward reward + gamma times the next-state estimate.', 'libraries': ['standard library']}, {'id': 'VI10', 'unit': 'VI', 'topic': 'Robot maze Q-Learning', 'statement': 'Demonstrate Q-Learning for a tiny three-state robot path.', 'keywords': ['robot', 'maze', 'q', 'learning', 'reinforcement', 'learning'], 'code': "import random\n\n# States 0 -> 1 -> 2 (goal); actions: 0=left, 1=right\nQ = [[0.0, 0.0] for _ in range(3)]\nalpha, gamma, epsilon = 0.5, 0.9, 0.2\nfor episode in range(200):\n state = 0\n for _ in range(10):\n if random.random() < epsilon:\n action = random.randrange(2)\n else:\n action = max(range(2), key=lambda a: Q[state][a])\n next_state = max(0, min(2, state + (1 if action == 1 else -1)))\n reward = 10 if next_state == 2 else -1\n best_next = max(Q[next_state]) if next_state != 2 else 0\n Q[state][action] += alpha * (reward + gamma * best_next - Q[state][action])\n state = next_state\n if state == 2:\n break\nprint('Learned Q-table:')\nfor state, values in enumerate(Q):\n print(state, values)", 'explanation': 'The agent explores the tiny maze and updates Q-values to learn actions that lead to the goal.', 'libraries': ['standard library']}]
|
|
6
|
-
_THEORY = [{'unit': 'IV', 'topic': 'Clustering', 'explanation': 'Grouping similar data points without predefined labels.'}, {'unit': 'IV', 'topic': 'K-Means', 'explanation': 'Partitions data into k clusters by iteratively updating centroids.'}, {'unit': 'IV', 'topic': 'Hierarchical clustering', 'explanation': 'Builds a hierarchy of clusters through repeated merges or splits.'}, {'unit': 'IV', 'topic': 'DBSCAN', 'explanation': 'Density-based clustering that can identify noise points.'}, {'unit': 'IV', 'topic': 'Apriori', 'explanation': 'Finds frequent itemsets using support and candidate pruning.'}, {'unit': 'IV', 'topic': 'Support count', 'explanation': 'Number of transactions containing an itemset.'}, {'unit': 'IV', 'topic': 'WCSS', 'explanation': 'Sum of squared distances from samples to their assigned cluster centers.'}, {'unit': 'IV', 'topic': 'Silhouette score', 'explanation': 'Measures how well a point fits its cluster compared with the nearest other cluster.'}, {'unit': 'IV', 'topic': 'Davies-Bouldin Index', 'explanation': 'Cluster quality metric; lower values are generally better.'}, {'unit': 'IV', 'topic': 'Anomaly detection', 'explanation': 'Identifies observations that differ substantially from expected patterns.'}, {'unit': 'V', 'topic': 'Ensemble learning', 'explanation': 'Combines several models to improve robustness or predictive performance.'}, {'unit': 'V', 'topic': 'Voting', 'explanation': 'Combines classification predictions by majority or weighted votes.'}, {'unit': 'V', 'topic': 'Averaging', 'explanation': 'Combines numeric model outputs by taking their mean.'}, {'unit': 'V', 'topic': 'Weighted averaging', 'explanation': 'Averages predictions with larger influence assigned to selected models.'}, {'unit': 'V', 'topic': 'Bagging', 'explanation': 'Trains models on bootstrap samples and aggregates their outputs.'}, {'unit': 'V', 'topic': 'Boosting', 'explanation': 'Trains weak learners sequentially to correct prior errors.'}, {'unit': 'V', 'topic': 'AdaBoost', 'explanation': 'Reweights difficult training examples as weak learners are added.'}, {'unit': 'V', 'topic': 'Gradient Boosting', 'explanation': 'Adds learners that reduce a loss function, often by fitting residual-like gradients.'}, {'unit': 'V', 'topic': 'XGBoost', 'explanation': 'An optimized gradient-boosted tree library.'}, {'unit': 'V', 'topic': 'Random Forest', 'explanation': 'Uses randomized decision trees and aggregates their predictions.'}, {'unit': 'V', 'topic': 'Stacking', 'explanation': 'Trains a meta-model on predictions from base models.'}, {'unit': 'VI', 'topic': 'Reinforcement Learning', 'explanation': 'An agent learns actions through interaction and rewards.'}, {'unit': 'VI', 'topic': 'MDP', 'explanation': 'A model with states, actions, transition probabilities, rewards, and discount factor.'}, {'unit': 'VI', 'topic': 'Exploration', 'explanation': 'Trying actions to learn their outcomes.'}, {'unit': 'VI', 'topic': 'Exploitation', 'explanation': 'Choosing the currently best-known action.'}, {'unit': 'VI', 'topic': 'Epsilon-greedy', 'explanation': 'Explores randomly with probability epsilon and otherwise exploits.'}, {'unit': 'VI', 'topic': 'Discounted return', 'explanation': 'Future rewards summed with discount factor gamma.'}, {'unit': 'VI', 'topic': 'Bellman equation', 'explanation': "Relates a state's value to immediate reward and future value."}, {'unit': 'VI', 'topic': 'Q-Learning', 'explanation': 'Off-policy learning using the maximum next-state action value.'}, {'unit': 'VI', 'topic': 'SARSA', 'explanation': 'On-policy learning using the next action actually selected.'}, {'unit': 'VI', 'topic': 'TD learning', 'explanation': 'Updates value estimates using a one-step prediction error.'}]
|
|
7
|
-
|
|
8
|
-
_ALIASES = {
|
|
9
|
-
"IV01": ["kmeans", "k means", "centroid clustering", "partition clustering"],
|
|
10
|
-
"IV02": ["hierarchical clustering", "agglomerative clustering", "bottom up clustering"],
|
|
11
|
-
"IV03": ["apriori", "frequent items", "frequent itemsets", "market basket analysis", "support count"],
|
|
12
|
-
"IV04": ["dbscan", "density based clustering", "density-based clustering", "noise points", "density clustering"],
|
|
13
|
-
"IV05": ["wcss", "within cluster sum of squares", "within-cluster sum of squares", "elbow method"],
|
|
14
|
-
"IV06": ["silhouette", "silhouette score", "silhouette samples", "silhouette score per point"],
|
|
15
|
-
"IV07": ["davies bouldin", "davies-bouldin", "db index", "davies bouldin index"],
|
|
16
|
-
"IV08": ["anomaly detection", "threshold anomaly", "outlier detection"],
|
|
17
|
-
"IV09": ["common words", "document similarity", "words common between documents"],
|
|
18
|
-
"IV10": ["customer segmentation", "retail segmentation", "spending score", "customer clusters"],
|
|
19
|
-
"V01": ["max voting", "majority voting", "majority vote", "hard voting"],
|
|
20
|
-
"V02": ["averaging predictions", "average predictions", "mean ensemble"],
|
|
21
|
-
"V03": ["weighted averaging", "weighted average", "weighted predictions"],
|
|
22
|
-
"V04": ["bagging", "bootstrap aggregation", "bootstrap samples"],
|
|
23
|
-
"V05": ["adaboost", "ada boost", "adaptive boosting"],
|
|
24
|
-
"V06": ["gradient boosting", "gradientboosting"],
|
|
25
|
-
"V07": ["xgboost", "xg boost", "extreme gradient boosting"],
|
|
26
|
-
"V08": ["random forest", "randomforest", "forest classifier"],
|
|
27
|
-
"V09": ["stacking", "stacked ensemble", "meta learner", "meta-model"],
|
|
28
|
-
"V10": ["fraud detection", "fraud classification", "compare models for fraud"],
|
|
29
|
-
"VI01": ["multi armed bandit", "multi-armed bandit", "epsilon greedy bandit"],
|
|
30
|
-
"VI02": ["discounted return", "discounted reward", "return gamma", "cumulative discounted reward"],
|
|
31
|
-
"VI03": ["state value", "value from rewards", "state value from rewards"],
|
|
32
|
-
"VI04": ["bellman", "bellman equation", "bellman update", "state value update"],
|
|
33
|
-
"VI05": ["q learning", "q-learning", "q learning update", "q value update"],
|
|
34
|
-
"VI06": ["sarsa", "sarsa update", "on policy update"],
|
|
35
|
-
"VI07": ["epsilon greedy", "epsilon-greedy", "action selection", "exploration exploitation"],
|
|
36
|
-
"VI08": ["mdp", "markov decision process", "states actions rewards"],
|
|
37
|
-
"VI09": ["temporal difference", "td learning", "td update"],
|
|
38
|
-
"VI10": ["robot maze", "maze q learning", "robot q learning"]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
def _normalize(text):
|
|
42
|
-
text = str(text).lower().replace("-", " ").replace("_", " ")
|
|
43
|
-
text = re.sub(r"[^a-z0-9]+", " ", text)
|
|
44
|
-
return " ".join(text.split())
|
|
45
|
-
|
|
46
|
-
def _tokens(text):
|
|
47
|
-
# Remove generic command words that add little meaning to a practical question.
|
|
48
|
-
ignored = {"write", "program", "code", "implement", "create", "make", "perform",
|
|
49
|
-
"calculate", "find", "using", "use", "for", "the", "a", "an", "to",
|
|
50
|
-
"on", "with", "and", "of", "in", "from", "apply", "develop", "show"}
|
|
51
|
-
return {t for t in _normalize(text).split() if t not in ignored}
|
|
52
|
-
|
|
53
|
-
def _score(query, entry):
|
|
54
|
-
qnorm = _normalize(query)
|
|
55
|
-
qtokens = _tokens(query)
|
|
56
|
-
if not qnorm or not qtokens:
|
|
57
|
-
return 0.0
|
|
58
|
-
|
|
59
|
-
pid = entry.get("id", "")
|
|
60
|
-
topic = _normalize(entry.get("topic", ""))
|
|
61
|
-
statement = _normalize(entry.get("statement", ""))
|
|
62
|
-
keywords = [_normalize(k) for k in entry.get("keywords", [])]
|
|
63
|
-
aliases = [_normalize(a) for a in _ALIASES.get(pid, [])]
|
|
64
|
-
candidates = [topic, statement] + keywords + aliases
|
|
65
|
-
|
|
66
|
-
# Strong exact phrase / known alias match, which fixes ambiguous matches such as DBSCAN.
|
|
67
|
-
best_phrase = max((1.0 if c and (c in qnorm or qnorm in c) else 0.0 for c in candidates), default=0.0)
|
|
68
|
-
if best_phrase:
|
|
69
|
-
return 0.98 if any(a and a in qnorm for a in aliases) else 0.96
|
|
70
|
-
|
|
71
|
-
# Token overlap against the topic and aliases matters more than broad statement overlap.
|
|
72
|
-
topic_tokens = _tokens(topic)
|
|
73
|
-
alias_tokens = set().union(*(_tokens(a) for a in aliases)) if aliases else set()
|
|
74
|
-
keyword_tokens = set().union(*(_tokens(k) for k in keywords)) if keywords else set()
|
|
75
|
-
statement_tokens = _tokens(statement)
|
|
76
|
-
def overlap(target):
|
|
77
|
-
return len(qtokens & target) / max(1, len(qtokens))
|
|
78
|
-
focused = max(overlap(topic_tokens), overlap(alias_tokens), overlap(keyword_tokens))
|
|
79
|
-
broad = overlap(statement_tokens)
|
|
80
|
-
from difflib import SequenceMatcher
|
|
81
|
-
fuzzy = max([SequenceMatcher(None, qnorm, c).ratio() for c in candidates] or [0.0])
|
|
82
|
-
return round(min(0.94, 0.68 * focused + 0.20 * broad + 0.12 * fuzzy), 4)
|
|
83
|
-
|
|
84
|
-
def search_programs(query, limit=5, unit=None):
|
|
85
|
-
"""Return matching program dictionaries ranked by relevance, including a score."""
|
|
86
|
-
results = []
|
|
87
|
-
for p in _PROGRAMS:
|
|
88
|
-
if unit and p["unit"].upper() != str(unit).upper():
|
|
89
|
-
continue
|
|
90
|
-
item = dict(p)
|
|
91
|
-
item["score"] = _score(query, p)
|
|
92
|
-
results.append(item)
|
|
93
|
-
results.sort(key=lambda x: x["score"], reverse=True)
|
|
94
|
-
return results[:max(0, int(limit))]
|
|
95
|
-
|
|
96
|
-
def find_program(query, min_score=0.40, unit=None):
|
|
97
|
-
"""Return the best matching program dictionary, or None for a weak match."""
|
|
98
|
-
results = search_programs(query, limit=1, unit=unit)
|
|
99
|
-
if not results or results[0]["score"] < float(min_score):
|
|
100
|
-
return None
|
|
101
|
-
return results[0]
|
|
102
|
-
|
|
103
|
-
def get_program(program_id):
|
|
104
|
-
"""Get a stored program by ID, such as IV04, V08, or VI05."""
|
|
105
|
-
key = str(program_id).strip().upper()
|
|
106
|
-
for p in _PROGRAMS:
|
|
107
|
-
if p["id"].upper() == key:
|
|
108
|
-
return dict(p)
|
|
109
|
-
raise KeyError(f"Unknown program ID: {program_id!r}")
|
|
110
|
-
|
|
111
|
-
def list_programs(unit=None):
|
|
112
|
-
"""List stored programs; optionally filter by IV, V, or VI."""
|
|
113
|
-
return [dict(p, code=None) for p in _PROGRAMS
|
|
114
|
-
if unit is None or p["unit"].upper() == str(unit).upper()]
|
|
115
|
-
|
|
116
|
-
def search_theory(query, unit=None, limit=5):
|
|
117
|
-
"""Return ranked theory-note dictionaries."""
|
|
118
|
-
results = []
|
|
119
|
-
for note in _THEORY:
|
|
120
|
-
if unit and note["unit"].upper() != str(unit).upper():
|
|
121
|
-
continue
|
|
122
|
-
entry = dict(note, keywords=[])
|
|
123
|
-
entry["score"] = _score(query, entry)
|
|
124
|
-
results.append(entry)
|
|
125
|
-
results.sort(key=lambda x: x["score"], reverse=True)
|
|
126
|
-
return results[:max(0, int(limit))]
|
|
127
|
-
|
|
128
|
-
def list_theory_topics(unit=None):
|
|
129
|
-
"""List theory topics, optionally filtered by unit."""
|
|
130
|
-
return [dict(n) for n in _THEORY
|
|
131
|
-
if unit is None or n["unit"].upper() == str(unit).upper()]
|
|
132
|
-
|
|
133
|
-
def __dir__():
|
|
134
|
-
return sorted(set(globals()) | {"find_program", "search_programs", "get_program",
|
|
135
|
-
"list_programs", "search_theory", "list_theory_topics"})
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def ask(question, unit=None):
|
|
140
|
-
"""Print the best matching practical program. Returns nothing to keep notebooks tidy."""
|
|
141
|
-
result = find_program(question, unit=unit)
|
|
142
|
-
if result is None:
|
|
143
|
-
print("I couldn't confidently match that question.")
|
|
144
|
-
print("Try the topic name or a keyword such as DBSCAN, XGBoost, SARSA, or WCSS.")
|
|
145
|
-
print("You can also use search_programs(question) to inspect possible matches.")
|
|
146
|
-
return
|
|
147
|
-
print(f"[{result['id']}] {result['topic']} (match: {result['score'] * 100:.1f}%)")
|
|
148
|
-
print(result["explanation"])
|
|
149
|
-
print("\n--- COMPLETE CODE ---\n")
|
|
150
|
-
print(result["code"])
|
|
151
|
-
print("\nRequired libraries:", ", ".join(result["libraries"]))
|
|
152
|
-
|
|
153
|
-
def run():
|
|
154
|
-
"""Interactive terminal loop: type practical questions, or 'exit' to quit."""
|
|
155
|
-
print("Practical08 — type a practical question (or 'exit' to quit).")
|
|
156
|
-
while True:
|
|
157
|
-
try:
|
|
158
|
-
question = input("\nQuestion: ").strip()
|
|
159
|
-
except (EOFError, KeyboardInterrupt):
|
|
160
|
-
print("\nExiting Practical08.")
|
|
161
|
-
break
|
|
162
|
-
if question.lower() in {"exit", "quit", "q"}:
|
|
163
|
-
break
|
|
164
|
-
if question:
|
|
165
|
-
ask(question)
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: practical08
|
|
3
|
-
Version: 0.4.0
|
|
4
|
-
Summary: Searchable AIML practical program library with simple ask interface
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
Keywords: education,machine-learning,practicals,jupyter
|
|
7
|
-
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: Operating System :: OS Independent
|
|
9
|
-
Classifier: Topic :: Education
|
|
10
|
-
Requires-Python: >=3.9
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
License-File: LICENSE
|
|
13
|
-
Dynamic: license-file
|
|
14
|
-
|
|
15
|
-
# Practical08
|
|
16
|
-
|
|
17
|
-
Finalized question-to-code library containing 30 AIML practical programs from Units IV, V and VI.
|
|
18
|
-
|
|
19
|
-
## Simple Jupyter use
|
|
20
|
-
|
|
21
|
-
```python
|
|
22
|
-
%pip install --upgrade practical08
|
|
23
|
-
from practical08 import ask
|
|
24
|
-
|
|
25
|
-
ask("Write a program for DBSCAN clustering")
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
`ask(question)` prints the best matching program, a brief explanation, the complete code and required libraries. It does not print an extra dictionary afterward.
|
|
29
|
-
|
|
30
|
-
## Examples
|
|
31
|
-
|
|
32
|
-
```python
|
|
33
|
-
ask("Implement Random Forest classifier")
|
|
34
|
-
ask("Calculate discounted return using gamma")
|
|
35
|
-
ask("Find frequent items using Apriori")
|
|
36
|
-
ask("Update Q value using Q-Learning")
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Optional exact lookup
|
|
40
|
-
|
|
41
|
-
```python
|
|
42
|
-
from practical08 import get_program
|
|
43
|
-
print(get_program("IV04")["code"])
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Search behavior
|
|
47
|
-
- Recognizes aliases such as DBSCAN / density-based clustering, XGBoost / extreme gradient boosting, and Q-learning / Q value update.
|
|
48
|
-
- Uses topic-focused scoring and rejects weak matches instead of silently selecting unrelated programs.
|
|
49
|
-
- No AI API key is required; matching uses Python's standard library and works offline after installation.
|
|
50
|
-
- Some returned examples need additional packages (e.g. `scikit-learn`, `numpy`, or `xgboost`) to execute.
|
|
51
|
-
- `ask()` prints code but never executes it automatically.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|