当前位置: 首页 > news >正文

从0开始学习R语言--Day60--EM插补法

虽然我们常常在数据处理中做数据分布以及异常值的处理,但实际上对于缺失值,很多时候我们都不能简单地去删除或赋予0值,毕竟很多都是有意义的数据,只是可能因为各种原因没有在数据面板中显示,直接删除或赋予0这种忽略数据本身意义的做法,会破坏数据的属性,扭曲数据的性质。

一般来说,对于各种缺失的数据,我们都会用EM插补法来填补数据,原理是根据缺失所属的数据列,粗略估计一个数据后,计算等于这个值的概率,然后重复这个过程指到数值不再发生变化,简单来说就是根据已有的数据列参考来回归一个数据。

以下是一个例子:

# 加载必要的包
install.packages('mice',type = 'binary')
library(mice)    # 提供EM插补功能
library(mvtnorm) # 用于生成多元正态分布数据
library(norm)    # 提供EM算法实现# 1. 生成模拟数据集
set.seed(123)
n <- 200  # 样本量
p <- 5    # 变量数# 生成完整的多元正态分布数据
mu <- c(5, 10, 15, 20, 25)  # 均值向量
sigma <- matrix(c(    # 协方差矩阵4, 2, 1, 0.5, 0.1,2, 9, 3, 1, 0.5,1, 3, 16, 4, 1,0.5, 1, 4, 25, 5,0.1, 0.5, 1, 5, 36
), ncol = p)complete_data <- rmvnorm(n, mean = mu, sigma = sigma)
colnames(complete_data) <- paste0("X", 1:p)# 2. 人为制造缺失值 (MCAR机制)
missing_data <- complete_data
for (j in 1:p) {# 每个变量随机缺失20%missing_indices <- sample(1:n, size = n * 0.2)missing_data[missing_indices, j] <- NA
}# 查看缺失模式
summary(missing_data)
md.pattern(missing_data)# 3. 使用norm包进行EM插补
# 首先需要对数据进行预处理
s <- prelim.norm(missing_data)  # 预处理
thetahat <- em.norm(s)          # EM算法估计参数# 获取插补后的数据集
em_imputed <- imp.norm(s, thetahat, missing_data)# 查看插补后的完整数据集
head(em_imputed)# 4. 使用mice包进行EM插补 (更简单的方法)
em_mice <- mice(missing_data, method = "norm", m = 1, maxit = 50)
complete_mice <- complete(em_mice)# 比较原始数据和插补数据
par(mfrow = c(2, 3))
for (i in 1:p) {plot(density(complete_data[, i], na.rm = TRUE), main = paste("X", i), col = "blue")lines(density(complete_mice[, i], na.rm = TRUE), col = "red")legend("topright", legend = c("Original", "Imputed"), col = c("blue", "red"), lty = 1)
}# 5. 评估插补质量
# 计算均方误差 (仅对缺失部分)
mse <- numeric(p)
for (i in 1:p) {missing_ind <- is.na(missing_data[, i])mse[i] <- mean((complete_data[missing_ind, i] - complete_mice[missing_ind, i])^2)
}
print(paste("MSE for each variable:", paste(round(mse, 3), collapse = ", ")))

输出:

从整体来看,插补前后的曲线重合的地方很多,表明能够较好地修复数据,尤其是插补后没有看到有新的峰值或极端值。注意,如果缺失的值是一整年,同年份没有参考数据的话,就不能用EM,这种情况下的插补本质是一种预测了,要用函数的方法来做。

http://www.lryc.cn/news/602254.html

相关文章:

  • git stash apply 冲突合并方法解决
  • Kafka 3.9.1的KRaft模式部署
  • linux系统----Ansible中的playbook简单应用
  • 从零开始的云计算生活——第三十七天,跬步千里,ansible之playbook
  • 【Blender小技巧】Blender使用多边形建形工具创建多边形模型,挤出面,模型创建修改编辑UV贴图
  • 【第四章:大模型(LLM)】01.神经网络中的 NLP-(2)Seq2Seq 原理及代码解析
  • 从0到500账号管理:亚矩阵云手机多开组队与虚拟定位实战指南
  • 【归并排序】排序数组(medium)
  • Rust/Tauri 优秀开源项目推荐
  • C/C++ 调用lua脚本,lua脚本调用另一个lua脚本
  • 最新的前端技术和趋势(2025)
  • Maven中的bom和父依赖
  • Nginx HTTP 反向代理负载均衡实验
  • YOLO11 改进、魔改|低分辨率自注意力机制LRSA ,提取全局上下文建模与局部细节,提升小目标、密集小目标的检测能力
  • 免费 SSL 证书申请简明教程,让网站实现 HTTPS 访问
  • ADAS测试:如何用自动化手段提升VV效率
  • 【CDA干货】金融超市电商App经营数据分析案例
  • unbuntn 22.04 coreutils文件系统故障
  • GaussDB as的用法
  • 亚马逊广告关键词优化:如何精准定位目标客户
  • MyBatis中#{}与${}的实战避坑指南
  • 性能测试-技术指标的含义和计算
  • Leetcode_242.有效的字母异位词
  • Apache Commons VFS:Java内存虚拟文件系统,屏蔽不同IO细节
  • python入门篇12-虚拟环境conda的安装与使用
  • 深入Go并发编程:Channel、Goroutine与Select的协同艺术
  • 博士申请 | 荷兰阿姆斯特丹大学 招收计算机视觉(CV)方向 全奖博士生
  • 达梦有多少个模式
  • 亚马逊地址关联暴雷:新算法下的账号安全保卫战
  • 四、计算机组成原理——第6章:总线