4. 分析师报告情绪摘要

任务说明

本案例针对某只股票,收集多家券商研究报告的摘要文本,使用基于金融词典的情感分析方法提取每份报告的评级倾向(正面/负面/中性),并汇总为综合情绪分数,输出各券商倾向及最终情绪判断。

实现方案

采用轻量级金融情感词典方法,无需外部大模型依赖。核心逻辑:对每份报告摘要进行分词,匹配金融正负面词典中的词汇,计算情感得分;根据得分映射为评级倾向;最后对所有报告得分做加权平均(按券商权重),得到综合情绪分数。

完整代码

import re
from collections import defaultdict

# ========== 金融情感词典(示例精简版) ==========
POS_WORDS = {
    '增长': 2, '提升': 1.5, '盈利': 2, '超预期': 2.5, '利好': 2,
    '买入': 2, '增持': 1.5, '推荐': 1.5, '优势': 1, '强劲': 2,
    '改善': 1.5, '突破': 2, '领先': 1.5, '看好': 2, '上调': 1.5
}
NEG_WORDS = {
    '下滑': -2, '亏损': -2.5, '低于预期': -2.5, '利空': -2,
    '卖出': -2, '减持': -1.5, '风险': -1.5, '劣势': -1,
    '疲软': -1.5, '恶化': -2, '下调': -1.5, '承压': -1.5,
    '担忧': -1.5, '谨慎': -1, '不确定': -1
}

# ========== 输入数据:券商报告摘要 ==========
# 格式: (券商名称, 权重, 报告摘要)
reports = [
    ("中信证券", 0.25,
     "公司Q3营收增长25%,净利润超预期,新业务突破明显,维持买入评级。"),
    ("国泰君安", 0.20,
     "行业竞争加剧带来一定风险,但公司成本改善显著,上调盈利预测,增持。"),
    ("华泰证券", 0.15,
     "产品销量下滑,毛利率承压,短期业绩低于预期,下调至中性。"),
    ("招商证券", 0.25,
     "技术领先优势明显,市场份额持续提升,强烈推荐买入。"),
    ("海通证券", 0.15,
     "海外业务不确定性增加,但整体盈利稳定,维持谨慎推荐。")
]

# ========== 情感分析核心函数 ==========
def analyze_sentiment(text):
    """返回 (情感得分, 匹配词列表)"""
    matched = []
    score = 0.0
    # 优先匹配双字及以上词汇
    for word, val in {**POS_WORDS, **NEG_WORDS}.items():
        if word in text:
            matched.append((word, val))
            score += val
    return score, matched

def rating_from_score(score):
    """根据得分映射评级倾向"""
    if score >= 1.5:
        return "正面"
    elif score <= -1.5:
        return "负面"
    else:
        return "中性"

# ========== 汇总计算 ==========
def summarize_sentiment(reports):
    results = []
    total_weight = sum(w for _, w, _ in reports)
    weighted_sum = 0.0

    for broker, weight, summary in reports:
        score, matched_words = analyze_sentiment(summary)
        rating = rating_from_score(score)
        # 归一化权重
        norm_weight = weight / total_weight
        weighted_sum += score * norm_weight
        results.append({
            'broker': broker,
            'score': score,
            'rating': rating,
            'matched': matched_words
        })

    # 综合情绪分数(加权平均)
    composite_score = weighted_sum
    if composite_score >= 1.0:
        composite_rating = "整体正面"
    elif composite_score <= -1.0:
        composite_rating = "整体负面"
    else:
        composite_rating = "整体中性"

    return results, composite_score, composite_rating

# ========== 执行与输出 ==========
if __name__ == "__main__":
    results, comp_score, comp_rating = summarize_sentiment(reports)

    print("=" * 50)
    print("各券商报告情绪分析结果")
    print("=" * 50)
    for r in results:
        matched_str = ", ".join([f"{w}({v:+.1f})" for w, v in r['matched']]) or "无匹配词"
        print(f"\n券商: {r['broker']}")
        print(f"  情感得分: {r['score']:+.2f}")
        print(f"  评级倾向: {r['rating']}")
        print(f"  匹配词: {matched_str}")

    print("\n" + "=" * 50)
    print("综合情绪汇总")
    print("=" * 50)
    print(f"综合情绪分数: {comp_score:+.2f}")
    print(f"综合评级倾向: {comp_rating}")

运行方式

将代码保存为 sentiment_summary.py,在Python 3.6+环境直接运行:

python sentiment_summary.py

验证方法

程序输出应包含5家券商的独立分析结果和最终汇总。判定通过的检查点:

  • 中信证券摘要含“增长”“超预期”“买入”等词,得分应为正且评级为“正面”;
  • 华泰证券摘要含“下滑”“承压”“低于预期”等词,得分应为负且评级为“负面”;
  • 综合情绪分数为各券商得分按权重(0.25/0.20/0.15/0.25/0.15)加权平均的结果,最终评级倾向应与加权分数一致。

可自行替换reports列表中的摘要文本或增删券商,验证词典匹配与加权逻辑的正确性。