红酒数据集预处理实战:缺失值处理的 5 种打开方式,从入门到进阶一步到位

在数据分析与建模流程中,缺失值处理是数据预处理阶段的关键步骤,直接影响后续模型的准确性与稳定性。本文以红酒数据集为研究对象,详细介绍如何通过基础统计方法(均值、中位数、众数)、完整案例分析(CCA)及机器学习算法(线性回归、随机森林)实现缺失值填充,并提供完整代码实现与结果保存方案,帮助读者系统化掌握缺失值处理逻辑。

一、项目背景与数据概览

1.1 数据集介绍

本项目使用的 “红酒.csv” 数据集包含红酒的多项理化指标(如酒精含量、酸度、糖分等)、矿物类型标签及最终质量评分,目标是通过预处理后的数据构建后续质量预测模型。数据中存在部分缺失值,需先进行填充处理。

1.2 核心需求

  • 查看数据基本结构(前 10 行、后 10 行),了解数据分布;
  • 采用 5 种不同方法处理缺失值,确保数据完整性;
  • 拆分训练集与测试集,按 “训练集规则填充测试集”(避免数据泄露);
  • 保存处理后的数据集,为后续建模提供输入。

二、项目环境与依赖库

首先需安装并导入以下 Python 库,核心用于数据读取、缺失值处理与模型构建:

import pandas as pd  # 数据处理核心库
from sklearn.model_selection import train_test_split  # 数据集拆分
from sklearn.linear_model import LinearRegression  # 线性回归模型
from sklearn.ensemble import RandomForestRegressor  # 随机森林回归模型

三、数据预处理核心流程

3.1 数据读取与初步探索

第一步读取数据并查看基本结构,同时统计缺失值总量,明确后续处理目标:

# 读取红酒数据(根据编码选择gbk或utf-8)
data = pd.read_csv('红酒.csv', encoding='gbk')# 查看数据前10行与后10行,了解数据结构
print("===== 数据前10行 =====")
print(data.head(10))
print("\n===== 数据后10行 =====")
print(data.tail(10))# 统计每列缺失值数量
null_total = data.isnull().sum()
print("\n===== 各列缺失值数量 =====")
print(null_total)# 拆分特征与标签(质量评分为目标变量,矿物类型为类别特征)
x_whole = data.drop(['质量评分'], axis=1)  # 所有特征(含矿物类型)
y_whole = data['质量评分']  # 目标变量:质量评分# 拆分训练集(75%)与测试集(25%),固定随机种子确保结果可复现
x_train, x_test, y_train, y_test = train_test_split(x_whole, y_whole, test_size=0.25, random_state=42
)

3.2 缺失值处理方法详解

为适配不同数据分布场景,本文实现 5 种缺失值处理方法,核心逻辑是 **“按矿物类型分组填充”**(同类红酒理化指标更相似,填充更精准),且严格遵循 “用训练集规则填充测试集” 原则,避免数据泄露。

所有方法封装在fill_data.py文件中,下文分模块解析核心逻辑。

方法 1:完整案例分析(CCA)—— 直接删除缺失值行

适用于缺失值占比极低的场景,直接保留无缺失值的完整样本,优点是简单无偏差,缺点是会损失数据量。

def cca_train_fill(train_data, train_label):"""训练集CCA填充:删除含缺失值的行"""# 合并特征与标签data = pd.concat([train_data, train_label], axis=1).reset_index(drop=True)# 删除含缺失值的行df_filled = data.dropna()# 返回填充后的特征与标签return df_filled.drop('矿物类型', axis=1), df_filled['矿物类型']def cca_test_fill(train_data, train_label, test_data, test_label):"""测试集CCA填充:逻辑与训练集一致,仅处理测试集"""data = pd.concat([test_data, test_label], axis=1).reset_index(drop=True)df_filled = data.dropna()return df_filled.drop('矿物类型', axis=1), df_filled['矿物类型']
方法 2-4:基础统计填充(均值 / 中位数 / 众数)
  • 均值填充:适用于数据近似正态分布、无极端值的场景;
  • 中位数填充:适用于数据含极端值(如异常高的酒精含量)的场景,抗干扰性更强;
  • 众数填充:适用于类别型或离散型特征(如某类矿物类型的红酒酸度集中在某个值)。

以均值填充为例,核心代码逻辑如下(中位数、众数仅需替换mean()median()/mode()):

def mean_train_method(data):"""计算单组数据的均值,用于填充"""fill_values = data.mean()return data.fillna(fill_values)def mean_train_fill(train_data, train_label):"""训练集均值填充:按矿物类型分组后填充"""data = pd.concat([train_data, train_label], axis=1).reset_index(drop=True)# 按矿物类型(0-3)分组groups = [data[data['矿物类型'] == i] for i in range(4)]# 每组单独用均值填充filled_groups = [mean_train_method(group) for group in groups]# 合并分组数据df_filled = pd.concat(filled_groups).reset_index(drop=True)return df_filled.drop('矿物类型', axis=1), df_filled['矿物类型']def mean_test_fill(train_data, train_label, test_data, test_label):"""测试集均值填充:用训练集的分组均值填充测试集"""# 合并训练集与测试集train_all = pd.concat([train_data, train_label], axis=1).reset_index(drop=True)test_all = pd.concat([test_data, test_label], axis=1).reset_index(drop=True)# 按矿物类型分组,用训练集分组均值填充测试集filled_test_groups = []for mineral_type in range(4):# 训练集该类别的均值train_group = train_all[train_all['矿物类型'] == mineral_type]# 测试集该类别数据test_group = test_all[test_all['矿物类型'] == mineral_type]# 用训练集均值填充测试集filled_test = test_group.fillna(train_group.mean())filled_test_groups.append(filled_test)df_filled = pd.concat(filled_test_groups).reset_index(drop=True)return df_filled.drop('矿物类型', axis=1), df_filled['矿物类型']
方法 5:机器学习填充(线性回归 / 随机森林)

适用于特征间存在明显相关性的场景,通过构建预测模型,用其他特征预测缺失值,填充精度更高。核心逻辑是 **“按缺失值数量从小到大处理”**(先填充缺失少的特征,用已填充的特征预测缺失多的特征)。

以随机森林填充为例,核心代码如下:

def rf_train_fill(train_data, train_label):"""训练集随机森林填充:用其他特征预测缺失值"""# 合并特征与标签data = pd.concat([train_data, train_label], axis=1).reset_index(drop=True)train_X = data.drop('矿物类型', axis=1)# 按缺失值数量从小到大排序,确定填充顺序null_num = train_X.isnull().sum()null_sorted = null_num.sort_values(ascending=True)filling_features = []  # 存储已处理的特征(用于构建模型输入)for feat in null_sorted.index:filling_features.append(feat)# 仅处理含缺失值的特征if null_sorted[feat] == 0:continue# 构建模型:以当前特征为目标变量,其他已处理特征为输入X = train_X[filling_features].drop(feat, axis=1)  # 输入特征y = train_X[feat]  # 目标变量(待填充的特征)# 筛选非缺失值样本作为训练集,缺失值样本作为测试集null_rows = train_X[train_X[feat].isnull()].index.tolist()X_train = X.drop(null_rows)y_train = y.drop(null_rows)X_test = X.iloc[null_rows]# 训练随机森林模型rf = RandomForestRegressor(n_estimators=100, random_state=42)rf.fit(X_train, y_train)# 预测缺失值并填充y_pred = rf.predict(X_test)train_X.loc[null_rows, feat] = y_predprint(f'完成训练集「{feat}」列填充')return train_X, data['矿物类型']def rf_test_fill(train_data, train_label, test_data, test_label):"""测试集随机森林填充:用训练集训练的模型逻辑填充测试集"""# 合并训练集与测试集train_all = pd.concat([train_data, train_label], axis=1).reset_index(drop=True)test_all = pd.concat([test_data, test_label], axis=1).reset_index(drop=True)train_X = train_all.drop('矿物类型', axis=1)test_X = test_all.drop('矿物类型', axis=1)# 按测试集缺失值数量排序,用训练集规则填充null_num = test_X.isnull().sum()null_sorted = null_num.sort_values(ascending=True)filling_features = []for feat in null_sorted.index:filling_features.append(feat)if null_sorted[feat] == 0:continue# 用训练集的特征构建模型X_train = train_X[filling_features].drop(feat, axis=1)y_train = train_X[feat]X_test = test_X[filling_features].drop(feat, axis=1)# 筛选测试集缺失值行null_rows = test_X[test_X[feat].isnull()].index.tolist()X_test = X_test.iloc[null_rows]# 训练模型并预测填充rf = RandomForestRegressor(n_estimators=100, random_state=42)rf.fit(X_train, y_train)y_pred = rf.predict(X_test)test_X.loc[null_rows, feat] = y_predprint(f'完成测试集「{feat}」列填充')return test_X, test_all['矿物类型']

3.3 数据保存与后续使用

填充完成后,需将训练集与测试集合并为完整 DataFrame,并保存为 Excel 文件,方便后续建模使用。同时对训练集进行随机打乱,避免顺序对模型训练的影响:

# 选择一种填充方法(以CCA为例,其他方法只需替换函数名)
x_train_fill, y_train_fill = fill_data.cca_train_fill(x_train, y_train)
x_test_fill, y_test_fill = fill_data.cca_test_fill(x_train, y_train, x_test, y_test)# 合并特征与标签,训练集随机打乱
data_train = pd.concat([x_train_fill, y_train_fill], axis=1).sample(frac=1, random_state=4)
data_test = pd.concat([x_test_fill, y_test_fill], axis=1)# 保存到本地(需提前创建“数据”文件夹)
data_train.to_excel('./数据/训练空值删除填充.xlsx', index=False)
data_test.to_excel('./数据/测试空值删除填充.xlsx', index=False)
print("数据保存完成!")

四、各方法对比与适用场景

不同缺失值处理方法各有优劣,需根据数据特点选择,下表为核心对比:

处理方法优点缺点适用场景
CCA(删除行)简单无偏差,不引入额外信息损失数据量,样本代表性下降缺失值占比 < 5%,数据量充足
均值填充计算简单,保留数据量受极端值影响大数据近似正态分布,无极端值
中位数填充抗极端值,稳定性强未利用特征相关性数据含极端值(如酒精含量异常值)
众数填充适用于离散型 / 类别型特征不适用于连续型特征离散特征(如某类矿物类型的酸度)
随机森林填充利用特征相关性,填充精度高计算复杂,需调参特征间相关性强,数据量中等

五、总结与后续优化方向

5.1 项目总结

本项目以红酒数据集为载体,完整实现了从 “数据探索→缺失值处理→结果保存” 的预处理流程,核心亮点:

  1. 严格遵循 “训练集规则填充测试集”,避免数据泄露;
  2. 按 “矿物类型分组填充”,贴合红酒数据的业务逻辑;
  3. 覆盖基础到进阶的 5 种方法,适配不同数据场景。

5.2 后续优化方向

  1. 填充效果评估:可通过 “插入人工缺失值” 的方式,对比不同方法的填充误差(如 MAE、RMSE);
  2. 特征标准化:在机器学习填充前对特征进行标准化(如StandardScaler),提升模型预测精度;
  3. 分类任务适配:若目标是 “红酒质量分级”(如好 / 中 / 差),可将随机森林回归改为分类器(RandomForestClassifier)。

通过本文的方法,可快速完成红酒数据集的缺失值处理,为后续的质量预测模型(如线性回归、随机森林、SVM)提供高质量的输入数据。

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

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

相关文章

Node.js 开发 JavaScript SDK 包的完整指南(AI)

一、核心概念SDK 包定义 专为特定服务/平台封装的工具库&#xff0c;提供标准化 API 调用、错误处理、类型声明等功能。示例&#xff1a;支付宝 SDK、AWS SDK、微信小程序 SDK。技术栈选择 语言&#xff1a;JavaScript/TypeScript&#xff08;推荐 TS&#xff0c;便于类型提示&…

Redis实战-基于Session实现分布式登录

1.流程分析1.1发送短信验证码提交手机号的时候要进行校验手机号&#xff0c;校验成功才会去生成验证码&#xff0c;将验证码保存到session&#xff0c;发生他把这部分那。1.2短信验证码登录/注册如果提交手机号和验证码之后&#xff0c;校验一致才进行根据手机号查询用户&#…

疯狂星期四文案网第47天运营日记

网站运营第47天&#xff0c;点击观站&#xff1a; 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 今日访问量 今日搜索引擎收录情况 必应现在是边收录边k页面 百度快倒闭 网站优化点 完善工作流&#xff0c;全面实现文案自动化采集&#xff0c;se…

Vue生命周期以及自定义钩子和路由

Vue生命周期常用的onMounted挂载后执行和onUnmounted卸载前以及onupdated更新后实际上用react对比就是useEffect&#xff0c;而且挂载顺序也是子组件先于父组件然后往外的栈结构&#xff0c;先进后出。1.Vue的生命周期<template><h2>当前求和为{{ sum }}</h2>…

探索Thompson Shell:Unix初代Shell的智慧

引言 在计算机科学的漫漫长河中&#xff0c;Thompson Shell 无疑占据着举足轻重的开创性地位&#xff0c;它是 Unix 系统的第一个 shell&#xff0c;诞生于 1971 年&#xff0c;由计算机领域的传奇人物 Ken Thompson 开发。在那个计算机技术刚刚起步、硬件资源极度匮乏的年代&a…

MySQL B+ 树索引详解:从原理到实战优化

引言在现代数据库应用中&#xff0c;查询效率是影响系统性能的关键因素之一。而索引&#xff0c;尤其是 B 树索引&#xff0c;是 MySQL 中最常用、最重要的性能优化手段。正确使用索引可以将查询时间从毫秒级降低到微秒级&#xff0c;极大地提升应用响应速度。1. B 树索引的重要…

计算机内存中的整型存储奥秘、大小端字节序及其判断方法

目录 一、回顾与引入&#xff1a;整数在内存中的存储方式 为什么要采用补码存储&#xff1f; 二、大小端字节序及其判断方法 1、什么是大小端&#xff1f; 2、为什么存在大小端&#xff1f; 3、练习 练习1&#xff1a;简述大小端概念并设计判断程序&#xff08;百度面试…

Redis 最常用的 5 种数据类型

Redis 支持多种灵活的数据类型&#xff0c;每种类型针对特定场景优化。以下是 **Redis 最常用的 5 种数据类型**及其核心特点和应用场景&#xff1a;1. 字符串&#xff08;String&#xff09;描述&#xff1a;最基本的数据类型&#xff0c;可存储文本、数字&#xff08;整数/浮…

【嵌入式】RK3588 对比 NVIDIA Jetson,Radxa Rock 5B vs Orange Pi 5 Max

RK3588这个芯片,适合AI应用么,为什么这么贵呢 AI 边缘盒子里的旗舰芯 深度分析一下 RK3588(瑞芯微 Rockchip RK3588) 为什么被很多人关注在 AI 应用,以及它价格偏高的原因。 🧩 1. RK3588 的基本情况 制程:8nm(Samsung 8nm LP) CPU:8 核 big.LITTLE 架构(4 Cortex-…

暴雨让高性能计算更“冷静”

当AI大模型的参数突破万亿&#xff0c;当深地探测的精度迈向微米&#xff0c;当数字经济的脉搏与千行百业深度共振&#xff0c;算力已成为驱动时代向前的核心引擎。然而&#xff0c;传统风冷技术在高密度算力需求面前渐显乏力——机柜内的热浪如同无形的枷锁&#xff0c;既制约…

SpringAI集成MCP

文章目录1_调用公用MCP2_Stdio方式3_Stdio实现原理4_SSE方式5_自定义MCP客户端6_MCP Server权限控制SpringAI 通过 SpringBoot 集成扩展了 MCP Java SDK &#xff0c;提供了客户端和服务端 starter&#xff0c;让 AI 应用程序快速支持 MCP。接下来直接演示。 1_调用公用MCP 在…

Spring Start Here 读书笔记:第10章 Implementing REST services

REST 服务可用于实现两个应用之间的通讯&#xff0c;包括 Web 应用中的客户端和服务器之间&#xff0c;移动应用与后端服务之间&#xff0c;或两个后端服务之间。 10.1 使用 REST 服务在应用之间交换数据 REST端点是应用程序通过 Web 协议公开服务的方式&#xff0c;因此也称…

SYBASE ASE、Oracle、MySQL/MariaDB、SQL Server及PostgreSQL在邮件/短信发送功能上的全面横向对比报告

以下是对SYBASE ASE、Oracle、MySQL/MariaDB、SQL Server及PostgreSQL在邮件/短信发送功能上的全面横向对比报告&#xff08;截至2025年8月最新版本&#xff09;&#xff0c;涵盖技术实现、配置复杂度、适用场景及权威评测&#xff1a;​​一、邮件发送能力对比​​​​1. Orac…

服务器与客户端

目录 一、服务器&#xff08;Server&#xff09; 核心特点 常见类型 二、客户端&#xff08;Client&#xff09; 核心特点 常见类型 客户端与服务器的交互流程 补充&#xff1a;与 “对等网络&#xff08;P2P&#xff09;” 的区别 C/S模式 一、C/S 模式的核心原理 …

GaussDB 并发自治事务数达到最大值处理案例

1 业务背景自治事务&#xff08;Autonomous Transactions&#xff09;是一种高级特性&#xff0c;允许你在一个事务中执行另一个独立的事务。这种机制特别有用&#xff0c;尤其是在需要在一个事务中执行多个操作但又不想因为其中一个操作失败而影响整个事务的场景。2 业务影响在…

【传奇开心果系列】Flet分页自定义组件CustomPaginationComponent封装版自定义模板

Flet分页自定义组件CustomPaginationComponent封装版自定义模板一、效果展示GIF动图二、应用场景三、特色说明四、源码下载地址一、效果展示GIF动图 二、应用场景 图片浏览应用&#xff1a; 用户可以通过分页组件浏览多张图片&#xff0c;每点击一次“上一页”或“下一页”按钮…

数据安全——39页解读数字化转型大数据安全基础培训方案【附全文阅读】

适应人群为企业数据安全管理人员、IT 运维人员、数字化转型决策者、网络安全工程师及关注大数据安全的从业人员。主要内容围绕数字化转型中大数据安全展开,核心包括基础概念(信息、数据与大数据的定义及区别,大数据 4V 特点与来源);安全风险(企业面临的数据资产管理缺失、…

week3-[二维数组]小方块

week3-[二维数组]小方块 题目描述 如果四个数 a,b,c,da,b,c,da,b,c,d 可以分成两组&#xff0c;每组两个数&#xff0c;满足每组里面的两个数一样&#xff0c;那么称这四个数是好的。 比如&#xff0c;2,5,2,52,5,2,52,5,2,5 是好的&#xff0c;因它满足两组&#xff1a;222 与…

Swift 项目结构详解:构建可维护的大型应用

Swift 项目结构详解&#xff1a;构建可维护的大型应用一、基础结构&#xff08;推荐新手使用&#xff09;二、组件化结构&#xff08;企业级应用推荐&#xff09;层级架构&#xff1a;MVVM Coordinator路由实现&#xff08;Coordinator模式&#xff09;三、通用组件实现DI&…

【实时Linux实战系列】基于实时Linux的数字转换器设计

在现代电子系统中&#xff0c;数字转换器&#xff08;如模数转换器ADC和数模转换器DAC&#xff09;扮演着至关重要的角色。它们负责将模拟信号转换为数字信号&#xff0c;或将数字信号转换为模拟信号&#xff0c;从而实现信号的数字化处理和传输。在实时系统中&#xff0c;如工…