【问题标题】:Creating a generic object that can take on several different model types创建可以采用多种不同模型类型的通用对象
【发布时间】:2012-07-04 18:15:43
【问题描述】:

我目前正在使用 Weka 编写一个构建模型的程序(使用 Weka 中包含的各种模型类型之一)。我遇到问题的部分是我想允许程序对同一功能使用多种类型。例如,如果我选择使用 J48 决策树,我需要在 J48 类型的变量上构建和调用函数。另一方面,如果我想使用 BayesNet,我需要在 BayesNet 类型的变量上构建和调用相同的函数。这个模型需要在程序的不同点使用,所以一个简单的 if-else 链是行不通的。

基本上我需要的是 C++ 中的 void 指针。可以采用各种类型的东西,它们都可以执行类似的功能。我尝试使用通用 Object 类,但发现它无法转换为正确的类型(出现“不兼容类型”错误)。

所以,我的问题的简短版本是:Java 程序员如何解决 C++ 程序员使用 void 指针解决的问题?

谢谢, -莫拉格

【问题讨论】:

    标签: java generics weka


    【解决方案1】:

    你的意思是这样的吗?

    public void doStuff(MyType<?> someObject) { }  
    

    ? 代表任何类型,代表unbounded wildcard

    请注意,此通配符有一定的限制。例如,您不能向List&lt;?&gt; 添加任何内容。

    请参阅Official TutorialAngelikaLanger Generics FAQ 了解更多信息。

    【讨论】:

    • 这看起来很有希望,我会试一试,看看能不能让它工作。
    【解决方案2】:

    我目前正在使用 Weka 编写一个构建模型的程序(使用 Weka 中包含的各种模型类型之一)。我遇到问题的部分是我想允许程序对同一功能使用多种类型。例如,如果我选择使用 J48 决策树,我需要在 J48 类型的变量上构建和调用函数。另一方面,如果我想使用 BayesNet,我需要在 BayesNet 类型的变量上构建和调用相同的函数。这个模型需要在程序的不同点使用,所以一个简单的 if-else 链是行不通的

    其实你真正需要的是多态行为。请查看我回答的这篇文章,对此进行了一些解释:Polymorphism

    在了解了多态背后的思想之后,再深入一些,寻找工厂模式。以下是 Java 模式的好资源:

    Source Making Patterns

    Wikipedia - Factory Pattern

    【讨论】:

      【解决方案3】:

      您可以使用超类Classifier 作为任何分类器对象的类型声明,即使每个对象都是Classifier 的子类,例如J48。它之所以有效,是因为它们都实现了超类的功能,因此即使您不一定知道您使用的是哪种特定类型的分类器,也会定义函数调用。 Axcdnt 的答案链接到有关多态性的更多详细信息。无论如何,我有一个带有以下代码片段的工作程序;他们完全按照您的需要做。

      Classifier Clfs = null;
      
          try {
              if (modelType.equals("J48")) {
                  Clfs = new J48();
              } else if (modelType.equals("MLP")) {
                  Clfs = new MultilayerPerceptron(); 
              } else if (modelType.equals("IB3")) {
                  Clfs = new IBk(3);
              } else if (modelType.equals("RF")) {
                  Clfs = new RandomForest(); 
              } else if (modelType.equals("NB")) {
                  Clfs = new NaiveBayes();
      //...
      

      和其他地方,在将分类器写入我调用的文件之后

      Classifier cls = (Classifier) weka.core.SerializationHelper.read(target);
      prediction = cls.distributionForInstance(data.instance(0));
      

      target 是一个字符串,其中包含用于加载模型的文件路径)正如您所见,我使用的分类器类型无关紧要,除非在创建时必须指定。注:仍然会有一些限制,例如j48 无法预测数字类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-08
        • 2016-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-12
        • 2020-05-14
        相关资源
        最近更新 更多