我正在尝试使用 OpenNLP Java API 从文档中提取实体,例如姓名、技能。但它没有提取正确的名称。我正在使用 opennlp sourceforge link 上可用的模型
这是一段java代码-
public class tikaOpenIntro {
public static void main(String[] args) throws IOException, SAXException,
TikaException {
tikaOpenIntro toi = new tikaOpenIntro();
toi.filest("");
String cnt = toi.contentEx();
toi.sentenceD(cnt);
toi.tokenization(cnt);
String names = toi.namefind(toi.Tokens);
toi.files(names);
}
public String Tokens[];
public String contentEx() throws IOException, SAXException, TikaException {
InputStream is = new BufferedInputStream(new FileInputStream(new File(
"/home/rahul/Downloads/rahul.pdf")));
// URL url=new URL("http://in.linkedin.com/in/rahulkulhari");
// InputStream is=url.openStream();
Parser ps = new AutoDetectParser(); // for detect parser related to
BodyContentHandler bch = new BodyContentHandler();
ps.parse(is, bch, new Metadata(), new ParseContext());
return bch.toString();
}
public void files(String st) throws IOException {
FileWriter fw = new FileWriter("/home/rahul/Documents/extrdata.txt",
true);
BufferedWriter bufferWritter = new BufferedWriter(fw);
bufferWritter.write(st + "\n");
bufferWritter.close();
}
public void filest(String st) throws IOException {
FileWriter fw = new FileWriter("/home/rahul/Documents/extrdata.txt",
false);
BufferedWriter bufferWritter = new BufferedWriter(fw);
bufferWritter.write(st);
bufferWritter.close();
}
public String namefind(String cnt[]) {
InputStream is;
TokenNameFinderModel tnf;
NameFinderME nf;
String sd = "";
try {
is = new FileInputStream(
"/home/rahul/opennlp/model/en-ner-person.bin");
tnf = new TokenNameFinderModel(is);
nf = new NameFinderME(tnf);
Span sp[] = nf.find(cnt);
String a[] = Span.spansToStrings(sp, cnt);
StringBuilder fd = new StringBuilder();
int l = a.length;
for (int j = 0; j < l; j++) {
fd = fd.append(a[j] + "\n");
}
sd = fd.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sd;
}
public void sentenceD(String content) {
String cnt[] = null;
InputStream om;
SentenceModel sm;
SentenceDetectorME sdm;
try {
om = new FileInputStream("/home/rahul/opennlp/model/en-sent.bin");
sm = new SentenceModel(om);
sdm = new SentenceDetectorME(sm);
cnt = sdm.sentDetect(content);
} catch (IOException e) {
e.printStackTrace();
}
}
public void tokenization(String tokens) {
InputStream is;
TokenizerModel tm;
try {
is = new FileInputStream("/home/rahul/opennlp/model/en-token.bin");
tm = new TokenizerModel(is);
Tokenizer tz = new TokenizerME(tm);
Tokens = tz.tokenize(tokens);
// System.out.println(Tokens[1]);
} catch (IOException e) {
e.printStackTrace();
}
}
}
我想做的是:
- 我正在使用 Apache Tika 将 PDF 文档转换为纯文本文档。
- 我正在传递纯文本文档以进行句子边界检测。
- 在此标记化之后
- 在此名称实体提取之后
但它是提取名称和其他单词。 它不是提取专有名称。和如何创建自定义模型以从游泳、编程等文档中提取技能?
给我一些想法!
任何帮助将不胜感激!?
最佳答案
听起来您对 OpenNLP 的预建名称模型的性能不满意。但是(a)模型从来都不是完美的,即使是最好的模型也会错过一些它应该捕捉到的东西,捕捉到一些它应该错过的东西; (b) 如果训练模型的文档在类型和文本样式上与您尝试标记的文档相匹配,则模型将表现最佳(因此,在混合大小写文本上训练的模型在所有情况下都不会很好地工作-限制文本,并且在新闻文章上训练的模型在推文等方面效果不佳)。您可以尝试其他公开可用的工具,例如 Stanford NE 工具包或 LingPipe;他们可能有性能更好的模型。但他们都不会是完美的。
要创建自定义模型,您需要生成一些训练数据。对于 OpenNLP,它看起来像
I have a Ph.D. in <START:skill> operations research <END>
对于像这样具体的事情,您可能需要自己提供这些数据。而且您将需要很多; OpenNLP 文档推荐了大约 15,000 个例句。有关详细信息,请参阅 OpenNLP 文档。
关于java - 如何使用 OpenNLP 创建自定义模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17963972/