5

私はC4.5アルゴリズムのC++実装を探していましたが、まだ見つけることができませんでした。QuinlanのC4.5リリース8を見つけましたが、Cで書かれています... C4.5アルゴリズムのオープンソースC++実装を見た人はいますか?

オープンソースのC++実装が見つからない場合は、 J48ソースコードを移植する(または単にCバージョンのラッパーを作成する)ことを考えていますが、そうする必要がないことを願っています。アルゴリズムのC++実装に遭遇した場合はお知らせください。

アップデート

私は、C5.0アルゴリズムのC実装の周りに薄いC ++ラッパーを作成するオプションを検討してきました( C5.0はC4.5の改良版です)。C5.0アルゴリズムのC実装をダウンロードしてコンパイルしましたが、C++に簡単に移植できるようには見えません。C実装は多くのグローバル変数を使用し、C関数の周りに薄いC ++ラッパーを記述するだけでは、各クラスインスタンスが同じグローバルパラメーターを変更するため、オブジェクト指向の設計にはなりません。言い換えれば、私にはカプセル化がなく、それは私が必要とするかなり基本的なことです。

カプセル化を取得するには、Cコードの本格的なポートをC ++に作成する必要があります。これは、Javaバージョン(J48)をC++に移植するのとほぼ同じです。

アップデート2.0

特定の要件は次のとおりです。

  1. 各分類子インスタンスは、独自のデータをカプセル化する必要があります(つまり、定数以外のグローバル変数は使用できません)。
  2. 分類器の同時トレーニングと分類器の同時評価をサポートします。

これが良いシナリオです。10分割交差検定を行っていると仮定して、トレーニングセットのそれぞれのスライスで10個の決定木を同時にトレーニングしたいと思います。スライスごとにCプログラムを実行するだけの場合、10個のプロセスを実行する必要がありますが、これは恐ろしいことではありません。ただし、何千ものデータサンプルをリアルタイムで分類する必要がある場合は、分類するサンプルごとに新しいプロセスを開始する必要があり、それはあまり効率的ではありません。

4

3 に答える 3

2

C5.0(See5.0)のC ++の「実装」の可能性を見つけたかもしれませんが、ソースコードを十分に掘り下げて、宣伝どおりに機能するかどうかを判断できませんでした。

私の最初の懸念を繰り返すために、ポートの作成者はC5.0アルゴリズムについて次のように述べています。

See5Sam [C5.0]のもう1つの欠点は、同時に複数のアプリケーションツリーを使用できないことです。アプリケーションは、実行可能ファイルが実行されるたびにファイルから読み取られ、あちこちでグローバル変数に格納されます。

ソースコードを調べる時間ができ次第、回答を更新します。

アップデート

見た目はかなり良いです。C++インターフェイスは次のとおりです。

class CMee5
{
  public:

    /**
      Create a See 5 engine from tree/rules files.
      \param pcFileStem The stem of the See 5 file system. The engine
             initialisation will look for the following files:
              - pcFileStem.names Vanilla See 5 names file (mandatory)
              - pcFileStem.tree or pcFileStem.rules Vanilla See 5 tree or rules
                file (mandatory)
              - pcFileStem.costs Vanilla See 5 costs file (mandatory)
    */
    inline CMee5(const char* pcFileStem, bool bUseRules);

    /**
      Release allocated memory for this engine.
    */
    inline ~CMee5();

    /**
      General classification routine accepting a data record.
    */
    inline unsigned int classifyDataRec(DataRec Case, float* pOutConfidence);

    /**
      Show rules that were used to classify the last case.
      Classify() will have set RulesUsed[] to
      number of active rules for trial 0,
      first active rule, second active rule, ..., last active rule,
      number of active rules for trial 1,
      first active rule, second active rule, ..., last active rule,
      and so on.
    */
    inline void showRules(int Spaces);

    /**
      Open file with given extension for read/write with the actual file stem.
    */
    inline FILE* GetFile(String Extension, String RW);

    /**
      Read a raw case from file Df.

      For each attribute, read the attribute value from the file.
      If it is a discrete valued attribute, find the associated no.
      of this attribute value (if the value is unknown this is 0).

      Returns the array of attribute values.
    */
    inline DataRec GetDataRec(FILE *Df, Boolean Train);
    inline DataRec GetDataRecFromVec(float* pfVals, Boolean Train);
    inline float TranslateStringField(int Att, const char* Name);

    inline void Error(int ErrNo, String S1, String S2);

    inline int getMaxClass() const;
    inline int getClassAtt() const;
    inline int getLabelAtt() const;
    inline int getCWtAtt() const;
    inline unsigned int getMaxAtt() const;
    inline const char* getClassName(int nClassNo) const;
    inline char* getIgnoredVals();

    inline void FreeLastCase(void* DVec);
}

これは私がこれまでに見つけた最良の選択肢だと思います。

于 2012-06-04T21:29:37.373 に答える
2

YaDTと呼ばれるC4.5のC++実装は、ここの「デシジョンツリー」セクションで入手できます
。http ://www.di.unipi.it/~ruggieri/software.html

これは最後のバージョンのソースコードです:
http ://www.di.unipi.it/~ruggieri/YaDT/YaDT1.2.5.zip

ツールが説明されている論文から:

[...]このホワイトペーパーでは、C4.5のスタイルでエントロピーベースの決定木を生成する決定木誘導アルゴリズムの新しいゼロからのC++実装について説明します。この実装はYaDTと呼ばれ、さらに別のディシジョンツリービルダーの頭字語です。このホワイトペーパーの目的は、非常に効率的なシステムの取得を可能にする実装の設計原則を提示することです。データとメタデータのメモリ表現とモデリング、アルゴリズムの最適化とメモリと時間のパフォーマンスへの影響、およびプルーニングヒューリスティックの効率と精度の間のトレードオフに関する選択について説明します。[...]

論文はこちらから入手できます。

于 2014-12-10T15:58:34.273 に答える
1

これを正しく読んでいると...CAPIとしてではなく、Cプログラムとして編成されているように見えます。データセットが入力され、アルゴリズムが実行され、ルールの説明が返されます。

私はあなたがとるべき道はあなたが次のことをするかどうかに依存すると思います:

  1. データを提供し、既存のエンジンからルールを取得するためのC++インターフェイスが必要なだけです。

  2. アルゴリズムを自分の目的に合わせて微調整するためにいじくり回すことができるC++実装が必要

必要なのが(1)の場合、プログラムをプロセスとして生成し、入力を文字列としてフィードし、出力を文字列として取得することができます。これはおそらく「ラッパー」を開発する最も簡単で将来性のある方法であり、入力を表し、ルールの結果をモデル化する(または既存のクラスをこれらの抽象化に一致させる)C++クラスを開発するだけで済みます。

しかし、必要なのが(2)の場合は、CまたはJavaのどちらか快適な方の既存のコードに加えて、考えているハックを試してみることをお勧めします。そのようにしてコードを知ることができ、改善があれば、それらを作成者にアップストリームでフィードできる可能性があります。長期的に関係を構築する場合は、言語が設計されているように、協力してCコードベースをC ++に、一度に1つの側面でゆっくりと進めることができます。

「ローマにいるとき」の哲学は、特に最初は、Port-In-One-Goよりも通常はうまく機能すると思います。


更新への応答:プロセスの分離により、グローバル変数の問題が処理されます。パフォーマンスとデータセットのサイズに関しては、コア/CPUとメモリの数は同じです。プロセスとスレッドのどちらを使用しているかは、そのレベルでの規模の問題について話しているときは通常問題ではありません。あなたが遭遇するオーバーヘッドは、マーシャリングが高すぎる場合です。

マーシャリングがボトルネックであり、どの程度であるかを証明します...そして、プロセスがスレッド上で問題になる理由のケースを構築できます。ただし、マーシャリングをより安価にするために既存のコードに小さな調整が加えられている可能性があり、書き直しは必要ありません。

于 2012-05-29T19:10:09.220 に答える