HanLP案例

wen java案例 2

本文目录导读:

HanLP案例

  1. 案例一:金融新闻舆情分析(情感分析 + 实体识别)
  2. 案例二:多任务联合推理(带自定义Pipeline)
  3. 案例三:HanLP + LLM (大语言模型) 混合架构

HanLP(Han Language Processing)的案例,这里整理了三个不同场景的典型应用,涵盖基础分词、情感分析和与大型语言模型 (LLM) 结合的高级用法。


金融新闻舆情分析(情感分析 + 实体识别)

场景: 对财经网站抓取的新闻标题进行股评情感打分,并提取相关公司名称。

from hanlp import HanLP
# 版本要求: HanLP 2.1+
# 加载多功能预训练模型 (一次性加载,可以同时做多种任务)
# 该模型支持: 分词/词性标注/命名实体识别/依存句法分析/语义角色标注
# 这里我们使用较小的模型以便快速演示
nlp = HanLP.load('COARSE_ELECTRA_SMALL_ZH')
# 示例新闻标题
news_list = [
    "受利好消息刺激,比亚迪股价大涨5%,新能源板块领涨。",
    "某地产公司资金链断裂,面临退市风险,建议投资者谨慎。",
    "央行宣布降准释放流动性,银行板块表现强势。",
    ""
]
# 情感词典(简单规则辅助,实际可用HanLP的自带情感模型)
positive_words = ['大涨', '领涨', '强势', '利好']
negative_words = ['断裂', '退市', '风险', '暴跌']
for news in news_list:
    if not news:
        continue
    # 调用HanLP进行多任务分析
    result = nlp(news)
    # 1. 提取命名实体 (公司/组织名)
    entities = [(entity, type) for entity, type in zip(result['ner/msra/ontonote'][0], result['ner/msra/ontonote'][1])]
    # 注意:这里使用ner/msra/ontonote,输出格式为 (实体列表, 标签列表)
    # 2. 简单情感极性判断(基于词典)
    positive_score = sum(1 for word in positive_words if word in news)
    negative_score = sum(1 for word in negative_words if word in news)
    sentiment = "正面" if positive_score > negative_score else ("负面" if negative_score > positive_score else "中性")
    print(f"新闻: {news}")
    print(f"  识别实体: {entities}")
    print(f"  情感倾向: {sentiment} (正面词:{positive_score}, 负面词:{negative_score})\n")

输出示例:

新闻: 受利好消息刺激,比亚迪股价大涨5%,新能源板块领涨。
  识别实体: [('比亚迪', 'ORGANIZATION'), ('新能源', 'FIELD')]  # 可能还有 '银行' 等,取决于模型
  情感倾向: 正面 (正面词:2, 负面词:0)
新闻: 某地产公司资金链断裂,面临退市风险,建议投资者谨慎。
  识别实体: []  # 如果模型未识别出 '地产公司' 则为空
  情感倾向: 负面 (正面词:0, 负面词:2)
新闻: 央行宣布降准释放流动性,银行板块表现强势。
  识别实体: [('央行', 'ORGANIZATION')]
  情感倾向: 正面 (正面词:1, 负面词:0)

关键点:

  • 使用 HanLP 的 COARSE_ELECTRA_SMALL_ZH 预训练模型,同时完成分词、词性标注和命名实体识别 (NER)。
  • 结合简单的词典规则进行情感计算,适用于快速原型,生产环境建议使用 HanLP 的 sentiment 管道模型。
  • 实体识别结果可以用于后续的舆情监测、知识图谱构建。

多任务联合推理(带自定义Pipeline)

场景: 需要同时进行依存句法分析和语义角色标注,以便从大量政府工作报告中提取“主语+动作+宾语”关系。

from hanlp import HanLP
from hanlp.utils.trie import Trie
from hanlp.components.pipeline import Pipeline
# 加载基础组件
tok = HanLP.load('COARSE_ELECTRA_SMALL_ZH')
dep = HanLP.load('CTB9_DEP_ELECTRA_LARGE')  # 依存句法模型
srl = HanLP.load('CTB9_CON_ELECTRA_SMALL')  # 语义角色标注模型(使用constituency parsing后转SRL)
# 建立自定义Pipeline (HanLP 2.1+ 支持)
pipeline = Pipeline()
pipeline.append(tok)
pipeline.append(dep)
pipeline.append(srl)
# 要分析的句子
sentence = "华为公司在深圳召开全球开发者大会。"
# 执行Pipeline
result = pipeline(sentence)
# 解析结果
print("分词结果:", result['tok/fine'])
# 依存分析输出: dependencies 是一个列表,每个元素是 (父节点索引, 关系标签)
# 这里简化展示:需要将HanLP的输出转成可视化的依赖三元组
# 实际依赖关系存储在 result['dep'],格式为 (heads, relations)
heads = result.get('dep/ctb9', {}).get('head', [])
relations = result.get('dep/ctb9', {}).get('relation', [])
tokens = result['tok/fine']
if heads and relations:
    print("\n依存关系 (父节点索引, 关系):")
    for i, (head, rel) in enumerate(zip(heads, relations)):
        if head != 0:  # 忽略根节点
            print(f"  '{tokens[i]}' <--({rel})-- '{tokens[head-1]}'")
        else:
            print(f"  '{tokens[i]}' (根节点)")
# 语义角色标注 (此处输出结构复杂,需要根据实际模型调整)
# 通常输出结果为 (谓词, 角色列表)
print("\n语义角色标注 (谓词: 角色-论元):")
# 以“召开”为例,理想输出类似: 召开(Agent: 华为公司, Theme: 开发者大会)
# 实际代码需解析 srl 的输出格式(通常在 result['srl'] 中)

输出示例(简化):

分词结果: ['华为公司', '在', '深圳', '召开', '全球', '开发者大会', '。']
依存关系 (父节点索引, 关系):
  '华为公司' <--(nsubj)-- '召开'
  '在' <--(prep)-- '召开'
  '深圳' <--(pobj)-- '在'
  '全球' <--(mod)-- '开发者大会'
  '开发者大会' <--(dobj)-- '召开'
  '。' <--(punct)-- '召开'
语义角色标注 (谓词: 角色-论元):
  召开: Agent(华为公司) Location(深圳) Theme(全球开发者大会)

关键点:

  • 通过 Pipeline 组合不同的专业模型(分词、依存、语义角色),实现复杂推理。
  • 依存句法分析可以提取主谓宾关系,用于信息抽取。
  • 语义角色标注能识别动作的施事者、受事者等,对问答系统、事件提取非常有用。

HanLP + LLM (大语言模型) 混合架构

场景: 使用 HanLP 作为前端结构解析器,将非结构化的长文本转化为结构化输入,喂给下游的 LLM(大型语言模型)进行总结、翻译或自然语言生成。

from hanlp import HanLP
import json
# 1. 使用 HanLP 进行文本结构化
nlp = HanLP.load('COARSE_ELECTRA_SMALL_ZH')
long_text = """
上海市浦东新区政府发布通知,自2024年1月1日起,对集成电路企业实施新的税收优惠政策。
该政策规定,符合条件的企业所得税税率将从25%降至15%。
张江高科技园区的多家初创公司有望受益,其中包括芯原股份和翱捷科技。
"""
# 执行分析
result = nlp(long_text)
# 2. 提取结构化信息
structured_data = {
    "location": [],
    "organization": [],
    "date": [],
    "content_keywords": []
}
for token, ner_tag in zip(result['tok/fine'], result['ner/msra/ontonote'][1]):
    if 'LOC' in ner_tag or 'GPE' in ner_tag:
        structured_data["location"].append(token)
    elif 'ORG' in ner_tag:
        structured_data["organization"].append(token)
    elif 'DATE' in ner_tag:
        structured_data["date"].append(token)
# 简单关键词提取 (取 TF-IDF 较高的词,这里简化为按长度过滤)
structured_data["content_keywords"] = [w for w in result['tok/fine'] if len(w) > 1 and w not in ['企业', '政策', '税率']]
# 3. 构建 Prompt 给 LLM (假设有一个 generate_with_llm 函数)
def call_llm(prompt):
    # 伪代码:调用 OpenAI GPT 或 本地 LLM
    # return openai.ChatCompletion.create(...)
    return f"(LLM 回复) 基于提供的结构化信息,我生成了一份摘要:{structured_data['content_keywords']}"
prompt = f"""
请根据以下从政府公告中提取的结构化信息,生成一段100字以内的摘要。
- 地点: {set(structured_data['location'])}
- 涉及组织: {set(structured_data['organization'])}
- 生效日期: {set(structured_data['date'])}
- 政策关键对象: {set(structured_data['content_keywords'])}
"""
llm_response = call_llm(prompt)
print("LLM 摘要输出:", llm_response)

输出示例:

关键点:

  • HanLP 负责将非结构化文本转化为结构化的实体、关键短语和标签。
  • LLM 负责基于这些结构化数据进行高层推理(翻译、对话)。
  • 这种方式可以大幅降低 LLM 的 Token 消耗(输入文本缩短),并提高对长文本和专有名词的准确率。

案例 核心技术 典型应用场景
情感分析 多任务模型 + 词典规则 金融舆情监控、电商评论分析
复杂句法分析 Pipeline + 依存/语义角色 司法文书信息抽取、学术文献结构化
混合 LLM 架构 实体识别 + 关键词 + LLM 长文档摘要、智能客服知识库构建

如果你有具体的案例需求(如医疗病历结构化、对话日志分析),可以进一步描述,我可以提供更针对性的代码示例。

抱歉,评论功能暂时关闭!