《AI大模型趣味实战》第6集:基于大模型和RSS聚合打造个人新闻电台

《AI大模型趣味实战》第6集:基于大模型和RSS聚合打造个人新闻电台

摘要

本文将带您探索如何结合AI大模型和RSS聚合技术,打造一个功能丰富的个人新闻电台系统。我们将使用Python和PyQt5构建一个桌面应用程序,该应用可以从多个RSS源抓取新闻,使用大模型进行内容优化和标签生成,并通过语音播报功能将文字新闻转化为语音广播。本项目融合了爬虫、自然语言处理、数据库存储和语音合成等多种技术,是一个非常实用且有趣的AI应用实例。
完整代码仓 https://github.com/wyg5208/rss_news_boke
在这里插入图片描述

核心概念和知识点

1. 项目架构概述

我们的RSS新闻电台系统由以下几个核心模块组成:

  • RSS抓取模块:负责从各种新闻源获取最新内容
  • 内容提取模块:使用多种策略从HTML页面中提取新闻正文
  • 大模型优化模块:利用Ollama本地大模型精炼内容、去除广告
  • 标签生成模块:基于大模型分析新闻内容并生成分类标签
  • 数据存储模块:使用SQLite数据库保存新闻和标签信息
  • 语音播报模块:将新闻转化为语音进行播报
  • 定时任务模块:实现定时抓取和播报功能

2. 环境设置与依赖安装

首先,我们需要安装必要的依赖包:

# requirements.txt
beautifulsoup4==4.13.3
feedparser==6.0.10
requests==2.31.0
selenium==4.15.2
webdriver-manager==4.0.1
lxml==4.9.3
ollama==0.1.5
PyQt5==5.15.9
schedule==1.2.1
pyttsx3==2.90

安装依赖包:

pip install -r requirements.txt

此外,确保安装了Ollama并拉取GLM4模型:

# 安装Ollama (按官方文档步骤)
# 启动Ollama服务
ollama serve
# 拉取GLM4模型
ollama pull glm4:latest

3. 大模型正文优化实现

大模型在新闻内容处理中扮演着关键角色。传统的HTML解析往往无法准确区分正文与广告、导航等无关内容。通过大模型,我们实现了智能内容精炼:

def refine_content_with_llm(title, description, raw_content):"""使用大模型精炼新闻正文内容,去除广告和无关信息"""try:if not raw_content or len(raw_content) < 200:return raw_content# 如果原始内容过长,截取适当长度content_for_processing = raw_content[:8000] if len(raw_content) > 8000 else raw_content# 准备提示词prompt = f"""请帮我提取以下网页内容中的新闻正文,清除广告、导航栏、版权声明等非核心内容。标题: {title}
描述: {description}
原始内容:
{content_for_processing}请按以下规则处理:
1. 只保留与新闻主题相关的正文内容
2. 移除所有广告、推荐阅读、社交媒体链接等无关内容
3. 移除网站导航、页脚版权信息等
4. 保持原文的段落结构
5. 如果找不到明确的正文,返回最有可能的主要内容
6. 直接返回处理后的纯文本,不要添加额外说明处理后的正文:
"""# 调用大模型进行内容处理response = ollama.chat(model='glm4:latest', messages=[{'role': 'user','content': prompt}])refined_content = response['message']['content']# 如果结果不合理,回退到原始内容if not refined_content or len(refined_content) < 100 or len(refined_content) > len(raw_content) * 1.5:print(f"大模型内容提取结果不合理,回退到原始内容处理")return raw_contentreturn refined_contentexcept Exception as e:print(f"使用大模型精炼内容失败: {str(e)}")return raw_content  # 出错时回退到原始内容

4. 大模型标签生成

除了内容优化,我们还利用大模型进行智能标签生成,帮助用户更好地分类和筛选新闻:

def generate_tags(self, title, description, content):try:# 获取标签库中的所有标签library_tags = self.get_library_tags()# 构建提示,让模型识别已有标签并建议新标签prompt = f"""请分析以下新闻内容,从标签库中选择最多5个相关标签,并在需要时建议最多2个新标签。标题: {title}描述: {description}内容概要: {content[:500]}...标签库中的现有标签:{', '.join(library_tags)}请按以下JSON格式返回:{{"existing_tags": ["已有标签1", "已有标签2", ...],"new_tags": ["新标签1", "新标签2"]}}"""response = ollama.chat(model='glm4:latest', messages=[{'role': 'user','content': prompt}])result = response['message']['content']# 提取JSON内容(可能需要从markdown代码块中提取)json_match = re.search(r'```json\s*(.*?)\s*```', result, re.DOTALL)if json_match:result = json_match.group(1)else:# 尝试直接解析JSONjson_match = re.search(r'({.*})', result, re.DOTALL)if json_match:result = json_match.group(1)try:tags_data = json.loads(result)# 处理现有标签existing_tags = tags_data.get("existing_tags", [])# 处理新标签并添加到标签库new_tags = tags_data.get("new_tags", [])for tag in new_tags:self.add_to_library(tag)# 合并所有标签all_tags = existing_tags + new_tags# 更新标签使用频率self.update_tag_frequency(all_tags)return all_tagsexcept json.JSONDecodeError:# 回退到基于关键词的标签生成return self.match_tags_from_library(title + " " + description)except Exception as e:print(f"生成标签失败: {str(e)}")# 回退到简单的标签匹配return self.match_tags_from_library(title + " " + description)

5. 语音播报功能

将文字转化为语音是本项目的核心功能之一,使用pyttsx3库实现:

class NewsBroadcaster:def __init__(self):"""初始化语音引擎"""self.engine = pyttsx3.init()# 设置默认语速和音量self.engine.setProperty('rate', 150)  # 语速self.engine.setProperty('volume', 0.8)  # 音量# 尝试设置中文语音voices = self.engine.getProperty('voices')for voice in voices:if "chinese" in voice.id.lower() or "zh" in voice.id.lower():self.engine.setProperty('voice', voice.id)breakdef broadcast(self, text):"""播报文本内容"""self.engine.say(text)self.engine.runAndWait()def broadcast_news(self, news_items):"""播报新闻列表"""if not news_items:self.broadcast("没有找到可播报的新闻")returnself.broadcast("开始播报今日新闻")time.sleep(1)for i, news in enumerate(news_items):# 播报标题self.broadcast(f"第{i+1}条新闻")self.broadcast(f"标题: {news['title']}")# 播报来源self.broadcast(f"来源: {news['source']}")# 播报摘要if news['description']:self.broadcast("新闻摘要:")self.broadcast(news['description'])# 间隔time.sleep(1)self.broadcast("新闻播报完毕")

6. 定时任务管理

通过schedule库实现定时抓取和播报功能:

class ScheduleManager:_instance = None_running = False_thread = None_fetch_tasks = {}  # 存储抓取任务_broadcast_tasks = {}  # 存储播报任务@classmethoddef get_instance(cls):if cls._instance is None:cls._instance = ScheduleManager()return cls._instancedef start(self):"""启动定时任务线程"""if not self._running:self._running = Trueself._thread = threading.Thread(target=self._run_scheduler, daemon=True)self._thread.start()def _run_scheduler(self):"""运行定时器"""while self._running:schedule.run_pending()time.sleep(1)# 添加月度任务示例def add_broadcast_task(self, task_id, schedule_type, value, time_value, app_instance, count=5):"""添加新闻播报定时任务"""# 先删除同ID的旧任务self.remove_broadcast_task(task_id)# 创建新任务job = Noneif schedule_type == "每天":job = schedule.every().day.at(time_value).do(app_instance.start_news_broadcast, count)elif schedule_type == "每周":days = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]day_attr = getattr(schedule.every(), days[value-1])job = day_attr.at(time_value).do(app_instance.start_news_broadcast, count)elif schedule_type == "每月":# 智能月度任务实现 - 使用每日检查日期方法def monthly_broadcast_job():# 仅在每月特定日期运行if datetime.now().day == value:app_instance.start_news_broadcast(count)job = schedule.every().day.at(time_value).do(monthly_broadcast_job)if job:self._broadcast_tasks[task_id] = jobreturn Truereturn False

疑难点和技术突破

1. 多层内容提取策略

一个主要的挑战是如何从各类网站中提取有效的新闻内容。我们采用了多层内容提取策略,结合传统爬虫和大模型:

def extract_content(url, use_selenium=False):# 第一层:尝试使用Selenium提取(处理动态内容)if use_selenium:try:return RSSParser.extract_with_selenium(url)except Exception as e:print(f"Selenium提取失败: {url}, 错误: {str(e)}")# 回退到普通提取# 第二层:使用requests+BeautifulSoup提取try:# 添加用户代理头,模拟Chrome浏览器headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...',# 其他请求头...}response = requests.get(url, headers=headers, timeout=15)response.raise_for_status()# 检测并处理页面编码if response.encoding == 'ISO-8859-1':response.encoding = response.apparent_encodingsoup = BeautifulSoup(response.text, 'html.parser')# 移除脚本、样式和其他非内容元素for element in soup(['script', 'style', 'nav', 'header', 'footer', 'aside', 'form', 'iframe']):element.extract()# 多种策略提取内容content = ""# 策略1: 尝试找到常见的文章容器article_containers = soup.find_all(['article', 'main', 'div'], class_=lambda x: x and any(term in str(x).lower() for term in ['article', 'content', 'post', 'entry', 'main', 'text', 'body']))if article_containers:# 使用最大的容器largest_container = max(article_containers, key=lambda x: len(str(x)))content = largest_container.get_text(separator='\n', strip=True)# 策略2: 尝试找长段落if not content or len(content) < 200:paragraphs = soup.find_all('p')# 筛选长段落 (可能是正文)long_paragraphs = [p.get_text(strip=True) for p in paragraphs if len(p.get_text(strip=True)) > 60]if long_paragraphs:content = '\n\n'.join(long_paragraphs)# 第三层:如上述方法都失败,则在主函数中会尝试使用大模型优化return contentexcept Exception as e:print(f"提取内容失败: {url}, 错误: {str(e)}")# 如果普通提取失败但还没尝试过Selenium,则尝试Seleniumif not use_selenium:try:return RSSParser.extract_with_selenium(url)except Exception as selenium_error:print(f"Selenium备选提取也失败: {url}, 错误: {str(selenium_error)}")return f"内容提取失败: {str(e)}"

2. WebDriver资源管理

在使用Selenium时,一个常见问题是浏览器资源未正确释放。我们通过单例模式解决这一问题:

class WebDriverManager:_instance = None_driver = None@classmethoddef get_instance(cls):if cls._instance is None:cls._instance = WebDriverManager()return cls._instancedef get_driver(self):"""获取或创建WebDriver实例"""if self._driver is None:try:service = Service(ChromeDriverManager().install())options = webdriver.ChromeOptions()options.add_argument("--headless")  # 无头模式options.add_argument("--disable-gpu")options.add_argument("--disable-extensions")options.add_argument("--disable-dev-shm-usage")options.add_argument("--no-sandbox")self._driver = webdriver.Chrome(service=service, options=options)print("已初始化WebDriver")except Exception as e:print(f"初始化WebDriver失败: {e}")raisereturn self._driverdef close_driver(self):"""关闭WebDriver释放资源"""if self._driver:try:self._driver.quit()except Exception as e:print(f"关闭WebDriver出错: {e}")finally:self._driver = Noneprint("已释放WebDriver资源")

3. 智能月度任务实现

在实现月度定时任务时,我们采用了一种创新的方法,通过每日检查当前日期来执行月度任务:

# 月度任务实现
def monthly_job():# 仅在每月特定日期运行if datetime.now().day == value:app_instance.start_fetch_scheduled()
job = schedule.every().day.at(time_value).do(monthly_job)

4. 链接去重机制

为了避免重复处理相同的新闻,我们实现了高效的链接去重机制:

def link_exists(self, link):"""检查链接是否已存在于数据库中"""conn = sqlite3.connect(self.db_path)cursor = conn.cursor()try:cursor.execute("SELECT id FROM news WHERE link = ?", (link,))result = cursor.fetchone()return result is not Noneexcept Exception as e:print(f"检查链接存在性失败: {e}")return Falsefinally:conn.close()# 在抓取线程中使用
if self.db.link_exists(link):self.update_signal.emit(f"已跳过(数据库中已存在): {title}")continue

完整代码实战

下面通过一个完整的流程示例,展示如何从RSS源抓取新闻、优化内容、生成标签并播报:

def run(self):total = len(self.rss_urls)total_processed = 0total_new = 0for i, url in enumerate(self.rss_urls):try:self.update_signal.emit(f"正在处理 ({i+1}/{total}): {url}")feed = self.parser.get_feed(url)if not feed:continuesource = feed.feed.title if hasattr(feed.feed, 'title') else urlprocessed = 0new_added = 0for entry in feed.entries[:100]:  # 每个源最多处理100条新闻title = entry.title if hasattr(entry, 'title') else "无标题"link = entry.link if hasattr(entry, 'link') else ""description = entry.description if hasattr(entry, 'description') else ""pub_date = entry.published if hasattr(entry, 'published') else ""if not link:continueprocessed += 1total_processed += 1# 检查链接是否已存在于数据库中if self.db.link_exists(link):self.update_signal.emit(f"已跳过(数据库中已存在): {title}")continueself.update_signal.emit(f"正在提取: {title}")# 提取正文内容,根据选项使用Seleniumraw_content = self.parser.extract_content(link, self.use_selenium)# 根据选项使用大模型精炼内容content = raw_contentif self.use_llm:self.update_signal.emit(f"正在使用大模型优化正文: {title}")content = self.parser.refine_content_with_llm(title, description, raw_content)# 生成标签self.update_signal.emit(f"正在生成标签: {title}")tags = self.tag_generator.generate_tags(title, description, content)# 保存到数据库if self.db.add_news(title, link, description, content, source, pub_date, tags):new_added += 1total_new += 1time.sleep(1)  # 避免过快请求self.update_signal.emit(f"完成 {url}: 处理 {processed} 条新闻,新增 {new_added} 条")self.news_added_signal.emit(processed, new_added)except Exception as e:self.update_signal.emit(f"处理RSS出错: {url}, 错误: {e}")self.update_signal.emit(f"抓取完成: 共处理 {total_processed} 条新闻,新增 {total_new} 条")self.finished_signal.emit()

播报新闻实例:

def start_news_broadcast(self, count=5):"""开始新闻播报"""self.log_message(f"开始新闻播报,播报{count}条最新新闻")# 获取最新的新闻news_list = self.db.get_latest_news(count)if not news_list:self.log_message("没有找到可播报的新闻")return# 使用单独线程进行播报,避免UI卡顿broadcast_thread = threading.Thread(target=self.broadcaster.broadcast_news,args=(news_list,),daemon=True)broadcast_thread.start()# 记录播报内容for i, news in enumerate(news_list):self.log_message(f"播报第{i+1}条: {news['title']} - {news['source']}")

运行效果

*图1: RSS新配置界面 *
在这里插入图片描述

*图2: 标签管理界面 *
在这里插入图片描述
*图3: 标签过滤管理界面 *
在这里插入图片描述
*图4: 定时播报管理界面 *
在这里插入图片描述

需要完整代码请私信

总结与扩展思考

项目总结

本项目成功实现了一个融合AI大模型的RSS新闻聚合与播报系统,具有以下特点:

  1. 多层内容提取:结合传统爬虫和大模型,提高内容提取的准确性
  2. 智能内容优化:使用大模型去除广告和无关内容,提升阅读体验
  3. 自动标签生成:利用大模型理解新闻内容,自动生成相关标签
  4. 语音播报功能:将文字转化为语音,打造个人专属新闻电台
  5. 定时任务管理:实现定时抓取和播报,保持内容更新
  6. 高效资源管理:采用单例模式管理浏览器资源,确保资源正确释放
  7. 多线程设计:避免UI卡顿,提升用户体验

扩展思考

本项目还有许多可扩展的方向:

  1. 个性化推荐:基于用户阅读历史,使用大模型推荐相关新闻
  2. 情感分析功能:使用大模型分析新闻情感倾向,提供情绪过滤功能
  3. 多语言支持:增加多语言翻译功能,使用大模型进行实时翻译
  4. 语音交互:添加语音命令功能,实现与系统的对话式交互
  5. 新闻摘要生成:使用大模型自动生成新闻摘要,便于快速浏览
  6. 跨平台支持:将应用移植到移动端或Web端,实现多设备访问
  7. 订阅源推荐:基于用户兴趣,使用大模型推荐相关RSS源

在AI时代,将大模型与传统应用结合,能极大提升软件的智能化水平和用户体验。本项目展示了如何在实际应用中使用本地大模型,避免了隐私问题和API调用成本,同时保持了强大的AI能力。希望这个实战案例能够启发更多开发者探索AI应用的无限可能。


通过本文的实战指南,您可以构建自己的AI新闻电台,享受个性化、高质量的新闻阅读和收听体验。结合大模型的内容优化和语音播报功能,让新闻消费变得更加智能和便捷。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38294.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(学习总结29)Linux 进程概念和进程状态

Linux 进程概念 冯诺依曼体系结构软件运行与存储分级数据流动的理论过程 操作系统操作系统(Operator System) 概念操作系统的功能与作用系统调用和库函数概念 进程概念描述进程 - PCBtask_struct查看进程通过系统调用获取进程标示符 PID通过系统调用 fork 函数创建进程简单使用…

LLM - CentOS上离线部署Ollama+Qwen2.5-coder模型完全指南

文章目录 离线安装OllamaOllama下载Ollama硬件需求Ollama 常用命令参考Ollama安装Ollama 服务管理&开机启动开启局域网访问 Ollama 服务 离线安装模型gguf 文件格式下载Qwen2.5-Coder-7B-Instruct-GGUF格式选择 ( gguf 版本 )构建Modelfile文件加载并运行离线模型测试 集成…

Linux——信号

目录 Linux——信号1.信号的基础了解2.技术应用角度的信号3.产生信号3.1按键组合3.2系统调用产生信号3.2.1 kill()3.2.2 raise()3.2.3 abort() 3.3**.** 软件条件产生信号3.4硬件异常产生信号3.4.1 /0异常3.4.2 内存越界异常 4.理解信号的存在5.总结一下6.核心转储7.全部信号都…

向量叉积的应用——正反画画

1 解题思路 解题思路涉及的向量积相关知识 c实现 #include<iostream> #include<vector>using namespace std;struct TrianglePoint {int x;int y; };int momentForce(TrianglePoint A, TrianglePoint B, TrianglePoint C) {//AB向量&#xff1a;(B.x-A.x, B.y-A.…

构建自定义MCP天气服务器:集成Claude for Desktop与实时天气数据

构建自定义MCP天气服务器:集成Claude for Desktop与实时天气数据 概述 本文将指导开发者构建一个MCP(Model Control Protocol)天气服务器,通过暴露get-alerts和get-forecast工具,为Claude for Desktop等客户端提供实时天气数据支持。该方案解决了传统LLM无法直接获取天气…

Web安全策略CSP详解与实践

引言 &#xff1a;在黑客攻击频发的今天&#xff0c;你的网站是否像“裸奔”一样毫无防护&#xff1f;跨站脚本&#xff08;XSS&#xff09;、数据注入等攻击随时可能让用户数据泄露。今天我们将揭秘一个网站的隐形保镖——内容安全策略&#xff08;CSP&#xff09;&#xff0c…

HC-05与HC-06蓝牙配对零基础教程 以及openmv识别及远程传输项目的概述

这个是上一年的项目&#xff0c;之前弄得不怎么完整&#xff0c;只有一个openmv的&#xff0c;所以openmv自己去我主页找&#xff0c;这篇主要讲蓝牙 这个是我在使用openmv连接单片机1然后单片机1与单片机2通过蓝牙进行通信 最终实现的效果是&#xff1a;openmv识别到图形和数…

点云分割方法

点云分割 通过判断三维距离&#xff0c;实现对创建3团点云的分割 通过判断三维距离&#xff0c;实现对创建3团点云的分割 * 点云1 gen_object_model_3d_from_points (rand(100), rand(100),rand(100), Points1)* 点云2 gen_object_model_3d_from_points (rand(100), 2rand(100…

SpringBoot3使用CompletableFuture时java.util.ConcurrentModificationException异常解决方案

问题描述 在Spring Boot 3项目中&#xff0c;使用CompletableFuture进行异步编程时&#xff0c;偶发{"code":500,"msg":"java.util.ConcurrentModificationException"}异常&#xff0c;但代码中并未直接操作List或CopyOnWriteArrayList等集合类…

细说卫星导航:测距定位原理

测距定位原理 1. 伪距测量技术 核心原理&#xff1a;卫星发射信号&#xff0c;用户接收并记录传播时间&#xff0c;乘以光速得到距离&#xff08;伪距&#xff09;。 技术细节&#xff1a; 信号传播路径分析 信号结构&#xff1a; 卫星信号包含三部分&#xff1a; 载波&…

Linux系统管理与编程09:任务驱动综合应用

兰生幽谷&#xff0c;不为莫服而不芳&#xff1b; 君子行义&#xff0c;不为莫知而止休。 [环境] windows11、centos9.9.2207、zabbix6、MobaXterm、Internet环境 [要求] zabbix6.0安装环境&#xff1a;Lamp&#xff08;linux httpd mysql8.0 php&#xff09; [步骤] 5 …

RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”与“陷阱”

嘿&#xff0c;亲爱的算法工程师们&#xff01;今天咱们聊一聊PDF解析的那些事儿&#xff0c;简直就像是在玩一场“信息捉迷藏”游戏&#xff01;PDF文档就像是个调皮的小精灵&#xff0c;表面上看起来规规矩矩&#xff0c;但当你想要从它那里提取信息时&#xff0c;它就开始跟…

RK3568 I2C底层驱动详解

前提须知&#xff1a;I2C协议不懂的话就去看之前的内容吧&#xff0c;这个文章需要读者一定的基础。 RK3568 I2C 简介 RK3568 支持 6 个独立 I2C: I2C0、I2C1、I2C2、I2C3、I2C4、I2C5。I2C 控制器支持以下特性: ① 兼容 i2c 总线 ② AMBA APB 从接口 ③ 支持 I2C 总线主模式…

UNIX网络编程笔记:基本TCP套接字编程

一、socket函数 一、socket函数核心参数与协议组合 函数原型与基本功能 #include <sys/socket.h> int socket(int family, int type, int protocol);• 功能&#xff1a;创建通信端点&#xff08;套接字&#xff09;&#xff0c;返回描述符供后续操作。 • 返回值&#…

JSON在AutoCAD二次开发中应用场景及具体案例

配置文件的读取 在AutoCAD插件开发中&#xff0c;可能需要生成、修改、读取配置文件中一些参数或设置。JSON格式的配置文件易于编写和修改&#xff0c;且可以方便地反序列化为对象进行使用。 运行后效果如下 using Autodesk.AutoCAD.ApplicationServices; using Autodesk.Au…

自由学习记录(46)

CG语法的数据类型 // uint : 无符号整数&#xff08;32位&#xff09; // int : 有符号整数&#xff08;32位&#xff09; // float : 单精度浮点数&#xff08;32位&#xff09;&#xff0c;通常带后缀 f&#xff08;如 1.0f&#xff09; // half : 半精度浮…

解决Selenium滑动页面到指定元素,点击失效的问题

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:君失臣兮龙为鱼&#xff0c;权归臣兮鼠变虎&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…

Vue基础

目录 -Vue基础- 1、插值表达式 {{}} 2、Vue核心特性&#xff1a;响应式 3、开发者工具Vue Devtools(极简插件下载) 4、Vue指令 v-text v-html v-bind v-on v-if v-show v-for v-model 5、Vue指令修饰符 .stop .prevent .capture .self .once .enter、.tab、…

收数据花式画图plt实战

目录 Python plt想把纵坐标化成对数形式代码 子图ax. 我又有ax scatter&#xff0c;又有ax plot&#xff0c;都要去对数 数字接近0&#xff0c;取对数没有定义&#xff0c;怎么办 创建数据 添加一个小的常数以避免对数未定义的问题 创建一个figure和一个子图ax 在子图a…

二项式分布(Binomial Distribution)

二项式分布&#xff08;Binomial Distribution&#xff09; 定义 让我们来看看玩板球这个例子。假设你今天赢了一场比赛&#xff0c;这表示一个成功的事件。你再比了一场&#xff0c;但你输了。如果你今天赢了一场比赛&#xff0c;但这并不表示你明天肯定会赢。我们来分配一个…