gaitsetpy.classification.models.mlp

  1from typing import List, Dict, Any, Optional, Union
  2import joblib
  3import numpy as np
  4from sklearn.neural_network import MLPClassifier
  5from sklearn.model_selection import train_test_split
  6from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
  7from ...core.base_classes import BaseClassificationModel
  8from ..utils.preprocess import preprocess_features
  9
 10class MLPModel(BaseClassificationModel):
 11    """
 12    Multi-Layer Perceptron (MLP) classification model.
 13    Implements the BaseClassificationModel interface using scikit-learn's MLPClassifier.
 14    """
 15    def __init__(self, hidden_layer_sizes=(100,), activation='relu', solver='adam', random_state=42, max_iter=200):
 16        super().__init__(
 17            name="mlp",
 18            description="Multi-Layer Perceptron classifier for gait data classification"
 19        )
 20        self.config = {
 21            'hidden_layer_sizes': hidden_layer_sizes,
 22            'activation': activation,
 23            'solver': solver,
 24            'random_state': random_state,
 25            'max_iter': max_iter
 26        }
 27        self.model = MLPClassifier(
 28            hidden_layer_sizes=hidden_layer_sizes,
 29            activation=activation,
 30            solver=solver,
 31            random_state=random_state,
 32            max_iter=max_iter
 33        )
 34        self.feature_names = []
 35        self.class_names = []
 36
 37    def train(self, features: List[Dict], **kwargs):
 38        X, y = preprocess_features(features)
 39        self.feature_names = [f"feature_{i}" for i in range(X.shape[1])]
 40        self.class_names = list(set(y))
 41        test_size = kwargs.get('test_size', 0.2)
 42        validation_split = kwargs.get('validation_split', True)
 43        if validation_split:
 44            X_train, X_test, y_train, y_test = train_test_split(
 45                X, y, test_size=test_size, random_state=self.config['random_state']
 46            )
 47            self.model.fit(X_train, y_train)
 48            self.X_test = X_test
 49            self.y_test = y_test
 50            train_accuracy = self.model.score(X_train, y_train)
 51            test_accuracy = self.model.score(X_test, y_test)
 52            print(f"Training accuracy: {train_accuracy:.4f}")
 53            print(f"Validation accuracy: {test_accuracy:.4f}")
 54        else:
 55            self.model.fit(X, y)
 56            train_accuracy = self.model.score(X, y)
 57            print(f"Training accuracy: {train_accuracy:.4f}")
 58        self.trained = True
 59        print("MLP model trained successfully.")
 60
 61    def predict(self, features: List[Dict], **kwargs) -> Union[np.ndarray, Any]:
 62        if not self.trained:
 63            raise ValueError("Model must be trained before making predictions")
 64        X, _ = preprocess_features(features)
 65        return_probabilities = kwargs.get('return_probabilities', False)
 66        if return_probabilities:
 67            return self.model.predict_proba(X)
 68        else:
 69            return self.model.predict(X)
 70
 71    def evaluate(self, features: List[Dict], **kwargs) -> Dict[str, float]:
 72        if not self.trained:
 73            raise ValueError("Model must be trained before evaluation")
 74        if hasattr(self, 'X_test') and hasattr(self, 'y_test'):
 75            X_test, y_test = self.X_test, self.y_test
 76        else:
 77            X_test, y_test = preprocess_features(features)
 78        y_pred = self.model.predict(X_test)
 79        accuracy = accuracy_score(y_test, y_pred)
 80        conf_matrix = confusion_matrix(y_test, y_pred)
 81        metrics = {
 82            'accuracy': accuracy,
 83            'confusion_matrix': conf_matrix.tolist()
 84        }
 85        detailed_report = kwargs.get('detailed_report', False)
 86        if detailed_report:
 87            class_report = classification_report(y_test, y_pred, output_dict=True)
 88            metrics['classification_report'] = class_report
 89        return metrics
 90
 91    def save_model(self, filepath: str):
 92        if not self.trained:
 93            raise ValueError("Model must be trained before saving")
 94        model_data = {
 95            'model': self.model,
 96            'config': self.config,
 97            'feature_names': self.feature_names,
 98            'class_names': self.class_names,
 99            'trained': self.trained
100        }
101        joblib.dump(model_data, filepath)
102        print(f"MLP model saved to {filepath}")
103
104    def load_model(self, filepath: str):
105        try:
106            model_data = joblib.load(filepath)
107            if isinstance(model_data, dict):
108                self.model = model_data['model']
109                self.config = model_data.get('config', self.config)
110                self.feature_names = model_data.get('feature_names', [])
111                self.class_names = model_data.get('class_names', [])
112                self.trained = model_data.get('trained', False)
113            else:
114                self.model = model_data
115                self.trained = True
116            print(f"MLP model loaded from {filepath}")
117        except Exception as e:
118            print(f"Failed to load MLP model: {e}")
 11class MLPModel(BaseClassificationModel):
 12    """
 13    Multi-Layer Perceptron (MLP) classification model.
 14    Implements the BaseClassificationModel interface using scikit-learn's MLPClassifier.
 15    """
 16    def __init__(self, hidden_layer_sizes=(100,), activation='relu', solver='adam', random_state=42, max_iter=200):
 17        super().__init__(
 18            name="mlp",
 19            description="Multi-Layer Perceptron classifier for gait data classification"
 20        )
 21        self.config = {
 22            'hidden_layer_sizes': hidden_layer_sizes,
 23            'activation': activation,
 24            'solver': solver,
 25            'random_state': random_state,
 26            'max_iter': max_iter
 27        }
 28        self.model = MLPClassifier(
 29            hidden_layer_sizes=hidden_layer_sizes,
 30            activation=activation,
 31            solver=solver,
 32            random_state=random_state,
 33            max_iter=max_iter
 34        )
 35        self.feature_names = []
 36        self.class_names = []
 37
 38    def train(self, features: List[Dict], **kwargs):
 39        X, y = preprocess_features(features)
 40        self.feature_names = [f"feature_{i}" for i in range(X.shape[1])]
 41        self.class_names = list(set(y))
 42        test_size = kwargs.get('test_size', 0.2)
 43        validation_split = kwargs.get('validation_split', True)
 44        if validation_split:
 45            X_train, X_test, y_train, y_test = train_test_split(
 46                X, y, test_size=test_size, random_state=self.config['random_state']
 47            )
 48            self.model.fit(X_train, y_train)
 49            self.X_test = X_test
 50            self.y_test = y_test
 51            train_accuracy = self.model.score(X_train, y_train)
 52            test_accuracy = self.model.score(X_test, y_test)
 53            print(f"Training accuracy: {train_accuracy:.4f}")
 54            print(f"Validation accuracy: {test_accuracy:.4f}")
 55        else:
 56            self.model.fit(X, y)
 57            train_accuracy = self.model.score(X, y)
 58            print(f"Training accuracy: {train_accuracy:.4f}")
 59        self.trained = True
 60        print("MLP model trained successfully.")
 61
 62    def predict(self, features: List[Dict], **kwargs) -> Union[np.ndarray, Any]:
 63        if not self.trained:
 64            raise ValueError("Model must be trained before making predictions")
 65        X, _ = preprocess_features(features)
 66        return_probabilities = kwargs.get('return_probabilities', False)
 67        if return_probabilities:
 68            return self.model.predict_proba(X)
 69        else:
 70            return self.model.predict(X)
 71
 72    def evaluate(self, features: List[Dict], **kwargs) -> Dict[str, float]:
 73        if not self.trained:
 74            raise ValueError("Model must be trained before evaluation")
 75        if hasattr(self, 'X_test') and hasattr(self, 'y_test'):
 76            X_test, y_test = self.X_test, self.y_test
 77        else:
 78            X_test, y_test = preprocess_features(features)
 79        y_pred = self.model.predict(X_test)
 80        accuracy = accuracy_score(y_test, y_pred)
 81        conf_matrix = confusion_matrix(y_test, y_pred)
 82        metrics = {
 83            'accuracy': accuracy,
 84            'confusion_matrix': conf_matrix.tolist()
 85        }
 86        detailed_report = kwargs.get('detailed_report', False)
 87        if detailed_report:
 88            class_report = classification_report(y_test, y_pred, output_dict=True)
 89            metrics['classification_report'] = class_report
 90        return metrics
 91
 92    def save_model(self, filepath: str):
 93        if not self.trained:
 94            raise ValueError("Model must be trained before saving")
 95        model_data = {
 96            'model': self.model,
 97            'config': self.config,
 98            'feature_names': self.feature_names,
 99            'class_names': self.class_names,
100            'trained': self.trained
101        }
102        joblib.dump(model_data, filepath)
103        print(f"MLP model saved to {filepath}")
104
105    def load_model(self, filepath: str):
106        try:
107            model_data = joblib.load(filepath)
108            if isinstance(model_data, dict):
109                self.model = model_data['model']
110                self.config = model_data.get('config', self.config)
111                self.feature_names = model_data.get('feature_names', [])
112                self.class_names = model_data.get('class_names', [])
113                self.trained = model_data.get('trained', False)
114            else:
115                self.model = model_data
116                self.trained = True
117            print(f"MLP model loaded from {filepath}")
118        except Exception as e:
119            print(f"Failed to load MLP model: {e}")

Multi-Layer Perceptron (MLP) classification model. Implements the BaseClassificationModel interface using scikit-learn's MLPClassifier.

MLPModel( hidden_layer_sizes=(100,), activation='relu', solver='adam', random_state=42, max_iter=200)
16    def __init__(self, hidden_layer_sizes=(100,), activation='relu', solver='adam', random_state=42, max_iter=200):
17        super().__init__(
18            name="mlp",
19            description="Multi-Layer Perceptron classifier for gait data classification"
20        )
21        self.config = {
22            'hidden_layer_sizes': hidden_layer_sizes,
23            'activation': activation,
24            'solver': solver,
25            'random_state': random_state,
26            'max_iter': max_iter
27        }
28        self.model = MLPClassifier(
29            hidden_layer_sizes=hidden_layer_sizes,
30            activation=activation,
31            solver=solver,
32            random_state=random_state,
33            max_iter=max_iter
34        )
35        self.feature_names = []
36        self.class_names = []

Initialize the classification model.

Args: name: Name of the classification model description: Description of the classification model

config
model
feature_names
class_names
def train(self, features: List[Dict], **kwargs):
38    def train(self, features: List[Dict], **kwargs):
39        X, y = preprocess_features(features)
40        self.feature_names = [f"feature_{i}" for i in range(X.shape[1])]
41        self.class_names = list(set(y))
42        test_size = kwargs.get('test_size', 0.2)
43        validation_split = kwargs.get('validation_split', True)
44        if validation_split:
45            X_train, X_test, y_train, y_test = train_test_split(
46                X, y, test_size=test_size, random_state=self.config['random_state']
47            )
48            self.model.fit(X_train, y_train)
49            self.X_test = X_test
50            self.y_test = y_test
51            train_accuracy = self.model.score(X_train, y_train)
52            test_accuracy = self.model.score(X_test, y_test)
53            print(f"Training accuracy: {train_accuracy:.4f}")
54            print(f"Validation accuracy: {test_accuracy:.4f}")
55        else:
56            self.model.fit(X, y)
57            train_accuracy = self.model.score(X, y)
58            print(f"Training accuracy: {train_accuracy:.4f}")
59        self.trained = True
60        print("MLP model trained successfully.")

Train the classification model.

Args: features: List of feature dictionaries **kwargs: Additional arguments for training

def predict(self, features: List[Dict], **kwargs) -> Union[numpy.ndarray, Any]:
62    def predict(self, features: List[Dict], **kwargs) -> Union[np.ndarray, Any]:
63        if not self.trained:
64            raise ValueError("Model must be trained before making predictions")
65        X, _ = preprocess_features(features)
66        return_probabilities = kwargs.get('return_probabilities', False)
67        if return_probabilities:
68            return self.model.predict_proba(X)
69        else:
70            return self.model.predict(X)

Make predictions using the trained model.

Args: features: List of feature dictionaries **kwargs: Additional arguments for prediction

Returns: Array of predictions

def evaluate(self, features: List[Dict], **kwargs) -> Dict[str, float]:
72    def evaluate(self, features: List[Dict], **kwargs) -> Dict[str, float]:
73        if not self.trained:
74            raise ValueError("Model must be trained before evaluation")
75        if hasattr(self, 'X_test') and hasattr(self, 'y_test'):
76            X_test, y_test = self.X_test, self.y_test
77        else:
78            X_test, y_test = preprocess_features(features)
79        y_pred = self.model.predict(X_test)
80        accuracy = accuracy_score(y_test, y_pred)
81        conf_matrix = confusion_matrix(y_test, y_pred)
82        metrics = {
83            'accuracy': accuracy,
84            'confusion_matrix': conf_matrix.tolist()
85        }
86        detailed_report = kwargs.get('detailed_report', False)
87        if detailed_report:
88            class_report = classification_report(y_test, y_pred, output_dict=True)
89            metrics['classification_report'] = class_report
90        return metrics

Evaluate the model performance.

Args: features: List of feature dictionaries **kwargs: Additional arguments for evaluation

Returns: Dictionary containing evaluation metrics

def save_model(self, filepath: str):
 92    def save_model(self, filepath: str):
 93        if not self.trained:
 94            raise ValueError("Model must be trained before saving")
 95        model_data = {
 96            'model': self.model,
 97            'config': self.config,
 98            'feature_names': self.feature_names,
 99            'class_names': self.class_names,
100            'trained': self.trained
101        }
102        joblib.dump(model_data, filepath)
103        print(f"MLP model saved to {filepath}")

Save the trained model to a file.

Args: filepath: Path to save the model

def load_model(self, filepath: str):
105    def load_model(self, filepath: str):
106        try:
107            model_data = joblib.load(filepath)
108            if isinstance(model_data, dict):
109                self.model = model_data['model']
110                self.config = model_data.get('config', self.config)
111                self.feature_names = model_data.get('feature_names', [])
112                self.class_names = model_data.get('class_names', [])
113                self.trained = model_data.get('trained', False)
114            else:
115                self.model = model_data
116                self.trained = True
117            print(f"MLP model loaded from {filepath}")
118        except Exception as e:
119            print(f"Failed to load MLP model: {e}")

Load a trained model from a file.

Args: filepath: Path to the saved model