1

一周前我做了一些关于文本挖掘的问题,但我有点困惑,但现在我知道我想做 wgat。

情况:我有很多包含 HTML 内容的下载页面。例如,其中一些可以是来自博客的文本。它们不是结构化的并且来自不同的站点。

我想要做什么:我将用空格分割所有单词,并且我想将每个单词或一组单词分类为一些预定义的项目,如姓名、数字、电话、电子邮件、网址、日期、金钱、温度等.

我所知道的:我知道/听说过有关自然语言处理、命名实体识别器、POSTagging、NayveBayesian、HMM、培训和很多分类的事情等的概念,但是有一些不同的 NLP 库具有不同的分类器和方法来做到这一点,我不知道有什么用或做什么。

我需要什么:我需要一些来自分类器、NLP 等的代码示例,它可以将每个单词从文本中单独分类,而不是整个文本。像这样的东西:

//This is pseudo-code for what I want, and not a implementation

classifier.trainFromFile("file-with-train-words.txt");
words = text.split(" ");
for(String word: words){
    classifiedWord = classifier.classify(word);
    System.out.println(classifiedWord.getType());
}

有人可以帮助我吗?我对各种 API、分类器和算法感到困惑。

4

4 回答 4

5

您应该尝试Apache OpenNLP。它易于使用和定制。

如果您正在为葡萄牙语做这件事,那么在使用 Amazonia Corpus 的项目文档中提供了有关如何做的信息。支持的类型有:

人、组织、组、地点、事件、ArtProd、抽象、事物、时间和数字。

  1. 下载 OpenNLP 和Amazonia Corpus。提取两者并将文件复制到文件amazonia.adapache-opennlp-1.5.1-incubating中。

  2. 执行 TokenNameFinderConverter 工具将 Amazonia 语料库转换为 OpenNLP 格式:

    bin/opennlp TokenNameFinderConverter ad -encoding ISO-8859-1 -data amazonia.ad -lang pt > corpus.txt
    
  3. 训练您的模型(将编码更改为 corpus.txt 文件的编码,这应该是您的系统默认编码。此命令可能需要几分钟):

    bin/opennlp TokenNameFinderTrainer -lang pt -encoding UTF-8 -data corpus.txt -model pt-ner.bin -cutoff 20
    
  4. 从命令行执行(您应该只执行一句话,并且应该分隔标记):

    $ bin/opennlp TokenNameFinder pt-ner.bin 
    Loading Token Name Finder model ... done (1,112s)
    Meu nome é João da Silva , moro no Brasil . Trabalho na Petrobras e tenho 50 anos .
    Meu nome é <START:person> João da Silva <END> , moro no <START:place> Brasil <END> . <START:abstract> Trabalho <END> na <START:abstract> Petrobras <END> e tenho <START:numeric> 50 anos <END> .
    
  5. 使用 API 执行它:

    InputStream modelIn = new FileInputStream("pt-ner.bin");
    
    try {
      TokenNameFinderModel model = new TokenNameFinderModel(modelIn);
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    finally {
      if (modelIn != null) {
        try {
           modelIn.close();
        }
        catch (IOException e) {
        }
      }
    }
    
    // load the name finder
    NameFinderME nameFinder = new NameFinderME(model);
    
    // pass the token array to the name finder
    String[] toks = {"Meu","nome","é","João","da","Silva",",","moro","no","Brasil",".","Trabalho","na","Petrobras","e","tenho","50","anos","."};
    
    // the Span objects will show the start and end of each name, also the type
    Span[] nameSpans = nameFinder.find(toks);
    
  6. 要评估您的模型,您可以使用 10 折交叉验证:(仅在 1.5.2-INCUBATOR 中可用,今天要使用它,您需要使用 SVN 主干)(可能需要几个小时)

    bin/opennlp TokenNameFinderCrossValidator -lang pt -encoding UTF-8 -data corpus.txt -cutoff 20
    
  7. 通过使用自定义特征生成(检查文档)来提高精度/召回率,例如通过添加名称字典。

于 2011-08-03T18:53:58.580 回答
2

您可以为此任务使用命名实体识别器 (NER) 方法,我强烈建议您查看Stanford Core NLP 页面并使用ner模块中的功能来完成您的任务。您可以将句子分解为标记,然后将它们传递给斯坦福 NER 系统。我认为斯坦福核心 NLP 页面有很多示例可以帮助您,如果您需要玩具代码,请告诉我。

这是示例代码,这只是整个代码的片段:

// creates a StanfordCoreNLP object, with NER
    Properties props = new Properties();
    props.put("annotators", "ner");
    StanfordCoreNLP pipeline = new StanfordCoreNLP(props);

classifier.trainFromFile("file-with-train-words.txt");
words = text.split(" ");
for(String word: words){
     Annotation document = new Annotation(word);
     pipeline.annotate(document);
     System.out.println(Annotation);
}
于 2011-08-01T16:31:09.583 回答
1

这个问题属于来自不同领域的几个想法的交叉点。您提到命名实体识别,就是其中之一。但是,您可能正在查看词性标记(用于名词、名称等)和信息提取(用于数字、电话号码、电子邮件)的混合。

不幸的是,这样做并让它在实际工作数据上工作需要一些努力,而且它不像使用这个或那个 API 那样简单。

于 2011-08-01T04:49:16.207 回答
0

您必须创建特定的函数来提取和检测每种数据类型及其错误。

或者作为其众所周知的面向对象的方式。即,为了检测货币,我们所做的是在开头或结尾检查美元符号,并检查是否附加了非数字字符,这意味着错误。

你应该用你的头脑写下你已经在做的事情。如果你遵守规则,这并不难。机器人/人工智能中有 3 条黄金法则:

  1. 分析它。
  2. 简化它
  3. 将其数字化。

这样你就可以和电脑对话了。

于 2017-10-21T16:56:51.200 回答