C# のコードに変換する必要がある決定木があります。
これを行う簡単な方法は、if-else ステートメントを使用することですが、このソリューションでは、4 ~ 5 個のネストされた条件を作成する必要があります。
私はそれを行うためのより良い方法を探しています。これまでのところ、ルールエンジンについて少し読んでいます。
4 ~ 5 個のネストされた条件を持つ決定木を作成する効率的な方法について、他に提案することはありますか?
C# のコードに変換する必要がある決定木があります。
これを行う簡単な方法は、if-else ステートメントを使用することですが、このソリューションでは、4 ~ 5 個のネストされた条件を作成する必要があります。
私はそれを行うためのより良い方法を探しています。これまでのところ、ルールエンジンについて少し読んでいます。
4 ~ 5 個のネストされた条件を持つ決定木を作成する効率的な方法について、他に提案することはありますか?
本のサンプルとして簡単な決定木を実装しました。コードはここからオンラインで入手できるので、インスピレーションとして使用できるかもしれません。デシジョンは基本的に、true
ブランチとfalse
ブランチへの参照を持ち、テストを実行する関数を含むクラスとして表されます。
class DecisionQuery : Decision {
public Decision Positive { get; set; }
public Decision Negative { get; set; }
// Primitive operation to be provided by the user
public Func<Client, bool> Test { get; set; }
public override bool Evaluate(Client client) {
// Test a client using the primitive operation
bool res = Test(client);
// Select a branch to follow
return res ? Positive.Evaluate(client) : Negative.Evaluate(client);
}
}
ここでDecision
は、メソッドを含む基本クラスでEvaluate
あり、ソースには、ツリーの最終決定 (はい/いいえ) を含む 1 つの追加の派生型が含まれています。タイプClient
は、ツリーを使用して分析しているサンプル入力データです。
決定木を作成するには、次のように記述します。
var tree = new DecisionQuery {
Test = (client) => client.Income > 40000,
Positive = otherTree,
Negative = someOtherTree
};
if
入れ子になった 5 つの static句を書きたいだけなら、書くだけで十分かもしれませんif
。このようなタイプを使用する利点は、ツリーを簡単に構成できることです。たとえば、ツリーの一部を再利用したり、構造をモジュール化したりできます。
以下は、回答https://stackoverflow.com/a/3889544/5288052で言及されている Tomas Petricek のコードです。
書籍「Real-World Functional Programming」のすべてのソース コードを含む zip は、https://www.manning.com/books/real-world-functional-programmingから入手できます。
// Section 8.4.2 Decision trees in C#
// Listing 8.15 Object oriented decision tree (C#)
abstract class Decision {
// Tests the given client
public abstract void Evaluate(Client client);
}
class DecisionResult : Decision {
public bool Result { get; set; }
public override void Evaluate(Client client) {
// Print the final result
Console.WriteLine("OFFER A LOAN: {0}", Result ? "YES" : "NO");
}
}
// Listing 8.16 Simplified implementation of Template method
class DecisionQuery : Decision {
public string Title { get; set; }
public Decision Positive { get; set; }
public Decision Negative { get; set; }
// Primitive operation to be provided by the user
public Func<Client, bool> Test { get; set; }
public override void Evaluate(Client client) {
// Test a client using the primitive operation
bool res = Test(client);
Console.WriteLine(" - {0}? {1}", Title, res ? "yes" : "no");
// Select a branch to follow
if (res) Positive.Evaluate(client);
else Negative.Evaluate(client);
}
}
static void MainDecisionTrees()
{
// The tree is constructed from a query
var tree =
new DecisionQuery
{
Title = "More than $40k",
// Test is specified using a lambda function
Test = (client) => client.Income > 40000,
// Sub-trees can be 'DecisionResult' or 'DecisionQuery'
Positive = new DecisionResult { Result = true },
Negative = new DecisionResult { Result = false }
};
// Test a client using this tree
// Create client using object initializer
var john = new Client {
Name = "John Doe", Income = 40000, YearsInJob = 1,
UsesCreditCard = true, CriminalRecord = false
};
tree.Evaluate(john);
}
private static void Main(string[] args)
{
MainDecisionTrees();
}