ml/classifiers.py (81 lines of code) (raw):

# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # """ Credit Risk Models The module contains model definitions of various tested models for credit assessment """ from typing import Any, Dict, List import joblib import logging import pandas as pd from django.core.exceptions import BadRequest from sklearn.preprocessing import LabelEncoder log = logging.getLogger(__name__) class Classifier(object): """ Basic Scorecard Model Warning: This class should not be used directly. Use derived classes instead. """ def __init__(self, model=None, categorical=[], label_encoders: List[LabelEncoder] = {}): self.model = model self.categorical = categorical self.label_encoders = label_encoders # def __str__(self): # return f""" # Model Object # ---------------------------------------------------------------- # Classifier: {self.classifier().__class__.__name__} # Test Size: {self.test_size} # Random State: {self.random_state} # Number of Splits: {self.n_splits} # Parameter Grid: {self.params} # {self.model} # """ def preprocessing(self, data: Dict[str, Any]): """ Preprocess python dict object for prediction Parameters ---------- data: dict dictionary of data to predict """ categorical = [x for x in self.categorical if x != 'risk'] # log.info(f"Categorical: {categorical}") # for category in categorical: # if category not in list(data.keys()): # data[category] = None for key, value in data.items(): if type(value) == str: data[key] = value data = pd.DataFrame(data, index=[0]) # fill missing values # data.fillna(self.values_fill_missing) le = self.label_encoders data = data.dropna() # convert categoricals for category in categorical: failed_trials = [] try: data[category] = le[category].transform(data[category]) except KeyError as e: failed_trials.append(e) log.debug(f"An error occured: {str(e)}") if len(failed_trials) >= 3: raise BadRequest(failed_trials) else: data[e] = None return data def predict(self, data): """ Predict scorecard model Args: data: array Data to perform prediction on. """ return self.model.predict_proba(data) def postprocessing(self, prediction): label = "bad" if prediction[1] > 0.5: label = "good" return {"probability": prediction[1], "label": label} def compute_prediction(self, data: Dict[str, Any]): try: input_data = self.preprocessing(data) prediction = self.predict(input_data)[0] prediction = self.postprocessing(prediction) except Exception as e: log.debug(f'An error occured: {str(e)}') raise BadRequest(str(e)) return prediction class RandomForestClassifier(Classifier): def __init__( self, model=joblib.load('zoo/models/german/rf_classifier.joblib'), categorical=joblib.load('zoo/models/german/categorical.joblib'), label_encoders=joblib.load('zoo/models/german/label_encoders.joblib')): super(RandomForestClassifier, self).__init__(model, categorical, label_encoders) class SVC(Classifier): def __init__( self, model=joblib.load('zoo/models/german/svc_classifier.joblib'), categorical=joblib.load('zoo/models/german/categorical.joblib'), label_encoders=joblib.load('zoo/models/german/label_encoders.joblib')): super(SVC, self).__init__(model, categorical, label_encoders) class MLP(Classifier): def __init__( self, model=joblib.load('zoo/models/german/mlp_classifier.joblib'), categorical=joblib.load('zoo/models/german/categorical.joblib'), label_encoders=joblib.load('zoo/models/german/label_encoders.joblib')): super(MLP, self).__init__(model, categorical, label_encoders) class GradientBoostClassifier(Classifier): def __init__( self, model=joblib.load('zoo/models/german/gb_classifier.joblib'), categorical=joblib.load('zoo/models/german/categorical.joblib'), label_encoders=joblib.load('zoo/models/german/label_encoders.joblib')): super(GradientBoostClassifier, self).__init__(model, categorical, label_encoders)