人工智能数学基础实验(四):最大似然估计的-AI 模型训练与参数优化

一、实验目的

  1. 理解最大似然估计(MLE)原理:掌握通过最大化数据出现概率估计模型参数的核心思想。
  2. 实现 MLE 与 AI 模型结合:使用 MLE 手动估计朴素贝叶斯模型参数,并与 Scikit-learn 内置模型对比,深入理解参数优化对分类性能的影响。
  3. 分析模型性能影响因素:探究训练集 / 测试集比例、特征数量对模型准确率、运行时间的影响,提升数据建模与调优能力。

二、实验要求

(一)数据准备

  • 生成或加载二分类数据集,使用 Scikit-learn 的make_classification创建含 20 维特征的 1000 样本数据。
  • 划分训练集与测试集,初始比例为 7:3。

(二)MLE 参数估计

  • 假设特征服从高斯分布,手动计算各分类的均值、方差及先验概率。
  • 推导后验概率公式,实现基于 MLE 的朴素贝叶斯分类器。

(三)模型构建与对比

  • 手动实现:基于 MLE 参数的朴素贝叶斯分类器,对新样本进行分类预测。
  • Scikit-learn 对比:使用GaussianNB内置模型,比较两者的准确率、精确率、召回率及运行时间。

(四)性能分析

  • 调整测试集比例(0.2~0.5),观察模型稳定性。
  • 改变特征数量(10~50),分析特征维度对模型性能的影响。

三、实验原理

四、实验步骤

(一)数据生成与预处理

import numpy as np  
from sklearn.datasets import make_classification  
# 生成二分类数据集  
X, y = make_classification(  n_samples=1000, n_features=20, n_classes=2, random_state=42  
)  
# 划分训练集与测试集(初始比例7:3)  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)  

(二)手动实现 MLE 与朴素贝叶斯

class ManualNaiveBayes:  def fit(self, X, y):  self.classes = np.unique(y)  self.params = {}  for c in self.classes:  X_c = X[y == c]  self.params[c] = {  'mean': np.mean(X_c, axis=0),  # 均值  'var': np.var(X_c, axis=0),    # 方差  'prior': len(X_c) / len(X)     # 先验概率  }  def predict(self, X):  posteriors = []  for c in self.classes:  prior = np.log(self.params[c]['prior'])  mean = self.params[c]['mean']  var = self.params[c]['var']  # 计算对数似然  likelihood = -0.5 * np.sum(np.log(2 * np.pi * var)) - 0.5 * np.sum(((X - mean)**2)/var, axis=1)  posterior = prior + likelihood  posteriors.append(posterior)  return self.classes[np.argmax(posteriors, axis=0)]  # 选择后验概率最大的类别  

(三)模型训练与对比

from sklearn.naive_bayes import GaussianNB  
from sklearn.metrics import accuracy_score  # 手动模型训练与预测  
manual_nb = ManualNaiveBayes()  
manual_nb.fit(X_train, y_train)  
y_pred_manual = manual_nb.predict(X_test)  # Scikit-learn模型训练与预测  
sklearn_nb = GaussianNB()  
sklearn_nb.fit(X_train, y_train)  
y_pred_sklearn = sklearn_nb.predict(X_test)  # 性能指标计算  
print(f"手动实现准确率:{accuracy_score(y_test, y_pred_manual):.4f}")  
print(f"Sklearn实现准确率:{accuracy_score(y_test, y_pred_sklearn):.4f}")  

(四)参数调优与分析

  • 测试集比例影响:循环测试test_size=[0.2, 0.3, 0.4, 0.5],发现两者准确率波动较小(手动实现约 0.69~0.71,Scikit-learn 约 0.70~0.72),但 Scikit-learn 在测试集比例较大时稳定性略优。
  • 特征数量影响:特征数从 10 增至 30 时,准确率上升(峰值约 0.73);超过 30 后因过拟合下降。手动实现运行时间随特征数呈平方级增长,Scikit-learn 因底层优化增长缓慢。

(五)完整源代码

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score, precision_score, recall_score
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
import timeplt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 1. 数据加载与预处理
# 生成随机二分类数据集
X, y = make_classification(n_samples=1000,  # 样本数量n_features=20,  # 特征数量n_classes=2,  # 类别数量n_informative=15,  # 有信息量的特征数量n_redundant=3,  # 冗余特征数量n_repeated=2,  # 重复特征数量class_sep=0.5,  # 类别之间的分离程度random_state=42
)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 2. 手动实现MLE估计(朴素贝叶斯)
class ManualNaiveBayes:def fit(self, X, y):self.classes = np.unique(y)self.params = {}for c in self.classes:X_c = X[y == c]self.params[c] = {'mean': np.mean(X_c, axis=0),'var': np.var(X_c, axis=0),'prior': len(X_c) / len(X)}def predict(self, X):X = np.array(X)  # 确保输入是numpy数组posteriors = []for c in self.classes:prior = np.log(self.params[c]['prior'])mean = self.params[c]['mean']var = self.params[c]['var']likelihood = -0.5 * np.sum(np.log(2 * np.pi * var)) - 0.5 * np.sum(((X - mean) ** 2) / var, axis=1)posterior = prior + likelihoodposteriors.append(posterior)return self.classes[np.argmax(posteriors, axis=0)]# 3. 使用sklearn的朴素贝叶斯对比
# 手动实现模型
manual_nb = ManualNaiveBayes()
start_time = time.time()
manual_nb.fit(X_train, y_train)
y_pred_manual = manual_nb.predict(X_test)
manual_time = time.time() - start_time# sklearn模型
sklearn_nb = GaussianNB()
start_time = time.time()
sklearn_nb.fit(X_train, y_train)
y_pred_sklearn = sklearn_nb.predict(X_test)
sklearn_time = time.time() - start_time# 4. 结果可视化输出
# 绘制原始数据分布
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o')
plt.title('原始数据分布')
plt.xlabel('特征1')
plt.ylabel('特征2')# 绘制手动实现模型的分类结果
plt.subplot(1, 3, 2)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred_manual, edgecolors='k', marker='o')
plt.title('手动实现分类结果')
plt.xlabel('特征1')
plt.ylabel('特征2')# 绘制sklearn模型的分类结果
plt.subplot(1, 3, 3)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred_sklearn, edgecolors='k', marker='o')
plt.title('sklearn分类结果')
plt.xlabel('特征1')
plt.ylabel('特征2')plt.tight_layout()
plt.show()# 5. 终端输出性能指标
# 计算手动实现的模型性能指标
manual_acc = accuracy_score(y_test, y_pred_manual)
manual_pre = precision_score(y_test, y_pred_manual)
manual_rec = recall_score(y_test, y_pred_manual)# 计算sklearn模型性能指标
sklearn_acc = accuracy_score(y_test, y_pred_sklearn)
sklearn_pre = precision_score(y_test, y_pred_sklearn)
sklearn_rec = recall_score(y_test, y_pred_sklearn)print("手动实现的朴素贝叶斯分类器:")
print(f"准确率:{manual_acc:.4f}")
print(f"精确率:{manual_pre:.4f}")
print(f"召回率:{manual_rec:.4f}")
print(f"运行时间:{manual_time:.4f}秒")print("\n使用sklearn的高斯朴素贝叶斯分类器:")
print(f"准确率:{sklearn_acc:.4f}")
print(f"精确率:{sklearn_pre:.4f}")
print(f"召回率:{sklearn_rec:.4f}")
print(f"运行时间:{sklearn_time:.4f}秒")# 6. 不同训练集/测试集比例下的性能指标变化分析
test_sizes = [0.2, 0.3, 0.4, 0.5]
manual_accs = []
sklearn_accs = []
manual_times = []
sklearn_times = []for test_size in test_sizes:X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=42)# 手动实现模型manual_nb = ManualNaiveBayes()start_time = time.time()manual_nb.fit(X_train, y_train)y_pred_manual = manual_nb.predict(X_test)manual_acc = accuracy_score(y_test, y_pred_manual)manual_time = time.time() - start_timemanual_accs.append(manual_acc)manual_times.append(manual_time)# sklearn模型sklearn_nb = GaussianNB()start_time = time.time()sklearn_nb.fit(X_train, y_train)y_pred_sklearn = sklearn_nb.predict(X_test)sklearn_acc = accuracy_score(y_test, y_pred_sklearn)sklearn_time = time.time() - start_timesklearn_accs.append(sklearn_acc)sklearn_times.append(sklearn_time)# 绘制不同测试集比例下的准确率变化
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.plot(test_sizes, manual_accs,color='red',marker='o',label='手动实现')
plt.plot(test_sizes, sklearn_accs,color='green', label='sklearn实现')
plt.xlabel('测试集比例')
plt.ylabel('准确率')
plt.title('不同测试集比例下的准确率变化')
plt.legend()
plt.grid(True)# 绘制不同测试集比例下的运行时间变化
plt.subplot(1, 2, 2)
plt.plot(test_sizes, manual_times, marker='o', label='手动实现')
plt.plot(test_sizes, sklearn_times, marker='o', label='sklearn实现')
plt.xlabel('测试集比例')
plt.ylabel('运行时间(秒)')
plt.title('不同测试集比例下的运行时间变化')
plt.legend()
plt.grid(True)plt.tight_layout()
plt.show()

五、实验结果

(一)基础性能对比

模型类型准确率精确率召回率运行时间(秒)
手动实现(MLE)0.69670.72790.64710.0009
Scikit-learn0.69670.72790.64710.0020

(二)关键结论

  1. MLE 的有效性:手动实现成功通过 MLE 估计参数,验证了朴素贝叶斯的分类逻辑,但细节优化不足(如未处理数值稳定性)。
  2. 库函数优势:Scikit-learn 的GaussianNB在相同准确率下更高效稳定,适合实际应用;手动实现适合学习算法原理。
  3. 特征与数据划分:特征数适中(20~30 维)时模型最佳,过多需降维;测试集比例对结果影响较小,建议使用交叉验证提升可靠性。

六、总结

   本次实验通过手动实现 MLE 与朴素贝叶斯分类器,深入理解了参数估计的数学原理,并对比了 Scikit-learn 库函数的性能。结果表明,MLE 是连接统计理论与机器学习的重要桥梁,而成熟库函数在工程实践中更具优势。未来可进一步优化手动代码(如向量化计算、正则化),或探索 MLE 在其他模型(如逻辑回归)中的应用。

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

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

相关文章

我的第1个爬虫程序——豆瓣Top250爬虫的详细步骤指南

我的第1个爬虫程序——豆瓣Top250爬虫的详细步骤指南 一、创建隔离开发环境 1. 使用虚拟环境(推荐venv) # 在项目目录打开终端执行 python -m venv douban_env # 创建虚拟环境 source douban_env/bin/activate # Linux/macOS激活 douban_env\Scri…

STM32八股【11】-----Linux Bootloader (U-Boot)

参考U-Boot U-Boot是什么 嵌入式Linux系统需要一个bootloader来加载系统 U-boot就是一个通用开源的嵌入式Linux bootloader 主要实现的功能: 初始化硬件资源(如内存、串口、存储器等)从存储介质加载Linux内核到内存中传递启动参数给内核启…

【设计模式】责任链+模板+工程模式使用模板

前言 方便写出优雅,解耦,高内聚,高复用的代码。 Demo // 1. 定义验证器接口(责任链模式) public interface Validator {Validator setNext(Validator next);boolean validate(Data data); }// 2. 创建抽象验证器&am…

Unity3D仿星露谷物语开发49之创建云杉树

1、目标 创建一颗既可以生长又可以砍伐的云杉树,这个和之前创建橡树类似。 2、创建云杉树预制体 创建新物体命名为CropTreeBlueSpruce,并且添加Box Collider 2D和Crop组件。 在CropTreeBlueSpruce下创建子物体命名为CropSprite,添加3个组件…

【C#】消息队列的使用

在C#中使用消息队列,通常是指使用微软的Message Queuing (MSMQ)技术。MSMQ提供了一种异步通信协议,允许应用程序通过暂时存储要发送到目的地的消息来相互通信。 安装MSMQ 首先,确保你的开发机器和部署服务器上都安装了MSMQ。可以通过“控制…

IP-guard发布新版本4.87.2241.0

IP-guard发布新版本4.87.2241.0 新版本下载地址: https://www.tec-development.com/down/IPguard/Release/V4/IPguard4.87.2241.0.zip?s=901D45ADB22CBBFE5C612DC40AFD6BFB1551A9CD54EF418D5E86BBD256813867 新版本升级地址:

【Linux 服务器磁盘映像备份与恢复实战指南】虚拟机备份,物理机上云都可以用这套方案!

Linux 服务器磁盘映像备份与恢复实战指南 背景 在服务器运维中,磁盘健康度下降可能导致数据丢失风险,特别是在未配置 RAID 的情况下。针对这种情况,备份磁盘数据并恢复到新设备是确保数据安全的关键。本文记录了使用 dd 命令通过 NFS 实现全…

深入理解 Linux 的 set、env 和 printenv 命令

在 Linux 和类 Unix 系统中,环境变量是配置和管理 Shell 及进程行为的核心机制。set、env 和 printenv 是与环境变量交互的三个重要命令,每个命令都有其独特的功能和用途。本文将详细探讨这三个命令的区别,帮助大家更好地理解和使用这些命令。…

icexmoon-tree

icexmoon-tree 一个轻量级的 Java 工具库&#xff0c;提供树形结构操作功能。 安装 <dependency><groupId>cn.icexmoon</groupId><artifactId>icexmoon-tree</artifactId><version>1.0.0</version> </dependency>使用 构建…

机器学习在智能水泥基复合材料中的应用与实践

“机器学习在智能水泥基复合材料中的应用与实践” 课程 内容 机器学习基础模型与复合材料研究融合 机器学习在复合材料中的应用概述机器学习用于复合材料研究的流程复合材料数据收集与数据预处理 实例&#xff1a;数据的收集和预处理 复合材料机器学习特征工程与选择 实例&a…

微软 Build 2025:开启 AI 智能体时代的产业革命

在 2025 年 5 月 19 日的微软 Build 开发者大会上&#xff0c;萨提亚・纳德拉以 "我们已进入 AI 智能体时代" 的宣言&#xff0c;正式拉开了人工智能发展的新纪元。这场汇聚了奥特曼、黄仁勋、马斯克三位科技领袖的盛会&#xff0c;不仅发布了 50 余项创新产品&#…

[Java恶补day6] 15. 三数之和

给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 示例 1&a…

《黄帝内经》数学建模与形式化表征方式的重构

黄帝内经的数学概括&#xff1a;《黄帝内经》数学建模与形式化表征方式的重构 摘要&#xff1a;《黄帝内经》通过现代数学理论如动力系统、代数拓扑和随机过程&#xff0c;被重构为一个形式化的人体健康模型。该模型包括阴阳动力学的微分几何、五行代数的李群结构、经络拓扑与同…

理论篇五:如何优化Webpack的打包速度

优化 Webpack 打包速度是提升前端开发效率的关键。以下是 10 种核心优化策略,涵盖开发和生产环境,附带具体配置和实测效果对比: 一、缩小文件搜索范围 1. 指定解析路径(Resolve) resolve: {extensions: [.js, .jsx],

[Windows] 游戏常用运行库- Game Runtime Libraries Package(6.2.25.0409)

游戏常用运行库 合集 整合了许多游戏会用到的运行库&#xff0c;支持 Windows XP – Windows 11 系统&#xff0c;并且支持自动检测系统勾选推荐的运行库&#xff0c;方便快捷。 本版特点&#xff1a; By&#xff1a;mefcl 整合常见最新游戏所需运行库 根据系统自动勾选推荐…

JDK8中的 Stream流式编程用法优化(工具类在文章最后)

Java从JDK8起提供了Stream流这个功能&#xff0c;于是项目里出现了大量基于Stream流的写法。随着项目的进行&#xff0c;慢慢的代码中铺天盖地的都是下面的写法&#xff1a; List<User> userList null;if (condition) {userList new ArrayList<>();userList.add(…

uni-app学习笔记十二-vue3中组件传值(对象传值)

一.单对象传值 父组件定义对象的值 <template><view><UserInfo :obj"userinfo"></UserInfo></view> </template><script setup>import {ref} from "vue"const userinfo ref({name:"蛛儿",avatar:&…

UV-python环境管理工具 入门教程

在学习使用 MCP 的时候接触到了 UV 这个环境管理工具&#xff0c;经过对比&#xff0c;发现它在诸多方面比 venv、conda 等工具更为出色&#xff0c;因此整理了这份简单的入门学习笔记&#xff0c;希望能帮助大家快速上手。 介绍 UV 是一款集 Python 版本管理、虚拟环境创建与…

【漫话机器学习系列】277.梯度裁剪(Gradient Clipping)

【深度学习】什么是梯度裁剪&#xff08;Gradient Clipping&#xff09;&#xff1f;一张图彻底搞懂&#xff01; 在训练深度神经网络&#xff0c;尤其是 RNN、LSTM、Transformer 这类深层结构时&#xff0c;你是否遇到过以下情况&#xff1a; 模型 loss 突然变成 NaN&#xf…

零基础弄懂 ngx_http_slice_module分片缓存加速

一、为什么需要 Slice&#xff1f; 在 NGINX 反向代理或 CDN 场景中&#xff0c;大文件&#xff08;视频、软件包、镜像等&#xff09;常因单体体积过大而令缓存命中率低、回源代价高。 ngx_http_slice_module 通过把一次完整响应拆分成 固定大小的字节块&#xff08;Slice&am…