mansi14883md/AI-Keystroke-Security-System
1
1import json2import os3 4import joblib5import pandas as pd6from sklearn.ensemble import RandomForestClassifier7from sklearn.ensemble import ExtraTreesClassifier8from sklearn.metrics import accuracy_score, classification_report, f1_score, precision_score, recall_score9from sklearn.model_selection import StratifiedKFold, cross_val_score10from sklearn.model_selection import train_test_split11from sklearn.pipeline import Pipeline12from sklearn.preprocessing import StandardScaler13from sklearn.svm import SVC14 15from backend_utils import engineered_feature_columns, transform_dataframe16 17 18DATA_FOLDER = "data"19MODEL_FOLDER = "models"20GENUINE_FILE = os.path.join(DATA_FOLDER, "genuine.csv")21IMPOSTOR_FILE = os.path.join(DATA_FOLDER, "impostor.csv")22MODEL_FILE = os.path.join(MODEL_FOLDER, "model.pkl")23METRICS_FILE = os.path.join(MODEL_FOLDER, "metrics.json")24 25 26def load_dataset() -> pd.DataFrame:27 if not os.path.exists(GENUINE_FILE):28 raise FileNotFoundError("genuine.csv not found. Run capture_data.py first.")29 if not os.path.exists(IMPOSTOR_FILE):30 raise FileNotFoundError("impostor.csv not found. Run capture_data.py first.")31 32 genuine_df = pd.read_csv(GENUINE_FILE)33 impostor_df = pd.read_csv(IMPOSTOR_FILE)34 return pd.concat([genuine_df, impostor_df], ignore_index=True)35 36 37def build_candidate_models() -> dict[str, object]:38 return {39 "Random Forest": RandomForestClassifier(n_estimators=200, random_state=42),40 "Extra Trees": ExtraTreesClassifier(n_estimators=300, random_state=42),41 "SVM": Pipeline(42 [43 ("scaler", StandardScaler()),44 ("classifier", SVC(kernel="rbf", probability=True, random_state=42)),45 ]46 ),47 }48 49 50def main() -> None:51 os.makedirs(MODEL_FOLDER, exist_ok=True)52 53 df = load_dataset()54 if len(df) < 10:55 raise ValueError("Dataset is too small. Record more samples before training.")56 57 feature_df = transform_dataframe(df)58 X = feature_df.drop(columns=["label"])59 y = feature_df["label"]60 61 X_train, X_test, y_train, y_test = train_test_split(62 X,63 y,64 test_size=0.3,65 random_state=42,66 stratify=y,67 )68 69 candidate_models = build_candidate_models()70 trained_models = {}71 model_scores = {}72 cv_scores = {}73 cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)74 75 for model_name, model in candidate_models.items():76 scores = cross_val_score(model, X, y, cv=cv, scoring="accuracy")77 cv_scores[model_name] = float(scores.mean())78 model.fit(X_train, y_train)79 predictions = model.predict(X_test)80 model_scores[model_name] = accuracy_score(y_test, predictions)81 trained_models[model_name] = model82 83 best_model_name = max(cv_scores, key=cv_scores.get)84 model = trained_models[best_model_name]85 86 # Fit the selected model again on the full dataset for stronger final deployment.87 model.fit(X, y)88 89 evaluation_model = trained_models[best_model_name]90 predictions = evaluation_model.predict(X_test)91 accuracy = accuracy_score(y_test, predictions)92 precision = precision_score(y_test, predictions, zero_division=0)93 recall = recall_score(y_test, predictions, zero_division=0)94 f1 = f1_score(y_test, predictions, zero_division=0)95 96 metrics = {97 "accuracy": round(float(accuracy), 4),98 "precision": round(float(precision), 4),99 "recall": round(float(recall), 4),100 "f1_score": round(float(f1), 4),101 "train_samples": int(len(X_train)),102 "test_samples": int(len(X_test)),103 "best_model": best_model_name,104 "model_comparison": {name: round(float(score), 4) for name, score in model_scores.items()},105 "cross_validation_accuracy": {name: round(float(score), 4) for name, score in cv_scores.items()},106 "feature_count": len(engineered_feature_columns()),107 "decision_threshold": 0.5,108 }109 110 model_bundle = {111 "model": model,112 "feature_columns": engineered_feature_columns(),113 "best_model": best_model_name,114 "decision_threshold": 0.5,115 "target_text": "secure123",116 }117 118 119 joblib.dump(model_bundle, MODEL_FILE)120 with open(METRICS_FILE, "w", encoding="utf-8") as file:121 json.dump(metrics, file, indent=4)122 123 print("Model training completed successfully.")124 print(f"Model saved as: {MODEL_FILE}")125 print(f"Metrics saved as: {METRICS_FILE}")126 print(f"Best model selected: {best_model_name}")127 print(f"Total engineered features: {len(engineered_feature_columns())}")128 print("\nModel comparison:")129 for model_name, score in model_scores.items():130 print(f"- {model_name}: {score * 100:.2f}%")131 print("\nCross-validation accuracy:")132 for model_name, score in cv_scores.items():133 print(f"- {model_name}: {score * 100:.2f}%")134 print("\nClassification Report:")135 print(classification_report(y_test, predictions, target_names=["Impostor", "Genuine"], zero_division=0))136 print(f"Accuracy: {metrics['accuracy'] * 100:.2f}%")137 138 139if __name__ == "__main__":140 main()141 