当前位置: 首页 > 知识库问答 >
问题:

在OpenNLP中使用带参数的自定义特征生成器

徐景明
2023-03-14

我正试图在一个项目中使用XML特性生成器描述符和一些非标准特性设置OpenNLP NameFinder。XML描述符支持自定义功能生成器:

<generators>
  <cache>
    <generators>
      ...
      <custom class="com.example.MyFeatureGenerator"/>
   </cache>
</generators>

但是,留档并没有提到将参数传递给特征生成器。为特征生成器的每一个稍微不同的配置创建一个新类是不可取的。另一方面,以编程方式创建特征生成器可能意味着复制大部分用于处理特征生成器设置的OpenNLP代码。在OpenNLP中使用自定义特征生成器的推荐方法是什么?

共有2个答案

钮誉
2023-03-14

还没有合适的解决方案,但我通过在OpenNLP中注册一个新功能工厂来解决这个问题。不幸的是,这需要通过反射访问OpenNLP类GeneratorFactory的私有部分。这是一个工作解决方案。

首先,定义一个新类,名为XMLDescriptorRutil

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

import opennlp.tools.util.InvalidFormatException;
import opennlp.tools.util.featuregen.AdaptiveFeatureGenerator;
import opennlp.tools.util.featuregen.FeatureGeneratorResourceProvider;
import opennlp.tools.util.featuregen.GeneratorFactory;

import org.w3c.dom.Element;

public final class XmlDescriptorUtil {
  private XmlDescriptorUtil(){};

  public static abstract class XmlDescriptorFactory implements InvocationHandler
  {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      return create((Element)args[0], (FeatureGeneratorResourceProvider)args[1]);
    }

    public abstract AdaptiveFeatureGenerator create(Element generatorElement, FeatureGeneratorResourceProvider resourceManager)
      throws InvalidFormatException;
  }

  public static void register(String name, XmlDescriptorFactory factory) throws Exception
  {
    Class<?> factoryInterface = Class.forName(GeneratorFactory.class.getName()+"$XmlFeatureGeneratorFactory");
    Object proxy = Proxy.newProxyInstance(GeneratorFactory.class.getClassLoader(), new Class[]{factoryInterface}, factory);
    registerByProxy(name, proxy);
  }

  private static void registerByProxy(String name, Object proxy) throws Exception
  {
    Field f = GeneratorFactory.class.getDeclaredField("factories");
    f.setAccessible(true);
    @SuppressWarnings("unchecked")
    Map<String, Object> factories = (Map<String, Object>) f.get(null);
    factories.put(name, proxy);
  }

}

然后,创建一个功能生成器工厂,该工厂实现公共接口XMLDescriptorRutil$XmlDescriptorFactory

public static void main(String[] args) {
  XmlDescriptorUtil.register("myCustom", new XmlDescriptorUtil.XmlDescriptorFactory() {
    @Override
    public AdaptiveFeatureGenerator create(Element generatorElement, FeatureGeneratorResourceProvider resourceManager) throws InvalidFormatException {
      return new MyFeatureGenerator();
    });
}

现在,功能生成器已准备就绪,可以在XML描述符中使用:

<generators>
  <cache>
    <generators>
      ...
      <myCustom/>
    </generators>
  </cache> 
</generators>

如果特征生成器需要参数,可以从factory类中的generatorElement中提取这些参数。

常培
2023-03-14

如果您不介意在Apache OpenNLP上打开一个jira问题并请求修复此问题。自定义元素应该可以传入参数和外部资源。

 类似资料:
  • 我想训练自己的模型,以便在中使用。 搜索了很多,最终找到了一个训练模型的工作代码,但并不准确。文件还说,你需要15000个句子才能有一个准确的模型。 所以你需要有15000个句子,每个句子都有一个好的上下文和名字

  • 我正在尝试使用OpenNLP为命名查找器API生成的自定义功能。 http://opennlp.apache.org/documentation/1.5.3/manual/opennlp.html 我通过留档,但我无法理解如何指定不同的功能。 它只是说: 但是,您如何实际使用这些不同的功能生成器来创建我自己的自定义功能呢。有人能发布一个定义这些特征生成器的示例代码吗?我们如何使用它来生成自定义特征

  • 在Prestashop 1.7中,“自定义”特征值和非自定义特征值之间的技术区别是什么(我说的是布尔字段)? 因为为了在DB中保存特征值,我想在初始化我的对象的属性之后使用。其中包括布尔值

  • 我有一个自定义文件,其中包含我所有图像的路径及其标签,我在一个数据框中加载使用: MyIndex有两列感兴趣的ImagePath和ClassName 接下来我做一些训练测试拆分和编码输出标签为: 我面临的问题是一次性加载的数据太大,无法放入当前的机器内存,因此我无法处理完整的数据集。 我曾尝试使用datagenerator,但不想遵循它遵循的目录约定,也无法消除增强部分。 问题是,是否有一种方法可

  • 问题内容: 我正在尝试制作一个用于创建自定义卡片的应用。我想在自定义背景上添加一些文本(jpg图像)。 最好的方法是什么?在将卡片发送到服务器之前,我需要向用户显示该卡片的预览。 谢谢 问题答案: 使用下面的代码来满足您的要求 您必须在清单文件中使用以下权限。 对于我的设备,访问外部SD卡的路径可能会因其他设备而异。某些设备可能是用于内部SD卡的。在使用此代码之前,只需检查一下即可。 实际上,我为

  • 我有一个这样的提供程序设置: 我正在尝试使用actix web中的内置方法,将 或类似的东西。 但是,我反而收到以下错误: 有人能帮我弄清楚怎么解决这个问题吗?我对std::marker::size做了一些研究,但我不知道如何使用它来解决这个问题。