先说基础建设。国内用中文分词最常碰到的问题就是新词识别。比如“裂墙推荐”“绝绝子”这种网络用语,用默认词典根本切不准。我这边用的是HanLP的扩展词典功能,直接在自定义词典文件里追加新词和频次,像“绝绝子 1000 nr”这样标注词性和频次。加载时通过enableCustomDictionary(true)开启,效果立竿见影。不过要注意词典加载顺序,自定义词典要优先于核心词典加载,否则还是会被系统词典覆盖。

命名实体识别在电商场景特别实用。我们之前用Stanford CoreNLP处理商品规格文本,比如“华为Mate60 Pro 12+512GB 黛紫色”。这里要识别品牌、型号、内存、颜色多类实体。关键是要训练自己的CRF模型,标注样本时要注意实体边界划分。有个经验:标注规范要明确“12+512GB”整体标为MEMORY,而不是拆成两个数字。训练时用Properties配置ner.model和ner.map,在流水线里用ner.fine.regexner.mapping忽略大小写,准确率能到92%左右。

情感分析这块我们走过弯路。最初用TextBlob直接跑英文模型处理中文,结果完全不对。后来改用组合方案:先基于HowNet情感词典做基础情感分,再用SnowNLP的贝叶斯模型修正。具体实现时要处理否定词反转,比如“不划算”要从负转正。还有程度副词加权,“非常满意”要比“满意”分数更高。我们构建了程度词词典,分极度、高度、中度三个级别,分别设置1.5、1.2、0.8的权重系数。

句法分析在智能客服里用得最多。比如用户问“怎么重置苹果手机的开机密码”,用Stanford Parser分析依存关系后,能提取出“重置-密码”这个核心动宾结构,和“苹果手机”这个设备修饰。这里要注意中文的短语句法树和英文差异很大,比如“开机密码”是定中关系,要专门配置ChinesePCFG.ser.gz模型文件。解析结果用GrammaticalStructure的typedDependencies拿到三元组,再转成自定义的语义框架。

深度学习方案现在也成熟了。DL4J训练BERT模型处理相似问匹配,需要先把文本转换成BERT的输入格式。这里要自己处理中文WordPiece分词,我们用的是BertTokenizer.fromPretrained("bert-base-chinese")。训练时注意max_seq_length设置,中文建议256,batchSize别超过32,否则显存容易爆。部署时用NativeModelLoader加载训练好的.zip模型,推理速度比Python快三倍左右。

最后说说性能调优。大规模文本处理时最怕内存泄漏,特别是Stanford CoreNLP的Annotation对象会缓存中间结果。我们的解决方案是每处理1000条文本就重启pipeline,用Runtime.getRuntime().gc()触发主动GC。另外多线程环境下要确保每个线程独享AnnotationPipeline,避免并发修改异常。

Java做NLP确实要踩不少坑,但一旦打通全链路,在吞吐量和稳定性上的优势就体现出来了。特别是在企业级应用中,与现有Java体系无缝集成的便利性,是其他语言方案难以比拟的。未来准备尝试用Tribuo训练自定义文本分类模型,据说在OOM处理上比Weka更稳健。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐