Создание Inline Service в среде Oracle Real-Time Decisions (RTD)
03.09.2009 от aryndin99Обзор
Beta версия
Платформа Oracle Real-Time Decisions (Oracle RTD) позволяет разрабатывать корпоративные программные решения, которые анализируют поведение бизнес процесс и открывающиеся возможности (opportunities) по мере их появления. В этой статье я расскажу, как конфигурировать, разворачивать, анализировать и обновлять Inline Service. Под Inline Service мы будем понимать сконфигурированное приложение, которое развернуто с использованием компонентов RTD. Oracle RTD состоит из пяти компонентов: Decision Studio, Real-Time Decision Server, Decision Center, Administration (JMX), и Load Generator. Inline Service конфигурируются и разворачиваются с использованием Decision Studio, анализ и изменение параметров работы осуществляется через Decision Center. Inlive Service работают на базе Real-Time Decision Server. Inlive Service может собирать и анализировать характеристики корпоративных бизнес процессов непрерывно в реальном времени. Он также используется эти данные и аналитические алгоритмы для принятия решений и формирования обратной связи с бизнес-процессами.
Сценарий
В этой статье мы построим Inline Service, который используется банковским контактным сентром. Inline Service собирает данные о клиенте, о звонке и принятых оператором решениях. Задачей Inline Service является построение моделей, связывающих звонки, причины звонков и информацию о клиенте. Мы сначала построим простейшую версию, затем будем расширять ее возможности для формирования рекомендаций о возможностях перекрестных продаж. Эти рекомендации будут передаваться CRM-системе, а результат (принятие или непринятие клиентом выданного предложения) будет также учитываться для построения обратной связи.
Предварительные требования
Прежде чем приступать к дальнейшему чтению, я рекомендую проверить, что выполнены следующие предварительные требования:
- Иметь доступ к проинсталлированному Oracle Real-Time Decisions (RTD), включая данные, идущие в поставке примеров CrossSell. Я ранее рассказывал, как проинсталлировать Oracle RTD для Oracle Weblogic.
- Если инсталляция сервера выполнена на Unix, то нужно иметь Windows-компьютер, на котором проинсталлирована клиентская часть
- Настроить пользователя rtdadmin с использованием JMX.
- Скачать текст программных кодов.
Создаем новый Inline Service
Наша цель – создать новый Inline Service. Задачей Inline Service будет извлекать информацию о клиенте из источника данных. Будет использован минимальный набор компонент: источники данных (data source), сущности (entity) и информаторы (Informant). Позже мы добавим больше функционала.
Для создания Inline Service выполняем следующие шаги:
- Создаем Inline Service проект
- Конфигурируем элемент Application
- Создаем источник данных и импортируем поля данных
- Создаем и сопоставляем сущности
- Разворачиваем и тестируем Inline Service
Для создания нового проекта Inline Service, мы выполняем следующие шаги:
1. Запускаем Decision Studio (по сути это плагин для Eclispe) на компьютере, где проинсталлированы клиент Oracle RTD: RTD_HOME\eclipse\eclipse.exe, где RTD_HOME это каталог, в который проинсталлирован Oracle RTD. Например, C:\OracleBI\RTD\.
2. Выбираем File > New > Inline Service Project.
3. Вводим Tutorial в качестве имени проекта
4. Выбираем Basic Template из списка шаблонов метаданных.
5. Проверяет, что выбран пункт Create new project in workspace .
6. Выберите Finish
Для конфигурации элемента Application, выполним следующие действия:
1. В Inline Service Explorer, развернем папку Tutorial > Service Metadata
2. Два раза щелкнем на элементе Application и введем описание в поле Description
3. Перейдем на закладку Permissions, нажмем кнопку Add, затем Select Server.
4. Откроектся окно Connect to a server, введем необходимую для подключения к серверу информацию (см. инсталляцию Oracle RTD). Проверьте соединение, нажав Connect.
5. При необходимости можно назначить права, но если инсталляция была проведена по инструкции, то наш пользователь rtdadmin уже является членом роли RTDAdministrators, а следовательно имеет все права.
Создадим источник данных и импортируем таблицы:
1. Щелкнем правой кнопкой Data Sources в Inline Service Explorer и выберем New SQL Data Source
2. Введем метку источника данные: Customer Data Source. Обратите внимание, что ID заполнится автоматически.
3. В открывшемся окне нажмем кнопку Import. Введем информацию для подключения к сервису.
4. В источниках данных выберем SDDS. В качестве таблицы выберем CROSSSELLCUSTOMERS. Затем нажмем Finish.
5. Выделим столбец ID и с помощью стрелки перенесем его вправо в Input List. Этот столбец будет использоваться, чтобы идентифицировать текущего обрабатываемого заказчика. ID будет поступать из внешнего источника – например из системы аутенфикации клиента (если самообслуживание), либо из CRM системы, если обслуживание ведется в контактном центре.
6. Также оставим только необходимые столбцы:
Age
HasCreditProtection
Language
LastStatementBalance
MaritalStatus
NumberOfChildren
Occupation
7. Введем описание и сохраним источник данных.
Создание и сопоставление сущностей.
Источники данных – это достаточно низкоуровневые объекты. Для более высокоуровневой работы используются сущности, которые могут представлять информацию из источников данных, но также могут включать и информацию, полученную другим путем (например, от информаторов).
Создадим сущность для атрибутов заказчика
1. Щелкнем правой кнопкой на элементе Entities в дереве Inline Service Explorer и выберем New Entity.
2. В качестве Display Label введем Customer. Нажмем OK.
3. В открывшемся окне нажмем кнопку Import, выберем созданный ранее источник. Нажмем OK. В результате импортируются все атрибуты. Для этих атрибутов установим значения по-умолчанию.
4. Нажмем кнопку Add Key. В поле Display Label введем customerId (обратите внимание, что имена чувствительны к регистру). Тип данных выберем Integer.
5. Нажмем ОК, чтобы сохранить изменения. Затем выберем меню File > Save All.
Создание сущности, поддерживаемой в рамках сессии.
1. Два раза щелкнем на сущность Session.
2. Добавим атрибут (Add Atribute) с именем customer. Тип данных выберем Other. В списке типов сущностей найдем недавно созданный тип Customer.
3. Нажмем два раза OK. И затем нажмем кнопку Select, чтобы указать поле, используемое в качестве идентификатора сессии. Выберем customerId. Нажмем ОК.
4. Сохраним все: File > Save All.
Сопоставим атрибуты сущностей и источника данных.
1. Откроем для редактирования сущность Customers и перейдем на закладку Mapping. Все поля уже сопоставлены. Осталось только поле ID в списке Data Source Input Values. Сопоставим его.
2. Щелкните на три точки для открытия диалогового окна
3. Выберем Attribute or Variable, а заем в дереве выберем Session > customer > customerId
4. Нажмем ОК и все сохраним.
Разворачиваем и тестируем Inline Service
Создаем информаторов для тестирования Inline Service.
1. В Inline Service Explorer выбираем Integration Points, затем щелкаем Informants правой кнопкой и выбираем – New Informant. Вводим названия информатора – Testing. Нажмем ОК.
2. Нажмем кнопку Advanced в окне редактирования информатора. В открывшемся окне снимем галку Show in Decision Center. Нажмем ОК
3. Выберем Session Keys кнопкой Select.
4. В поле Logic введем код
logInfo("Customer age = " + session().getCustomer().getAge());
5. Сохраним все.
Развернем Inline Service
1. Выберем в меню Project > Deploy. В открывшемся окне выберем подключение и поставим галки как показано на рисунке:
2. Нажмем кнопку Deploy.
Протестируем работу Inline Service
1. Выберем в меню Window > Show View > Test
2. Введем значение 1 в качестве номера клиента и запустим запрос
3. Если получите ошибку
Request failed for Integration Point "Testing" in Inline Service "Tutorial".
Error detail: com.sigmadynamics.exception.SDRuntimeException: A Decision Service request was received from untrusted host, 192.168.92.1
at com.sigmadynamics.server.kernel.RtisKernelImpl.checkAuthenticated(RtisKernelImpl.java:1605)
at com.sigmadynamics.server.rtis.servlet.SDHttpServerEndPoint.sdPost(SDHttpServerEndPoint.java:100)
то необходимо разрешить подключение к Inline Service с указанного IP адреса. Сделать это можно через JMX консоль (как настроить смотрите в инсталляции RTD).
Создание модели для анализа звонков
Мы выполним следующие шаги:
- Создадим информаторы и внешние системы
- Создадим группу вариантов и модель для анализа звонков
- Выполним первоначальную тренировку модели с помощью утилиты Load Generator
Создадим информаторы и внешние системы
Наша цель в этом разделе создать информаторы и сопоставить их с пользовательской сессией и внешними системами. Мы уже создали Inline Service и протестировали его простейшие функции. Информаторы мы сконфигурируем принимать ключ сессии с целью привязать данные к конкретным сессиям.
Для создания информатора мы выполним следующие действия:
- Создадим сущность Звонок (Call)
- Свяжем сущности Звонок и Сессия
- Создадим внешние системы
- Создадим новые информаторы
- Протестируем и отладим информаторы
Создаем сущность Звонок
1. В Inline Service Explorer, в дереве выберем Tutorial > Service Metadata > Entities.
2. Щелкнем правой кнопкой на Entities и выберем New Entity.
3. Введем Call в поле Display Label. Нажмем ОК.
4. Перейдем на закладку Definition и нажмем Add Attribute, чтобы добавить новый атрибут
5. Введем agent и тип данных выберем String.
6. Аналогично создадим еще 2 поля. Сверьтесь с карткинкой ниже
| Display Label | Data Type |
| length | Integer |
| reason code | Integer |
Свяжем сущности Звонок и Сессия
1. Откроем сущность Session для редактирования.
2. Добавим атрибут (Add Attribute). Введем его название (call) и выберем среди типов данных Other…, а затем выберем нужный тип данных (т.е. Entity Types > Call).
3. Сохраним изменения.
Создадим внешние системы
1. В Inline Service Explorer, откроем Integration Points > External Systems.
2. Правой кнопкой по External Systems и выберем New External System.
3. Введем IVR в поле Display Label.
4. Создадим еще одну систему CRM.
Создадим новые информаторы
1. В Inline Service Explorer, в папке Integration Points создадим Информатор (New Informant).
2. Назовем его Call Begin (в поле Display Label).
3. Выберем в качеств ключа сессии (Session Keys) – поле customerId.
4. В поле External System выберем, а в поле Order введем 1.
5. На закладке Logic введем программный код
/*Prepopulate customer data during start of call even though the information may not be used until much later. This is not explicitly necessary since the server will automatically retrieve the information whenever logic in the Inline Service needs it. */
//session().getCustomer().fill();
int CustomerID = session().getCustomer().getCustomerId();
logInfo("Integration Point - CallBegin: Start Session for customerID = " + CustomerID);
6. Создадим еще один информатор.
| Поле | Значение |
| Display Label | Service Complete |
| Session Keys | customer / customerId |
| External System | CRM |
| Order | 2 |
7. В созданный информатор Service Complete добавим атрибуты
| Название атрибута | Тип данных | Session Attribute |
| agent | String | call / agent |
| length | Integer | call / length |
| reason code | Integer | call / reason code |
8. Сохраним изменения.
9. Создадим еще один информатор.
| Поле | Значение |
| Display Label | Call End |
| Session Keys | customer / customerId |
| External System | CRM |
| Order | 5 |
10. Настроим окончание сессии при вызове данного информатора.
11. На закладке Logic введем программный код.
logInfo("Integration Point - CallEnd");
logInfo("***************************");
Протестируем и отладим информаторы
1. Сохраним все File > Save All
2. Выполним развертывание приложения Project > Deploy.
3. Протестируем вызов информаторов.
4. На данный момент мы создали информаторы, которые в формировании предложения не участвуют. Первый информатор сигнализирует о начале звонка, второй говорит, что обслуживание клиента закончено и можно начинать что-то предлагать дополнительное(делать перекрестные продажи), а последний (CallEnd) создан, чтобы показать, что общение закончено. Информаторы, работающие до формирования предложения обычно служат, чтобы начать работу и получить максимум информации о клиенте. Остался незаконченным пока что Get Cross Sell Offer – это ключевой элемент, который будет использоваться для формирования предложения. Давайте приступ к этому элементу.
Создадим группы выбора (choice groups) и модель для анализа звонков.
- Создадим группу выбора
- Создадим модель группы
- Протестируем модель
Создадим группу выбора
1. В Inline Services Explorer, выберем Tutorial > Service Metadata > Choices.
2. Щелкнем правой кнопкой и выбрем New Choice Group.
3. Введем название группы Call Reason в поле Display Label.
4. У всех вариантов в группе выбора будет атрибут под названием code (помните наш reason code, который мы передаем в систему в информаторе Service Complete?) и типом данных Integer. Добавим это атрибут для группы Call Reason.
5. Щелкнув правой кнопкой на нашу группу Call Reason в дерем Inline Service Explorer и выбираем New Choice. В поле Display Label введем Check Balance. Нажмем OK.
6. В поле поле значения атрибута code введем 17.
7. Создадим еще 3 варианта по таблице.
| Choice | Code |
| Make Payment | 18 |
| Rate Inquiry | 19 |
| Other | 20 |
8. Сохраним все File > Save All
На базе созданной группы мы создадим модель, которую не будем использовать для прогнозирования, а лишь для того, чтобы понять, по каким причинам звонят наши клиенты.
1. Выберем Tutorial > Service Metadata > Models
2. Создадим новую модель, щелкнув правой кнопкой и выбрав New Choice Model.
3. Назовем модель Reason Analysis
4. В открывшемся окне уберем галку Use for prediction, а для анализа выберем созданную нами группу Call Reason, а поле Label for Choice введем Reason for call.
5. Теперь укажем, когда должна запускаться модель. Для этого на закладке Learn Location укажем интеграционную точку – Service Complete
6. Вернемся теперь к информатору Service Complete и введем программный код на закладке Logic
logInfo ("Integration Point - Service Complete. ");
logInfo (" Reason Code: " + session().getCall().getReasonCode());
logInfo (" Agent: " + session().getCall().getAgent());
logInfo (" Length: " + session().getCall().getLength());
int code=session().getCall().getReasonCode();
switch (code) {
case 17:
ReasonAnalysis.addToChoice("CheckBalance");
logInfo (" CheckBalance was added to the model");
break;
case 18:
ReasonAnalysis.addToChoice("MakePayment");
logInfo (" MakePayment was added to the model");
break;
case 19:
ReasonAnalysis.addToChoice("RateInquiry");
logInfo (" RateInquiry was added to the model");
break;
default:
ReasonAnalysis.addToChoice("Other");
logInfo (" Other was added to the model");
break;
}
7. На данный момент наше приложение можно описать следующей диаграммой
Протестируем модель
1. Выполним развертывание приложения Project > Deploy
2. В представлении Test выберем информатор Sevice Complete и введем следующие значения
| customerId | 7 |
| agent | John |
| length | 21 |
| reasonCode | 18 |
3. Зайдем в Decision Cetner по адресу http://rtdserver:port/ui, введем имя и пароль. Перейдем по дереву слева Tutorial > Decision Process > Call Reason.
4. Слева откроется диаграмма, на закладке Performance появится диаграмма показывающая то, какой выбор был осуществлен позвонившими клиентами. Эта информация может быть использована аналитиками для анализа ситуации. Если варианты распределить по группам (так чтобы группы имели двойную вложенность), то можно использовать галочку Rollup для того, чтобы свернуть данные на графике по результатам групп.
Выполним первоначальную тренировку модели с помощью утилиты Load Generator
- Создадим скрипт для Load Generator
- Добавим переменные в скрипт Load Generator
- Добавим интеграционные точки (информаторы) в скрипт
- Запустим скрипт и просмотрим результаты в Decision Center
Создадим скрипт для Load Generator
1. Запустим Load Generator на Windows-компьютере (на Unix-системах его нет). RTD_HOME\scripts\loadgen.cmd.
2. Выберем Create a new Load Generator script.
3. На закладке укажем указан файл конфигурации клиента C:\OracleBI\RTD\client\clientHttpEndPoints.properties. Этот файл содержит настройки подключения к серверу. По умолчанию это HTTP1.url = http://localhost:8080. Необходимо изменить этот файл, чтобы он указывал на ваш сервер.
4. В поле Inline Service введите Tutorial. Выберите в поле Think Time значение Fixed Global Think Time. В поле Constant (пауза между посылкой ответов) введите 0. Укажите количество параллельных скриптов(Number of Concurrent Scripts to Run) 1, а количество загрузок(Maximum Number of Scripts to Run) 2000
Добавим переменные в скрипт Load Generator
1. Перейдем на закладку Variables
2. Щелкнем правой кнопкой на Script и выберем Add Variable.
3. В названии введем var_customerId, установим Integer Range и диапазон от 1 до 2000. Тип доступа – Sequential.
4. Создадим еще 2 переменные.
| Variable Name | Content Type | Minimum | Maximum | Access Type |
| var_reasonCode | Integer Range | 17 | 20 | Random |
| var_length | Integer Range | 75 | 267 | Sequential |
| var_agent | String Array | John, Peter, Mary, Sara | Random |
Переменную var_agent мы создаем строковой и вводим 4 предопределенных значения, которые будут чередоваться случайным образом.
Добавим интеграционные точки (информаторы) в скрипт
1. Перейдем на закладку Edit Script
2. Щелкнем правой кнопкой в пустом окне дерева и выберем Add Action.
3. В типе действия выберем Message, в качестве точки интеграции введем CallBegin.
3. Щелкнем Input Fields правой кнопкой и выберем Add Item.
4. В поле Name введем Enter customerId, в поле Variable выберем var_customerId. Установим галку Session Key.
5. Создадим еще одно действие с именем интеграционной точки ServiceComplete и со следующими параметрами
| Name | Variables |
| customerId | var_customerId |
| reasonCode | var_reasonCode |
| agent | var_agent |
| length | var_length |
6. Параметр customerId выберем в качестве Session Key.
7. Создадим еще одно действие с именем интеграционной точки CallEnd со следующими параметрами (выберем этот параметр как ключ сессии).
| Name | Variables |
| customerId | var_customerId |
8. В поле Name введем Enter customerId, в поле Variable выберем var_customerId. Установим галку Session Key.
9. Сохраним скрипт.
Запустим скрипт и просмотрим результаты в Decision Center
1. Перейдем на закладку Run
2. Выберем Run > Run
3. Проверим, что не будут возникать ошибки.
4. Опять перейдем в Decision Center по адресу http://rtdserver:port/ui, введем имя и пароль.
5. Откроем наш Inline Service.
6. Выберем в дереве группу вариантов Call Reason и перейдем опять на закладку Performance. Варианты распределились примерно равномерно чего и следовало ожидать.
7. Выберем слева вариант Make Paymment и перейдем на закладку Analysis. Мы увидим следующую картину
8. Из этой информации видно, что call reason code очень сильно кореллирует с выбором Make Payment. Это очевидный и тривиальный факт, т.к. это поле определяет значение, передаваемое модели.
9. Чтобы убрать это поле из анализа щелкнем 2 раза на модели Reason Analysis в Decision Studio. Перейдем на закладку Attribute и введем данное поле в Exclude Attributes:
10. Сохраним проект и выполним повторное развертывание.
11. Для того, чтобы очистить результаты тренировки модели необходимо с помощью JConsole дать команду серверу. Для этого запустим JDK_HOME/bin/jconsole.exe и подключимся удаленно к серверу RTD. Как настроить JConsole смотрите в конце статьи Инсталляция RTD для Weblogic. Я буду использовать JConsole из комплекта JDK 6.
12. После подключения к системе перейдем на закладку MBeans. В дереве объектов выберем OracleRTD > InlineServiceManager > Tutorial > Development > Loadable > Operations
13. Выберем deleteAllOperationalData( ). Это займет пару секунд. После окончания выполнения процедуры все данные, накопленные моделью будут очищены.
14. Перейдем опять в Decision Center мы увидим, что данные изменились и не отражают тривиальную корелляцию с call reason. Из полученных данных видно, что самым лучшим клиентом для нас является 54-55 летний человек, позвонивший проверить баланс и разговаривавший с оператором в течение 99-103 секунд. Модель некачественная, что показывается параметром Model Quality. Очевидно, что на случайно сгенерированных данных и могло возникнуть сколь бы то ни было точной модели.
Формирование предложений исходя из целей оптимизации
Цель этого раздела – сформировать предложение для перекрестных продаж. При выборе предложения алгоритм должен исходить из целей минимизации стоимости. Мы уже построили простейший Inline Service, содержащий модель для анализа причин, по которым осуществляются звонки в контактный центр. Теперь мы расширим этот сервис, чтобы он мог выдавать рекомендации.
Выполним следующие шаги:
- Создадим группу вариантов
- Создадим варианты
- Выберем цели оптимизации
- Создадим правило для расчета очков (scoring rule) для случая, когда очки будут расчитываться динамически на основе других параметров
- Назначим очки для вариантов группы
- Создадим решения
- Создадим советника (Advisor)
- Протестируем
Создадим группу вариантов
1. Запустим Decision Studio. Перейдем Tutorial > Service Metadata > Choices.
2. Создадим новую группу вариантов (New Choice Group) с именем Cross Selling Offer.
3. Для группы зададим следующие атрибуты. Сохраним все.
Attribute
Data Type
Send to client
Overridable
Agent Script
String
Включить
Включить
Offer Description
String
Включить
Включить
URL
String
Включить
Включить
Создадим варианты
1. Выберем созданную группу и внутри нее создадим следующие варианты (New Choice):
| Choice | Agent Script | Offer Description | URL |
| Brokerage Account | Would you like to try our new brokerage account? | Brokerage Account offer | http://www.offer.com/offer1.html |
| Credit Card | Would you like to try our new credit card? | Credit Card offer | http://www.offer.com/offer2.html |
| Life Insurance | Would you like to try our new life insurance? | Life Insurance offer | http://www.offer.com/offer3.html |
| Roth IRA | Would you like to try our new Roth IRA? | Roth IRA offer | http://www.offer.com/offer4.html |
| Savings Account | Would you like to try our new savings account? | Savings Account offer | http://www.offer.com/offer5.html |
Выберем цели оптимизации
Прежде чем идти дальше необходимо определиться с тем, какова цель нашей оптимизации. В реальной ситуации цель не одна – их несколько и зачастую они с другом конфликтуют. Мы будем пока рассматривать простейший случай – минимизация затрат.
1. Выберем Tutorial > Service Metadata > Performance Goal. Щелкнем 2 раза.
2. Нажмем кнопку Add. Введем название цели – Cost. Нажмем OK.
3. Для созданной цели мы выберем направление оптимизации – будем минимизировать стоимость, т.е. Minimize.
4. Откроем созданную нами группу вариантов Cross Selling Offer и на закладке Scores добавим созданную цель. Тем самым мы задали, что варианты будут оцениваться с точки зрения стоимости.
После этого необходимо прописать стоимость для групп и вариантов. Стоимость может задаваться статическим значением, а может вычисляться динамически на основе правил (например, если возраст клиента до 45 лет, то стоимость страхования будет ниже, чем если возраст более 60 лет).
Создадим правило для расчета очков (scoring rule) для случая, когда очки будут расчитываться динамически на основе других параметров
1. Создадим внутри папки Scoring Rules новое правило с именем Credit Card Score.
2. Щелкнем правой кнопкой по заголовку Value и выберем Add Condition.
3. В левом поле для ввода выберем атрибут AGE
4. В поле ввода для оператора сравнения введем <=, а во второе поле ввода введем константу 40. Результирующее значение выберем равным 130 (следует читать, если возраст меньше либо равен 40, то стоимость 130). В поле Otherwise… введем 147 (это говорит о том, что если возраст больше 40 – стоимость будет считаться равной 147).
5. Сохраним все.
Назначим очки для вариантов группы
1. Откроем вариант Brokerage Account в группе Cross Selling Offer. И назначим ему очки – 150.
2. Аналогично введем очки для остальных вариантов, кроме Credit Card.
| Вариант | Очки |
| Life Insurance | 140 |
| Roth IRA | 145 |
| Savings Account | 135 |
3. Теперь откроем вариант Credit Card и назначим правило расчета очков, созданное ранее. Для этого нажмем на троеточие, выберем Function or rule call, а затем созданное ранее правило Credit Card Score.
4. Сохраним изменения.
Создадим решения
Задача решения – комбинировать цели определенным образом и на базе этой комбинации делать вывод о принятии того или иного варианта.
1. Щелкнем правой кнопкой по Tutorial > Service Metadata > Decisions и выберем New Decision.
2. Введем название Select Offer. Нажмем ОК.
3. Нажмем кнопку Select, чтобы выбрать группу, которую будет анализировать решение. Выберем группу Cross Selling Offer. Нажмем ОК.
4. Создадим второе такое же решение. Назовем его Random Choice, но в этом решении выберем пункт Select at random.
Создадим советника (Advisor)
Этим шагом мы создадим еще одну точку контакта с внешними приложениями, но в отличие от информаторов эта точка будет не только принимать значения на вход, но также и будет выдавать предложение обратно в пользовательское приложение.
1. В Inline Service Explorer, выберем Tutorial > Service Metadata > Integration Points > Advisors.
2. Щелкнем правой кнопкой и создадим нового советника с именем Get Cross Sell Offer.
3. На закладке Request выберем ключ сессии customer / customerId. Выберем CRM в списке внешних систем. Выберем также этап, на котором выполняется помощник – 3.
4. На закладке Response выберем решение – Select Offer. Для контрольной группы (Control Group Decision) выберем Random Choice. В качестве варианта по-умолчанию выберем Cross Selling Offer > Life Insurance. Этот вариант будет выдан в качестве рекомендации, если оказалось невозможным подбрать подходящий вариант за разумное время.
5. Перейдем на закладку Asynchronous Logic и введем программный код
logInfo("Integration Point - Get Cross Sell Offer");
logInfo(" Customer age = " + session().getCustomer().getAge() );// 'choices' is array returned by the 'Select Offer' decision
if (choices.size() > 0) {
//Get the first offer from array
Choice offer = choices.get(0);
logInfo(" Offer presented: '" + offer.getSDOLabel() + "'");
}
6. Сохраним, выполним развертывание и протестируем сервис
| customerId | 7 |
| customerId | 55 |
7. Перейдем в Decision Center. Выберем Integration Map – диаграмма должна выглядеть следующим образом.
Конфигурируем Inline Service для изучения поведения клиентов в плане принятия или непринятия предложения
До настоящего момента мы строили сервис, который анализирует причины звонков клиентов, различные характеристики (как, например, возраст) и, учитывая заданные нами бизнес-правила, предлагает вариант.
Предложенный вариант может быть принят или непринят клиентом. Возможно клиент заинтересуется предложением, но решения примет не сразу. Нам необходимо изучать это поведение и делать такие предложения, которые не только интересны нам (например, с точки зрения заработка), но и интересны клиентам. Inline Service позволяет проводить такую работу.
Для конфигурации анализа принятия или неприятия предложения выполним следующие действия:
- Добавим модель для изучения принятия предложений
- Выполним первоначальное обучение модели
Добавим модель для изучения принятия предложений
- Создадим события для предложений
- Создадим модель анализа событий
- Сконфигурируем сущность сессии для запоминания предложений
- Изменим поведения советника Get Cross Sell Offer, чтобы он запоминал выполненное предложение
- Создадим информаторов для отслеживания ответов
- Протестируем информатор, отслеживающий ответы
Создадим события для предложений
1. В Decision Studio откройте группу вариантов Cross Selling Offer. Перейдем на закладку Choice Events.
2. Добавим 2 события Presented и Accepted.
Создадим модель анализа событий
1. Щелкнем правой кнопкой пункту Models и выберем New Choice Event Model. Назовем модель Offer Acceptance Predictor.
2. В настройках модели уберем галку Default time window. Временное окно выберем – Week. Группу выберем Cross Selling Offer. Основное событие – Presented. Положительный выход – Accepted.
3. На закладке Learn Location выберем момент обучения – On session close.
4. Сохраним все.
Сконфигурируем сущность сессии для запоминания предложений
Откроем сущность Session и добавим атрибут:
| Display Label | Offer Extended |
| Data Type | String |
| Show in Decision Center | Unchecked |
| Use for analysis | Unchecked |
Изменим поведения советника Get Cross Sell Offer, чтобы он запоминал выполненное предложение
1. Откроем советника Get Cross Sell Offer, перейдем на закладку Asynchronous Logic.
2. Заменим программный код на следующий
logInfo("Integration Point - Get Cross Sell Offer");
logInfo(" Customer age = " + session().getCustomer().getAge() );
// 'choices' is array returned by the 'Select Offer' decision
if (choices.size() > 0) {
//Get the first offer from array
Choice offer = choices.get(0);
//For the selected offer, record that it has been 'presented'
offer.recordEvent("Presented");
//Set the session attribute 'OfferExtended' with the offer's ID.
session().setOfferExtended(offer.getSDOId());
logInfo(" Offer presented: '" + offer.getSDOLabel() + "'");
}
Создадим информаторов для отслеживания ответов
1. Создадим новый информатор с названием Offer Feedback. Установим для него External System равной CRM, а порядок выполнения 4. Ключом сессии выберем customerId.
2. Добавим атрибут Positive типа String.
3. На закладке Logic добавим программный код.
logInfo("Integration Point - Offer Feedback");
//"yes" or "no" to accept offer.
String positive = request.getPositive();
positive = positive.toLowerCase();
//Get the offer id from session attribute 'OfferExtended'
String extendedOfferID = session().getOfferExtended();
if (extendedOfferID != null) {
//Get the offer from choice group 'Cross Selling Offer'
Choice offer = CrossSellingOffer.getChoice(extendedOfferID);
if (offer != null){
String offerId = offer.getSDOId();
//If response is "yes", then record the offer as accepted.
if (positive.equals("yes")) {
offer.recordEvent ("Accepted");
logInfo(" Offer '" + offer.getSDOLabel() + "' accepted");
}
}
}
4. Сохраним все.
Протестируем информатор, отслеживающий ответы
1. Выполним развертывание проекта.
2. Запустим советника Get Cross Sell Offer и на вход подадим номер клиента 10.
3. Сформируем ответ клиента 10, введем в качестве ответа yes.
Выполним первоначальное обучение модели
- Создадим скрипт Load Generator
- Очистим статистику и историю обучения
- Запустим скрипт наполнения.
Создадим скрипт Load Generator
1. Запусти Load Generator и откроем ранее созданный скрипт.
2. Добавим переменную var_positive. Содержимое переменной выставим Weighted String Array (взвешенный набор строк – каждой строке можно сопоставить % времени, когда она будет появляться). Введем 2 строки: yes – 30%, no – 20%.
3. Откроем закладку Edit Script. В левой панели добавим еще одно действие, щелкнув правой кнопкой и выбрав Add Action. Тип события выберем Message, а точку контакта – GetCrossSellOffer. В списке полей добавим поле customerId и значение для этого поля будем брать из переменной var_customerId. Укажем, что это ключ сессии.
4. Переместим это действие в позицию после Service Complete, щелкнув на действии правой кнопкой и выбрав Move Up.
5. Создадим еще одной действие с интеграционной точкой OfferFeedback. В этом действии будет 2 поля:
| Поле | Переменная |
| customerId | var_customerId |
| positive | var_positive |
6. Также переместим его в позицию до CallEnd.
7. Сохраним настройки.
Очистим статистику и историю обучения
1. Запусти JConsole. Подключимся к серверу RTD.
2. Перейдем на закладку Mbeans и выберем OracleRTD > InlineServiceManager > Tutorial > Development > Loadable > Operations. Выберем операцию deleteAllOperationalData().
3. Дождитесь окна и закройте JConsole.
Запустим скрипт наполнения.
1. В Load Generator перейдем на закладку Run и через меню Run > Run запусти выполнения скрипта. Проверим, что не возникло ошибок.
2. Зайдем в Decision Center. Выберем в дереве Decision Process > Cross Selling Offer. Перейдем на закладку Performance.
3. Обратите внимание, что выбираются только 2 из 5 предложений. Это отражает ситуацию, когда оптимизация происходит только с точки зрения стоимости. Очки, назначаемые для каждого варианта зависят от возраста. Мы также видим прогнозируемое значение количества принятых предложений – около 30% (это было задано в Load Generator).
Используем модель, что повлиять на формирование предложений.
- Расширим цели оптимизации
- Выполним наполнение модели
Расширим цели оптимизации
- Создадим атрибут, показывающий доход от принятия предложения
- Создадим цель оптимизации – увеличить доход от предложений
- Изменим решение, чтобы оно включало также метрику Expected Revenue
- Проверим какие значения вероятности принятия предложения формируются
- Протестируем логику советника
Создадим атрибут, показывающий доход от принятия предложения
1. Добавим в группу Cross Selling Offer новый атрибут Revenue с типом данные Integer. Проверим, что установлена галка – Отправлять клиенту (Send to client).
2. Для варианта Brokerage Account установим значение этого атрибута равным 300.
3. Для остальных вариантов установим значения в соответствие с таблицей
| Credit Card | 205 |
| Life Insurance | 185 |
| Roth IRA | 190 |
| Savings Account | 175 |
Создадим цель оптимизации – увеличить доход от предложений
1. Откроем Performance Goals и добавим новую цель Expected Revenue с задачей ее максимизации.
2. Откроем группу вариантов Cross Selling Offer и добавим новую метрику Expected Revenue.
3. Создадим функцию, которая будет вычислять метрику Expected Revenue. Нам понадобится функция перемножение. В дереве Inline Service Explorer щелкаем правой кнопкой на Functions и создаем функцию Multiply.
4. Щелкнем на троеточии напротив Expected Revenue, чтобы задать вычисление ожидаемого дохода, выберем Function or rule call, затем функцию Multiply.
5. Для параметра a выберем атрибут вариант Revenue
6. Для параметра b соответственно соответственно выберем Model prediction, укажем модель Offer Acceptance Predictor, а событие – Accepted.
7. В результате получим для Expected Revenue очки
8. Посмотрите на метрику Expected Revenue. Эта метрика равна Revenue умножить на вероятность принятия предложения. Вероятность принятия решения это значение от 0 до 1 (1 – это 100% вероятность принятия). Если для предложения A и B будет одинаковый доход, то будет выбрано то предложение, которое будет иметь большую вероятность принятия.
Изменим решение, чтобы оно включало также метрику Expected Revenue
1. Откроем решение Select Offer по адресу Tutorial > Service Metadata > Decisions.
2. Нажмем кнопку Goals и добавим еще одну цель – Expected Revenue.
3. Обратите внимание, что оптимизация идет для двух целей и каждая из них равноприоритетна (50%). При необходимости мы может увеличить приорит одной из целей.
Проверим какие значения вероятности принятия предложения формируются
Для этого мы добавим атрибут к варианта, который будет вычисляться динамически и равняться вероятности принятия.
1. Откроем Cross Selling Offer и добавим атрибут Likelihood of Acceptance типа Double. Укажем, что этот атрибут посылается клиенту.
2. Зададим формулу для этого атрибута
3. Откроем советника Get Cross Sell Offer и вставим на закладке программный код
logInfo("Integration Point - Get Cross Sell Offer");
logInfo(" Customer age = " + session().getCustomer().getAge() );
// 'choices' is array returned by the 'Select Offer' decision. The
// name 'choices' was set (and can be changed) in the 'Choice Array'
// text box in the 'Select Offer' decision’s 'Pre/Post Selection
// Logic' tab.
if (choices.size() > 0) {
//Get the first offer from array
Choice offer = choices.get(0);
//For the selected offer, record that it has been 'presented'
offer.recordEvent("Presented");
//Set the session attribute 'OfferExtended' with the offer's ID.
session().setOfferExtended(offer.getSDOId());
logInfo(" Offer presented: '" + offer.getSDOLabel() + "'");
//Cast selected offer to type CrossSellingOfficeChoice -
//the base Choice type of choice group 'Cross Selling Offer'
CrossSellingOfferChoice cso = (CrossSellingOfferChoice) offer;
logInfo(" Likelihood of Acceptance = " + cso.getLikelihoodOfAcceptance());
}
Протестируем логику советника
1. Выполним развертывание сервиса.
2. Вызовем помощника Get Cross Sell Offer со значением 10 для customerId. Если для Likelihood of Acceptance вы получите значение NaN, то это нормально, т.к. модель еще не имеет достаточно данных.
Внесем небольшую неопределенность в логику принятия решений
1. До сих пор решения принималось случайным образом (мы прописали это в Load Generator). Теперь мы сделаем небольшое отклонение. Заменим программную логику для информатора Offer Feedback на следующую. Эта логика принимает решение "yes", если предлагается решение LifeInsurance и количество детей больше, чем 1.
logInfo("Integration Point - Offer Feedback");
//"yes" or "no" to accept offer.
String positive = request.getPositive();
positive = positive.toLowerCase();
//Get the offer id from session attribute 'OfferExtended'
String extendedOfferID = session().getOfferExtended();
if (extendedOfferID != null) {
//Get the offer from choice group 'Cross Selling Offer'
Choice offer = CrossSellingOffer.getChoice(extendedOfferID);
if (offer != null){
String offerId = offer.getSDOId();
//Introduce artificial bias for customers with 2 or more
//children to always accept "LifeInsurance" if it was
//selected after scoring.
//If data source is Oracle, change the following method from
//getNumberOfChildren() to getNumberofchildren()
int numOfChildren = session().getCustomer().getNumberOfChildren();
if ( numOfChildren >= 2 && offerId.equals("LifeInsurance")) {
positive="yes";
}
//If response is "yes", then record the offer as accepted.
if (positive.equals("yes")) {
offer.recordEvent ("accepted");
logInfo(" Offer '" + offer.getSDOLabel() + "' accepted");
}
}
}
2. Сохраним все.
Выполним наполнение модели
1. Запусти JConsole. Подключимся к серверу RTD.
2. Перейдем на закладку Mbeans и выберем OracleRTD > InlineServiceManager > Tutorial > Development > Loadable > Operations. Выберем операцию deleteAllOperationalData().
3. Дождитесь окна и закройте JConsole.
4. Откроем в Load Generator ранее созданный скрипт и перейдем на закладку Run и через меню Run > Run запусти выполнения скрипта. Проверим, что не возникло ошибок. Поставим скрипт на паузы на коичестве запусков около 200. Посмотрим журнал сервера (у меня этой файл /u01/app/oracle/user_projects/domains/rtd/servers/RTD_Server/logs/RTD_Server.out).
5. Продолжим выполнение скрипта.
6. Перейдем в Decision Center, в котором можно видеть информацию о принятых решениях
7. Выберем пункт Life Insurance и перейдем на закладку Analysic > Best fit. Из таблицы видно, что именно количество детей равное 2 является основным влияющим на выбор клиентов фактором.
Итоги:
Мы рассмотрели следующие темы:
- Создание Inline Service
- Создание модели для анализа звонков
- Генерацию предложений на основе целей оптимизации
- Конфигурацию Inline Service для изучения принятия/неприятия предложения
- Использование модели для влияния на генерацию предложений
- Вам также могут быть интересны следующие статьи:
- Обзор Oracle Real-Time Decisions
- Oracle RTD Batch Framework
- Построение отчетов Oracle BI на основе данных RTD
- Поиск в Oracle Mapviewer
- Использование веб-сервисов для анализа LOD-сетей
Рубрики: BEA, Business Intelligence, Oracle Real-Time Decisions | Комментариев нет »
