万字详解AI开发中的数据预处理(清洗)

数据清洗(Data Cleaning)是通过修改、添加或删除数据的方式为数据分析做准备的过程,这个过程通常也被称为数据预处理(Data Preprocessing)。对于数据科学家和机器学习工程师来说,熟练掌握数据清洗全流程至关重要,因为数据预处理后的质量将直接影响他们或训练的模型从数据中获得的所有结论和观点(insights)

在这篇博文中,我们将重点讲述类别型特征(categorical feature)方面的数据清理概念(本文第5部分),给出合适的图片以帮助理解,并提供代码演示等。

在本文结束时,我相信你不仅会了解什么是数据清洗,还能完美地掌握数据清洗的步骤,如何进行实操,以及最重要的是如何从你的数据中得到最好的结果。

01 为什么我们需要清洗数据?

有时,在我们能够从数据中提取有用的信息之前,需要对数据进行清洗/预处理。大多数现实生活中的数据都有很多需要处理的地方,如缺失值、非信息特征等,因此,在使用数据之前,我们一直需要对其进行清洗,以便在使用数据时达到最佳效果。

以机器学习流程为例,它的工作对象只有数字。如果我们打算使用具有文本、日期时间特征和其他非数字特征的数据,我们需要找到一种方法,用数字****来表示它们,而不丢失它们所携带的信息

比如说一个简单的逻辑回归模型只是用一个线性函数将因变量映射到自变量上,如:y= wx + b。其中,w是权重,可以是任何数字,b是偏差,也是一个数字。

如果给你一组数据;[小、中、大],你会发现不可能计算出:y=w*small+b。

但如果你把“小”编码为1,“中”编码为2,“大”的编码为3,从而把你的数据转化为[1,2,3],你会发现你不仅能够计算y=w*1+b,而且其中编码的信息仍然被保留

02 数据清洗有哪些步骤?

数据清洗是我们在为数据分析做准备的过程中对数据进行的一系列操作的统称。

数据清洗的步骤包括:

  • 处理缺失值(Handling missing values)
  • 对类别型特征进行编码(Encoding categorical features)
  • 异常值检测(Outliers detection)
  • 变换(Transformations)

后续我们将重点展开处理缺失值和对类别型特征进行编码。

03 处理缺失值(Handling missing values)

在进行数据预处理时遇到的最常见的问题之一就是我们数据中存在缺失值。这个情况是非常常见的,可能因为 :

  • 填写数据的人有意或无意的遗漏,或者数据根本不适合填在此处。
  • 工作人员将数据输入电脑时出现遗漏。

数据科学家如果不注意,可能会从包含缺失值的数据中得出错误的推论,这就是为什么我们需要研究缺失值并学会有效地解决它。

早期的机器学习库(比如scikit learn)不允许将缺失值传入。这就会带来一定的挑战,因为数据科学家在将数据传递给scikit learn ML模型之前,需要迭代很多方法来处理缺失值。最新的机器学习模型和平台已经解除了这一障碍,特别是基于梯度提升机(gradient boosting machines)的一些算法或工具,如Xgboost、Catboost、LightGBM等等

我特别看好的是Catboost方法,它允许用户在三个选项(Forbidden, Min, and Max)中进行选择。Forbidden将缺失值视为错误,而Min将缺失值设定为小于特定特征(列)中的所有其他值。这样,我们就可以肯定,在对特征进行基本的决策树分裂(decision tree splitting)时,这些缺失值也会被考虑在内。

LightGBM[1]和XGboost[2]也能以相当方便的方式处理缺失值。然而,在进行预处理时,要尽可能多地尝试各种方法。使用像我们上面讨论的那些库,其他的工具,如automl等等。

缺失值一般分为三类,即:

  1. 完全随机缺失(MCAR) 。如果我们没有任何信息、理由或任何可以帮助计算它的东西,那么这个缺失值就是完全随机缺失。例如,“我是一个很困的研究生,不小心把咖啡打翻在我们收集的纸质调查表上,让我们失去了所有本来我们会有的数据。”

  2. 随机缺失(MAR) 。如果我们有信息、理由或任何东西(特别是来自其他已知值)可以帮助计算,那么这个缺失值就是随机缺失。例如,“我进行一项调查,其中有一个关于个人收入的问题。但是女性不太可能直接回答关于收入的问题。”

  3. 非随机缺失(NMAR) 。缺失的变量的值与它缺失的原因有关。例如,“如果我进行的调查包括一个关于个人收入的问题。那些低收入的人明显不太可能回答这个问题”。因此,我们知道为什么这种数据点可能缺失。

04 如何使用Python检测缺失值?

在我们处理缺失值之前,我们理应学习如何检测它们,并根据缺失值的数量、我们有多少数据等等来决定如何处理我们的数据。我喜欢并经常使用的一个方法是为某一列设置一个阈值,以决定它是可以修复还是无法修复。

下面,你会看到一个函数,它实现了我们在之前讨论的一些想法。

ini复制代码def missing_removal(df, thresh, confirm= None):holder= {}for col in df.columns:rate= df[col].isnull().sum() / df.shape[0]if rate > thresh:holder[col]= rateif confirm==True:df.drop(columns= [i for i in holder], inplace= True)return dfelse:print(f' Number of columns that have Nan values above the thresh specified{len(holder)}')return holder

Quick note

如果confirm参数设置为True,所有缺失值百分比高于设定阈值的列都会被删除;如果confirm参数设置为None或False,该函数会返回数据中所有列的缺失值百分比列表。现在去你的数据上试试吧!

4.1 统计归纳法(Statistical imputation)

这是一种被长期证明有效的方法。只需要简单地用某一列的平均数、中位数、模式来填补该列中的缺失数据。这很有效,正在阅读的伙伴们,请相信我!

Scikit-learn提供了一个名为SimpleImputer[3]的子类,就是以这种方式处理我们的缺失值。

下面是一个简短的代码描述,能够有助于我们更好地理解统计归因法。

ini复制代码from sklearn.impute import SimpleImputer
# store the columns of the dataframe 存储dataframe的所有列
cols= df.columns#instantiate the SimpleImputer subclass 实例化SimpleImputer子类
#Depending on how you want to imput, you can use most_frequent, mean, median and constant 根据你想输入的方式,你可以使用most_frequent、mean、median和constant。
imputer= SimpleImputer(strategy= 'most_frequent')
df= imputer.fit_transform(df)# convert back to dataframe 转换回dataframe
df= pd.DataFrame(df, columns= cols)

4.2 链式方程多重填补 Multiple Imputation by Chained Equations (MICE)

在这种方法中,每一列和它的缺失值被建模为数据中其他列的函数。 这个过程不断重复,直到之前计算出的值与当前值之间的公差非常小,并且低于给定的阈值。

Scikit-learn提供了一个名为IterativeImputer[4]的子类,可以用它处理缺失值。

下面是一个简短的代码描述,希望能帮你理解这种方法。

ini复制代码from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer# store the columns of the dataframe 存储dataframe的所有列
cols= df.columns#instantiate IterativeImputer subclass 实例化IterativeImputer子类
imputer= IterativeImputer(max_iter= 3)
df= imputer.fit_transform(df)# convert back to dataframe 转换回dataframe
df= pd.DataFrame(df, columns= cols)

希望上述这些内容足以让你有效地处理缺失值。

关于缺失值的更多信息,请查看Matt Brems的这份材料[5]。

05 对类别型特征进行编码(Encoding categorical features)

5.1 什么是类别型特征

类别型特征是只取离散值的特征。它们不具有连续值,如3.45,2.67等。一个类别型特征的值可以是大、中、小,1-5的排名,是和不是,1和0,黄色、红色、蓝色等等。它们基本上代表类别,如年龄组、国家、颜色、性别等。

很多时候类别型特征是以文本格式出现的,有些时候它们是以数字格式出现的(大多数人经常无法识别这种格式的类别型特征)。

5.2 如何识别类别型特征?

如何识别类别型特征不应该是一个大问题,大多数时候,分类特征是以文本格式出现的。

如果有一种排名形式,而且它们实际上是以数字格式出现的,那怎么办?此时要做的就是检查一列中唯一值的数量,并将其与该列中的行数进行比较。 例如,一列有2000行,只有5或10个唯一值,你很可能不需要别人来告诉你该列是分类列。这没有什么规则,只能依靠直觉,你可能是对的,也可能是错的。

5.3 类别型特征编码方法

  • 给定一个类别型特征,正如前文我们所研究的那样,我们面临的问题是将每个特征中的独特类别转换为数字,同时不丢失其中编码的信息。基于一些可观察的特征,有各种类别型特征的编码方法。同时也有两类类别型特征:
  • 有序的类别型特征:在这一特定特征中,类别之间存在固有的顺序或关系,例如大小(小、大、中)、年龄组等。
  • 无序的类别型特征:该特征的类别之间没有合理的顺序,如国家、城市、名称等。

处理上述两类的方法是不同的。我在处理无序的类别型特征时使用下面这些方法:

  • 独热编码(One-hot encoding)
  • 频数编码(Frequency/count encoding)
  • 目标编码/均值编码(Target mean encoding)
  • 有序整数编码(Ordered integer encoding)
  • 二进制编码(Binary encoding)
  • 留一法(Leave-one-out)编码
  • 证据权重编码(Weight of evidence encoding)

对于有序的类别型特征,我们只使用

  • 标签编码或序号编码(Label encoding or ordinal encoding)

现在,我们将尝试一个接一个地研究其中的一些方法。并尽可能地用Python实现它们,主要是使用名为category_encoders的Python库。

可以使用 pip install category_encoders 来安装这个库。

1) 独热编码(One-hot encoding)

独热编码是对无序的类别型特征(nominal categorical features)进行编码的最有效方法之一。这种方法为列中的每个类别创建一个新的二进制列。理想情况下,我们会删除其中一列以避免各列之间的共线性,因此,具有K个唯一类别的特征会在数据中产生额外的K-1列。

这种方法的缺点是,当一个特征有许多唯一的类别或数据中有许多类别型特征时,它就会扩展特征空间(feature space)。

图片

上图解释了独热编码的概念,以该种方式对特征进行编码能够消除所有形式的分层结构。

下面介绍如何在Python中实现这种方法。

kotlin复制代码import pandas as pd
data= pd.get_dummies(data, columns, drop_first= True)
#check https://pandas.pydata.org/docs/reference/api/pandas.get_dummies.html for more info

2)频数编码(Frequency/count encoding)

这种方法同样非常有效。它根据无序的类别型特征在特征(列)中出现的频率为无序的类别型特征引入了分层结构(hierarchy)。 它与计数编码非常相似,因为计数编码可以取任何值,而频率编码则规一化为0到1之间。

图片

下面介绍频数编码在Python中的实现:

python复制代码# Frequency encoding 频率编码
# cols is the columns we wish to encode cols参数是我们要编码的那些列
#df is the dataFrame df参数是dataFrame
def freq_enc(df, cols):for col in cols:df[col]= df[col].map(round(df[col].value_counts()/len(df),4))return df# count encoding 计数编码
def count_enc(df, cols):for col in cols:df[col]= df[col].map(round(df[col].value_counts()))return df

3) 目标编码/均值编码(Target mean encoding)

这种方法的思路是非常好的!它有一个非常独特的地方,就是它在计算过程中使用了目标列,这在一般的机器学习应用过程中是非常罕见的。类别型特征中的每一个类别都被替换成该类别目标列的平均值。

该方法非常好,但是如果它编码了太多关于目标列的信息,可能会导致过拟合。因此,在使用该方法之前,我们需要确保这个类别型特征与目标列没有高度关联。

测试数据通过映射使用来自训练数据的存储值进行编码。

图片

下面介绍目标编码/均值编码在Python中的实现:

ini复制代码# target mean encoding
#target_col is the name of the target column (str)
def target_mean_enc(df, cols, target_col):mean_holder= {}for col in cols:col_mean= {}cat= list(df[col].unique())for i in cat:data= df[df[col]== i]mean= np.mean(data[target_col])col_mean[i]= meanmean_holder[col]= col_meanreturn mean_holder

上面的函数返回一个字典,其中包含被编码列的平均值,然后将字典映射到数据上。见下图:

图片

4) 有序整数编码(Ordered integer encoding)

这种方法与目标编码/均值编码非常相似,只是它更进一步,它根据目标均值(target mean)的大小对类别进行排序。

图片

在实现有序整数编码后,dataframe看起来像这样:

图片

下面介绍有序整数编码在Python中的实现:

css复制代码def ordered_interger_encoder(data, cols, target_col):mean_holder= {}for col in cols:labels = list(enumerate(data.groupby([col])[target_col].mean().sort_values().index))col_mean= {value:order for order,value in labels}mean_holder[col]= col_meanreturn mean_holder

5) 二进制编码(Binary encoding)

二进制编码的工作原理是独一无二的,几乎与独热编码类似,不过还是有很多创新点。首先,它根据那些唯一特征(unique features)在数据中的出现方式为其分配level(不过这个level没有任何意义) 。然后,这些level被转换为二进制最后各个数字被划分到不同的列

图片

下面介绍了使用category_encoders库进行二进制编码的演示:

ini复制代码from category_encoders import BinaryEncoder
binary= BinaryEncoder(cols= ['STATUS'])
binary.fit(data)
train= binary.transform(train_data)
test= binary.transform(test_data)

6) 留一法(Leave-one-out)编码

这种方法也非常类似于目标编码/均值编码,只是在每个级别上都计算目标均值,而不是只考虑在特定级别上。不过,目标编码/均值编码仍用于测试数据(查看更多信息[6])。

图片

下面介绍留一法(Leave-one-out)编码在Python中的实现:

ini复制代码from category_encoders import leave_one_out
binary= leave_one_out(cols= ['STATUS'])
binary.fit(data)
train= binary.transform(train_data)
test= binary.transform(test_data)

7) 证据权重编码(Weight of evidence encoding)

这是一种已经在信用风险分析中使用了长达七十年的方法。它通常用于逻辑回归任务的特征转化,因为它有助于揭示我们之前可能看不到的特征之间的相关性。这种方法只能用于分类任务。

它通过对列中的每个类别应用ln(p(good)/p(bad))来转换分类列。

p(good)是目标列的一个类别,例如p(1),而p(bad)是第二种类别,可能只是p(0)。

图片

下面介绍了使用category_encoders库进行证据权重编码的演示:

ini复制代码from category_encoders import WOEEncoder
binary= WOEEncoder(cols= ['STATUS'])
binary.fit(data)
train= binary.transform(train_data)
test= binary.transform(test_data)

8) 标签编码(Label Encoding)和序号编码(Ordinal Encoding)

这种方法用于对无序的类别型特征进行编码,我们只需要根据我们可以推断出的大小为每个类别分配数字。

图片

下面介绍这种方法在Python中的实现:

bash复制代码df['size']= df['size'].map({'small':1, 'medium':2, 'big':3})
df

06 数据清洗工具和库

在该文章中提到了一些机器学习库,如scikit learn[7]和category_encoders[8]。还有其他一些有助于数据预处理的Python库,包括:Numpy, Pandas, Seaborn, Matplotlib, Imblearn等等。

然而,如果你是那种不喜欢写太多代码的人,你可以看看OpenRefine[9]、Trifacta Wrangler[10]等这些工具。

07 总结

到此为止,我们所讨论的大部分概念的代码实现与实例都可以在本文找到。我希望这篇文章能够让你对特征编码(Categorical Encoding) 的概念和如何填补缺失值有一个较深刻的认识。

如果你要问应该使用哪种方法?

数据清洗是一个反复的过程,因此,你可以随意尝试,并坚持使用对你的数据最有效的那一种。

读者福利:如果大家对大模型感兴趣,这套大模型学习资料一定对你有用

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

资源分享

图片

大模型AGI学习包

图片

图片

资料目录

  1. 成长路线图&学习规划
  2. 配套视频教程
  3. 实战LLM
  4. 人工智能比赛资料
  5. AI人工智能必读书单
  6. 面试题合集

人工智能\大模型入门学习大礼包》,可以扫描下方二维码免费领取

1.成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

图片

2.视频教程

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩

图片

3.LLM

大家最喜欢也是最关心的LLM(大语言模型)

图片

人工智能\大模型入门学习大礼包》,可以扫描下方二维码免费领取

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

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

相关文章

21_硬件电路基础

目录 组合逻辑电路 组合逻辑电路原理 真值表 布尔代数 门电路 译码器 发光二极管LED 液晶字符显示器LCD 数据选择器 数据分配器 多路开关 时序逻辑电路 时序逻辑电路原理 时钟信号 触发器 电位触发方式触发器 边沿触发方式触发器 寄存器 移位器 计数器 总线…

经营人心:Mrs. B的百年传奇

这个故事的主角是Rose Blumkin,也被称为Mrs. B,她是Nebraska Furniture Mart的创始人。 她的故事确实是一个关于用户思维、客户关系和创业精神的经典案例。 Rose Blumkin于1893年出生在俄罗斯的一个小村庄,她在1921年移民到美国。 1937年&…

ImportError cannot import name ‘uic‘ from ‘PyQt5‘

ImportError cannot import name ‘uic’ from ‘PyQt5’ 1、描述 使用nuitka把PyQt5打包exe文件时报错: ImportError cannot import name ‘uic’ from ‘PyQt5’ 2、原因 这个是由于无法找到uic的目录导致的,在PyQt5的目录下是有uic文件的。 3、解决方案 找到导入uic…

SQL Server 2022的组成

《SQL Server 2022从入门到精通(视频教学超值版)》图书介绍-CSDN博客 SQL Server 2022主要由4部分组成,分别是数据库引擎、分析服务、集成服务和报表服务。本节将详细介绍这些内容。 1.2.1 SQL Server 2022的数据库引擎 SQL Server 2022的…

NGINX+KEEPALIVED | 一文搞懂NG+KL负载均衡高可用架构的实操教程(详细)

文章目录 NGINXKEEPALIVED负载均衡高可用架构为什么需要多节点应用为什么需要Nginx服务为什么需要Keepalived服务NGKL简述前期准备Linux服务器公共环境配置Server1 NGKL服务器配置Server2 NGKL服务器配置Server3 HTTP服务器配置Server4 HTTP服务器配置运行测试用例 NGINXKEEPAL…

使用Keil将STM32部分程序放在RAM中运行

手动分配RAM区域,新建.sct文件,定义RAM_CODE区域,并指定其正确的起始地址和大小。 ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************…

C语言 -- 函数

C语言 -- 函数 1. 函数的概念2. 库函数2.1 标准库和头文件2.2 库函数的使用方法2.2.1 功能2.2.2 头文件包含2.2.3 实践2.2.4 库函数文档的一般格式 3. 自定义函数3.1 函数的语法形式3.2 函数的举例 4. 形参和实参4.1 实参4.2 形参4.3 实参和形参的关系 5. return 语句6. 数组做…

Element中的消息提示组件Message和弹框组件MessageBox

简述:在 Element UI 中,Message和MessageBox都是比较常用的组件,Message用来提示消息,而MessageBox是一个用于创建模态对话框的组件。它可以用于在页面上快速展示信息、警告或错误提示,而不会阻止用户的其他操作。简单…

116-基于5VLX110T FPGA FMC接口功能验证6U CPCI平台

一、板卡概述 本板卡是Xilinx公司芯片V5系列芯片设计信号处理板卡。由一片Xilinx公司的XC5VLX110T-1FF1136 / XC5VSX95T-1FF1136 / XC5VFX70T-1FF1136芯片组成。FPGA接1片DDR2内存条 2GB,32MB Nor flash存储器,用于存储程序。外扩 SATA、PCI、PCI expres…

【期末复习】数据库系统概论(附带考点汇总)

第1章.绪论 目录 第1章.绪论1.1. 数据库系统概述1.1.1.基本概念1.1.2.产生和发展 1.2.概念模型1.2.1.三种模型1.2.2.概念模型1.2.3.关系模型 1.3.数据库系统结构1.3.1三级模式结构1.3.2.两级映像与数据独立性 第2章.关系型数据库2.1.关系2.2.关系操作2.2.1.基本关系操作2.2.2.关…

SALOME源码分析:View Model

作为一款开源的CAx(CAD/CAE/CAM)软件集成平台,为了实现各个Module支持不同的数据显示与交互方案,出于扩展性的考虑,SALOME引入了View Model,用以支持OpenGL、OCC、VTK、ParaView、Qwt等数据显示与交互实现。 本文将以OCCViewer、…

昇思25天学习打卡营第16天|Diffusion扩散模型

导入必要的库函数 import math from functools import partial %matplotlib inline import matplotlib.pyplot as plt from tqdm.auto import tqdm import numpy as np from multiprocessing import cpu_count from download import downloadimport mindspore as ms import mi…

Python基于卷积神经网络分类模型(CNN分类算法)实现时装类别识别项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 在深度学习领域,卷积神经网络(Convolutional Neural Networks, CNNs&#xff0…

【架构-20】死锁

什么是死锁? 死锁(Deadlock)是指两个或多个线程/进程在执行过程中,由于资源的互相占用和等待,而陷入一种互相等待的僵局,无法继续往下执行的情况。 产生死锁的四个必要条件: (1)互斥条件(Mutual Exclusion):至少有一个资源是非共享…

Elasticsearch:结合稀疏、密集和地理字段

作者:来自 Elastic Madhusudhan Konda 如何以自定义方式组合多个稀疏、密集和地理字段 Elasticsearch 是一款强大的工具,可用于近乎实时地搜索和分析数据。作为开发人员,我们经常会遇到包含各种不同字段的数据集。有些字段是必填字段&#x…

relation-graph——数据组装+鼠标移入后的详情(自定义插槽的用法)——js技能提升

最近在写后台管理系统的时候,遇到一个需求,就是给我一些节点,让我渲染到页面上,效果图如下: 之前写过一篇文章关于relation-graph关系图组件http://t.csdnimg.cn/7BGYm的用法 还有一篇关于relation-graph——实现右击…

回溯算法-以单位人事管理系统为例

1.回溯算法介绍 1.来源 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。 用回溯算法解决问题的一般步骤: 1、 针对所给问题,定义问题的解空间,它至少包含问题的一个(最优)解。 2 、确定易于搜…

rk3568 OpenHarmony 串口uart与电脑通讯开发案例

一、需求描述: rk3568开发板运行OpenHarmony4.0,通过开发板上的uart串口与电脑进行通讯,相互收发字符串。 二、案例展示 1、开发环境: (1)rk3568开发板 (2)系统:OpenHar…

又一个被催的相亲对象!家庭不和,是因为智慧不够?——早读(逆天打工人爬取热门微信文章解读)

你相亲过吗? 引言Python 代码第一篇 洞见 家庭不和,是因为智慧不够第二篇 口播结尾 引言 yue 昨天居然忘记了 正事:拍视频j 居然忘记了 别着急 让我找下理由(借口) 前天我妈给我介绍了个相亲对象 推给我了她的微信 我…

网络攻防——kali操作系统基本使用

1.阅读前的声明 本文章中生成的木马带有一定的攻击性,使用时请遵守网络安全相关的法律法规(恶意攻击操作系统属于违法行为)。 2.环境安装 生成木马主要需要如下工具:kali操作系统,VMware15(搭建kali操作…