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"]
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()
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,""]