首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在OpenNLP中使用带有参数的自定义特征生成器

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

Stack Overflow用户
提问于 2013-10-15 06:59:58
回答 2查看 892关注 0票数 0

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

代码语言:javascript
复制
<generators>
  <cache>
    <generators>
      ...
      <custom class="com.example.MyFeatureGenerator"/>
   </cache>
</generators>

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-15 09:09:00

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

首先,定义一个名为XmlDescriptorUtil的新类

代码语言:javascript
复制
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);
  }

}

然后,创建一个实现公共接口XmlDescriptorUtil$XmlDescriptorFactory的特性生成器工厂。

代码语言:javascript
复制
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描述符中使用:

代码语言:javascript
复制
<generators>
  <cache>
    <generators>
      ...
      <myCustom/>
    </generators>
  </cache> 
</generators>

如果特征生成器需要参数,可以从工厂类的generatorElement中提取它们。

票数 0
EN

Stack Overflow用户

发布于 2013-10-15 19:00:05

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19375053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档