예제 #1
0
    def save_model(model, path, tmp_files_path, new_model):
        """
        Guarda el modelo en el path solicitado.

        :model: [SpacyModelRef] - Referencia a un modelo de spacy.

        :path: [String] - Ruta en la cual guardar el modelo.

        :tmp_files_path: [String] - Ruta donde se encuentran los archivos temporales del modelo.

        :new_model: [Model] - Objeto que representa el nuevo modelo.
        """
        Logger.log('L-0030')
        base_path = build_path(MODEL_MANAGER_ROOT_DIR, path)
        if check_dir_existence(base_path):
            ErrorHandler.raise_error('E-0030')
        model_storage_path = get_absoulute_path(base_path)
        model.to_disk(model_storage_path)
        custom_model_files_path = build_path(base_path, MODEL_MANAGER_CUSTOM_FILES_DIR)
        create_dir_if_not_exist(custom_model_files_path)
        model_seed_path = build_path(tmp_files_path, TOKEN_RULES_GEN_MODEL_SEED_FILENAME)
        model_seed_copy_path = build_path(custom_model_files_path, TOKEN_RULES_GEN_MODEL_SEED_FILENAME, add_absolute_root=True)
        copy_file(model_seed_path, model_seed_copy_path, is_absolute_path=True)
        cfg_file_path = build_path(model_storage_path, MODEL_CONFIG_FILE_NAME)
        dictionary_to_disk(cfg_file_path, {
            'model_name': new_model.get_model_name(),
            'description': new_model.get_description(),
            'author': new_model.get_author(),
            'analyzer_rule_set': new_model.get_analyser_rules_set()
        }, True)
        Logger.log('L-0032')
예제 #2
0
    def __create_custom_verb_token_rules(self, verb, base_verb, person,
                                         time_key, max_dist):
        """
        A partir de un verbo conjugado, utiliza el modulo WordProcessor para deformarlo. 
        Para cada deformación que cumpla con la distancia máxima deseada, se crea una regla.

        :verb: [String] - Cadena de caracteres con la forma "bien escrita" de la
        palabra a deformar.

        :base_verb: [String] - Forma base de la palabra (Ej. vende --> vender)

        :person: [int] - Indice de la persona (0 - 5)

        :time_key: [String] - Clave del tiempo verbal.

        :max_dist: Distancia de levenshtein máxima para que una variación
        de una palabra sea tomada como válida.
        """
        Logger.log('L-0014', [{'text': verb, 'color': HIGHLIGHT_COLOR}])
        fuzzy_token_set = self.__word_processor.get_fuzzy_set(verb, max_dist)
        tokenizer_exceptions_set = list([])
        for fuzzy_token in fuzzy_token_set:
            token_exception = self.__get_verb_token_rule(
                fuzzy_token, base_verb, person, time_key)
            tokenizer_exceptions_set.append(token_exception)
        return tokenizer_exceptions_set
    def approve_traning_examples(self, examples_id_list):
        """
        Aprueba un conjunto de ejemplos de entrenamiento cuyos ids se encuentran en la lista de 
        ids provista. Si alguno de los ids en la lista no existe la operación no se realizará para
        ningún ejemplo.

        :examples_id_list: [List(int)] - Lista con los ids de los ejemplos de entrenamiento a aprobar.

        :return: [List(dict)] - Listado indicando los ejemplos de entrenamiento que se han podido
        aceptar y los que no.
        """
        Logger.log('L-0305')
        results = list([])
        for example_id in examples_id_list:
            status = False
            error = None
            try:
                self.__train_data_manager.approve_example(example_id)
                status = True
            except Exception as e:
                error = ErrorHandler.get_error_dict(e)
            finally:
                results.append({
                    'example_id': example_id,
                    'status': status,
                    'error': error
                })
        Logger.log('L-0306')
        return results
예제 #4
0
    def __create_task(self, task, is_able_to_start):
        """
        Crea una tarea, la agrega al administrador y si es posible la inicializa.

        :task: [Task] - Tarea a crear.

        :is_able_to_start: [boolean] - Indica si la tarea se puede inicializar inmediatamente 
        después de creada.
        """
        try:
            self.__lock.acquire()
            Logger.log('L-0227')
            self.__active_tasks.append(task)
            task.add_observer(self)
            Logger.log('L-0228')
            running_tasks_count = len([
                task for task in self.__active_tasks
                if task.get_task_status_data()['status'] == TASK_STATUS_RUNNING
            ])
            if is_able_to_start and running_tasks_count <= MAX_CONCURRENT_TASKS and not task.is_alive(
            ):
                task.init()
        except:
            pass
        finally:
            self.__lock.release()
    def discard_training_examples(self, examples_id_list):
        """
        Rechaza el conjunto de ejemplos de entrenamiento que tienen los ids especificados en la lista
        de ids provista. Todos los ids provistos deben existir, de lo contrario, no se descartará
        ninguno.

        :examples_id_list: [List(int)] - Listado con los ids de los ejemplos a rechazar.

        :return: [List(dict)] - Listado indicando los ejemplos de entrenamiento que se han podido
        rechazar y los que no.
        """
        Logger.log('L-0314')
        results = list([])
        for example_id in examples_id_list:
            status = False
            error = None
            try:
                self.__train_data_manager.discard_example(example_id)
                status = True
            except Exception as e:
                error = ErrorHandler.get_error_dict(e)
            finally:
                results.append({
                    'example_id': example_id,
                    'status': status,
                    'error': error
                })
        Logger.log('L-0315')
        return results
예제 #6
0
    def create_model_creation_task(self, model_id, model_name, description,
                                   author, tokenizer_exceptions, max_dist):
        """
        Crea y agrega a la cola una nueva tarea de creación de modelo.

        :model_id: [String] - Id del modelo a crear.

        :model_name: [String] - Nombre del modelo a crear.

        :description: [String] - Descripcion del modelo a crear.

        :author: [String] - Autor del modelo a crear.

        :tokenizer_exceptions: [Dict] - Datos de las excepciones al tokenizer a aplicar al nuevo modelo.

        :max_dist: [int] - Distancia de demerau levenshtein máxima.

        :return: [int] - Id. de la tarea creada.
        """
        Logger.log('L-0225')
        next_task_id = self.__get_next_task_id()
        new_task = ModelCreationTask(next_task_id, model_id, model_name,
                                     description, author, tokenizer_exceptions,
                                     max_dist)
        is_able_to_init = not self.__check_active_status_for_model(
            model_id, model_name)
        self.__create_task(new_task, is_able_to_init)
        Logger.log('L-0226')
        return next_task_id
예제 #7
0
    def generate_model_data(self, model_seed, path, max_dist):
        """
        A partir de una model_seed, crea los archivos de configuración para modificar el tokenizer
        de un modelo de spacy. 

        :model_seed: [Dict] - Semilla para la creación del modelo.

        :base_path: [String] - Directorio base del modelo.

        :max_dist: [int] - Distancia de demerau levenshtein máxima para las deformaciones a los token.
        """
        base_path = build_path(TOKEN_RULES_GEN_TMP_ROOT_PATH, path)
        if check_dir_existence(base_path):
            ErrorHandler.raise_error('E-0027')
        Logger.log('L-0003')
        create_dir_if_not_exist(base_path)
        self.__save_model_seed(model_seed, base_path)
        nouns_path = build_path(base_path, TOKEN_RULES_GEN_TYPE_NOUN)
        create_dir_if_not_exist(nouns_path)
        verbs_path = build_path(base_path, TOKEN_RULES_GEN_TYPE_VERB)
        create_dir_if_not_exist(verbs_path)
        self.__generate_noun_rules(model_seed['nouns'], max_dist, nouns_path)
        self.__generate_verb_rules(model_seed['verbs'], max_dist, verbs_path)
        Logger.log('L-0004')
        return get_absoulute_path(base_path)
예제 #8
0
    def edit_model_data(self, model_id, new_model_name=None, new_description=None):
        """
        Edita los datos de un modelo existente. Si el modelo no existe u ocurre algún error durante
        la edición de sus datos devolverá false.

        :model_id: [String] - Nombre actual del modelo.

        :new_model_name: [String] - Nuevo nombre a asignar al modelo.

        :new_description: [String] - Nueva descripción para el modelo.
        """
        Logger.log('L-0074')
        current_model = self.__model_manager.get_model(model_id)
        if current_model is None:
            ErrorHandler.raise_error('E-0074')
        current_model_name = current_model.get_model_name()
        edited_model_name = new_model_name
        current_description = current_model.get_description()
        edited_description = new_description
        if new_model_name is None or new_model_name == '':
            edited_model_name = current_model_name
        if new_description is None or new_description == '':
            edited_description = current_description
        if edited_model_name == current_model_name and edited_description == current_description:
            ErrorHandler.raise_error('E-0075')
        self.__model_manager.edit_model(model_id, edited_model_name, edited_description)
예제 #9
0
    def save_model_data(model_id, model_name, description, author, path,
                        analyser_rules_set):
        """
        Guarda información de un modelo.

        :model_id: [String] - Id del modelo.

        :model_name: [String] - Nombre del modelo (actua como id).

        :description: [String] - Descripción del modelo.

        :author: [String] - Nombre del creador del modelo.

        :path: [String] - Ruta relativa para encontrar el modelo.

        :analyser_rules_set: [List(Dict)] - Lista de reglas para el analizador
        """
        Logger.log('L-0026')
        if ModelDataManager.check_existing_model(model_id):
            ErrorHandler.raise_error('E-0029')
        data_dict = {
            'model_id': model_id,
            'model_name': model_name,
            'description': description,
            'author': author,
            'path': path,
            'analyzer_rules_set': analyser_rules_set
        }
        db_insert_item(MODEL_MANAGER_DB, MODEL_MANAGER_MODELS_COLLECTION,
                       data_dict)
        Logger.log('L-0029')
예제 #10
0
    def import_model(model_id, source):
        """
        Obtiene los archivos de modelo, los descomprime y obtiene el diccionario de
        configuración del modelo remoto solicitado.

        :model_id: [String] - Id del modelo a importar.

        :return: [Dict] - Dicionario con la configuración del modelo.
        """
        try:
            local_path = '%s/%s/%s' % (CURRENT_BASE_PATH, MODEL_MANAGER_ROOT_DIR, model_id)
            model_cfg_file = '%s/%s' % (local_path, MODEL_CONFIG_FILE_NAME)
            if source['remote']:
                remote_repo_url = '%s/%s%s' % (source['path'], model_id, MODEL_IMPORT_EXT)
                Logger.log('L-0134', [{'text': remote_repo_url, 'color': HIGHLIGHT_COLOR}])
                Repo.clone_from(remote_repo_url, local_path)
            else:
                Logger.log('L-0140', [{'text': source['path'], 'color': HIGHLIGHT_COLOR}])
                copy_dir(source['path'], local_path)
            Logger.log('L-0147')
            Logger.log('L-0154')
            unzip_model(local_path, model_id)
            remove_files(local_path, '%s%s' % (model_id, MODEL_PACKAGING_EXTENSION))
            remove_files(local_path, '%s' % MODEL_TMP_JOINT_FILE_NAME)
            Logger.log('L-0161')
            return load_json_file(model_cfg_file)
        except Exception as e:
            ErrorHandler.raise_error('E-0119', [{'text': e, 'color': ERROR_COLOR}])
예제 #11
0
    def delete_model_files(path):
        """
        Elimina los archivos de un modelo del disco.

        :path: [String] - Ruta a eliminar.
        """
        Logger.log('L-0070')
        full_path = build_path(MODEL_MANAGER_ROOT_DIR, path)
        remove_dir(full_path)
예제 #12
0
    def log_error(error_data, log_data):
        """
        Loggea los datos de un error

        :error_data: [Dict] - Datos del error

        :log_data: [List] - Datos adicionales de log
        """
        log_code = error_data['log']
        Logger.log(log_code, log_data)
예제 #13
0
    def get_available_models(self):
        """
        Devuelve una lista con todos los modelos disponibles en el sistema (esten cargados o no).

        :return: [List] - Listado de los modelos disponibles en el sistema.
        """
        if not self.__init_success:
            Logger.log('L-0095')
            return None
        return self.__model_manager.get_available_models_dict()
예제 #14
0
 def run(self):
     """
     Inicia la ejecución del thread
     """
     Logger.log('L-0229', [{'text': self.__id, 'color': HIGHLIGHT_COLOR}])
     self.__init_time = datetime.datetime.now()
     self.__status = TASK_STATUS_RUNNING
     self.task_init_hook()
     self.__end_time = datetime.datetime.now()
     self.__status = TASK_STATUS_FINISHED
     self.notify(self)
     Logger.log('L-0230')
 def __init(self):
     """
     Inicializa el módulo.
     """
     Logger.log('L-0243')
     self.__init_success = False
     self.__model_trainer = ModelTrainerManager()
     self.__model_manager = ModelManagerController()
     self.__model_manager.add_observer(self)
     available_models = self.__model_manager.get_available_models()
     self.__train_data_manager = TrainDataManager(available_models)
     Logger.log('L-0245')
     self.__init_success = True
예제 #16
0
    def add_ner_labels(ner, training_data):
        """
        Agrega las nuevas etiquetas al ner.

        :ner: [SpacyNER] - NER al cual aplicar las nuevas etiquetas

        :training_data: [List(Dict)] - Set de datos de entrenamiento.
        """
        Logger.log('L-0345')
        for _, annotations in training_data:
            for ent in annotations.get('entities'):
                ner.add_label(ent[2])
        Logger.log('L-0346')
예제 #17
0
    def load_model(self, model_id):
        """
        Carga un modelo en memoria para poder tener un acceso más rapido al mismo. Solo se aconseja su uso para
        la realización de pruebas.

        :model_id: [String] - Nombre del modelo a cargar.

        :return: [bool] - True si el modelo ha sido exitosamente cargado, False en caso contrario.
        """
        if not self.__init_success:
            Logger.log('L-0096')
            return None
        return self.__model_manager.load_model(model_id)
예제 #18
0
    def get_examples_history(self, model_id):
        """
        Retorna un listado con todos los ejemplos, sin importar su estado, para un determinado
        modelo.

        :model_id: [String] - Id del modelo.

        :return: [List] - Listado de todos los ejemplos para el modelo solicitado.
        """
        if not self.__find_model(model_id):
            ErrorHandler.raise_error('E-0082')
        results = list([])
        Logger.log('L-0326')
        examples_data = db_get_items(TRAIN_MANAGER_DB,
                                     TRAIN_DATA_EXAMPLES_COLLECTION,
                                     {'model_id': model_id})
        Logger.log('L-0327')
        Logger.log('L-0328')
        for example_data in examples_data:
            example = TrainExample(example_data['example_id'],
                                   example_data['sentence'],
                                   example_data['tags'], example_data['type'],
                                   example_data['status'])
            results.append(example)
        Logger.log('L-0329')
        return results
예제 #19
0
    def discard_example(self, example_id):
        """
        Rechaza el ejemplo de entrenamiento. El ejemplo solicitado debe existir y no
        estar ya rechazado o aplicado.

        :example_id: [int] - Id del ejemplo de entrenamiento.
        """
        Logger.log('L-0316', [{'text': example_id, 'color': HIGHLIGHT_COLOR}])
        example = self.__find_example(example_id)
        if example is None:
            ErrorHandler.raise_error('E-0104')
        if example.get_status() != TRAIN_EXAMPLE_STATUS_SUBMITTED:
            ErrorHandler.raise_error('E-0105')
        Logger.log('L-0318')
        updated_items = db_update_item(
            TRAIN_MANAGER_DB, TRAIN_DATA_EXAMPLES_COLLECTION, {
                'example_id': example_id
            }, {
                'status': TRAIN_EXAMPLE_STATUS_REJECTED
            }).modified_count
        if updated_items <= 0:
            ErrorHandler.raise_error('E-0106')
        Logger.log('L-0319')
        example.reject()
        Logger.log('L-0320', [{'text': example_id, 'color': HIGHLIGHT_COLOR}])
예제 #20
0
    def import_model(self, model_id, source=None):
        """
        Importa un modelo existente desde el repositorio de modelos. No debe existir
        un modelo local con dicho id y, además, el módelo debe existir en el repositorio
        remoto de modelos.

        :model_id: [String] - Id del modelo a importar.

        :source: [Dict] - Fuente de donde obtener el modelo, puede ser un repositorio
        git o un directorio local.
        """
        Logger.log('L-0116')
        model = self.get_model(model_id)
        if model:
            ErrorHandler.raise_error('E-0118')
        if not source:
            source = REMOTE_MODEL_SOURCE
        cfg = ModelLoader.import_model(model_id, source)
        analyzer_exceptions_set_data = cfg['analyzer_exceptions_set']
        Logger.log('L-0179')
        ModelDataManager.save_model_data(model_id, cfg['model_name'], cfg['description'], cfg['author'], model_id, cfg['analyzer_rules_set'])
        remote_model = Model(model_id, cfg['model_name'], cfg['description'], cfg['author'], model_id, cfg['analyzer_rules_set'], [])
        self.__models.append(remote_model)
        for exception in analyzer_exceptions_set_data:
            self.add_analyzer_exception(model_id, exception['base_form'], exception['token_text'], exception['enabled'])
        Logger.log('L-0188')
        Logger.log('L-0197')
예제 #21
0
    def __build_annotations(self, examples):
        """
        Crea el listado de ejemplos a partir de los ejemplos de entrenamiento.

        :examples: [List(TrainExample)] - Lista de ejemplos de entrenamiento.

        :return: [List] - Listado con la anotaciones.
        """
        Logger.log('L-0338')
        annotations = list([])
        for training_example in examples:
            annotations.append(training_example.get_annotations())
        Logger.log('L-0339')
        return annotations
예제 #22
0
    def edit_custom_tag_entity(self, name, description):
        """
        Edita un tag personalizado. El tag debe existir, solamente se puede modificar 
        la descripción.

        :name: [String] - Nombre del tag a actualizar.

        :description: [String] - Descripción actualizada del tag.
        """
        Logger.log('L-0284')
        entity = self.__get_entity(name)
        if entity is None:
            ErrorHandler.raise_error('E-0101')
        if entity.get_description() == description:
            ErrorHandler.raise_error('E-0102')
        Logger.log('L-0287')
        updated_entries = db_update_item(TRAIN_MANAGER_DB,
                                         CUSTOM_ENTITY_MANAGER_COLLECTION, {
                                             'name': name
                                         }, {
                                             'description': description
                                         }).modified_count
        if updated_entries <= 0:
            ErrorHandler.raise_error('E-103')
        Logger.log('L-0288')
        entity.set_description(description)
        Logger.log('L-0290')
예제 #23
0
    def approve_example(self, example_id):
        """
        Aprueba el ejemplo de entrenamiento identificado on el id solicitado. El 
        ejemplo debe existir y no estar ya aprobado o aplicado.

        :example_id: [int] - Id del ejemplo de entrenamiento.
        """
        Logger.log('L-0307', [{'text': example_id, 'color': HIGHLIGHT_COLOR}])
        example = self.__find_example(example_id)
        if example is None:
            ErrorHandler.raise_error('E-0077')
        if example.get_status() != TRAIN_EXAMPLE_STATUS_SUBMITTED:
            ErrorHandler.raise_error('E-0078')
        example_id = example.get_example_id()
        Logger.log('L-0309')
        updated_items = db_update_item(
            TRAIN_MANAGER_DB, TRAIN_DATA_EXAMPLES_COLLECTION, {
                'example_id': example_id
            }, {
                'status': TRAIN_EXAMPLE_STATUS_APPROVED
            }).modified_count
        if updated_items <= 0:
            ErrorHandler.raise_error('E-0079')
        Logger.log('L-0310')
        example.approve()
        Logger.log('L-0311', [{'text': example_id, 'color': HIGHLIGHT_COLOR}])
예제 #24
0
    def create_model_training_task(self, model_id):
        """
        Crea y agrega a la cola una nueva tarea de entrenamiento de modelo.

        :model_id: [String] - Id del modelo a utilizar.

        :return: [int] - Id. de la tarea creada.
        """
        Logger.log('L-0231')
        next_task_id = self.__get_next_task_id()
        new_task = ModelTrainingTask(next_task_id, model_id)
        is_able_to_init = not self.__check_active_status_for_model(model_id)
        self.__create_task(new_task, is_able_to_init)
        Logger.log('L-0232')
        return next_task_id
예제 #25
0
    def edit_model(self, model_id, model_name, description):
        """
        Permite editar la descripción de un modelo. El modelo debe existir.

        :model_id: [String] - Id del modelo.

        :model_name: [String] - Nuevo nombre para el modelo.

        :description: [String] - Nueva descripción para el modelo.
        """
        selected_model = self.get_model(model_id)
        ModelDataManager.modify_model_data(model_id, model_name, description)
        selected_model.set_model_name(model_name)
        selected_model.set_description(description)
        Logger.log('L-0082')
예제 #26
0
    def __apply_tokenizer_exceptions(self, model, tokenizer_exceptions_path):
        """
        Aplica todas las excepciones contenidas en el directorio de excepciones al modelo.

        :model: [SpacyModelRef] - Modelo sobre el cual aplicar las excepc¡ones.

        :tokenizer_exceptions_path: [String] - Ruta al directorio de excepciones para el modelo.
        """
        Logger.log('L-0023')
        tokenizer_exceptions_files = get_files_in_dir(tokenizer_exceptions_path, TOKEN_RULES_GEN_RULES_EXT)
        for source_file in tokenizer_exceptions_files:
            rule_set = load_json_file(source_file)
            for key in rule_set:
                model.add_tokenizer_rule_set(rule_set[key])
        Logger.log('L-0024')
예제 #27
0
    def remove_model_data(model_id):
        """
        Elimina la entrada para un modelo.

        :model_id: [String] - Id del modelo a eliminar.
        """
        Logger.log('L-0066')
        model_delete_count = db_delete_item(MODEL_MANAGER_DB,
                                            MODEL_MANAGER_MODELS_COLLECTION, {
                                                'model_id': model_id
                                            }).deleted_count
        if model_delete_count <= 0:
            ErrorHandler.raise_error('E-0072')
        db_delete_items(MODEL_MANAGER_DB, ANALYZER_EXCEPTIONS_COLLECTION,
                        {'model_id': model_id})
    def add_training_examples(self, model_id, examples_list):
        """
        Agrega una lista de ejemplos de entrenamiento. Para que la operación sea exitosa todos los
        ejemplos deben poder ser validados correctamente, en caso contrario no se añadirá ninguno.

        :model_id: [String] - Id del modelo al cual se aplicará el ejemplo.

        :examples_list: [List(Dict)] - Listado de ejemplos de entrenamiento.
        """
        Logger.log('L-0292')
        model = self.__model_manager.get_model(model_id)
        if model is None:
            ErrorHandler.raise_error('E-0084')
        self.__train_data_manager.add_training_examples(
            model_id, examples_list)
        Logger.log('L-0295')
예제 #29
0
    def get_model_ner(model_ref):
        """
        Obtiene el NER de un determinado modelo. Si el mismo no existe, crea uno nuevo y lo agrega
        al pipeline del modelo.

        :model_reference: [SpacyModelRef] - Referencia al modelo de spacy
        """
        Logger.log('L-0343')
        ner = None
        if MODEL_NER in model_ref.pipe_names:
            ner = model_ref.get_pipe(MODEL_NER)
        else:
            ner = model_ref.create_pipe(MODEL_NER)
            model_ref.add_pipe(ner, last=True)
        Logger.log('L-0344')
        return ner
예제 #30
0
    def __initialize(self, is_retry=False):
        """
        Inicializa el modulo. Si la inicialización es exitosa, setea el atributo ready a True.
        En caso contrario se pasará (si no estuviese ya) a False

        :is_retry: [Bool] - Indica si es un reintento de inicialización
        """
        Logger.log('L-0036')
        self.__init_success = False
        self.__word_processor = WordProcessorController()
        if is_retry:
            self.__word_processor.retry_initialization()
        self.__tokenizer_rules_generator = TokenizerRulesGenerator()
        self.__model_manager = ModelManagerController()
        self.__train_manager = ModelTrainingController()
        self.__analyzer_rules_generator = AnalyzerRulesGerator()
        self.__init_success = True
        Logger.log('L-0037')