Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

hanlp打包问题 #983

Closed
1 task done
yooopan opened this issue Sep 28, 2018 · 9 comments
Closed
1 task done

hanlp打包问题 #983

yooopan opened this issue Sep 28, 2018 · 9 comments
Labels

Comments

@yooopan
Copy link

yooopan commented Sep 28, 2018

注意事项

请确认下列注意事项:

  • 我已仔细阅读下列文档,都没有找到答案:
  • 我已经通过Googleissue区检索功能搜索了我的问题,也没有找到答案。
  • 我明白开源社区是出于兴趣爱好聚集起来的自由社区,不承担任何责任或义务。我会礼貌发言,向每一个帮助我的人表示感谢。
  • 我在此括号内输入x打钩,代表上述事项确认完毕

版本号

当前最新版本号是:1.6.8
我使用的版本是:1.6.8

我的问题

打包后找不到hanlp.properties

步骤

  1. 首先: 下载hanlp源码(master分支),在com.hankcs.hanlp.HanLP类中加了一个main方法用于测试:
    public static void main(String[] args) {
        System.out.println(HanLP.segment("商品和服务"));
    }
  1. 然后: 打包,执行打包命令 mvn clean package -Dmaven.test.skip=true

  2. 接着: 修改hanlp.properties中的root路径为data的父文件夹并放到target目录下,和hanlp-1.6.8-sources.jar、hanlp-1.6.8.jar在同一目录下,命令运行com.hankcs.hanlp.HanLP类的main方法:

java -cp hanlp-1.6.8.jar com.hankcs.hanlp.HanLP start

期望输出

[商品/n, 和/cc, 服务/vn]

期望和hanlp-1.6.8-release.zip里面打包出来的效果一样,两个jar包一个配置文件。

实际输出

sep 28, 2018 1:47:03 PM com.hankcs.hanlp.HanLP$Config <clinit>
SEVERE: 没有找到hanlp.properties,可能会导致找不到data
========Tips========
请将hanlp.properties放在下列目录:
Web项目则请放到下列目录:
Webapp/WEB-INF/lib
Webapp/WEB-INF/classes
Appserver/lib
JRE/lib
并且编辑root=PARENT/path/to/your/data
现在HanLP将尝试从/Users/pan/github/HanLP-master/target读取data……
Sep 28, 2018 1:47:03 PM com.hankcs.hanlp.corpus.io.IOUtil readBytes
WARNING: 读取data/dictionary/CoreNatureDictionary.txt.bin时发生异常java.io.FileNotFoundException: data/dictionary/CoreNatureDictionary.txt.bin (No such file or directory)
Sep 28, 2018 1:47:03 PM com.hankcs.hanlp.dictionary.CoreDictionary load
WARNING: 核心词典data/dictionary/CoreNatureDictionary.txt不存在!java.io.FileNotFoundException: data/dictionary/CoreNatureDictionary.txt (No such file or directory)
Exception in thread "main" java.lang.ExceptionInInitializerError
	at com.hankcs.hanlp.seg.common.Vertex.newB(Vertex.java:455)
	at com.hankcs.hanlp.seg.common.WordNet.<init>(WordNet.java:73)
	at com.hankcs.hanlp.seg.Viterbi.ViterbiSegment.segSentence(ViterbiSegment.java:40)
	at com.hankcs.hanlp.seg.Segment.seg(Segment.java:573)
	at com.hankcs.hanlp.tokenizer.StandardTokenizer.segment(StandardTokenizer.java:50)
	at com.hankcs.hanlp.HanLP.segment(HanLP.java:626)
	at com.hankcs.hanlp.HanLP.main(HanLP.java:860)
Caused by: java.lang.IllegalArgumentException: 核心词典data/dictionary/CoreNatureDictionary.txt加载失败
	at com.hankcs.hanlp.dictionary.CoreDictionary.<clinit>(CoreDictionary.java:44)
	... 7 more

其他信息

@hankcs
Copy link
Owner

hankcs commented Sep 29, 2018

有很多方案,任选一个:

  1. 假设配置文件的绝对路径是/Users/myname/HanLP/hanlp.properties,且第一行root配置正确,则用配置文件解决:java -cp hanlp-1.6.8.jar:/Users/myname/HanLP/ com.hankcs.hanlp.HanLP
  2. JVM的启动参数解决:java -DHANLP_ROOT=/Users/myname/HanLP -cp hanlp-1.6.8.jar com.hankcs.hanlp.HanLP
  3. 假设自己的data的父目录是/Users/myname/HanLP,用环境变量解决export HANLP_ROOT=/Users/myname/HanLP
  4. 确保当前路径下有data,默认从当前路径下加载data:
$ ls                                                     
LICENSE   README.md data     pom.xml   src       target
$ java -cp target/hanlp-1.6.8.jar com.hankcs.hanlp.HanLP
[商品/n, 和/cc, 服务/vn]

从前往后优先级递减,一旦触发相应规则,无论data是否存在,不再检查后续规则。

@victorzhrn
Copy link
Contributor

可以将data文件夹放入src/main/resources(mvn项目资源默认文件夹, 或在pom中定义mvn资源文件夹地址), hanlp 默认的在corpus.io.IOAdaptor interface中默认是读取当前执行路径下的fileIO, 但是你可以根据当前环境具体情况改写. 可以自己overwrite corpus.io.FileIOAdapator来从resource文件夹读取data语聊.

@Override
    public InputStream open(String path) throws FileNotFoundException
    {
        InputStream is = getClass().getClassLoader().getResourceAsStream(path);
        return is;
//        return new FileInputStream(path);
    }

    @Override
    public OutputStream create(String path) throws FileNotFoundException
    {
        try{
            File file = new File(getClass().getClassLoader().getResource(path).toURI());
            OutputStream output = new FileOutputStream(file);
            return output;
        }catch (Exception e) {
            OutputStream output = new FileOutputStream(path);
            return output;
        }
//        return new FileOutputStream(path);
    }

然后在com.hankcs.hanlp.HanLP.class 下修改

/**
         * IO适配器(默认null,表示从本地文件系统读取),实现com.hankcs.hanlp.corpus.io.IIOAdapter接口
         * 以在不同的平台(Hadoop、Redis等)上运行HanLP
         */
        public static IIOAdapter IOAdapter = new FileIOAdapter();

@batizhao
Copy link

batizhao commented Apr 22, 2019

@zhangruinan @hankcs 请问这种情况如何处理?
1、我希望自己定义的词典放在自己的目录,例如:/opt/dictionary ,这样方便版本管理;
2、HanLP 的 data 文件放在另外独立 /opt/hanlp/data,这样方便 hanlp 无脑更新;
3、我自己的 java 应用 App 根目录在 /opt/app, 通过 hanlp.properties 自定义指向 /opt/dictionary 加载自己的词典,同时不影响 hanlp 词典的加载。
4、并且不希望把 hanlp 的 data 放到自己的项目中(太大、不方便更新、不希望把 hanlp 的文件加入版本控制)
总结一下,就是三个目录:应用 /opt/app、词典 /opt/dictionary,hanlp 在 /opt/hanlp/data,这样目前好像行不通?

@victorzhrn
Copy link
Contributor

@zhangruinan @hankcs 请问这种情况如何处理?
1、我希望自己定义的词典放在自己的目录,例如:/opt/dictionary ,这样方便版本管理;
2、HanLP 的 data 文件放在另外独立 /opt/hanlp/data,这样方便 hanlp 无脑更新;
3、我自己的 java 应用 App 根目录在 /opt/app, 通过 hanlp.properties 自定义指向 /opt/dictionary 加载自己的词典,同时不影响 hanlp 词典的加载。
4、并且不希望把 hanlp 的 data 放到自己的项目中(太大、不方便更新、不希望把 hanlp 的文件加入版本控制)
总结一下,就是三个目录:应用 /opt/app、词典 /opt/dictionary,hanlp 在 /opt/hanlp/data,这样目前好像行不通?

  • 1和3. 建议你修改hanlp.properties的以下部分, 可以将root改为/opt, 然后重新mvn build hanlp项目,
#Windows用户请注意,路径分隔符统一使用/
root=/opt

CoreDictionaryPath=/app/*
# CoreDictionaryPath=/hanlp/data/*
  • 2 如果你是maven项目开发, 建议直接dependency引用hanlp-portable版本(包含data), 这样不用考虑数据在哪儿的问题

  • 4 建议你自己git clone 一个hanlp的master branch, 然后自己字段和对应的文件.

@batizhao
Copy link

batizhao commented Apr 22, 2019

@zhangruinan 感谢及时回复,不过可能我表述不清楚,着实有点晕。其实这 4 点是一个统一的问题。
我现在基本知道怎么做了,谢谢!

@hankcs
Copy link
Owner

hankcs commented Apr 22, 2019

行得通,你可以把root设为/,就可以用各种绝对路径了。

@batizhao
Copy link

@hankcs 感谢回复,已经解决。

目前目录结构是这样的:

opt
    nlp
        data
        my-dictionary

hanlp.properties

root=/opt/nlp
PerceptronCWSModelPath=my-dictionary/200/cws.bin
PerceptronPOSModelPath=my-dictionary/200/pos.bin
PerceptronNERModelPath=my-dictionary/200/ner.bin

CustomDictionaryPath=my-dictionary/人名词典.txt nr; 机构名词典.txt nt; 全国地名大全.txt ns; 上海地名.txt ns;

@hankcs
Copy link
Owner

hankcs commented Jan 1, 2020

感谢您对HanLP1.x的支持,我一直为没有时间回复所有issue感到抱歉,希望您提的问题已经解决。或者,您可以从《自然语言处理入门》中找到答案。

时光飞逝,HanLP1.x感谢您的一路相伴。我于东部标准时间2019年12月31日发布了HanLP1.x在上一个十年最后一个版本,代号为最后的武士。此后1.x分支将提供稳定性维护,但不是未来开发的焦点。

值此2020新年之际,我很高兴地宣布,HanLP2.0发布了。HanLP2.0的愿景是下一个十年的前沿NLP技术。为此,HanLP2.0采用TensorFlow2.0实现了最前沿的深度学习模型,通过精心设计的框架支撑下游NLP任务,在海量语料库上取得了最前沿的准确率。作为第一个alpha版本,HanLP 2.0.0a0支持分词、词性标注、命名实体识别、依存句法分析、语义依存分析以及文本分类。而且,这些功能并不仅限中文,而是面向全人类语种设计。HanLP2.0提供许多预训练模型,而终端用户仅需两行代码即可部署,深度学习落地不再困难。更多详情,欢迎观看HanLP2.0的介绍视频,或参与论坛讨论

展望未来,HanLP2.0将集成1.x时代继承下来的高效率务实风范,同时冲刺前沿研究,做工业界和学术界的两栖战舰,请诸君继续多多指教,谢谢。

@sly123197811
Copy link

您好,我打包pyhanlp,要如何修改呀。

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants