Exemplo n.º 1
0
    def index(self, category_uuid):

        tmpl = lookup.get_template("ktree_show_category.html")
        session_context = cherrypy.session.get('session_context')
        session_context['back_ref'] = '/ktree'
        session_context['menu'] = 'ktree_category'
        if session_context['menu'] == 'ktree_category':
            #session_context['back_ref'] = '/ktree/' + str(category_uuid)
            session_context['menu'] = 'ktree_category'

        if session_context['menu'] == 'ktree_settings':
            session_context['back_ref'] = '/settings?menu=ktree'
            session_context['menu'] = 'ktree_settings'

        cherrypy.session['session_context'] = session_context

        # print category_uuid

        session = rwObjects.Session()
        leaf = rwObjects.get_by_uuid(category_uuid)[0]

        # Получаем все связанные объекты для этого пользователя
        neighbors = G.neighbors(session_context['uuid'])
        neighbors.append(session_context['uuid'])

        # Получаем все объекты связанные с этим узлом НЗ
        try:
            response = session.query(rwObjects.Reference). \
                filter(rwObjects.or_(rwObjects.Reference.source_uuid == leaf.uuid, \
                                     rwObjects.Reference.target_uuid == leaf.uuid)). \
                order_by(rwObjects.desc(rwObjects.Reference.timestamp)).all()
        except Exception as e:
            raise e
        else:
            pass
        nodes = list()
        for line in response:
            source = rwObjects.get_by_uuid(line.source_uuid)[0]
            target = rwObjects.get_by_uuid(line.target_uuid)[0]
            if line.link == 0 and source.uuid == category_uuid:
                nodes.append(target)
            elif line.link == 0 and target.uuid == category_uuid:
                nodes.append(source)

        # Получаем результаты автоклассификации для объектов в этом узле НЗ
        auto_cats = dict()
        for node in nodes:
            auto_cats[node.uuid] = rwObjects.get_classification_results(session, node.uuid)
            # print "Автоклассификация : %s" % auto_cats[node.uuid]

        return tmpl.render(obj=leaf, session=session, name=leaf.name,
                           nodes=nodes, session_context=session_context,
                           auto_cats=auto_cats, cats_name=rwObjects.get_ktree_custom(session),
                           neighbors=neighbors)
def check_conditions_for_classify():
    """
    Проверяет:
     -- сколько кастомных разделов в ДЗ создано, если меньше 2-х то не дает инициировать классификатор.
     -- сколько объектов с типами из FOR_CLASSIFY создано в системе и с какими кастомными разделами они связаны. Если
     в разделе нет ни одного документа, то не дает инициировать классификатор.

    :return: Список. Первый элемент статус - True/False проверки условий, второй - строка с комментарием.
    """
    session = rwObjects.Session()

    # Проверка кастомных разделов
    try:
        count = session.query(rwObjects.KnowledgeTree).filter(rwObjects.KnowledgeTree.type == 'custom').count()
    except Exception as e:
        return [False,"Ошибка доступа к базе классификаторов."]
    else:
        pass
    if count < 2:
        return [False,"Мало разделов в ДЗ. У вас %s, надо больше 2 или больше." % count]

    # Проверка количества объектов из FOR_CLASSIFY. Должно быть >= количеству разделов.
    """
    try:
        obj_count = session.query(rwObjects.DynamicObject).\
            filter(rwObjects.DynamicObject.obj_type.in_(rwObjects.FOR_CLASSIFY)).count()
    except Exception as e:
        return [False,"Ошибка доступа к объектам."]
    else:
        pass

    if obj_count < count:
        return [False,"Мало объектов для связи с ДЗ. У вас %s, надо больше %s." % (obj_count, count)]
    """

    # Получаем кастом узлы
    custom_leafs = rwObjects.get_ktree_custom(session)
    obj_count = 0
    # Считаем для каждого количество связанных объектов, в каждом узле должен быть 1 или больше
    for leaf in custom_leafs.values():
        if leaf.get_category_objects_count(session) != 0:
            obj_count += 1
    if obj_count < 2:
        return [False,"Как минимум к двум разделам Навигатора Знаний, необходимо привязать по одному сообщению."]

    session.close()
    return [True,"OK"]
Exemplo n.º 3
0
    def addlink(self, uuid):
        data = cherrypy.request.params
        session = rwObjects.Session()
        tmpl = lookup.get_template("add_link_to_ktree.html")

        try:
            obj = rwObjects.get_by_uuid(uuid)[0]
            custom = rwObjects.get_ktree_custom(session)
        except Exception as e:
            return ShowError("""LinkObject.addlink. Операция rwObjects.get_by_uuid() или
                                rwObjects.get_by_uuid(uuid)[0]. Ошибка : %s""" % str(e))
        print custom.values()
        used_category = rwObjects.get_ktree_for_object(session, uuid)[0]

        session.close()
        return tmpl.render(obj=obj, category=custom,
                           session_context=cherrypy.session.get('session_context'),
                           used_category=used_category)
def autoclassify_all_notlinked_objects():
    """
    Проводит автоматическую классификацию всех не связанных ни с одним custom узлом Навигатора Знаний объектов класса
    DynamicObject. При этом используется текущие настройки и обученная модель классификатора. Если автоматическая
    классификация для объекта уже существует, то ее результаты будут перезаписаны.

    :return:
    """

    # Ищем все сообщения, их них отбираем только те которые не имеют связей с custom
    # т.е. имею пустое свойство self.__dict__['custom_category']
    session = rwObjects.Session()
    resp = session.query(rwObjects.DynamicObject).all()
    for obj in resp:
        obj.read(session)
        print obj.uuid
        print obj.__dict__['custom_category']
        if not obj.__dict__['custom_category'] and obj.obj_type in rwObjects.FOR_CLASSIFY:
            print "-------- Классифицируем объект : %s ---------" % obj.uuid
            obj = rwObjects.get_by_uuid(obj.uuid)[0]

            obj.clear_text()
            #print str(obj.text_clear)
            try:
                probe, Z = predict(rwObjects.default_classifier, [obj.text_clear])
            except Exception as e:
                raise e
            else:
                pass
            print 'Вероятности : %s' % probe
            categories = rwObjects.get_ktree_custom(session)
            print 'Категория : %s' % categories[Z[0]].name
            print "--------------Классификация закончена.------------------"

            # Сохраняем результаты классификации
            status = save_classification_result(session,obj.uuid,rwObjects.default_classifier,probe)
            if status[0]:
                print "Данные классификации сохранены."
            else:
                print "Данные классификации НЕ сохранены."

    session.close()
Exemplo n.º 5
0
def apply_rules_for_1(source_uuid, source_type, target_uuid, target_type):
    """
    В момент появления связи "создания" между объектами проходит проверка автоматических правил.
    Эта функция вызывается автоматически при вызове функции Reference.create()
    :param source_uuid: UUID объекта источника
    :param source_type: тип объекта источника
    :param target_uuid: UUID объекта цели
    :param target_type: тип объекта цели
    :return string: OK, в случае успеха.
    :exception e: Ошибка в случае исключения.
    """
    session = rwObjects.Session()
    """
    Если среди участников проверки есть DynamicObject, то ищем его внутренний тип.
    """
    tt = target_type
    st = source_type
    if target_type == "dynamic_object":
        response = session.query(rwObjects.DynamicObject). \
            filter(rwObjects.DynamicObject.uuid == target_uuid).one()
        tt = response.obj_type

    elif source_type == "dynamic_object":
        response = session.query(rwObjects.DynamicObject). \
            filter(rwObjects.DynamicObject.uuid == source_uuid).one()
        tt = response.obj_type

        """
        Objects Rule #1
        Acc создает Msg
        Если S = Account и T = Messages, то связываем Сотрудника владеющего аккаунтом и сообщение.
        Владелец аккаунта всегда один и связан с ним связью весом 0.
         """
    if st == "accounts" and tt == "messages":
        try:
            response = session.query(rwObjects.Reference). \
                filter(rwObjects.and_(0 == rwObjects.Reference.link,\
                                      rwObjects.Reference.target_uuid == source_uuid,\
                                      rwObjects.Reference.source_type == 'employees')).one()
        except Exception as e:
            raise Exception(str(e))
        else:
            owner_uuid = response.source_uuid
            print "Objects Rule #1"
            print "Линкуем %s с %s " % (owner_uuid, target_uuid)
            """Делаем линкование объектов """
            rwObjects.link_objects(session, owner_uuid, target_uuid)

        """
        Objects Rule #1.1
        Acc создает Msg
        Если S = Account и T = Messages, то ищем о полю References в новом сообщении, существующие сообщения
        с входящими в него message-id. Если находим линкуем.
         """
        # Получаем новый объект класса DO
        try:
            new_msg = rwObjects.get_by_uuid(target_uuid)[0]
        except Exception as e:
            raise Exception(str(e))
        all = dict()

        # Получаем все сообщения и записываем их id и uuid
        try:
            resp = session.query(rwObjects.DynamicObject).all()
        except Exception as e:
            raise Exception(str(e))

        for msg in resp:
            try:
                obj = rwObjects.get_by_uuid(msg.uuid)[0]
            except Exception as e:
                raise Exception(str(e))
            all[obj.__dict__['message-id'].strip("[ |<|>]")] = msg.uuid

        # Если есть поле References, то работаем по нему, иначе ничего не делаем
        if 'references' in new_msg.__dict__.keys():
            refs = list()
            for r in new_msg.__dict__['references'].split(" "):
                refs.append(r.strip("[ |<|>]"))

            links = list()
            for r in refs:
                if r in all.keys():
                    links.append([all[r],new_msg.uuid])
            print links
            for l in links:
                rwObjects.link_objects(session, l[0], l[1])


        """
        Objects Rule #2
        Правило 2. Empl создает Empl
        Если S = Employee и T = Employee, то связываем нового пользователя с Компанией.
            Пользователя создает суперюзер, он связан со своей компанией линком весом 0.
        """
    elif st == "" and tt == "":
        # 1. Находим компанию
        pass

        """
        Objects Rule #3
        Правило 3. Empl создает Acc
        Если S = Employee и T = Account, то связываем новый Аккаунт с Пользователем.
        """
    elif st == "" and tt == "":
        # 1.
        pass

    """
    Knowledge Rule #1
    Линкуем стандартные объекты в момент создания со стандартными ветками дерева знаний.
    Стандартные типы объектов перечисленны в STANDARD_OBJECT_TYPES.
    Если ветки в ДЗ нет, то она создается в корне дерева.
    """
    standard = rwObjects.STANDARD_OBJECTS_TYPES
    classes = dict()
    try:
        response = session.query(rwObjects.KnowledgeTree).all()
    except Exception as e:
        raise Exception("Ошибка чтения ДЗ." + str(e))
    else:
        pass
    for leaf in response:
        cls = leaf.get_objects_classes()
        for c in cls:
            if c not in classes.keys():
                classes[c] = leaf.uuid

    #print classes.keys()
    #print standard
    print "Проверка Knowledge Rule #1 для :",tt
    if tt in standard and tt in classes.keys():
        print "Выполняем Knowledge Rule #1"
        rwObjects.link_objects(session, classes[tt], target_uuid)
        pass


    """
    Knowledge Rule #2
    Класифицируем объекты типы которых указаны в константе FOR_CLASSIFY.
    """
    print "Проверка Knowledge Rule #2 для : %s" % tt
    status = rwLearn.check_conditions_for_classify()
    if not status[0]:
        raise Exception("Не соблюдены условия для тренировки." + status[1])

    if tt in rwObjects.FOR_CLASSIFY:
        print "-------- Классифицируем объект : %s ---------" % target_uuid
        obj = rwObjects.get_by_uuid(target_uuid)[0]
        clf_uuid = rwObjects.default_classifier
        obj.clear_text()
        print str(obj.text_plain)
        probe, Z = rwLearn.predict(clf_uuid, [obj.text_plain])
        print 'Вероятности : %s' % probe
        categories = rwObjects.get_ktree_custom(session)
        print 'Категория : %s' % categories[Z[0]].name
        print "--------------Классификация закончена.------------------"

        # Сохраняем результаты классификации
        status = rwLearn.save_classification_result(session,target_uuid,clf_uuid,probe)
        if status[0]:
            print "Данные классификации сохранены."
        else:
            print "Данные классификации НЕ сохранены."

    session.close()
    return "OK"
def retrain_classifier(session,clf_uuid):
    """
    Готовит данные для тренировки классификатора и проводит ее.
    :param session: сессия ORM
    :param clf_uuid: UUID классификатора для обучения
    :return: список статуса. Первый элемент - статус операции True/Flase, второй - описание.
    """

    status = check_conditions_for_classify()
    if not status[0]:
        raise Exception("Не соблюдены условия для тренировки."+status[1])

    # Готовим данные для тренировки. Делаем выборку из Reference с типами из FOR_CLASSIFY привязанных к custom веткам
    #  ДЗ.
    # Отбираем кастом ветки
    custom = rwObjects.get_ktree_custom(session)
    print custom
    custom_uuid = custom.keys()

    print "Custom ветки ДЗ: "
    for i in custom.values():
        print i.name

    # Делаем выборку всех DynamicObjects
    objects = list()
    try:
        res = session.query(rwObjects.DynamicObject).\
            filter(rwObjects.DynamicObject.obj_type.in_(rwObjects.FOR_CLASSIFY)).all()
    except Exception as e:
        return [False,"Ошибка доступа к базе DO."]
    else:
        for r in res:
            objects.append(r.uuid)

    # Ищем только связанные с custom узлами DO из нашего списка.
    try:
        res = session.query(rwObjects.Reference).\
            filter(rwObjects.and_(rwObjects.Reference.source_uuid.in_(custom_uuid),
                                  rwObjects.Reference.target_uuid.in_(objects))).all()
    except Exception as e:
        return [False,"Ошибка доступа к базе Reference объектов."]
    else:
        pass

    print "Объекты для обучения: "
    # Готовим данные в объектах для обучения классификатора
    keys = list()
    dataset = list()
    targets = list()
    for r in res:
        obj = rwObjects.get_by_uuid(r.target_uuid)[0]
        obj.clear_text()
        keys.append(r.target_uuid)
        dataset.append(obj.text_clear)
        targets.append(r.source_uuid)
        print "Объект: ",r.target_uuid
        print "Текст длина в признаках: ",obj.text_clear
        print "Категория",r.source_uuid
        print ""

    print "Dataset len :",len(dataset)
    print "Key len :",len(keys)
    print "Targets len :",len(targets)

    fit_classifier(rwObjects.default_classifier, dataset, targets)

    return [True,""]