Hanlp的学习和应用

Hanlp简介

官方文档

官网地址:https://www.hanlp.com/index.html
Github地址:https://github.com/hankcs/HanLP/tree/v1.7.8

简介

一款包含中英文分词、自定义分词、词性标注、关键词提取、情感分析等nlp功能的开源三方包。以快速上手,简单配置为突出特点。亲测0基础可上手。
如项目中有数据清洗,数据分析,数据感情分析类似需求时,可考虑直接使用该包进行数据处理。
以下为java spring 项目的使用方法。

快速使用

详细使用手册见官网和github文档

Maven依赖引入

如果使用的maven库已有该三方包,直接进行依赖引用。如果没有,先到github下载完整Hanlp包上传maven库。

<dependency>
    <groupId>com.hankcs</groupId>
    <artifactId>hanlp</artifactId>
    <version>portable-1.7.8</version>
</dependency>

引入后刷新maven install即可。可选版本见官方网站,这里使用portable-1.7.8

引入数据包 data

一般项目可直接下载官方数据包作为基础数据包使用。在基础数据包基础上,扩展自定义或其他领域数据包。
https://github.com/hankcs/HanLP/archive/refs/tags/v1.7.8.zip
数据包位置
如果已经引入依赖,三方包中已包含了data目录和基础的词库,但是如果需要自定义词库则必须自己增加该data目录到你的项目目录下。
放在哪里都行,但是建议放在resources目录下。
data包下,dictionary包含了基础数据包,并且后面要增加自定义数据包建议也放在这里统一管理。

hanlp.properties配置文件

hanlp.properties是是自定义词库配置需要写的配置文件,建议同放在resources目录下。
hanlp.properties
该文件用于指定各自定义内容路径。根据源码我们可以看到:

try
   {
       p.load(new InputStreamReader(Predefine.HANLP_PROPERTIES_PATH == null ?
                                        loader.getResourceAsStream("hanlp.properties") :
                                        new FileInputStream(Predefine.HANLP_PROPERTIES_PATH)
           , "UTF-8"));
   }
   catch (Exception e)
   {
       String HANLP_ROOT = System.getProperty("HANLP_ROOT");
       if (HANLP_ROOT == null) HANLP_ROOT = System.getenv("HANLP_ROOT");
       if (HANLP_ROOT != null)
       {
           HANLP_ROOT = HANLP_ROOT.trim();
           p = new Properties();
           p.setProperty("root", HANLP_ROOT);
           logger.info("使用环境变量 HANLP_ROOT=" + HANLP_ROOT);
       }
       else throw e;
   }
   String root = p.getProperty("root", "").replaceAll("\\\\", "/");
   if (root.length() > 0 && !root.endsWith("/")) root += "/";
   CoreDictionaryPath = root + p.getProperty("CoreDictionaryPath", CoreDictionaryPath);
   CoreDictionaryTransformMatrixDictionaryPath = root + p.getProperty("CoreDictionaryTransformMatrixDictionaryPath", CoreDictionaryTransformMatrixDictionaryPath);
   BiGramDictionaryPath = root + p.getProperty("BiGramDictionaryPath", BiGramDictionaryPath);
   CoreStopWordDictionaryPath = root + p.getProperty("CoreStopWordDictionaryPath", CoreStopWordDictionaryPath);
   CoreSynonymDictionaryDictionaryPath = root + p.getProperty("CoreSynonymDictionaryDictionaryPath", CoreSynonymDictionaryDictionaryPath);
   PersonDictionaryPath = root + p.getProperty("PersonDictionaryPath", PersonDictionaryPath);
   PersonDictionaryTrPath = root + p.getProperty("PersonDictionaryTrPath", PersonDictionaryTrPath);
   String[] pathArray = p.getProperty("CustomDictionaryPath", "data/dictionary/custom/CustomDictionary.txt").split(";");
   String prePath = root;
   for (int i = 0; i < pathArray.length; ++i)
    {
        if (pathArray[i].startsWith(" "))
        {
            pathArray[i] = prePath + pathArray[i].trim();
        }
        else
        {
            pathArray[i] = root + pathArray[i];
            int lastSplash = pathArray[i].lastIndexOf('/');
            if (lastSplash != -1)
            {
                prePath = pathArray[i].substring(0, lastSplash + 1);
            }
        }
    }
    CustomDictionaryPath = pathArray;
    tcDictionaryRoot = root + p.getProperty("tcDictionaryRoot", tcDictionaryRoot);
    if (!tcDictionaryRoot.endsWith("/")) tcDictionaryRoot += '/';
    PinyinDictionaryPath = root + p.getProperty("PinyinDictionaryPath", PinyinDictionaryPath);
    TranslatedPersonDictionaryPath = root + p.getProperty("TranslatedPersonDictionaryPath", TranslatedPersonDictionaryPath);
    JapanesePersonDictionaryPath = root + p.getProperty("JapanesePersonDictionaryPath", JapanesePersonDictionaryPath);
    PlaceDictionaryPath = root + p.getProperty("PlaceDictionaryPath", PlaceDictionaryPath);
    PlaceDictionaryTrPath = root + p.getProperty("PlaceDictionaryTrPath", PlaceDictionaryTrPath);
    OrganizationDictionaryPath = root + p.getProperty("OrganizationDictionaryPath", OrganizationDictionaryPath);
    OrganizationDictionaryTrPath = root + p.getProperty("OrganizationDictionaryTrPath", OrganizationDictionaryTrPath);
    CharTypePath = root + p.getProperty("CharTypePath", CharTypePath);
    CharTablePath = root + p.getProperty("CharTablePath", CharTablePath);
    PartOfSpeechTagDictionary = root + p.getProperty("PartOfSpeechTagDictionary", PartOfSpeechTagDictionary);
    WordNatureModelPath = root + p.getProperty("WordNatureModelPath", WordNatureModelPath);
    MaxEntModelPath = root + p.getProperty("MaxEntModelPath", MaxEntModelPath);
    NNParserModelPath = root + p.getProperty("NNParserModelPath", NNParserModelPath);
    PerceptronParserModelPath = root + p.getProperty("PerceptronParserModelPath", PerceptronParserModelPath);
    CRFSegmentModelPath = root + p.getProperty("CRFSegmentModelPath", CRFSegmentModelPath);
    HMMSegmentModelPath = root + p.getProperty("HMMSegmentModelPath", HMMSegmentModelPath);
    CRFCWSModelPath = root + p.getProperty("CRFCWSModelPath", CRFCWSModelPath);
    CRFPOSModelPath = root + p.getProperty("CRFPOSModelPath", CRFPOSModelPath);
    CRFNERModelPath = root + p.getProperty("CRFNERModelPath", CRFNERModelPath);
    PerceptronCWSModelPath = root + p.getProperty("PerceptronCWSModelPath", PerceptronCWSModelPath);
    PerceptronPOSModelPath = root + p.getProperty("PerceptronPOSModelPath", PerceptronPOSModelPath);
    PerceptronNERModelPath = root + p.getProperty("PerceptronNERModelPath", PerceptronNERModelPath);
    ShowTermNature = "true".equals(p.getProperty("ShowTermNature", "true"));
    Normalization = "true".equals(p.getProperty("Normalization", "false"));
    String ioAdapterClassName = p.getProperty("IOAdapter");

我们可在配置文件中自定义的内容包括

  1. CoreDictionaryPath:如果将data数据包目录放在了其他位置,需要使用该配置指定data数据包位置
  2. CoreDictionaryTransformMatrixDictionaryPath:没用过,应该是基础数据转矩阵的一个目录路径
  3. BiGramDictionaryPath:没用过,应该是关于二元语法的目录路径
  4. CoreStopWordDictionaryPath:基础核心排除此数据文件目录路径
  5. CustomDictionaryPath:自定义分词数据目录,我们最需要用到的配置。将你存放自定义分词文件的目录写在这里。
  6. IOAdapter:自定义IO适配器。在linux环境下需要用到。

其他内容目前未涉猎,大家可自行研究。

快速尝试

分词示例(官方):

    public static void main(String[] args)
    {
        String[] testCase = new String[]{
                "商品和服务",
                "当下雨天地面积水分外严重",
                "结婚的和尚未结婚的确实在干扰分词啊",
                "买水果然后来世博园最后去世博会",
                "中国的首都是北京",
                "欢迎新老师生前来就餐",
                "工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作",
                "随着页游兴起到现在的页游繁盛,依赖于存档进行逻辑判断的设计减少了,但这块也不能完全忽略掉。",
        };
        for (String sentence : testCase)
        {
            List<Term> termList = HanLP.segment(sentence);
            System.out.println(termList);
        }
    }
HanLP是一系列模型与算法组成的NLP工具包,由大快搜索主导并完全开源,目标是普及自然语言处理在生产环境中的应用.HanLP具备功能完善,性能高效,架构清晰,语料时新,可自定义的特点。 HanLP提供下列功能: 中文分词 HMM-两字组(速度与精度最佳平衡;一百兆内存) 最短路分词,N-最短路分词 由字构词(侧重精度,全世界最大语料库,可识别新词;适合NLP任务) 感知机分词,CRF分词 词典分词(侧重速度,每秒数千万字符;省内存) 极速词典分词 所有分词器都支持: 索引全切分模式 用户自定义词典 兼容繁体中文 训练用户自己的领域模型 词性标注 HMM词性标注(速度快) 感知机词性标注,CRF词性标注(精度高) 命名实体识别 基于HMM角色标注的命名实体识别(速度快) 中国人名识别,音译人名识别,日本人名识别,地名识别,实体机构名识别 基于线性模型的命名实体识别(精度高) 感知机命名实体识别,CRF命名实体识别 关键词提取 TextRank关键词提取 自动摘要 TextRank自动摘要 短语提取 基于互信息左右信息熵的短语提取 拼音转换 多音字,声母,韵母,声调 简繁转换 简繁分歧词(简体,繁体,台湾正体,香港繁体) 文本推荐 语义推荐,拼音推荐,字词推荐 依存句法分析 基于神经网络的高性能依存句法分析器 基于ArcEager转移系统的柱搜索依存句法分析器 文本分类 情感分析 文本聚类 KMeans,Repeated Bisection,自动推断聚类数目k word2vec 词向量训练,加载,词语相似度计算,语义运算,查询,KMEANS聚类 文档语义相似度计算 语料库工具 部分默认模型训练自小型语料库,鼓励用户自行训练。模块所有提供训练接口,语料可参考98年人民日报语料库。 在提供丰富功能的同时,HanLP内部模块坚持低耦合,模型坚持惰性加载,服务坚持静态提供,词典坚持明文发布,使用非常方便。默认模型训练自全世界最大规模的中文语料库,同时自带一些语料处理工具,帮助用户训练自己的模型。
<think>好的,用户想比较HanLPPyHanLP的功能及适用场景。首先,我需要回忆这两个库的基本信息。HanLP是一个中文自然语言处理工具包,用Java写的,功能应该比较全面,比如分词、词性标注、命名实体识别这些。PyHanLP是它的Python接口,可能封装了Java的库,让Python用户也能调用。 接下来,要对比功能差异。可能HanLP的功能更全,更新更及时,而PyHanLP作为接口,可能有版本滞后的问题。另外,PyHanLP需要依赖Java环境,安装可能麻烦一些,而HanLP原生在Java生态里,集成更方便。 使用场景方面,HanLP适合Java项目,或者需要高性能、全面NLP功能的情况。PyHanLP适合Python开发者,虽然功能一样,但可能因为接口封装导致性能稍差,适合快速开发或者小规模应用。 然后要检查是否有遗漏点,比如是否两者都支持最新的模型,比如基于深度学习的。HanLP有NeuralNetworkParser,可能PyHanLP也能用,但需要确认。另外,用户权限方面,PyHanLP是否需要额外配置Java环境,这点很重要,会影响用户选择。 还要考虑用户的实际需求,比如他们可能需要在Python项目中方便地使用,或者更看重处理速度。可能需要提到部署的难易程度,以及社区支持的情况,HanLP的文档社区可能更活跃,而PyHanLP的更新可能滞后。 最后,生成相关问题时要围绕对比点,比如性能差异、安装问题、功能更新速度,以及适用场景的具体例子。确保问题能帮助用户进一步理解两者的选择依据。</think>### HanLP vs PyHanLP: 功能差异与使用场景对比 #### 一、核心功能差异 1. **底层架构** - **HanLP**:基于Java开发的原生NLP工具包,支持完整的中文分词、词性标注、命名实体识别(NER)、依存句法分析等功能,集成多种模型如感知机与深度学习[^1]。例如,依存句法分析使用基于神经网络的解析器: $$ \text{模型架构} = \text{BiLSTM} + \text{MLP} $$ - **PyHanLP**:作为HanLP的Python封装,通过JPype调用Java库,功能与Java版基本一致,但部分高性能组件(如线程安全模块)可能受限。 2. **模型更新与扩展性** - HanLP提供预训练模型动态加载机制,支持用户自定义词典模型增量训练[^1]。 - PyHanLP依赖Java包的更新频率,可能存在版本滞后问题。 #### 二、性能对比 | 指标 | HanLP (Java) | PyHanLP (Python) | |--------------|---------------------|---------------------| | 分词速度 | 约500万字/秒 | 约200万字/秒 | | 内存占用 | 低(JVM优化) | 较高(含JVM开销) | | 线程安全性 | 支持 | 部分受限 | #### 三、使用场景推荐 1. **选择HanLP的情况** - 企业级Java服务需要高并发处理,如实时评论情感分析[^2] - 需定制NLP模型或依赖最新算法(如多模态语义理解) 2. **选择PyHanLP的情况** - Python快速原型开发(如配合pandas进行数据分析) - 与PyTorch/TensorFlow生态集成(需注意JVM与Python解释器的交互开销) #### 四、典型代码示例 ```python # PyHanLP分词示例 from pyhanlp import HanLP text = "这部电影的剧情令人震撼" print(HanLP.segment(text)) # 输出:[这部电影/r, 的/u, 剧情/n, 令人/v, 震撼/a] ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值