Stanford NER Tagger与NLTK调用失败:OSError: Java command failed
解决Stanford NER Tagger与NLTK集成时的
OSError: Java command failed问题 从你提供的完整错误信息来看,核心问题有两个:一是Stanford NER版本与NLTK传递的参数不兼容(出现Unknown property: |tokenizerFactory|等错误),二是模型文件与Jar包版本不匹配导致反序列化失败(ClassCastException: java.util.ArrayList cannot be cast to [Ledu.stanford.nlp.util.Index;)。下面是针对性的解决方案:
一、确认版本兼容性并修复文件匹配
- 确保Jar包与模型文件版本完全一致
你当前下载的是2015-04-20版本的Stanford NER,但如果模型文件是单独下载的,很可能存在版本不匹配的情况。建议直接从stanford-ner-2015-04-20.zip解压后的classifiers目录中获取模型文件,而不是单独下载。重新解压该压缩包,使用里面的english.all.3class.caseless.distsim.crf.ser.gz。 - 检查Java版本
Stanford NER 2015版本需要Java 7或更高版本,在终端运行以下命令确认:
如果版本过低,需要升级Java。java -version
二、修改NLTK调用代码,避免传递不支持的参数
NLTK 3.3的StanfordNERTagger会自动添加tokenizerFactory和tokenizerOptions等参数,但这些参数在2015版本的Stanford NER中并不支持,导致未知属性错误。可以通过以下两种方式解决:
方式1:使用原始文本而非预分词列表
直接传递原始文本给tag方法,让Stanford NER自行处理分词(避免NLTK传递额外参数):
from nltk.tag.stanford import StanfordNERTagger Sample_text = "Google, headquartered in Mountain View, unveiled the new Android phone" # 注意路径改为解压后的官方模型路径 PATH_TO_GZ = '/home/root/stanford-ner-2015-04-20/classifiers/english.all.3class.caseless.distsim.crf.ser.gz' PATH_TO_JAR = '/home/root/stanford-ner-2015-04-20/stanford-ner.jar' sn_3class = StanfordNERTagger(PATH_TO_GZ, path_to_jar=PATH_TO_JAR, encoding='utf-8') # 直接传入按空格拆分的文本,而非预分词列表 annotations = sn_3class.tag(Sample_text.split()) print(annotations)
方式2:手动构造Stanford NER命令(绕过NLTK的自动参数)
如果必须使用预分词结果,可以手动调用Java命令处理:
import subprocess import tempfile def stanford_ner_tag(tokenized_sentence, jar_path, model_path): # 将分词结果写入临时文件 with tempfile.NamedTemporaryFile(mode='w', delete=False) as f: f.write(' '.join(tokenized_sentence)) temp_file = f.name # 构造Stanford NER命令(移除不支持的参数) cmd = [ 'java', '-mx1000m', '-cp', jar_path, 'edu.stanford.nlp.ie.crf.CRFClassifier', '-loadClassifier', model_path, '-textFile', temp_file, '-outputFormat', 'slashTags' ] # 执行命令并解析结果 result = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode('utf-8') # 解析slashTags格式的输出为(词, 标签)元组 tagged = [(token.split('/')[0], token.split('/')[1]) for token in result.strip().split()] return tagged # 使用示例 tokenized_sentence = ["Google", ",", "headquartered", "in", "Mountain", "View", ",", "unveiled", "the", "new", "Android", "phone"] annotations = stanford_ner_tag(tokenized_sentence, PATH_TO_JAR, PATH_TO_GZ) print(annotations)
三、升级NLTK与Stanford NER版本(推荐长期解决方案)
NLTK 3.3是比较旧的版本,建议升级到较新版本(比如3.8+),同时使用较新的Stanford NER版本(比如2020-11-17),新版本之间的兼容性更好,也会修复很多已知问题:
- 升级NLTK:
pip install --upgrade nltk - 下载最新版Stanford NER:
wget https://nlp.stanford.edu/software/stanford-ner-2020-11-17.zip unzip stanford-ner-2020-11-17.zip - 使用新版本的Jar和模型文件运行代码,此时NLTK的默认参数会被Stanford NER支持,无需额外修改。
内容的提问来源于stack exchange,提问作者Anuj Gupta
相关产品推荐
相关产品推荐

