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.
- scikit_lab/__init__.py +3 -0
- scikit_lab/__main__.py +4 -0
- scikit_lab/practicals/01_data_cleaning_missing_values.txt +72 -0
- scikit_lab/practicals/02_data_cleaning_noisy_data.txt +69 -0
- scikit_lab/practicals/03_data_cleaning_on_dataset.txt +70 -0
- scikit_lab/practicals/04_preprocessing_contingency.txt +42 -0
- scikit_lab/practicals/05_eda.txt +252 -0
- scikit_lab/practicals/06_decision_tree.txt +75 -0
- scikit_lab/practicals/07_compare_classification_models.txt +372 -0
- scikit_lab/practicals/08_classification_improvement.txt +162 -0
- scikit_lab/practicals/09_clustering.txt +101 -0
- scikit_lab/practicals/10_association_apriori_groceries.txt +65 -0
- scikit_lab/practicals/11_association_apriori_own_dataset.txt +140 -0
- scikit_lab/practicals/12_fp_tree_association.txt +36 -0
- scikit_lab/practicals/13_classifiers_explanation.txt +51 -0
- scikit_lab/practicals/14_pca.txt +16 -0
- scikit_lab/viewer.py +106 -0
- scikit_lab_kit-0.1.0.dist-info/METADATA +46 -0
- scikit_lab_kit-0.1.0.dist-info/RECORD +22 -0
- scikit_lab_kit-0.1.0.dist-info/WHEEL +5 -0
- scikit_lab_kit-0.1.0.dist-info/entry_points.txt +2 -0
- scikit_lab_kit-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -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.
|