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

机器学习中的数据预处理:从入门到实践

在当今的智能时代,机器学习已经渗透到我们生活的方方面面。比如我们常用的推荐系统,它能根据我们的浏览记录精准推送喜欢的商品或视频,这背后就离不开机器学习的支撑。而一个优秀的机器学习模型,离不开高质量的数据,数据预处理正是保证数据质量的关键环节,它就像烹饪前的食材处理,直接影响着最终 “菜品” 的口感,也就是模型的性能。今天,我们就来全面学习机器学习中数据预处理的关键步骤。​

一、数据预处理的重要性​

数据预处理是机器学习流程中不可或缺的一步。想象一下,我们做一道菜,食材如果不新鲜、处理不干净,再好的厨艺也做不出美味佳肴。机器学习也是如此,原始数据往往存在各种问题,如缺失值、格式不统一等,不经过处理就直接用于建模,会导致模型预测不准确、性能下降。所以,做好数据预处理,是构建可靠机器学习模型的基础。​

二、数据预处理的关键步骤​

(一)导入需要的库​

在进行数据预处理之前,我们首先要导入一些必要的库,就像做菜前要准备好厨具一样。其中,NumPy 和 Pandas 是两个每次都需要导入的重要库。​

NumPy 包含了大量的数学计算函数,能帮助我们高效地进行数值运算。比如在生活中,我们计算多个商品的总价,用 NumPy 可以快速实现批量计算。​

Pandas 则用于导入和管理数据集,它能像处理表格一样轻松地操作数据。​

下面是导入这两个库的代码:​

import numpy as np​

import pandas as pd​

(二)导入数据集​

数据集通常是 CSV 格式,它以文本形式保存表格数据,每一行就是一条数据记录,类似于我们生活中记录信息的表格,比如学生信息表,每一行是一个学生的信息。​

我们可以使用 Pandas 的 read_csv 方法读取本地 CSV 文件为一个数据帧。然后,从数据帧中制作自变量和因变量的矩阵和向量。​

例如,我们有一个学生成绩数据集 “student_scores.csv”,里面包含学生的平时成绩、期末成绩和是否及格等信息。读取并划分自变量和因变量的代码如下:​

dataset = pd.read_csv('student_scores.csv')

X = dataset.iloc[ : , :-1].values # 自变量矩阵,取所有行和除最后一列外的所有列

Y = dataset.iloc[ : , 2].values # 因变量向量,取所有行的第三列(假设第三列是结果)

print("X")

print(X)

print("Y")

print(Y)

(三)处理丢失数据​

在实际生活中,我们收集到的数据很少是完整的,就像我们记录日常开销时,可能会忘记某天的花费,导致数据中出现 NaN 值。这些缺失的数据如果不处理,会降低机器学习模型的性能。​

处理方法通常是用整列的平均值或中间值替换丢失的数据。我们可以使用 sklearn.preprocessing 库中的 SimpleImputer 类来完成这项任务。​

from sklearn.impute import SimpleImputer​

imputer = SimpleImputer(missing_values=np.nan, strategy="mean") # 用平均值替换NaN值​

imputer = imputer.fit(X[ : , 1:3]) # 对X中第二列和第三列进行拟合​

X[ : , 1:3] = imputer.transform(X[ : , 1:3]) # 转换处理缺失值​

print("---------------------")​

print("Step 3: Handling the missing data")​

print("X")​

print(X)​

比如在一个学生成绩数据集中,某学生的数学成绩缺失了,我们就可以用全班同学的数学平均成绩来填补这个缺失值。​

(四)解析分类数据​

分类数据指的是含有标签值而不是数字值的变量,其取值范围通常是固定的。例如在问卷调查中,“是否满意” 的答案 “Yes” 和 “No”,这些不能直接用于模型的数学计算,所以需要解析成数字。​

我们可以从 sklearn.preprocessing 库导入 LabelEncoder 类和 OneHotEncoder 类来实现这一功能。LabelEncoder 用于将标签值转换为数字,OneHotEncoder 用于进行独热编码,避免分类变量之间产生虚假的数值关系。​

from sklearn.preprocessing import LabelEncoder, OneHotEncoder​

from sklearn.compose import ColumnTransformer​

# 对自变量中的分类数据进行独热编码​

ct = ColumnTransformer([("", OneHotEncoder(), [0])], remainder='passthrough')​

X = ct.fit_transform(X)​

# 对因变量中的分类数据进行编码​

labelencoder_Y = LabelEncoder()​

Y = labelencoder_Y.fit_transform(Y)​

print("---------------------")​

print("Step 4: Encoding categorical data")​

print("X")​

print(X)​

print("Y")​

print(Y)​

比如对于 “国家” 这一分类变量,有 “中国”“美国”“英国” 等取值,独热编码后会将其转换为多个 0 和 1 组成的向量,更适合模型计算。​

(五)拆分数据集为测试集合和训练集合​

为了评估机器学习模型的性能,我们需要把数据集拆分成两个部分:一个是用来训练模型的训练集合,另一个是用来验证模型的测试集合,两者比例一般是 80:20。​

我们可以导入 sklearn.model_selection 库中的 train_test_split () 方法来实现。​

from sklearn.model_selection import train_test_split​

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)​

print("---------------------")​

print("Step 5: Splitting the datasets into training sets and Test sets")​

print("X_train")​

print(X_train)​

print("X_test")​

print(X_test)​

print("Y_train")​

print(Y_train)​

print("Y_test")​

print(Y_test)​

这就好比我们学习知识,用 80% 的练习题来学习掌握(训练集),用 20% 的题来检验学习效果(测试集)。​

(六)特征缩放​

大部分模型算法使用两点间的欧式距离进行计算,但不同特征在幅度、单位和范围上可能有很大差异。例如,在一个包含年龄(0-100 岁)和收入(0-100000 元)的数据集里,收入的幅度远大于年龄,在距离计算中,收入会比年龄权重更大,这会影响模型的准确性。​

我们可以通过特征标准化或 Z 值归一化来解决这个问题,导入 sklearn.preprocessing 库的 StandardScaler 类即可实现。​

from sklearn.preprocessing import StandardScaler​

sc_X = StandardScaler()​

X_train = sc_X.fit_transform(X_train) # 对训练集进行拟合和标准化​

X_test = sc_X.transform(X_test) # 用训练集的参数对测试集进行标准化​

print("---------------------")​

print("Step 6: Feature Scaling")​

print("X_train")​

print(X_train)​

print("X_test")​

print(X_test)​

为什么 fit_transform 和 transform 不一样?​

  • fit_transform(X_train):该操作分为两步,先通过训练集数据计算出均值、标准差等统计参数,再依据这些参数对训练集进行标准化处理,将其转化为均值为 0、标准差为 1 的分布。这一步是让模型基于训练集的分布特性进行学习,为后续建模奠定基础。​
  • transform(X_test):处理测试集时,不会重新计算其统计参数,而是直接复用训练集的均值和标准差来进行标准化。这样做是为了保证训练集和测试集的处理标准一致,防止测试集的信息干扰模型训练,从而更准确地评估模型对新数据的适应能力。​

(七)异常值处理​

异常值是指数据集中与其他数据偏离较大的值,如同班级中某同学的成绩远高于或远低于其他同学。这些异常值可能会干扰模型对数据规律的学习,导致模型预测出现偏差。​

异常值检测方法​

  • 箱线图法:通过计算数据的四分位数,确定异常值的边界(上下限为 Q1-1.5IQR 和 Q3+1.5IQR,其中 Q1 为下四分位数,Q3 为上四分位数,IQR 为四分位距)。​
  • Z-score 法:若数据服从正态分布,Z-score 的绝对值大于 3 的通常被视为异常值。​

异常值处理代码示例​

import matplotlib.pyplot as plt​

# 以训练集中的某一特征为例绘制箱线图检测异常值​

plt.figure(figsize=(8, 4))​

plt.boxplot(X_train[:, 1]) # 假设第二列是需要检测的特征​

plt.title("特征值箱线图(检测异常值)")​

plt.show()​

# 计算四分位数和异常值边界​

Q1 = np.percentile(X_train[:, 1], 25)​

Q3 = np.percentile(X_train[:, 1], 75)​

IQR = Q3 - Q1​

lower_bound = Q1 - 1.5 * IQR​

upper_bound = Q3 + 1.5 * IQR​

# 过滤异常值​

X_train_clean = X_train[(X_train[:, 1] >= lower_bound) & (X_train[:, 1] <= upper_bound)]​

Y_train_clean = Y_train[(X_train[:, 1] >= lower_bound) & (X_train[:, 1] <= upper_bound)]​

比如在一个电商平台的用户消费数据中,若大部分用户月消费在 100-1000 元,而某条数据显示月消费 100000 元,这很可能是异常值,可根据实际情况删除或修正。​

(八)特征选择​

特征选择是从众多特征中挑选出对模型预测有重要影响的特征,减少冗余信息,提高模型的训练效率和预测精度,避免 “维度灾难”。​

常用特征选择方法​

  • 方差选择法:删除方差过小的特征(如某特征大部分值相同,对模型影响小)。​
  • 相关性分析:计算特征与目标变量的相关性,选择相关性高的特征。​

特征选择代码示例​

# 计算特征与目标变量的相关性​

corr_matrix = np.corrcoef(X_train_clean.T, Y_train_clean)​

# 提取特征与目标变量的相关系数(排除最后一行目标变量自身的相关性)​

feature_corr = np.abs(corr_matrix[:-1, -1])​

# 选择相关性大于0.5的特征​

selected_indices = np.where(feature_corr > 0.5)[0]​

X_train_selected = X_train_clean[:, selected_indices]​

X_test_selected = X_test[:, selected_indices]​

print("选择的特征索引:", selected_indices)​

print("选择后的训练集特征:")​

print(X_train_selected)​

例如在预测房价的模型中,房屋面积、卧室数量等特征与房价相关性较高,而房屋朝向(在某些地区)相关性较低,我们会优先选择前者作为模型输入。​

(九)数据转换​

部分数据可能不符合模型对数据分布的假设(如线性模型常假设数据服从正态分布),此时需要进行数据转换。常见的转换方法有对数转换、平方根转换等,用于处理偏态分布的数据。​

数据转换代码示例​

# 假设某特征呈现右偏分布,进行对数转换(避免值为0或负数,先加一个小常数)​

X_train_transformed = X_train_selected.copy()​

X_train_transformed[:, 0] = np.log(X_train_transformed[:, 0] + 1e-5)​

# 查看转换前后的分布​

plt.figure(figsize=(12, 4))​

plt.subplot(1, 2, 1)​

plt.hist(X_train_selected[:, 0], bins=20)​

plt.title("转换前的特征分布(右偏)")​

plt.subplot(1, 2, 2)​

plt.hist(X_train_transformed[:, 0], bins=20)​

plt.title("对数转换后的特征分布(接近正态)")​

plt.show()​

像居民收入数据通常呈右偏分布,通过对数转换可使其更接近正态分布,更符合模型的假设,提升模型性能。​

(十)构建预处理管道​

在实际项目中,数据预处理步骤较多,为了避免步骤混乱和数据泄露,我们可以使用sklearn.pipeline构建预处理管道,将所有预处理步骤整合起来,使流程更简洁高效。​

预处理管道构建代码示例​

numeric_transformer = Pipeline(steps=[​

('imputer', SimpleImputer(strategy='mean')),​

('scaler', StandardScaler())​

])​

# 构建分类型特征的预处理管道:填充缺失值+独热编码​

categorical_transformer = Pipeline(steps=[​

('imputer', SimpleImputer(strategy='most_frequent')), # 分类型特征用众数填充​

('onehot', OneHotEncoder(handle_unknown='ignore'))​

])​

# 整合所有特征的预处理管道​

preprocessor = ColumnTransformer(​

transformers=[​

('num', numeric_transformer, numeric_features),​

('cat', categorical_transformer, categorical_features)​

])​

# 构建完整的预处理+模型管道(此处仅展示预处理部分)​

pipeline = Pipeline(steps=[('preprocessor', preprocessor)])​

# 对训练集进行预处理​

X_train_processed = pipeline.fit_transform(X_train)​

# 对测试集进行预处理​

X_test_processed = pipeline.transform(X_test)​

print("管道处理后的训练集:")​

print(X_train_processed)​

比如在一个包含多种类型特征的数据集(如既有数值型的年龄、收入,又有分类型的职业、学历)中,使用预处理管道可以自动对不同类型的特征应用相应的预处理步骤,避免人工操作的繁琐和错误。​

(十一)不同数据类型的预处理差异​

除了结构化数据,我们在实际应用中还会遇到文本、图像等非结构化数据,它们的预处理方法与结构化数据有所不同。​

1. 文本数据预处理​

文本数据需要进行分词、去除停用词、词向量转换等操作。例如:​

from sklearn.feature_extraction.text import TfidfVectorizer​

import nltk​

from nltk.corpus import stopwords​

nltk.download('stopwords')​

# 示例文本数据​

texts = ["I love machine learning", "Machine learning is interesting"]​

# 文本预处理:去除停用词+TF-IDF转换​

tfidf = TfidfVectorizer(stop_words=stopwords.words('english'))​

text_features = tfidf.fit_transform(texts).toarray()​

print("文本数据预处理后:")​

print(text_features)​

2. 图像数据预处理​

图像数据通常需要进行缩放、归一化、数据增强等操作。例如:​

from PIL import Image​

import numpy as np​

# 读取图像并缩放为28x28​

image = Image.open('image.jpg').resize((28, 28))​

# 转换为数组并归一化到[0,1]​

image_array = np.array(image) / 255.0​

print("图像数据预处理后形状:", image_array.shape)​

(十二)预处理后的验证​

预处理完成后,我们需要对处理结果进行验证,确保预处理步骤正确有效。可以通过以下方式验证:​

  • 统计指标:查看处理后数据的均值、标准差、缺失值比例等,确认符合预期。​
  • 可视化:绘制处理后数据的分布直方图、箱线图等,观察数据分布是否合理。​
  • 模型验证:使用处理后的数据训练简单模型,若模型性能明显提升,说明预处理有效。​

例如,我们可以对比预处理前后模型在测试集上的准确率:​

from sklearn.linear_model import LogisticRegression​

# 用未预处理的数据训练模型​

model_raw = LogisticRegression()​

model_raw.fit(X_train, Y_train)​

acc_raw = model_raw.score(X_test, Y_test)​

# 用预处理后的数据训练模型​

model_processed = LogisticRegression()​

model_processed.fit(X_train_processed, Y_train)​

acc_processed = model_processed.score(X_test_processed, Y_test)​

print("未预处理模型准确率:", acc_raw)​

print("预处理后模型准确率:", acc_processed)​

若预处理后模型准确率显著提高,说明预处理步骤是有效的。​

总结​

数据预处理是机器学习项目成功的关键,它涉及数据清洗、转换、选择等多个环节。从基础的缺失值处理、特征缩放,到高级的预处理管道构建,每一步都需要结合数据特点和模型需求进行合理选择。同时,对于不同类型的数据(结构化、文本、图像等),要采用相应的预处理方法。通过构建规范的预处理流程并进行有效验证,我们能为后续的模型训练提供高质量的数据,从而提升机器学习模型的性能和可靠性。希望本文的内容能帮助读者在实际项目中更好地进行数据预处理,为构建优秀的机器学习模型奠定坚实基础。

 还想看更多,来啦!!!

1,大数据比赛篇全国职业院校技能大赛-大数据比赛心得体会_全国职业职业技能比赛 大数据-CSDN博客

2,求职简历篇(超实用)大学生简历写作指南:让你的简历脱颖而出-CSDN博客

3,AIGC心得篇aigc时代,普通人需要知道的-CSDN博客

4,数据分析思维篇学习数据分析思维的共鸣-CSDN博客

5,中年危机篇“中年危机”如何转变为“中年机遇”-CSDN博客

其他需求,看主页哦!

http://www.xdnf.cn/news/15901.html

相关文章:

  • FastMCP全篇教程以及解决400 Bad Request和session termination的问题
  • IOPaint+CPolar:零公网IP也能搭建专属AI图像编辑平台
  • Git 完全手册:从入门到团队协作实战(3)
  • doker centos7安装1
  • uni-app 鸿蒙平台条件编译指南
  • 【C++11】哈希表与无序容器:从概念到应用
  • 完整的 SquareStudio 注册登录功能实现方案:
  • 亚马逊新品推广关键:如何通过广告数据反馈不断优化关键词
  • 【安全篇 / 反病毒】(7.6) ❀ 01. 查杀HTTPS加密网站病毒 ❀ FortiGate 防火墙
  • Docker安装Elasticsearch 7.17.0和Kibana 7.17.0并配置基础安全
  • 17 BTLO 蓝队靶场 Pretium 解题记录
  • MySQL表的基础操作
  • 微软CEO Satya Nadella提出AI重构法则:从范式跃迁到社会盈余
  • 病历数智化3分钟:AI重构医院数据价值链
  • OpenGL鼠标控制沿着指定轴旋转
  • JSX(JavaScript XML)‌简介
  • wordle game(猜词游戏)小demo【react + ts】
  • 删除 XML 格式中双引号内的空格
  • 前后端分离项目进阶1---后端
  • Apache IoTDB(2):时序数据库 IoTDB 集群安装部署的技术优势与适用场景分析
  • Electron 主进程与渲染进程之间交互方式
  • 跑腿小程序|基于微信小程序的跑腿平台小程序设计与实现(源码+数据库+文档)
  • kotlin和Jetpack Compose对于Android系统来说是什么关系?
  • 【HTTP缓存机制深度解析:从ETag到实践策略】
  • c语言 进阶 动态内存管理
  • 客流分析核心算法 trajectory_event_analyzer数据结构
  • 深入解析Hadoop YARN:三层调度模型与资源管理机制
  • 单表查询-counter的使用
  • Centos卷挂载失败系统无法启动
  • c++ duiLib 使用xml文件编写界面布局