web-dev-qa-db-ja.com

c#でデシジョンツリーを実装する方法(Visual Studio 2008)-ヘルプ

C#のコードに目を向ける必要がある決定木があります

それを行う簡単な方法はif-elseステートメントを使用することですが、このソリューションでは4〜5個のネストされた条件を作成する必要があります。

私はそれを行うためのより良い方法を探しています、そして今のところ私はルールエンジンについて少し読んでいます。

4〜5個のネストされた条件で決定木を開発する効率的な方法について提案する他の何かがありますか?

19
Chen

私は自分の本のサンプルとして簡単な決定木を実装しました。コードは入手可能です オンラインはこちら なので、おそらくインスピレーションとして使用できます。決定は基本的に、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);
  }
}

ここで、DecisionEvaluateメソッドを含む基本クラスであり、ソースにはツリーの最終決定(yes/no)を含む1つの追加の派生型が含まれています。タイプClientは、ツリーを使用して分析しているサンプル入力データです。

デシジョンツリーを作成するには、次のように記述します。

var tree = new DecisionQuery {
    Test = (client) => client.Income > 40000,
    Positive = otherTree,
    Negative = someOtherTree
  };

ネストされた静的なif句を5つだけ記述したい場合は、ifを記述しても問題ありません。このようなタイプを使用する利点は、ツリーを簡単に作成できることです。ツリーの一部を再利用するか、構造をモジュール化します。

23
Tomas Petricek

以下は、回答で言及されているTomas Petricekのコードです https://stackoverflow.com/a/3889544/5288052

「Real-WorldFunctionalProgramming」という本のすべてのソースコードを含む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();
}
2

理由は...私はこれを試してみましたが、結果はここにあります... https://github.com/jkennerley/DeeTree

1
judek