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

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

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

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

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

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

(一)导入需要的库​

在进行数据预处理之前,我们首先要导入一些必要的库,就像做菜前要准备好厨具一样。其中,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.dtcms.com/a/291600.html

相关文章:

  • Spring 对数组和集合类的自动注入
  • 234、回文链表
  • 使用AI把普通的条形柱状图,丰富成“好看高大上”的条形柱状图
  • 解决win10下Vmware虚拟机在笔记本睡眠唤醒后ssh连接不上的问题
  • PyQt5—QInputDialog 学习笔记
  • 印度给巴铁断水,中国悄然开建雅鲁藏布江水电站,纯属巧合!
  • Python 标准库之 os 模块全面讲解
  • 大模型为什么出现幻觉?
  • 在Anolis8.6上源码编译安装部署OpenVAS(GVM)未完待续
  • 华为云CCE-PV使用OBS存储类之坑
  • Android NDK ffmpeg 音视频开发实战
  • 语义化版本规范(SemVer)
  • 【计算机组成原理】符号位OF、ZF、CF、SF详解
  • c语言 进阶 动态内存管理
  • stream event
  • Playwright-MCP浏览器会话复用全解析
  • swiper js无缝滚动---解决播放总是有间隔、动画一闪一跳的问题
  • 3.组合式API父子通信
  • 【免费版】开启 Youtube 双语字幕
  • 神经网络——非线性激活
  • Java学习-----AIO模型
  • STM32小实验四--按键控制LED灯
  • tar 解压:Cannot change ownership to uid 1000, gid 1000: Operation not permitted
  • 2021-06-27 51单片机外部中断0控制数码管0自增到9
  • 知识之镜:当检索生成照见人类认知的深渊
  • C++ 分配内存释放内存
  • LinkedList的模拟实现(双向链表Java)
  • JavaScript的引入方式和基础语法的快速入门与学习
  • 单表查询-分页提前获取数据
  • ni-app 对鸿蒙的支持现状