21.5. 価格設定のデシジョン例 (デシジョンテーブル)

価格設定のデシジョンセットの例では、スプレッドシートのデシジョンテーブルを使用して、DRL ファイルに直接ではなく、表形式で保険料金の価格を計算する方法を説明します。

以下は価格設定の例の概要です。

  • 名前: decisiontable
  • Main クラス: (src/main/java の場合) org.drools.examples.decisiontable.PricingRuleDTExample
  • モジュール: drools-examples
  • タイプ: Java アプリケーション
  • ルールファイル: org.drools.examples.decisiontable.ExamplePolicyPricing.xls (src/main/resources 内)
  • 目的: スプレッドシートのデシジョンテーブルを使用してルールを定義する方法を示します。

スプレッドシートのデシジョンテーブルは、表形式でビジネスルールを定義する XLS 形式または XLSX 形式のスプレッドシートです。スプレッドシートのデシジョンテーブルは、スタンドアロンの Red Hat Process Automation Manager プロジェクトに追加したり、Business Central のプロジェクトにアップロードしたりできます。スプレッドシートの各行がルールになり、各列が条件、アクション、または別のルール属性になります。最初に Red Hat Process Automation Manager でデシジョンテーブルを作成してアップロードします。次に、その他のすべてのルールアセットと同じように、定義したルールを Drools Rule Language (DRL) ルールにコンパイルします。

この価格設定の例では、特定タイプの保険を申請するドライバーに対して基本価格と割引を計算するビジネスルールセットを提供します。ドライバーの年齢と履歴、およびポリシータイプはすべて、基本保険料の計算に役立ち、追加のルールは、ドライバーが適格となる可能性のある潜在的な割引を計算します。

この例を実行するには、IDE で Java アプリケーションとして org.drools.examples.decisiontable.PricingRuleDTExample クラスを実行します。

実行後に、以下の出力が IDE コンソールウィンドウに表示されます。

Cheapest possible
BASE PRICE IS: 120
DISCOUNT IS: 20

この例を実行するコードは、標準の実行パターンに準拠しています。ルールが読み込まれ、ファクトが挿入されて、ステートレス KIE セッションが作成されます。この例における違いは、DRL ファイルや他のソースではなく、ExamplePolicyPricing.xls ファイルでルールが定義されるという点です。このスプレッドシートファイルは、テンプレートと DRL ルールを使用してデシジョンエンジンに読み込まれます。

スプレッドシートのデシジョンテーブルの設定

ExamplePolicyPricing.xls スプレッドシートには、以下の 2 つのデシジョンテーブルが含まれています。

  • Base pricing rules
  • Promotional discount rules

この例のスプレッドシートで分かるように、デシジョンテーブルの作成にはスプレッドシートの最初のタブしか使用できませんが、単一のタブ内に複数のテーブルが作成できます。デシジョンテーブルは必ずしもトップダウンの論理に従うものではなく、ルールとなるデータを補足する手段です。ルールの評価は、ルールエンジンのすべての通常のメカニックが適用されるため、必ずしも特定の順序で行われるわけではありません。このために、スプレッドシートの同一タブ内に複数のデシジョンテーブルが作成可能となります。

デシジョンテーブルは、対応するルールテンプレートファイルである BasePricing.drtPromotionalPricing.drt で実行されます。これらのテンプレートファイルはテンプレートパラメーターによってデシジョンテーブルを参照し、デシジョンテーブルの条件およびアクションの各種ヘッダーを直接参照します。

BasePricing.drt ルールテンプレートファイル

template header
age[]
profile
priorClaims
policyType
base
reason

package org.drools.examples.decisiontable;

template "Pricing bracket"
age
policyType
base

rule "Pricing bracket_@{row.rowNumber}"
  when
    Driver(age >= @{age0}, age <= @{age1}
        , priorClaims == "@{priorClaims}"
        , locationRiskProfile == "@{profile}"
    )
    policy: Policy(type == "@{policyType}")
  then
    policy.setBasePrice(@{base});
    System.out.println("@{reason}");
end
end template

PromotionalPricing.drt ルールテンプレートファイル

template header
age[]
priorClaims
policyType
discount

package org.drools.examples.decisiontable;

template "discounts"
age
priorClaims
policyType
discount

rule "Discounts_@{row.rowNumber}"
  when
    Driver(age >= @{age0}, age <= @{age1}, priorClaims == "@{priorClaims}")
    policy: Policy(type == "@{policyType}")
  then
    policy.applyDiscount(@{discount});
end
end template

ルールは、KIE セッション DTableWithTemplateKBkmodule.xml 参照によって実行されます。これは ExamplePolicyPricing.xls スプレッドシートを特定して参照するもので、ルールの実行の成功には必要なものです。この実行方法により、ルールをスタンドアロンユニットとして実行したり (ここでの例) パッケージ化されたナレッジ JAR (KJAR) ファイルにルールを含めたりすることができるため、スプレッドシートはルール実行とともにパッケージ化されます。

kmodule.xml ファイルの以下のセクションは、ルールが正常に実行され、スプレッドシートが機能するために必要になります。

    <kbase name="DecisionTableKB" packages="org.drools.examples.decisiontable">
        <ksession name="DecisionTableKS" type="stateless"/>
    </kbase>

    <kbase name="DTableWithTemplateKB" packages="org.drools.examples.decisiontable-template">
        <ruleTemplate dtable="org/drools/examples/decisiontable-template/ExamplePolicyPricingTemplateData.xls"
                      template="org/drools/examples/decisiontable-template/BasePricing.drt"
                      row="3" col="3"/>
        <ruleTemplate dtable="org/drools/examples/decisiontable-template/ExamplePolicyPricingTemplateData.xls"
                      template="org/drools/examples/decisiontable-template/PromotionalPricing.drt"
                      row="18" col="3"/>
        <ksession name="DTableWithTemplateKS"/>
    </kbase>

ルールテンプレートファイルを使用したデシジョンテーブルの実行方法とは別に、DecisionTableConfiguration オブジェクトを使用して、DecisionTableInputType.xls のような入力スプレッドシートを入力タイプとして指定することもできます。

DecisionTableConfiguration dtableconfiguration =
    KnowledgeBuilderFactory.newDecisionTableConfiguration();
        dtableconfiguration.setInputType( DecisionTableInputType.XLS );

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

        Resource xlsRes = ResourceFactory.newClassPathResource( "ExamplePolicyPricing.xls",
                                                                getClass() );
        kbuilder.add( xlsRes,
                      ResourceType.DTABLE,
                      dtableconfiguration );

価格設定の例では以下の 2 つのファクトタイプを使用します。

  • Driver
  • Policy

この例では、これらのファクトのデフォルト値をそれぞれの Java クラス Driver.javaPolicy.java に設定します。この Driver は 30 歳で、これまでに保険の請求をしたことがなく、現在のリスクプロファイルが LOW となっています。申請している PolicyCOMPREHENSIVE です。

デシジョンテーブルでは、各行は異なるルールと見なされ、各列は条件またはアクションとみなされます。実行時にアジェンダがクリアされなければ、デシジョンテーブルの各行が評価されます。

デシジョンテーブルのスプレッドシート (XLS または XLSX) には、ルールデータを定義する以下の 2 つの主要なエリアが必要です。

  • RuleSet エリア
  • RuleTable エリア

RuleSet 領域では、ルールセット名、ユニバーサルルール属性など、(このスプレッドシートだけでなく) すべてのルールをパッケージ全体に、グローバルに適用する要素を定義します。RuleTable 領域では、実際のルール (行) と、指定したルールセットのルールテーブルを設定する条件、アクション、その他のルール属性 (列) を定義します。デシジョンテーブルのスプレッドシートには複数の RuleTable エリアを追加できますが、RuleSet エリアは 1 つのみとなります。

図21.11 デシジョンテーブルの設定

DT Config

RuleTable エリアでは、ルール属性を適用するオブジェクトも定義します。この例では、DriverPolicy、さらにオブジェクトの制限です。たとえば、Driver オブジェクトの制限では、Age Bracket 列が age >= $1, age <= $2 と定義されています。ここでのコンマ区切りの範囲は、18,24 などのテーブルの列値で定義されます。

Base pricing rules

価格設定例での Base pricing rules デシジョンテーブルでは、ドライバーの年齢、リスクプロファイル、請求数、ポリシータイプを評価し、これらの条件をベースにしたポリシーの基本価格を算定します。

図21.12 基本価格の計算

DT Table1

Driver 属性は、以下のテーブル列で定義されます。

  • Age Bracket: この年齢層には、ドライバー年齢の条件範囲を定義する条件 age >=$1, age <=$2 の定義があります。この条件列では $1 and $2 を使用しており、スプレッドシートではコンマ区切りになります。ここでの値入力は 18,2418, 24 の形式となり、両方ともビジネスルールの実行で機能する形式です。
  • Location risk profile: リスクプロファイルは、この例のプロブラムでは常に LOW として渡す文字列です。ただし、MED または HIGH に変更することが可能です。
  • Number of prior claims: これまでの請求数は整数で定義し、アクションをトリガーするには条件列のものと同一である必要があります。この値は範囲ではなく、完全一致のみになります。

デシジョンテーブルの Policy は、ルールの条件とアクションの両方で使用され、属性は以下のテーブル列で定義されます。

  • Policy type applying for: ポリシータイプは文字列として渡される条件で、適用する以下のいずれかのポリシータイプ (COMPREHENSIVEFIRE_THEFT、または THIRD_PARTY) を定義します。
  • Base $ AUD: basePriceACTION として定義され、これはこの値に対応するスプレッドシートのセルをベースに制限 policy.setBasePrice($param); で価格を設定します。このデシジョンテーブルの対応する DRL ルールを実行する際には、ファクトに合致する true 条件でルールの then 部分がこのアクションステートメントを実行し、基本価格を対応する値に設定します。
  • Record Reason: ルールが正常に実行されると、アクションは出力メッセージを System.out コンソールに生成し、どのルールが適用されたかが反映されます。これは後でアプリケーションにキャプチャーされ、出力されます。

この例では、左側の最初の列でルールをカテゴリー分けしています。この列は注釈目的で、ルール実行には影響がありません。

Promotional discount rules

価格設定例での Promotional discount rules デシジョンテーブルでは、ドライバーの年齢、請求数、ポリシータイプを評価し、ポリシー価格の割引を算定します。

図21.13 割引計算

DT Table2

このデシジョンテーブルには、ドライバーに適用可能な割引条件が含まれています。基本価格の算定と同様に、このテーブルではドライバーの AgeNumber of prior claims、および Policy type applying for を評価して、適用する Discount % 率を判定します。たとえば、ドライバーは 30 歳であり、請求履歴がなく、COMPREHENSIVE ポリシーを申請している場合は、20 パーセントの割引率が導き出されます。