среда, 13 июня 2012 г.

Экспертная система "Book advisor"


Лабораторная работа

по курсу 

"Интеллектуальные системы":

Разработка экспертной системы

Выполнил 
студент группы ИУ5-81
Баришок Н.И.


Краткое описание
Разработка программного модуля диалога с пользователем, логика работы которого определяется вне тела программы и может быть изменена пользователем без обновления ее кода.
Задания лабораторной работы:
Выбрать предметную область и формализовать задачу, которая может быть решена с помощью ЭС:
  • Определить перечень объектов принятия решения O.
  • Определить свойства (атрибуты) объектов принятия решения A и их значения.
  • Определить параметры P других объектов, событий, процессов и т.д., которые влияют на выбор конкретных значений свойств объектов O.
Разработать схему разветвленного диалога с пользователем:
  • Придумать множество вопросов Q, позволяющих определить значения параметров P
  • Разработать граф диалога вопросов и ответов
  • Составить правила выбора последующего вопроса на основе ответов предыдущего.
Разработать базу знаний (БЗ) и компьютерную программу (программный модуль), которая опрашивает пользователя на основе спроектированной схемы диалога (Q->P):
  • Создание базы знаний для хранения вариантов ответов, вопросов и правил их задавания.
  • Разработка программы, которая считывает вопросы из БЗ, анализирует ответы и на основе правил БЗ определяет очередность последующих вопросов.
  • Разработать интерфейс с пользователем, который обеспечивает эффективный режим диалога.
Реализовать программные модули, которые осуществляют обработку результатов диалога с пользователем:
  • P -> A: Обработка (анализ) полученных данных P для определения атрибутов A
  • A ->Oi: Принятие решения на основе полученных характеристик A - выбор одного из заранее определенных вариантов решения (объекта O)
  • Вывод результата (рекомендации) пользователю.
В рамках выбранной предметной области ЭС, где уже определены объекты принятия решения (O), их свойства (A), а также параметры других объектов, событий, процессов и т.д (P), спроектировать множество продукционных правил (R).

Доработать базу знаний (БЗ) и компьютерную программу из л/р ES-1, реализовав в ней возможность вывода правил (P->A):
  • Создание в БЗ информационных структур для хранения продукционных правил различного типа (с одной или несколькими посылками).
  • Разработка программы (программного модуля), которая осуществляет обработку (вывод) правил для определения свойств объекта принятия решения (A).
  • Разработка компоненты, которая на основе полученных свойств осуществляет выбор конкретного объекта или совета.
  • Интеграция с программными модулями л/р ES-1.

Разработанная модель базы знаний, ее поля и типы полей, связи между сущностями показаны на рисунке ниже:

В разработанной программе предметная область - книги, т.е. данная программа помогает пользователю выбрать книгу на основании вопросов, не касающихся напрямую подбираемых атрибутов книг. Например, пользователю могут быть заданы следующие вопросы:
-С чем связано самое запоминающееся событие в вашей жизни за последний месяц?
-Любите ли вы комиксы?
-Сколько сериалов Вы смотрите?
-Ваш характер?
-Ваш темперамент?
-и т.д.

Все правила задавания следующего вопроса заложены в БЗ, таким образом, при желании их можно посмотреть в БД.
Полный список вопросов и ответов на них можно увидеть в сформированной базе знаний, которая прилагается в проекте решения ниже.

Код, связанный с выбором вопросов, анализом ответов, в целом с работой с БЗ (в основном использованы лямбда-выражения для работы с БЗ):
        private void AskQuestion(QuestionRule qr)
        {
            CurrentQuestion = (from quest in qList
                               where quest.Order == qr.NextQuestionIndex
                               select quest).FirstOrDefault();
        }

        public void PrepareNextQuestion()
        {
            if (!this.CurrentQuestion.IsOpened)
            {
                this.CurrentQuestion.AskedParameter.Value = this.SelectedCAnswer.Value;//closed question, so simply copy selected answer
            }
            else //opened(
            {
                double var;
                if (Double.TryParse((string)this.SelectedOpenedAnswer, out var))
                {
                    //analyse and save answer
                    for (int i = 0; i < CurrentQuestion.AnswerVariants.Count; i++)
                    {
                        AnswerVariant aw = CurrentQuestion.AnswerVariants.ElementAt(i);
                        if (var > (aw as OpenedAnswerVariant).MinValue && var <= (aw as OpenedAnswerVariant).MaxValue)
                        {
                            CurrentQuestion.AskedParameter.Value = (aw as OpenedAnswerVariant).Mapping;
                            break;
                        }
                    }
                    if (CurrentQuestion.AskedParameter.Value == null) throw new Exception("Что-то не так с получением AskedParameter");//change for only proper data might be written
                }
                else
                {
                    throw new Exception("Что-то не так с получением AskedParameter");
                }
            }

            List<AskedParameter> aps = (from qt in CurrentQuestion.Parameter.Questions
                                        select qt.AskedParameter).OrderBy(o => o.Number).ToList<AskedParameter>();//get all asked parmeters asceding

            List<Dependency> deps = (from p in CurrentQuestion.Parameter.Dependencies
                                     select p).ToList();//get all dependencies

            if (CurrentQuestion.IsStartQuestion && CurrentQuestion.IsFinishQuestion) //simple question
            {
                for (int i = 0; i < CurrentQuestion.Parameter.Dependencies.Count; i++)
                {
                    SimpleDependency sdep = CurrentQuestion.Parameter.Dependencies.ElementAt(i) as SimpleDependency;
                    if (CurrentQuestion.AskedParameter.Value == sdep.AskedPropertyValue)
                    {
                        CurrentQuestion.Parameter.Value = sdep.BParameterValue;
                        break;
                    }
                }
            }

            else //complex(
            {
                if (CurrentQuestion.IsFinishQuestion && !CurrentQuestion.IsStartQuestion)
                    if (deps != null)
                        if (deps.Count != 0)
                            this.FillParameter(aps, deps);
            }
            //ask next question using rule

            //select rule
            QuestionRule qr = (from temp in CurrentQuestion.QuestionRules
                               where (temp.AnswerSelected == CurrentQuestion.AskedParameter.Value) || (temp.AnswerSelected == null)
                               select temp).FirstOrDefault();

            //are we finishing?
            if (qr.NextQuestionIndex == -1)
            {
                if (qr.Question.Parameter.Value == null) this.FillParameter(aps, deps);
                this.TestFinished = true;
                return;
            }
            if (qr.Question.Parameter.Value == null)
                if (qr.Question.Parameter != (from q in qList where q.Order == qr.NextQuestionIndex select q).First().Parameter)
                    this.FillParameter(aps, deps);

            this.AskQuestion(qr);

        }


        private void FillParameter(List<AskedParameter> aps, List<Dependency> deps)
        {
            if (deps.ElementAt(0) is TripleDependency)
            {
                //dowork for tripledependency analysis
                IEnumerable<TripleDependency> firstIteration = from temp in deps
                                                               where (((temp as TripleDependency).FPropValue == ((from a in aps where a.Number == (temp as TripleDependency).FPropNumber select a).First()).Value))
                                                               select (TripleDependency)temp;
                if (firstIteration == null) return;
                IEnumerable<TripleDependency> secondIteration = from temp in firstIteration
                                                                where temp.SPropValue == ((from a in aps where a.Number == temp.SPropNumber select a).First()).Value
                                                                select temp;
                if (secondIteration == null) return;
                TripleDependency finalIteration = (from temp in secondIteration
                                                   where temp.ThPropValue == ((from a in aps where a.Number == temp.ThPropNumber select a).First()).Value
                                                   select temp).FirstOrDefault();
                if (finalIteration != null)
                    CurrentQuestion.Parameter.Value = finalIteration.BParameterValue;

            }
            else if (deps.ElementAt(0) is DoubleDependency)
            {
                IEnumerable<DoubleDependency> firstIteration = from temp in deps
                                                               where ((temp as DoubleDependency).FPropValue == ((from a in aps where a.Number == (temp as DoubleDependency).FPropNumber select a).First()).Value)
                                                               select (DoubleDependency)temp;
                if (firstIteration == null) return;

                DoubleDependency finalIteration = (from temp in firstIteration
                                                   where temp.SPropValue == ((from a in aps where a.Number == temp.SPropNumber select a).First()).Value
                                                   select temp).FirstOrDefault();
                if (finalIteration != null)
                    CurrentQuestion.Parameter.Value = finalIteration.BParameterValue;
            }
            else throw new Exception("ЧТО-ТО ПОШЛО НЕ ТАК, ПАРЕНЬ!");
        }
Скриншоты сессии опроса пользователя представлены ниже:




Архив с решением доступен здесь

При выполнении ЛР были использованы следующие источники:
-"интеллектуальная" часть:
+Введение в эксепртные системы; Правила построения экспертных систем.
+конспекты лекций
-программная часть:
+msdn.microsoft.com
+stackoverflow.com
Описание разработки:
-язык программирования: C#
-техннология: WPF + EntityFramework
-среда разработки: VS 2010
* для корректной работы прораммы на ПК необходимо установить:
-.net frameork v4.0
-entity framework v4.2
-Tools for entity designer
-SQL Server compact

Комментариев нет:

Отправить комментарий