Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Metodich.doc
Скачиваний:
5
Добавлен:
06.12.2018
Размер:
348.16 Кб
Скачать

9. Организация в экспертных системах ответов на вопросы “Почему” и “Как”.

Система вывода, способная объяснить свое поведение внушает больше доверия пользователям. Существует два типа вопросов, которые пользователь хотел бы для себя прояснить во время работы с системой. Когда система запрашивает какое либо свидетельство, пользователь может поинтересоваться: ”Почему ты об этом спрашиваешь ? “ Когда система приходит к некоторому заключению, пользователю, как правило, хочется спросить: ”Как ты пришла к такому заключению? “

Вопросы “как” и “почему” имеют некоторые отличительные особенности, влияющие на их использование в автоматических рассуждающих программах. В дереве рассуждений они могут располагаться в нескольких местах на его противоположных концах. Разумно обеспечить пользователю возможность задавать вопросы “почему”, когда система работает с импликациями, находящиеся в основании дерева, т.е. когда пользователя нужно просить о введении данных. При работе с узлами верхних уровней дерева, системе никогда не требуется запрашивать дополнительную информацию. Эти узлы являются заключениями, самостоятельно выведенными системой. Поэтому вопрос “почему” в таком случае будет неуместен. Система старается проследить за своей информацией, относящейся к заключениям, и поэтому когда она выдает результаты рассуждений применительно к этим узлам, есть смысл задавать ей вопрос “как”.

Для иллюстрации механизмов объяснения используют сеть вывода, представленную на рисунке 4.{вставка рис. 4} Она описывается следующими правилами :

imp(о,r,c4,pos,c11,pos,c2,0.8).

imp(a,r,c1,pos, e1, pos,e2 ,0.7).

imp(о,r,c2,neg,e3, pos,c3,0.9).

imp(a,r,c3,pos,e4, pos,e5, 0.8).

Конечные узлы дерева определяются следующим образом:

terminal-node(e1),

terminal-node(e2),

terminal-node(e3),

terminal-node(e4),

terminal-node(e5).

Организация ответов на вопросы “почему”.

Работая с основанием дерева, система должна запрашивать информацию. Но вместо введения информации, пользователь может набрать на клавиатуре слово “почему” для получения объяснений относительно хода рассуждений. Приведём пример типичного диалога:

С: Введите п (почему) или коэффициент определенности для узла е4.

П: п.

C: Пытаюсь установить с3 с помощью импликации е4 and e5 → c3.

Введите п (почему ) или коэффициент определенности для узла е4.

П : п.

C: Пытаюсь установить с2 с помощью импликации not е3 or с3→с2.

Введите п(почему) или коэффициент определенности для узла е4.

П : п.

C: Пытаюсь установить с4 с помощью импликации с1 or с2 → с4.

Введите n(почему) или коэффициент определенности для узла е4.

П : 0.85.

Таким образом, система последовательно перечисляет свои всё усложняющиеся цели. Когда пользователь наконец вводит коэффициент определенности для е4, рассуждение продолжается с того места, где оно было прервано задаваемыми вопросами.

Если система задействует какое-либо правило вывода и собирает подтверждающую информацию, то это правило должно быть помещено в специальный стек, используемый для объяснений. В тот момент, когда система собирается прекратить работу с правилом вывода в определенном узле, последним шагом должно быть извлечение правила из стека. В результате в стеке будут сохраняться следы, по которым в любой момент можно увидеть, над чем работает система в данный момент. Назовём эту структуру данных “стек ПОЧЕМУ”.

Будем наблюдать за стеком ПОЧЕМУ, в то время как система путем обратного рассуждения собирает свидетельства о верхнем узле с4.

Первое, что делает система, это помещает запись об использовании правила, для которого с4, является заключением, в стек ПОЧЕМУ. Для этого используется правило dbimp. Оно обозначает форму трассировки стека ПОЧЕМУ, а не базисное правило сети вывода:

dbimp(о,r,c4,pos,c1,pos,c2,0.8).

Далее, для работы с узлом c4, система должна использовать вывод, связанный с с1. Применяя правило, основанное на с1, она помещает запись об этом в стек. Теперь стек выглядит так:

dbimp(a,r,с1,pos,е1,pos,е2,0.7).

dbimp(о,r,с4,pos,с1,pos,с2,0.8).

Затем пользователь получает запрос о е1 и е2, и вычисляется коэффициент определенности для с1. Закончив работу с с1, система обработает стек и удалит из него верхнюю запись.

Далее работа продолжается над тем первичным выводом, где нужно установить с4. Здесь применяется правило с2 и делается запись в стек ПОЧЕМУ:

dbimp(о,r,с2,neg,е3,pos,с3,0.9).

dbimp(о,r,с4,pos,с1,pos,с2,0.8).

Затем система запросит пользователя о е3. Пусть он указал коэффициент определенности, тогда система попытается сделать вывод, поддерживающий с3. В стек ПОЧЕМУ будет помещена соответствующая запись:

dbimp(a,r,с3,pos,е4,pos,е55,0.8).

dbimp(о,r,с2,neg,е3,pos.с3,0.9).

dbimp(о,r,с4,pos,с1,pos,с2,0.8).

Далее система запрашивает пользователя о е4. Допустим пользователь спрашивает систему “почему”. В данный момент в стеке содержится трассировка всего пути в обратном направлении до самого высшего вывода. Для ответа на этот вопрос система извлекает первую запись из стека и конструирует ответ, т. е. представляет информацию в форме более удобной для чтения.

Например, ответ пользователю будет выглядеть следующим образом: “Пытаюсь вывести с1, пользуясь импликацией: е4 and е5l → с3”.

На каждый последний вопрос система отвечает, извлекая следующий элемент из стека ПОЧЕМУ и строя из него ответ. Когда пользователь перестает задавать вопрос ПОЧЕМУ и сообщает численное значение коэффициента определенности, то стек ПОЧЕМУ необходимо возвратить в то состояние, которое он имел в момент приостановки рассуждений.

Подведем итоги изложенному выше. Ответы на вопросы “почему” даются посредством указания пути от некоторого свидетельства, расположенного в основании дерева до самой вершины. Стек ПОЧЕМУ имеет тенденцию к уменьшению, т. к. в нем хранится только путь от верхнего вывода до того свидетельства, которое в данный момент представляет интерес. Все остальные области дерева не имеют к этому отношения. Средний размер стека ПОЧЕМУ отражает среднюю глубину дерева. Максимальный же его размер будет определяться самым длинным путем от верхнего узла до основания дерева.

Организация ответов на вопрос “как”.

Вопрос “как” может требовать перечисление всех свидетельств, лежащих в основе сделанного системой заключения. Все свидетельства означают ту часть дерева, которая расположена ниже данного узла.

Вопросы “как” должны быть обязательно разрешены в верхних узлах дерева. По желанию пользователя такие вопросы должны быть разрешены и в других местах. Приведем пример диалога для нашего примера:

C : введите к (как) имя узла, или п (продолжить).

П : к с4.

С: с4 присвоен коэффициент определенности 0.68 на основе:

с1 or с2 → с4.

Правило обратимо.

Коэффициент определенности с1 = 0.6

Коэффициент определенности с2= 0.85

Коэффициент определенности импликации = 0.8

Правило, использованное в одиночку, предполагает коэффициент определенности 0.68.

Введите к (как) имя узла или п (продолжить).

Механизм вывода здесь очень прост. Необходимо лишь всякий раз, когда вывод для данного узла заканчивается, помещать в базу данных предложение, содержащее информацию о том, какое правило применялось и какой коэффициент определенности был предложен для этого узла. При вводе пользователем вопроса “как” типа к с4 система должна вычислить имя узла и далее использовать его при просмотре базы данных для поиска предложения, подводящего итоги выводу, поддерживающему этот узел. Затем должен быть сгенерирован хороший ответ.

Программа с возможностями объяснения.

Рассмотрим программу сети вывода из раздела 8 и видоизменим ее таким образом, чтобы она обладала возможностями объяснения. Начнём с изменений, которые необходимо внести в правила вывода.

Правило infer, разрабатываемое с целью трассировки, выглядит так:

infer (Node , Ct ) if

imp(a, Use, Node, SignL, Node1, SignR, Node2, C1),

asserta(dbimp((a, Use, Node, SignL,Node1, SignR, Node2, C1)),

asserta(tdbimp((a, Use, Node, SignL, Node1, SignR, Node2, C1)),

allinter(Node1, C2), allinter(Node2, C3),

find-multiplier(SignL, MultL, SignR, MultR),

C2S=MultL*C2, C3S=MultR*C3, min(C2S, C3S, CE),

qualinfer(Use, CE, Qmult), Ct=CE*C1*Qmult,

assertz (infer-summary(

imp(a, Use, Node, SignL, Node1, SignR, Node2, C1), Ct)),

retract(dbimp((a, Use, Node, SignL, Node1, SignR, Node2, C1))),

retract(tdbimp((a, Use, Node, SignL, Node1, SignR, Node2, C1))).

Рассмотрим правило подробнее. В начале правила сразу после определения возможной импликации И в базу данных помещаются два факта. Здесь применяется команда asserta, то есть база данных будет действовать как стек. Включенные предложения являются точными копиями, используемых в данный момент фактов импликации, не считая изменения имени. В этом месте создается стек ПОЧЕМУ. Команда asserta применена дважды, потому что желательно создать две копии стека ПОЧЕМУ. Механизм ответов на вопросы “почему” изменяет стек ПОЧЕМУ, и вторая копия служит для его восстановления после окончания процесса объяснения.

В конце правила, где использована команда retract, трассировка вывода удаляется из стека ПОЧЕМУ, так как возможность задавать вопрос “почему” исключается, когда контроль доходит до этого места. Каждый новый вопрос “почему” пойдет по другому пути в сети.

В конце правила находится предложение asserta, имеющее иную цель. Оно поддерживает объяснение “как”. Когда управление достигает этой точки, вывод, описываемый правилом И, получит коэффициент определенности, и система заканчивает работу с ним. Теперь мы можем объединить все сделанные итоги и записать их в базу данных с помощью сложного факта, называемого infer-summary.

Далее опишем объяснение “как”. Для этого вначале опишем управляющие правила, продвигающие систему. Предположим, множество таких правил содержит правило генерирующее все ответы одновременно, и потому за ним следует предложение, показывающее результаты:

exsys-driver if getallans, showresults,!.

Предположим также, что мы определили как гипотетический каждый узел, для которого собираемся вычислить коэффициент определённости, например:

hypothesis-node(c4).

Правило для получения ответа выглядит так:

getallans if not (prepare-answer).

prepare-answer if answer ( X, Y), fail.

answer (X, Y) if

hypothesis-node(X), allinfer(X, Y),

assert(danswer (X, Y)).

Предикат prepare-answer оканчивается fail, чтобы заставить систему использовать answer всеми возможными способами при возвращении назад (fail-вызывает состояние неудачи при доказательстве целевого утверждения). Предикат getallans содержит оператор not, потому что prepare-answer перестанет действовать после успешного завершения работы.

В системе есть предикат answer, задачей которого является выполнение всех рассуждений, связанных с любым гипотетическим узлом. С помощью факта danswer он записывает имя узла и полученный коэффициент определенности в базу данных.

Для вывода ответов на экран используется правило:

showresults if not (displayall).

displayall if display-one-answer, fail.

display-one-answer if danswer(X,Y),clearwindow,

write( “Для этой гипотезы: “) , nl,

write(“ “, X ), nl,

write(“Коэффициент определенности равен: “, Y), nl,nl,

not (how-describer(X)).

Правило display-one-answer показывает все, относящееся к одному заключению. Оно выводит один ответ и затем передает управление механизму объяснения “как”. Оно называется how-describer:

how-describer(Node) if

repeat,nl,

write(“Введите к (КАК) имя узла или п (продолжить).”),

nl,readln(Reply),nl,how-explain(Reply),!.

Для обработки ответов пользователя используется следующее правило

how-explain(Reply) if Reply=”п”.

how-explain(Reply) if

fronttoken(Reply,_,X1),fronttoken(X1,X,_),

infer-summary(_,_,X,_,_,_,_,_),_),clearwindow,!,

write(“Правила, которые участвуют в выводе этого заключения:”),nl,nl,

infer-summary(imp(A,A1,X,R,S,C,D,E),F),

write(“Выведено:”,X),nl, gettype (A,Z),

write(“из “, Z),nl,

write(“посылкой 1 была”,S),nl,

write(“посылкой 2 была”, D),nl,

write(“Правило, использованное в одиночку, дало коэффициент определенности: “, F), nl,nl,fail.

how-explain(Reply) if

fronttoken (Reply,_,X1),fronttoken(X1,X,_),

terminal-node(X),evidence(X,C),

write(“Сообщаю, что для”),nl,write(“ “,X),nl,

write(“коэффициент определенности равен: “,C),nl,fail.

Таким образом, если пользователь печатает “п”, то правило заканчивает работу, т. к. пользователь удовлетворен ответом. В противном случае, начинает действовать один из последующих двух вариантов, которые перечисляют результаты вывода, влияющие на узел, о котором сделан запрос. Обе версии how-explain заканчивают свою работу неудачей (fail), потому что необходимо произвести возврат. Таким образом, выявляются все возможные выводы, если для поддержки текущего узла использовалось более одного правила.

Перейдем к рассмотрению механизма объяснения “почему”. Такие вопросы встречаются только на низких уровнях системы,где достигается основание сети вывода, игде система должна обращаться за объяснениями. Это система вывода с обратной цепочкой рассуждений. Основание сети достигается в результате применения правила infer несколько раз. В основании сети правиле infer должны быть дополнительные предложения, которые управляют накоплением информации:

infer(Node,Ct) if

terminal-node(Node), evidence(Node,Ct),!.

infer(Node,Ct ) if

terminal-node(Node), repeat, nl,

write(“Введите п (почему) или указать коэффициент определенности “,Node),

nl, readln(Reply),reply-to-input(Node,Reply,Ct),!.

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

Получив ответ, оно передает управление правилу reply-to-input, которое может как запрашивать информацию, так и обслуживать объяснения “почему”:

reply-to-input (Node,Reply, Ct) if

not ( isname(Reply), adjuststack,str_real(Reply,Ct),

asserta(evidence(Node,Ct),!.

reply-to-input(_,Reply,_) if

isname(Reply,Reply=”w”,nl,

dbimp(U,V,R,S,S1,X,Y,Y1),

why-describer(U,V,R,S,S1,X,Y,Y1),

retract(dbimp(U,V,R,S,S1,X,Y,Y1)),

putadjuststack,

pauser,!,fail.

Если пользователь ввел коэффициент определенности для запрашиваемого узда, то выполняется первое предложение reply-to-input, которое переводит введенные данные из строкового выражения в числовое и помещает его как свидетельство в базу данных для последующих применений. Оно также активизирует правило adjuststack, которое инициализирует стек ПОЧЕМУ, если он был изменен вопросом почему.

Во втором правиле, когда пользователь задает вопрос почему, из стека ПОЧЕМУ извлекается запись, в которой хранится только один шаг вывода. С помощью подчиненной программы why-describer эта запись используется для приготовления объяснения пользователю. Затем запись удаляется из стека ПОЧЕМУ на случай, если потребуются дальнейшие объяснения. Наконец устанавливается флаг, указывающий системе, что из стека ПОЧЕМУ удалялись записи и после окончания объяснений его надо будет восстановить.

После получения ответа на вопрос почему система снова выдает запрос пользователю:

Введите п (почему) или укажите коэффициент определенности для узла e4.

Если пользователь продолжает вводить “п”, то с помощью записей , хранящихся в стеке ПОЧЕМУ, ему будут даны более общие объяснения. В конце концов запас объяснений исчерпывается. Если после того, как запас объяснений исчерпался, пользователь введет коэффициент определенности как ответ на первоначальный вопрос, то система продолжит рассуждения. Подсказка будет выводиться до тех пор, пока пользователь не введет значение коэффициента определенности, потому что второе предложение reply-to-input заканчивается fail. Это вызывает возврат назад в правило infer, которое снова запросит у пользователя данные или дальнейшие объяснения. Таков основной механизм объяснений почему.

Упражнение: Видоизменить программу из упражнения к предыдущему разделу, дополнив её возможностями объяснения.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]