scikit-lab-kit 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,372 @@
1
+ PRACTICAL 7: COMPARING CLASSIFICATION MODELS
2
+
3
+ Dataset: pulsar_stars.csv (target_class = 0 / 1)
4
+
5
+ STEPS (same for every model):
6
+ 1. Install the libraries: pip install pandas numpy scikit-learn matplotlib
7
+ 2. Load pulsar_stars.csv and separate the features X and the target y (target_class).
8
+ 3. Scale the features (StandardScaler) and split the data into training and testing sets.
9
+ 4. Train the model on the training set and predict on the test set.
10
+ 5. Calculate the metrics (accuracy, confusion matrix, precision, sensitivity, specificity, AUC).
11
+ 6. Draw the plots and compare the results of all six models.
12
+
13
+
14
+ 1. LINEAR REGRESSION
15
+
16
+ CODE:
17
+ import pandas as pd
18
+ from sklearn.preprocessing import StandardScaler
19
+ from sklearn.model_selection import train_test_split
20
+ from sklearn.linear_model import LinearRegression
21
+ from sklearn.metrics import mean_squared_error, r2_score, accuracy_score
22
+ import matplotlib.pyplot as plt
23
+ import numpy as np
24
+ file_path = "C:/Users/Admin/Downloads/pulsar_stars.csv"
25
+ data = pd.read_csv(file_path)
26
+ data.columns = data.columns.str.strip()
27
+ X = data[['Skewness_DM_SNR_curve']]
28
+ y = data['target_class']
29
+ scaler = StandardScaler()
30
+ X_scaled = scaler.fit_transform(X)
31
+ X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
32
+ lr_model = LinearRegression()
33
+ lr_model.fit(X_train, y_train)
34
+ y_pred = lr_model.predict(X_test)
35
+ y_pred_binary = [1 if pred >= 0.5 else 0 for pred in y_pred]
36
+ mse = mean_squared_error(y_test, y_pred)
37
+ r2 = r2_score(y_test, y_pred)
38
+ accuracy = accuracy_score(y_test, y_pred_binary)
39
+ plt.figure(figsize=(10, 6))
40
+ plt.scatter(y_test, y_pred, color='blue', alpha=0.6, edgecolor='k')
41
+ plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color='red', lw=2)
42
+ plt.xlabel('Actual Values')
43
+ plt.ylabel('Predicted Values')
44
+ plt.title('Actual vs Predicted Values - Linear Regression')
45
+ plt.show()
46
+ residuals = y_test - y_pred
47
+ plt.figure(figsize=(10, 6))
48
+ plt.scatter(y_pred, residuals, color='green', alpha=0.6, edgecolor='k')
49
+ plt.axhline(0, color='red', linestyle='--', lw=2)
50
+ plt.xlabel('Predicted Values')
51
+ plt.ylabel('Residuals')
52
+ plt.title('Residuals Plot - Linear Regression')
53
+ plt.show()
54
+ print("Mean Squared Error:", mse)
55
+ print("R-squared:", r2)
56
+ print("Accuracy:", accuracy)
57
+
58
+ EXPLANATION:
59
+ - Linear regression is used with one feature (Skewness_DM_SNR_curve) to predict the class value.
60
+ - The predicted values are converted to 0 / 1 using the 0.5 threshold, so accuracy can be calculated.
61
+ - Mean squared error and R-squared tell how close the predictions are to the actual values.
62
+ - The Actual vs Predicted plot and the Residuals plot show the errors of the model.
63
+ - Linear regression is not really meant for classification, so it is the weakest model here.
64
+
65
+
66
+ 2. DECISION TREE
67
+
68
+ CODE:
69
+ import pandas as pd
70
+ from sklearn.model_selection import train_test_split
71
+ from sklearn.tree import DecisionTreeClassifier, plot_tree
72
+ from sklearn.metrics import (accuracy_score, confusion_matrix,
73
+ precision_score,
74
+ recall_score, roc_curve, auc)
75
+ import matplotlib.pyplot as plt
76
+ import numpy as np
77
+ filepath = "C:/Users/Admin/Downloads/pulsar_stars.csv"
78
+ data = pd.read_csv(filepath)
79
+ # Binarize the target_class
80
+ data['target_class'] = data['target_class'].apply(lambda x: 1 if x >= 0.5 else 0)
81
+ X = data.drop(columns=['target_class'])
82
+ y = data['target_class']
83
+ # Split the dataset
84
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
85
+ random_state=42)
86
+ # Initialize and train the model
87
+ clf = DecisionTreeClassifier(random_state=42)
88
+ clf.fit(X_train, y_train)
89
+ # Get predictions and probabilities
90
+ y_pred = clf.predict(X_test)
91
+ y_pred_prob = clf.predict_proba(X_test)[:, 1]
92
+ # Calculate metrics
93
+ accuracy = accuracy_score(y_test, y_pred)
94
+ conf_matrix = confusion_matrix(y_test, y_pred)
95
+ precision = precision_score(y_test, y_pred)
96
+ sensitivity = recall_score(y_test, y_pred)
97
+ TN = conf_matrix[0, 0]
98
+ FP = conf_matrix[0, 1]
99
+ specificity = TN / (TN + FP)
100
+ standard_error = np.sqrt((accuracy * (1 - accuracy)) / len(y_test))
101
+ # ROC and AUC
102
+ fpr, tpr, _ = roc_curve(y_test, y_pred_prob)
103
+ roc_auc = auc(fpr, tpr)
104
+ # Plot ROC Curve
105
+ plt.figure()
106
+ plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)'% roc_auc)
107
+ plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
108
+ plt.xlabel('False Positive Rate')
109
+ plt.ylabel('True Positive Rate')
110
+ plt.title('Receiver Operating Characteristic')
111
+ plt.legend(loc="lower right")
112
+ plt.show()
113
+ # Plot Decision Tree
114
+ plt.figure(figsize=(12, 8))
115
+ plot_tree(clf, feature_names=X.columns, class_names=['0', '1'], filled=True,
116
+ max_depth=3)
117
+ plt.title("Decision Tree (Max Depth = 3)")
118
+ plt.show()
119
+ # Print Results
120
+ print("Predictions:", y_pred)
121
+ print("Accuracy:", accuracy)
122
+ print("Confusion Matrix:\n", conf_matrix)
123
+ print("Standard Error:", standard_error)
124
+ print("Precision:", precision)
125
+ print("Sensitivity (Recall):", sensitivity)
126
+ print("Specificity:", specificity)
127
+ print("AUC:", roc_auc)
128
+
129
+ EXPLANATION:
130
+ - The decision tree splits the data again and again on feature conditions until the classes are separated.
131
+ - All eight features are used and the data is split 80% train / 20% test.
132
+ - The confusion matrix gives precision, sensitivity (recall), specificity and the standard error of the accuracy.
133
+ - The ROC curve and AUC value show how well the tree separates pulsar and non-pulsar stars.
134
+ - plot_tree() draws the first 3 levels of the tree.
135
+
136
+
137
+ 3. NAIVE BAYES
138
+
139
+ CODE:
140
+ #Naive Bayes
141
+ import pandas as pd
142
+ from sklearn.model_selection import train_test_split
143
+ from sklearn.preprocessing import StandardScaler
144
+ from sklearn.naive_bayes import GaussianNB
145
+ from sklearn.metrics import (
146
+ accuracy_score,
147
+ confusion_matrix,
148
+ precision_score,
149
+ recall_score,
150
+ roc_curve,
151
+ auc
152
+ )
153
+ import matplotlib.pyplot as plt
154
+ import numpy as np
155
+ # Load the dataset
156
+ file_path = "C:/Users/Admin/Downloads/pulsar_stars.csv"
157
+ data = pd.read_csv(file_path)
158
+ # Convert target_class to binary if it has continuous values
159
+ data['target_class'] = data['target_class'].apply(lambda x: 1 if x >= 0.5 else 0)
160
+ # Define features and target variable
161
+ X = data.drop(columns=['target_class'])
162
+ y = data['target_class']
163
+ # Standardize the features
164
+ scaler = StandardScaler()
165
+ X_scaled = scaler.fit_transform(X)
166
+ # Split the dataset (20% for test and 80% for train)
167
+ X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
168
+ # Create a Naive Bayes Classifier
169
+ nb_model = GaussianNB()
170
+ # Train the model
171
+ nb_model.fit(X_train, y_train)
172
+ # Make predictions
173
+ y_pred = nb_model.predict(X_test)
174
+ y_pred_prob = nb_model.predict_proba(X_test)[:, 1]
175
+ # Calculate metrics
176
+ accuracy = accuracy_score(y_test, y_pred)
177
+ conf_matrix = confusion_matrix(y_test, y_pred)
178
+ precision = precision_score(y_test, y_pred)
179
+ sensitivity = recall_score(y_test, y_pred)
180
+ # Specificity calculation
181
+ TN = conf_matrix[0, 0]
182
+ FP = conf_matrix[0, 1]
183
+ specificity = TN / (TN + FP)
184
+ # Standard error
185
+ standard_error = np.sqrt((accuracy * (1 - accuracy)) / len(y_test))
186
+ # Calculate ROC curve and AUC
187
+ fpr, tpr, _ = roc_curve(y_test, y_pred_prob)
188
+ roc_auc = auc(fpr, tpr)
189
+ # Plot ROC curve
190
+ plt.figure()
191
+ plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % roc_auc)
192
+ plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
193
+ plt.xlabel('False Positive Rate')
194
+ plt.ylabel('True Positive Rate')
195
+ plt.title('Receiver Operating Characteristic - Naive Bayes')
196
+ plt.legend(loc="lower right")
197
+ plt.show()
198
+ # Print results
199
+ print("Predictions:", y_pred)
200
+ print("Accuracy:", accuracy)
201
+ print("Confusion Matrix:\n", conf_matrix)
202
+ print("Standard Error:", standard_error)
203
+ print("Precision:", precision)
204
+ print("Sensitivity (Recall):", sensitivity)
205
+ print("Specificity:", specificity)
206
+ print("AUC:", roc_auc)
207
+
208
+ EXPLANATION:
209
+ - Gaussian Naive Bayes uses Bayes' theorem and assumes the features are independent and follow a normal distribution.
210
+ - The features are standardized first and the data is split 80% train / 20% test.
211
+ - It is very fast because it only calculates the mean and variance of each feature for each class.
212
+ - predict_proba() gives the class probabilities, which are used to draw the ROC curve.
213
+ - Accuracy, precision, sensitivity, specificity, standard error and AUC are printed for comparison.
214
+
215
+
216
+ 4. PCA (PRINCIPAL COMPONENT ANALYSIS) WITH LOGISTIC REGRESSION
217
+
218
+ CODE:
219
+ import pandas as pd
220
+ from sklearn.preprocessing import StandardScaler
221
+ from sklearn.decomposition import PCA
222
+ from sklearn.model_selection import train_test_split
223
+ from sklearn.linear_model import LogisticRegression
224
+ from sklearn.metrics import accuracy_score
225
+ import matplotlib.pyplot as plt
226
+ import numpy as np
227
+ # Load the dataset
228
+ file_path = "C:/Users/Admin/Downloads/pulsar_stars.csv"
229
+ data = pd.read_csv(file_path)
230
+ # Convert target_class to binary if it has continuous values
231
+ data['target_class'] = data['target_class'].apply(lambda x: 1 if x >= 0.5 else 0)
232
+ # Define features and target variable
233
+ X = data.drop(columns=['target_class'])
234
+ y = data['target_class']
235
+ # Standardize the features
236
+ scaler = StandardScaler()
237
+ X_scaled = scaler.fit_transform(X)
238
+ # Apply PCA to reduce dimensionality
239
+ n_components = 7
240
+ pca = PCA(n_components=n_components)
241
+ X_pca = pca.fit_transform(X_scaled)
242
+ # Explained variance ratio for PCA
243
+ explained_variance_ratio = pca.explained_variance_ratio_
244
+ total_variance_explained = np.sum(explained_variance_ratio)
245
+ # Print PCA results
246
+ print("Explained Variance Ratio:", explained_variance_ratio)
247
+ print("Total Variance Explained:", total_variance_explained)
248
+ # Visualize the explained variance ratio
249
+ plt.figure(figsize=(8, 5))
250
+ plt.bar(range(1, n_components + 1), explained_variance_ratio, alpha=0.7, align='center', label='Individual Explained Variance')
251
+ plt.step(range(1, n_components + 1), np.cumsum(explained_variance_ratio), where='mid', label='Cumulative Explained Variance')
252
+ plt.xlabel('Principal Component Index')
253
+ plt.ylabel('Explained Variance Ratio')
254
+ plt.title('PCA Explained Variance')
255
+ plt.legend(loc='best')
256
+ plt.show()
257
+ # Split the dataset using PCA features
258
+ X_train, X_test, y_train, y_test = train_test_split(X_pca, y, test_size=0.2, random_state=42)
259
+ # Train a Logistic Regression model
260
+ model = LogisticRegression()
261
+ model.fit(X_train, y_train)
262
+ # Make predictions
263
+ y_pred = model.predict(X_test)
264
+ # Calculate accuracy
265
+ accuracy = accuracy_score(y_test, y_pred)
266
+ # Print accuracy
267
+ print("Accuracy:", accuracy)
268
+
269
+ EXPLANATION:
270
+ - PCA reduces the 8 features to 7 new uncorrelated features called principal components.
271
+ - The explained variance ratio tells how much of the information each component keeps.
272
+ - The bar and step plot show individual and cumulative explained variance.
273
+ - Logistic regression is trained on the reduced features and its accuracy is printed.
274
+ - This checks whether the model still works well after reducing the dimensions.
275
+
276
+
277
+ 5. SVM (SUPPORT VECTOR MACHINE)
278
+
279
+ CODE:
280
+ import pandas as pd
281
+ import numpy as np
282
+ from sklearn.model_selection import train_test_split
283
+ from sklearn.preprocessing import StandardScaler
284
+ from sklearn.svm import SVC
285
+ from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
286
+ file_path = "C:/Users/Admin/Downloads/pulsar_stars.csv"
287
+ data = pd.read_csv(file_path)
288
+ data.columns = data.columns.str.strip()
289
+ X = data.drop(columns=['target_class'])
290
+ y = data['target_class']
291
+ X_train, X_test, y_train, y_test = train_test_split(
292
+ X, y, test_size=0.3, random_state=42, stratify=y
293
+ )
294
+ scaler = StandardScaler()
295
+ X_train_scaled = scaler.fit_transform(X_train)
296
+ X_test_scaled = scaler.transform(X_test)
297
+ svm_model = SVC(
298
+ kernel='rbf',
299
+ class_weight='balanced',
300
+ probability=True,
301
+ random_state=42
302
+ )
303
+ svm_model.fit(X_train_scaled, y_train)
304
+ # Make Predictions
305
+ y_pred = svm_model.predict(X_test_scaled)
306
+ y_prob = svm_model.predict_proba(X_test_scaled)[:, 1]
307
+ # Evaluate the Model
308
+ print("--- Confusion Matrix ---")
309
+ print(confusion_matrix(y_test, y_pred))
310
+ print("\n--- Classification Report ---")
311
+ # Focus heavily on Precision and Recall for Class 1 (Pulsars)
312
+ print(classification_report(y_test, y_pred))
313
+ print(f"ROC-AUC Score: {roc_auc_score(y_test, y_prob):.4f}")
314
+
315
+ EXPLANATION:
316
+ - SVM finds the best boundary (hyperplane) that separates the two classes with the widest margin.
317
+ - The RBF kernel lets it draw a curved boundary, and class_weight='balanced' gives more importance to the rare pulsar class.
318
+ - The data is split 70% / 30% with stratify=y so both sets keep the same class ratio.
319
+ - The scaler is fitted only on the training data and then applied to the test data.
320
+ - Confusion matrix, classification report and ROC-AUC score show how well the rare class is found.
321
+
322
+
323
+ 6. RANDOM FOREST
324
+
325
+ CODE:
326
+ import pandas as pd
327
+ import numpy as np
328
+ from sklearn.model_selection import train_test_split
329
+ from sklearn.preprocessing import StandardScaler
330
+ from sklearn.ensemble import RandomForestClassifier
331
+ from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
332
+ df = pd.read_csv('C:/Users/Admin/Downloads/pulsar_stars.csv')
333
+ df.columns = df.columns.str.strip()
334
+ X = df.drop(columns=['target_class'])
335
+ y = df['target_class']
336
+ # Split into training and testing sets (Stratified to maintain class balance)
337
+ X_train, X_test, y_train, y_test = train_test_split(
338
+ X, y, test_size=0.3, random_state=42, stratify=y
339
+ )
340
+ # Feature Scaling
341
+ scaler = StandardScaler()
342
+ X_train_scaled = scaler.fit_transform(X_train)
343
+ X_test_scaled = scaler.transform(X_test)
344
+ # Initialize and Train Random Forest
345
+ # class_weight='balanced' penalizes mistakes on the rare pulsar class heavily.
346
+ rf_model = RandomForestClassifier(
347
+ n_estimators=100,
348
+ class_weight='balanced',
349
+ random_state=42,
350
+ n_jobs=-1
351
+ )
352
+ rf_model.fit(X_train_scaled, y_train)
353
+ # Make Predictions
354
+ y_pred = rf_model.predict(X_test_scaled)
355
+ y_prob = rf_model.predict_proba(X_test_scaled)[:, 1] # Probability estimates for ROC-AUC
356
+ # Evaluate the Model
357
+ print("--- Confusion Matrix ---")
358
+ print(confusion_matrix(y_test, y_pred))
359
+ print("\n--- Classification Report ---")
360
+ print(classification_report(y_test, y_pred))
361
+ print(f"ROC-AUC Score: {roc_auc_score(y_test, y_prob):.4f}")
362
+ # Feature Importance
363
+ importances = pd.Series(rf_model.feature_importances_, index=X.columns)
364
+ print("\n--- Feature Importances ---")
365
+ print(importances.sort_values(ascending=False))
366
+
367
+ EXPLANATION:
368
+ - Random forest builds 100 decision trees on random samples of the data and the final class is decided by their majority vote.
369
+ - Voting over many trees reduces overfitting compared with a single decision tree.
370
+ - class_weight='balanced' penalizes mistakes on the rare pulsar class more.
371
+ - The same confusion matrix, classification report and ROC-AUC score are printed for comparison.
372
+ - feature_importances_ shows which features contributed most to the prediction.
@@ -0,0 +1,162 @@
1
+ PRACTICAL 8: CLASSIFICATION IMPROVEMENT (BAGGING AND BOOSTING)
2
+
3
+ Dataset: electric_vehicles.csv (target = drivetrain)
4
+
5
+ STEPS:
6
+ 1. Install the libraries: pip install pandas numpy seaborn matplotlib scikit-learn
7
+ 2. Load electric_vehicles.csv and drop the rows where drivetrain is missing.
8
+ 3. Convert the numeric columns to numbers and fill their missing values with the median.
9
+ 4. Encode the brand column (one-hot) and the target (label encoding).
10
+ 5. Draw the correlation heatmap and scale the features (StandardScaler).
11
+ 6. Split the data 80% / 20% (stratified) and create the models: Bagging with Decision Tree, Bagging with Naive Bayes, Logistic Regression and AdaBoost.
12
+ 7. Train the models, predict and calculate accuracy, precision, sensitivity, standard error and AUC.
13
+ 8. Calculate the 5-fold cross-validation accuracy and print the summary table and confusion matrices.
14
+
15
+ CODE:
16
+ import pandas as pd
17
+ import numpy as np
18
+ import seaborn as sns
19
+ import matplotlib.pyplot as plt
20
+ from sklearn.model_selection import train_test_split, cross_val_score, KFold
21
+ from sklearn.tree import DecisionTreeClassifier
22
+ from sklearn.naive_bayes import GaussianNB
23
+ from sklearn.linear_model import LogisticRegression
24
+ from sklearn.decomposition import PCA
25
+ from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, roc_auc_score
26
+ from sklearn.preprocessing import StandardScaler, MinMaxScaler, LabelEncoder
27
+ from sklearn.ensemble import BaggingClassifier, AdaBoostClassifier
28
+ def main():
29
+ df = pd.read_csv('C:/Users/Admin/Downloads/electric_vehicles.csv')
30
+ target_col = 'drivetrain'
31
+ df = df.dropna(subset=[target_col]).copy()
32
+ numerical_features = [
33
+ 'top_speed_kmh',
34
+ 'battery_capacity_kWh',
35
+ 'torque_nm',
36
+ 'efficiency',
37
+ 'range_km',
38
+ 'acceleration_0_100_s',
39
+ 'fast_charging_power_kw_dc',
40
+ 'seats',
41
+ 'length_mm',
42
+ 'width_mm',
43
+ 'height_mm'
44
+ ]
45
+ feature_cols = []
46
+ for col in numerical_features:
47
+ if col in df.columns:
48
+ df[col] = pd.to_numeric(df[col], errors='coerce')
49
+ df[col] = df[col].fillna(df[col].median())
50
+ feature_cols.append(col)
51
+ # Encode categorical features if available (e.g., 'brand')
52
+ if 'brand' in df.columns:
53
+ df = pd.get_dummies(df, columns=['brand'], drop_first=True)
54
+ # Add encoded brand columns to features list
55
+ brand_cols = [c for c in df.columns if c.startswith('brand_')]
56
+ feature_cols.extend(brand_cols)
57
+ # Target Encoding (Convert categorical classes to numeric labels)
58
+ label_enc = LabelEncoder()
59
+ y = label_enc.fit_transform(df[target_col].astype(str))
60
+ # Feature matrix (Ensure strictly numeric data types)
61
+ X = df[feature_cols].select_dtypes(include=[np.number])
62
+ # Exploratory Data Analysis - Heatmap
63
+ plt.figure(figsize=(12, 8))
64
+ sns.heatmap(X.corr(numeric_only=True), annot=False, cmap='coolwarm')
65
+ plt.title("EV Features Correlation Heatmap")
66
+ plt.tight_layout()
67
+ plt.show()
68
+ # Scaling
69
+ standard_scaler = StandardScaler()
70
+ minmax_scaler = MinMaxScaler()
71
+ X_std = standard_scaler.fit_transform(X)
72
+ X_mm = minmax_scaler.fit_transform(X)
73
+ # Train / Test Split
74
+ X_train_std, X_test_std, y_train, y_test = train_test_split(
75
+ X_std, y, test_size=0.2, random_state=69, stratify=y
76
+ )
77
+ # Evaluation Function
78
+ def evaluate_model(y_true, y_pred, y_prob):
79
+ acc = accuracy_score(y_true, y_pred)
80
+ cm = confusion_matrix(y_true, y_pred)
81
+ # Weighted precision and recall for multiclass/binary
82
+ prec = precision_score(y_true, y_pred, average='weighted', zero_division=0)
83
+ sens = recall_score(y_true, y_pred, average='weighted', zero_division=0)
84
+ # Standard Error of Accuracy
85
+ se = np.sqrt((acc * (1 - acc)) / len(y_true))
86
+ # Multiclass/binary AUC calculation
87
+ try:
88
+ n_classes = len(np.unique(y_true))
89
+ if n_classes == 2:
90
+ model_auc = roc_auc_score(y_true, y_prob[:, 1])
91
+ else:
92
+ model_auc = roc_auc_score(y_true, y_prob, multi_class='ovr', average='weighted')
93
+ except Exception:
94
+ model_auc = np.nan
95
+ return {
96
+ 'Accuracy': acc,
97
+ 'Precision': prec,
98
+ 'Sensitivity': sens,
99
+ 'Std Error': se,
100
+ 'AUC': model_auc,
101
+ 'Confusion Matrix': cm
102
+ }
103
+ # Model Initialization
104
+ dt_bag = BaggingClassifier(
105
+ estimator=DecisionTreeClassifier(random_state=69),
106
+ n_estimators=50,
107
+ random_state=69
108
+ )
109
+ nb_bag = BaggingClassifier(
110
+ estimator=GaussianNB(),
111
+ n_estimators=50,
112
+ random_state=69
113
+ )
114
+ log_reg = LogisticRegression(max_iter=1000)
115
+ dt_ada = AdaBoostClassifier(
116
+ estimator=DecisionTreeClassifier(max_depth=1, random_state=69),
117
+ n_estimators=50,
118
+ random_state=69
119
+ )
120
+ # Train Models
121
+ dt_bag.fit(X_train_std, y_train)
122
+ nb_bag.fit(X_train_std, y_train)
123
+ log_reg.fit(X_train_std, y_train)
124
+ dt_ada.fit(X_train_std, y_train)
125
+ # Predictions
126
+ pred_dt_bag = dt_bag.predict(X_test_std)
127
+ pred_nb_bag = nb_bag.predict(X_test_std)
128
+ pred_log_reg = log_reg.predict(X_test_std)
129
+ pred_dt_ada = dt_ada.predict(X_test_std)
130
+ # Results Compilation
131
+ results = {
132
+ 'Bagging DT': evaluate_model(y_test, pred_dt_bag, dt_bag.predict_proba(X_test_std)),
133
+ 'Bagging NB': evaluate_model(y_test, pred_nb_bag, nb_bag.predict_proba(X_test_std)),
134
+ 'Logistic Regression': evaluate_model(y_test, pred_log_reg, log_reg.predict_proba(X_test_std)),
135
+ 'AdaBoost DT': evaluate_model(y_test, pred_dt_ada, dt_ada.predict_proba(X_test_std))
136
+ }
137
+ # Cross-Validation Score
138
+ cv = KFold(n_splits=5, shuffle=True, random_state=69)
139
+ dt_cv_std = np.mean(cross_val_score(dt_bag, X_std, y, cv=cv, scoring='accuracy'))
140
+ # Print Summary Table
141
+ summary_df = pd.DataFrame(results).T.drop(columns=['Confusion Matrix'])
142
+ print("\n" + "="*65)
143
+ print(" EV DATASET MODEL EVALUATION SUMMARY (STANDARDIZED)")
144
+ print("="*65)
145
+ print(summary_df.round(4).to_string())
146
+ print("-" * 65)
147
+ print(f"Bagging DT 5-Fold Cross-Validation Accuracy: {dt_cv_std:.4f}")
148
+ print("="*65 + "\n")
149
+ # Display Confusion Matrices with Class Names
150
+ print("--- Detailed Confusion Matrices ---")
151
+ for name, res in results.items():
152
+ print(f"\n{name} Confusion Matrix:")
153
+ print(pd.DataFrame(res['Confusion Matrix'], index=label_enc.classes_, columns=label_enc.classes_))
154
+ if __name__ == '__main__':
155
+ main()
156
+
157
+ EXPLANATION:
158
+ - The data is cleaned first (median for missing numbers, one-hot for brand, label encoding for drivetrain) and then standardized.
159
+ - Bagging trains 50 copies of a model (decision tree / naive bayes) on random samples and combines their votes to reduce variance.
160
+ - AdaBoost trains small trees one after another, and each new tree gives more weight to the records the earlier trees got wrong.
161
+ - evaluate_model() gives accuracy, weighted precision and sensitivity, standard error and AUC, so all models can be compared in one table.
162
+ - 5-fold cross-validation checks the accuracy on 5 different train/test splits to confirm the result is stable.
@@ -0,0 +1,101 @@
1
+ PRACTICAL 9: CLUSTERING (K-MEANS AND HIERARCHICAL)
2
+
3
+ Dataset: Wine dataset (load_wine from scikit-learn)
4
+
5
+ STEPS:
6
+ 1. Install the libraries: pip install numpy pandas matplotlib scipy scikit-learn
7
+ 2. Load the Wine dataset into a DataFrame and print its summary.
8
+ 3. Scale the data with StandardScaler.
9
+ 4. Use the Elbow method (K = 1 to 10) to find the best number of clusters.
10
+ 5. Apply K-Means with K = 3 and calculate the silhouette score.
11
+ 6. Reduce the data to 2 dimensions with PCA and plot the K-Means clusters.
12
+ 7. Draw the dendrogram (ward linkage) for hierarchical clustering.
13
+ 8. Apply Agglomerative clustering with 3 clusters, calculate its silhouette score and plot the clusters (alcohol vs malic acid).
14
+
15
+ CODE:
16
+ import numpy as np
17
+ import pandas as pd
18
+ import matplotlib.pyplot as plt
19
+ from scipy.cluster.hierarchy import dendrogram, linkage
20
+ from sklearn.cluster import AgglomerativeClustering, KMeans
21
+ from sklearn.datasets import load_wine
22
+ from sklearn.decomposition import PCA
23
+ from sklearn.metrics import silhouette_score
24
+ from sklearn.preprocessing import StandardScaler
25
+ # 1. Load the Wine Dataset
26
+ wine = load_wine()
27
+ wine_df = pd.DataFrame(data=wine.data, columns=wine.feature_names)
28
+ print("Data Summary:")
29
+ print(wine_df.describe())
30
+ scaler = StandardScaler()
31
+ X_scaled = scaler.fit_transform(wine_df)
32
+ # 3. Elbow Method to Find Optimal K
33
+ wss = []
34
+ for k in range(1, 11):
35
+ kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
36
+ kmeans.fit(X_scaled)
37
+ wss.append(kmeans.inertia_)
38
+ plt.figure(figsize=(8, 4))
39
+ plt.plot(range(1, 11), wss, marker="o")
40
+ plt.xlabel("Number of clusters k")
41
+ plt.ylabel("Total within-cluster sum of squares (Inertia)")
42
+ plt.title("Elbow Method for Optimal K")
43
+ plt.show()
44
+ # 4. K-Means Clustering (Using k=3 since Wine has 3 natural classes)
45
+ kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
46
+ wine_df["kmeans_cluster"] = kmeans.fit_predict(X_scaled)
47
+ # Calculate Silhouette Score for K-Means
48
+ silhouette_avg_kmeans = silhouette_score(X_scaled, wine_df["kmeans_cluster"])
49
+ print(
50
+ f"\nMean Silhouette Width for K-Means Clustering: {silhouette_avg_kmeans:.4f}"
51
+ )
52
+ # 5. Visualize K-Means with PCA (2D Projection)
53
+ pca = PCA(n_components=2)
54
+ X_pca = pca.fit_transform(X_scaled)
55
+ plt.figure(figsize=(8, 5))
56
+ plt.scatter(
57
+ X_pca[:, 0], X_pca[:, 1], c=wine_df["kmeans_cluster"], cmap="viridis", s=50
58
+ )
59
+ plt.title("K-Means Clustering (PCA Reduced)")
60
+ plt.xlabel("Principal Component 1")
61
+ plt.ylabel("Principal Component 2")
62
+ plt.show()
63
+ # 6. Hierarchical Clustering - Dendrogram
64
+ linkage_matrix = linkage(X_scaled, method="ward")
65
+ plt.figure(figsize=(10, 5))
66
+ dendrogram(linkage_matrix)
67
+ plt.title("Hierarchical Clustering Dendrogram")
68
+ plt.xlabel("Sample Index")
69
+ plt.ylabel("Distance")
70
+ plt.show()
71
+ # 7. Agglomerative Clustering
72
+ agglomerative = AgglomerativeClustering(n_clusters=3)
73
+ wine_df["hierarchical_cluster"] = agglomerative.fit_predict(X_scaled)
74
+ # Calculate Silhouette Score for Hierarchical Clustering
75
+ silhouette_avg_hierarchical = silhouette_score(
76
+ X_scaled, wine_df["hierarchical_cluster"]
77
+ )
78
+ print(
79
+ f"Mean Silhouette Width for Hierarchical Clustering: {silhouette_avg_hierarchical:.4f}"
80
+ )
81
+ # 8. Visualize Hierarchical Clusters (e.g., Alcohol vs. Malic Acid)
82
+ plt.figure(figsize=(8, 5))
83
+ plt.scatter(
84
+ wine_df["alcohol"],
85
+ wine_df["malic_acid"],
86
+ c=wine_df["hierarchical_cluster"],
87
+ cmap="viridis",
88
+ alpha=0.8,
89
+ s=50,
90
+ )
91
+ plt.xlabel("Alcohol")
92
+ plt.ylabel("Malic Acid")
93
+ plt.title("Hierarchical Clustering (Alcohol vs Malic Acid)")
94
+ plt.show()
95
+
96
+ EXPLANATION:
97
+ - Clustering is unsupervised: it groups similar wines together without using any class labels.
98
+ - The elbow plot shows the inertia for K = 1 to 10, and the bend of the curve gives the best K (here 3).
99
+ - K-Means puts each wine in the nearest of 3 centres, and PCA reduces the data to 2D only to draw the clusters.
100
+ - The dendrogram shows how hierarchical (ward) clustering merges the samples step by step, and Agglomerative clustering cuts it into 3 clusters.
101
+ - The silhouette score (closer to 1 is better) is used to compare K-Means and hierarchical clustering.