> 作者: frank13522

> 项目: SenseFlow - GitHub

> 标签: Python, Streamlit, 新闻分析, NLP, 情感分析, 开源


前言:为什么我要做这个工具?

每天早上打开手机,各种新闻 APP 铺天盖地 — 财经、科技、国际、社会... 信息爆炸的时代,我们缺的不是信息,而是从噪音中提取信号的能力

于是我用 Python 撸了一个工具:SenseFlow — 多模态新闻智能聚合与深度分析系统

核心特点:

  • 纯本地运行 — 无需下载任何深度学习模型(0 MB)

  • 零配置启动 — pip install 后直接运行

  • 双语支持 — 中英文新闻都能分析

  • 精美界面 — Streamlit Dashboard,毛玻璃卡片 + 渐变色

GitHub 开源地址: https://github.com/frank13522/SenseFlow


一、项目功能概览

SenseFlow 能帮你做什么?

功能模块

技术实现

说明

🔍 新闻聚合

RSS 解析 + 并发抓取

支持中英文、多源、自动去重

🧠 话题聚类

TF-IDF + 层次聚类

自动发现热点话题(无需 Embedding 模型)

😊 情感分析

双语词典引擎(>1600 词)

中文 + 英文,6 级强度评分

📊 可视化分析

Plotly 图表

情感分布、话题柱状图、趋势折线图

📋 智能报告

规则生成

自动输出每日简报

亮点:不依赖任何深度学习框架(No PyTorch! No TensorFlow!),纯 Python 标准库 + sklearn 搞定。


二、技术架构详解

2.1 新闻聚合模块(src/news_fetcher.py)

使用 feedparser 并发抓取多个 RSS 源:

import feedparser
import requests
from concurrent.futures import ThreadPoolExecutor

def fetch_feed(url, timeout=10):
    """抓取单个 RSS 源"""
    headers = {"User-Agent": "Mozilla/5.0 ..."}
    resp = requests.get(url, timeout=timeout, headers=headers)
    feed = feedparser.parse(resp.content)
    return [{
        "title": entry.get("title", ""),
        "summary": entry.get("summary", ""),
        "link": entry.get("link", ""),
        "source": feed.feed.get("title", url),
    } for entry in feed.entries]

支持的新闻源(可在 config.py 中配置):

  • 中文科技:36氪、少数派等

  • 中文综合:新闻博客聚合

  • 英文 AI:TechCrunch、BBC Technology

  • 英文综合:NYT Technology


2.2 文本聚类模块(src/text_processor.py)

核心技术:TF-IDF + 层次聚类

为什么不用 Sentence-Transformers?

  • ❌ 需要下载 ~500MB 模型

  • ❌ 国内网络经常超时

  • ❌ 依赖 PyTorch(~200MB+)

我们的方案:TF-IDF + 结巴分词 + 余弦相似度

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import AgglomerativeClustering

class TextProcessor:
    def __init__(self):
        self.vectorizer = TfidfVectorizer(
            tokenizer=jieba_tokenizer,  # 结巴分词
            max_features=3000,
            ngram_range=(1, 2),       # 1-gram + 2-gram
            min_df=2,                  # 最少出现 2 次
            max_df=0.85,               # 最多 85% 文档出现
        )

    def cluster_articles(self, articles):
        """层次聚类"""
        texts = [a["title"] + ". " + a["summary"] for a in articles]
        embeddings = self.vectorizer.fit_transform(texts).toarray()

        clustering = AgglomerativeClustering(
            n_clusters=auto,           # 自动确定聚类数
            metric="cosine",           # 余弦距离
            linkage="complete",
        )
        labels = clustering.fit_predict(embeddings)
        return group_by_labels(labels, articles)

效果:100 篇新闻 → 自动分成 5-10 个话题(AI、市场、国际...)


2.3 情感分析模块(src/sentiment_analyzer.py)

核心技术:双语词典引擎(纯规则,无模型)

词典结构(>1600 词):

POSITIVE_LEVEL1 = ["突破", "领先", "首创", "涨停", "暴涨", ...]  # 强正面 (权重 3.0)
POSITIVE_LEVEL2 = ["增长", "提升", "改善", "利好", ...]          # 中正面 (权重 2.0)
POSITIVE_LEVEL3 = ["向好", "积极", "乐观", ...]                  # 弱正面 (权重 1.0)
# 负面同理,分为 3 级
NEGATORS = {"不", "没", "无", "非", ...}                       # 否定词
INTENSIFIERS = {"非常": 1.5, "极其": 1.8, "十分": 1.5, ...}   # 程度词

评分算法:

def _lexicon_score(self, text):
    score = 0.0
    words = jieba.lcut(text)
    for i, w in enumerate(words):
        weight = 1.0
        # 检查前面是否有程度词
        if i > 0 and words[i-1] in INTENSIFIERS:
            weight = INTENSIFIERS[words[i-1]]
        # 检查前面是否有否定词
        if i > 0 and words[i-1] in NEGATORS:
            weight *= -1
        # 累加权重
        if w in positive_words:
            score += positive_word_weights[w] * weight
        elif w in negative_words:
            score -= negative_word_weights[w] * weight
    return score  # range: [-3, 3]

中英文自动切换:

def _has_chinese(self, text):
    return any('\u4e00' <= c <= '\u9fff' for c in text)

def analyze(self, text):
    if self._has_chinese(text):
        return self._analyze_chinese(text)
    else:
        return self._analyze_english(text)  # 英文词典(~500 词)

效果:

  • 中文:"公司业绩超预期,股价涨停" → positive (0.92)

  • 英文:"Market crashes, stocks plummet" → negative (0.88)


2.4 Streamlit Dashboard(app.py)

精美 UI 设计:

  • 渐变背景 + 毛玻璃卡片

  • 5 个指标卡(文章数、正面、负面、中性、话题数)

  • 4 个 Plotly 图表(2x2 网格)

  • 侧边栏:分析按钮 + Demo 按钮 + 参数调节

核心代码:

import streamlit as st
import plotly.express as px

st.set_page_config(page_title="SenseFlow", layout="wide")

# 指标卡
col1, col2, col3, col4, col5 = st.columns(5)
col1.metric("📄 文章总数", len(articles))
col2.metric("😊 正面", pos_count, delta=pos_pct)
col3.metric("😐 中性", neu_count)
col4.metric("😡 负面", neg_count, delta=-neg_pct)
col5.metric("🔥 话题数", len(topics))

# 图表
fig1 = px.pie(values=sentiment_counts, names=["正面", "中性", "负面"])
fig2 = px.bar(x=topic_names, y=topic_counts)
st.plotly_chart(fig1)
st.plotly_chart(fig2)

三、快速开始(3 步搞定)

步骤 1:克隆仓库

git clone https://github.com/frank13522/SenseFlow.git
cd SenseFlow

步骤 2:安装依赖

pip install -r requirements.txt

依赖清单(精简):

streamlit>=1.28.0     # Web UI
plotly>=5.15.0         # 图表
pandas>=2.0.0          # 数据处理
scikit-learn>=1.3.0    # 聚类算法
feedparser>=6.0.10      # RSS 解析
jieba>=0.42.1          # 中文分词
numpy>=1.24.0,<2.0     # 数值计算

总大小:~200 MB(主要是 sklearn + pandas)


步骤 3:运行分析

streamlit run app.py --server.port 8080

浏览器自动打开 http://localhost:8080

界面操作:

  1. 侧边栏点击 "🚀 开始分析"

  2. 等待 10-30 秒(抓取 RSS)

  3. 查看 Dashboard:

    1. 指标卡

    2. 情感分布饼图

    3. 话题柱状图

    4. 文章详情


四、实战演示

Demo 1:分析中文科技新闻

输入:36氪 RSS(最新 20 篇)

输出

📊 分析结果
━━━━━━━━━━━━━━━━━━━━━━
📄 文章总数: 20
😊 正面: 8 篇 (40%)
😐 中性: 10 篇 (50%)
😡 负面: 2 篇 (10%)

🔥 热点话题
  1. AI 大模型 (5 篇)
  2. 芯片半导体 (4 篇)
  3. 新能源 (3 篇)
  4. 企业融资 (3 篇)
  5. 其他 (5 篇)

Demo 2:情感趋势检测

功能:检测最近 7 天的新闻情感变化

算法

daily_sentiment = [mean(scores) for each_day]
baseline = mean(daily_sentiment)
std = std(daily_sentiment)
for day in timeline:
    z = abs(score - baseline) / std
    if z > 1.5:  # 超过 1.5 倍标准差
        alert(f"⚠️ 情感突变: {day.date}")

应用:发现某天突然大量负面新闻 → 可能有重大事件(如财报暴雷、政策突变)


五、项目结构

SenseFlow/
├── app.py                      # Streamlit 主界面
├── config.py                   # 配置文件(新闻源、模型参数)
├── requirements.txt            # Python 依赖
├── README.md                  # 项目说明
├── LICENSE                    # MIT 开源协议
└── src/
    ├── __init__.py            # 模块初始化
    ├── news_fetcher.py        # 新闻获取(RSS + 并发)
    ├── text_processor.py      # 文本聚类(TF-IDF + 层次聚类)
    ├── sentiment_analyzer.py  # 情感分析(双语词典引擎)
    └── report_generator.py    # 智能报告生成

核心代码量:~500 行 Python(不含注释)


六、与其他项目的对比

项目

模型依赖

启动难度

分析精度

适用场景

SenseFlow(本项目)

❌ 无

⭐ 极简

⭐⭐⭐ 良好

快速原型、本地部署

项目 A(基于 BERT)

✅ 需要

⭐⭐⭐ 复杂

⭐⭐⭐⭐ 优秀

研究、高精度需求

项目 B(基于 LLM)

✅ API

⭐⭐ 中等

⭐⭐⭐⭐⭐ 卓越

有钱任性

结论:SenseFlow 适合想快速搭建原型、或者在不方便下载大模型的环境下使用。


七、后续扩展方向

  • [ ] 接入 NewsAPI(获取更全数据)

  • [ ] 添加知识图谱可视化

  • [ ] 实时推送(Telegram / 微信)

  • [ ] 使用 LLM 生成新闻摘要(可选)

  • [ ] 历史趋势回测

欢迎 PR! 有任何想法欢迎在 GitHub Issues 讨论。


八、总结

  • 纯本地 — 无需下载 500MB+ 模型

  • 零配置 — pip install 后直接运行

  • 双语支持 — 中英文新闻都能分析

  • 开源免费 — MIT 协议,可自由修改

GitHub 星星⭐: https://github.com/frank13522/SenseFlow

如果觉得有用,欢迎 Star + Fork!有问题尽管提 Issue~ 😊


附录:常见问题 FAQ

Q1: 为什么不用深度学习模型?

A: 两个原因:

  1. 网络问题 — 国内下载 HuggingFace 模型经常超时

  2. 依赖问题 — PyTorch 太大(~200MB+),安装慢

Q2: 词典情感分析的精度如何?

A: 在新闻领域,词典法能达到 75-85% 准确率(BERT 是 ~90%)。对于大多数应用场景已经够用。

Q3: 能分析英文新闻吗?

A: 可以!我们内置了 ~500 个英文情感词(positive/negative/degree/negation)。

Q4: 如何添加自定义新闻源?

A: 编辑 config.py:


RSS_SOURCES = {
    "我的分类": [
        "https://your-feed-url.com/rss",
    ],
}


参考文献

  1. TF-IDF 算法原理 — https://en.wikipedia.org/wiki/Tf%E2%80%93idf

  2. 层次聚类算法 — https://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering

  3. 中文情感词典构建 — 参考《情感分析》书籍


版权声明

本文为博主原创文章,转载请注明出处。

项目地址: https://github.com/frank13522/SenseFlow


补充:关联网页访问异常说明

本次文档中涉及的外部链接,存在以下访问失败情况,本地运行项目时可直接忽略链接访问,不影响代码本身运行:

  1. 自定义RSS测试链接:https://your-feed-url.com/rss,解析失败,提示:网页解析失败,可能是不支持的网页类型,请检查网页或稍后重试

  2. TF-IDF维基百科外文链接:https://en.wikipedia.org/wiki/Tf%E2%80%93idf,访问失败,提示:这是一个境外网页,当前无法访问,请尝试其他网页

  3. scikit-learn官方聚类文档链接:网页内容字数超限,无法完整抓取详情,可直接查阅本地sklearn官方文档

  4. 项目GitHub主页及Git克隆地址:网页内容字数超限,无法完整抓取仓库详情,可直接使用文中给出的克隆命令拉取源码

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐