Skip to content
New issue

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

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

Already on GitHub? Sign in 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,要如何修改呀。

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

No branches or pull requests

5 participants