10000字!图解机器学习特征工程

news2024/12/23 14:14:40

文章目录

  • 引言
  • 特征工程
  • 1.特征类型
    • 1.1 结构化 vs 非结构化数据
    • 1.2 定量 vs 定性数据
  • 2.数据清洗
    • 2.1 数据对齐
    • 2.2 缺失值处理

原文链接:https://www.showmeai.tech/article-detail/208
作者:showmeAI

引言

在这里插入图片描述
上图为大家熟悉的机器学习建模流程图,ShowMeAI在前序机器学习实战文章 Python机器学习算法应用实践中和大家讲到了整个建模流程非常重要的一步,是对于数据的预处理和特征工程,它很大程度决定了最后建模效果的好坏,在本篇内容汇总,我们给大家展开对数据预处理和特征工程的实战应用细节做一个全面的解读。

特征工程

首先我们来了解一下「特征工程」,事实上大家在ShowMeAI的实战系列文章 Python机器学习综合项目-电商销量预估Python机器学习综合项目-电商销量预估<进阶> 中已经看到了我们做了特征工程的处理。

如果我们对特征工程(feature engineering)做一个定义,那它指的是:利用领域知识和现有数据,创造出新的特征,用于机器学习算法;可以手动(manual)或自动(automated)。

  • 特征:数据中抽取出来的对结果预测有用的信息。
  • 特征工程:使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。

在业界有一个很流行的说法:

数据与特征工程决定了模型的上限,改进算法只不过是逼近这个上限而已。

在这里插入图片描述

这是因为,在数据建模上,「理想状态」和「真实场景」是有差别的,很多时候原始数据并不是规矩干净含义明确充分的形态:
在这里插入图片描述
而特征工程处理,相当于对数据做一个梳理,结合业务提取有意义的信息,以干净整齐地形态进行组织:
在这里插入图片描述
特征工程有着非常重要的意义:

  • 特征越好,灵活性越强。只要特征选得好,即使是一般的模型(或算法)也能获得很好的性能,好特征的灵活性在于它允许你选择不复杂的模型,同时运行速度也更快,也更容易理解和维护。
  • 特征越好,构建的模型越简单。有了好的特征,即便你的参数不是最优的,你的模型性能也能仍然会表现的很好,所以你就不需要花太多的时间去寻找最优参数,这大大的降低了模型的复杂度,使模型趋于简单。
  • 特征越好,模型的性能越出色。显然,这一点是毫无争议的,我们进行特征工程的最终目的就是提升模型的性能。

本篇内容,ShowMeAI带大家一起来系统学习一下特征工程,包括「特征类型」「数据清洗」「特征构建」「特征变换」「特征选择」等板块内容。

我们这里用最简单和常用的Titanic数据集给大家讲解。

Titanic数据集是非常适合数据科学和机器学习新手入门练习的数据集,数据集为1912年泰坦尼克号沉船事件中一些船员的个人信息以及存活状况。我们可以根据数据集训练出合适的模型并预测新数据(测试集)中的存活状况。

Titanic数据集可以通过 seaborn 工具库直接加载,如下代码所示:

import pandas as pd
import numpy as np
import seaborn as sns

df_titanic = sns.load_dataset('titanic')

其中数据集的数据字段描述如下图所示:
在这里插入图片描述

1.特征类型

在具体演示Titanic的数据预处理与特征工程之前,ShowMeAI再给大家构建一些关于数据的基础知识。

1.1 结构化 vs 非结构化数据

数据可以分为「结构化数据」和「非结构化数据」,比如在互联网领域,大部分存储在数据库内的表格态业务数据,都是结构化数据;而文本、语音、图像视频等就属于非结构化数据。
在这里插入图片描述

1.2 定量 vs 定性数据

对于我们记录到的数据,我们通常又可以以「定量数据」和「定性数据」对齐进行区分,其中:

  • 定量数据:指的是一些数值,用于衡量数量与大小。
    例如高度,长度,体积,面积,湿度,温度等测量值。
  • 定性数据:指的是一些类别,用于描述物品性质。
    例如纹理,味道,气味,颜色等。

在这里插入图片描述
如下图是两类数据示例以及它们常见的处理分析方法的总结:
在这里插入图片描述

2.数据清洗

实际数据挖掘或者建模之前,我们会有「数据预处理」环节,对原始态的数据进行数据清洗等操作处理。因为现实世界中数据大体上都是不完整、不一致的「脏数据」,无法直接进行数据挖掘,或者挖掘结果差强人意。

「脏数据」产生的主要成因包括:

  • 篡改数据
  • 数据不完整
  • 数据不一致
  • 数据重复
  • 异常数据

数据清洗过程包括数据对齐、缺失值处理、异常值处理、数据转化等数据处理方法,如下图所示:
在这里插入图片描述
下面我们注意对上述提到的处理方法做一个讲解。

2.1 数据对齐

采集到的原始数据,格式形态不一,我们会对时间、字段以及相关量纲等进行数据对齐处理,数据对齐和规整化之后的数据整齐一致,更加适合建模。如下图为一些处理示例:
在这里插入图片描述
(1) 时间

  • 日期格式不一致【2022-02-20、20220220、2022/02/20、20/02/2022】。
  • 时间戳单位不一致,有的用秒表示,有的用毫秒表示。
  • 使用无效时间表示,时间戳使用0表示,结束时间戳使用FFFF表示。
    (2) 字段
  • 姓名写了性别,身份证号写了手机号等。
    (3) 量纲
  • 数值类型统一【如1、2.0、3.21E3、四】。
  • 单位统一【如180cm、1.80m】。

2.2 缺失值处理

数据缺失是真实数据中常见的问题,因为种种原因我们采集到的数据并不一定是完整的,我们有一些缺失值的常见处理方式:

  • 不处理(部分模型如XGBoost/LightGBM等可以处理缺失值)。
  • 删除缺失数据(按照样本维度或者字段维度)。
  • 采用均值、中位数、众数、同类均值或预估值填充。

具体的处理方式可以展开成下图:
在这里插入图片描述
下面回到我们的Titanic数据集,我们演示一下各种方法:

我们先对数据集的缺失值情况做一个了解(汇总分布):

df_titanic.isnull().sum()
survived         0
pclass           0
sex              0
age            177
sibsp            0
parch            0
fare             0
embarked         2
class            0
who              0
adult_male       0
deck           688
embark_town      2
alive            0
alone            0

(1) 删除
最直接粗暴的处理是剔除缺失值,即将存在遗漏信息属性值的对象 (字段,样本/记录) 删除,从而得到一个完备的信息表。优缺点如下:

  • 优点:简单易行,在对象有多个属性缺失值、被删除的含缺失值的对象与初始数据集的数据量相比非常小的情况下有效;
  • 不足:当缺失数据所占比例较大,特别当遗漏数据非随机分布时,这种方法可能导致数据发生偏离,从而引出错误的结论。

在我们当前Titanic的案例中,embark_town字段有 2 个空值,考虑删除缺失处理下。

df_titanic[df_titanic["embark_town"].isnull()]
df_titanic.dropna(axis=0,how='any',subset=['embark_town'],inplace=True)

在这里插入图片描述
(2) 数据填充
第2大类是我们可以通过一些方法去填充缺失值。比如基于统计方法、模型方法、结合业务的方法等进行填充。
在这里插入图片描述
① 手动填充
根据业务知识来进行人工手动填充。

② 特殊值填充
将空值作为一种特殊的属性值来处理,它不同于其他的任何属性值。如所有的空值都用unknown填充。一般作为临时填充或中间过程。

代码实现

df_titanic['embark_town'].fillna('unknown', inplace=True)

③ 统计量填充
若缺失率较低,可以根据数据分布的情况进行填充。常用填充统计量如下:

  • 中位数:对于数据存在倾斜分布的情况,采用中位数填补缺失值。
  • 众数:离散特征可使用众数进行填充缺失值。
  • 平均值:对于数据符合均匀分布,用该变量的均值填补缺失值。

中位数填充——fare:缺失值较多,使用中位数填充
在这里插入图片描述

df_titanic['fare'].fillna(df_titanic['fare'].median(), inplace=True)

众数填充——embarked:只有两个缺失值,使用众数填充

df_titanic['embarked'].isnull().sum()
#执行结果:2
df_titanic['embarked'].fillna(df_titanic['embarked'].mode(), inplace=True)
df_titanic['embarked'].value_counts()
#执行结果:
#S    64

同类均值填充

age:根据 sex、pclass 和 who 分组,如果落在相同的组别里,就用这个组别的均值或中位数填充。

df_titanic.groupby(['sex', 'pclass', 'who'])['age'].mean()
age_group_mean = df_titanic.groupby(['sex', 'pclass', 'who'])['age'].mean().reset_index()
def select_group_age_median(row):
    condition = ((row['sex'] == age_group_mean['sex']) &
                (row['pclass'] == age_group_mean['pclass']) &
                (row['who'] == age_group_mean['who']))
    return age_group_mean[condition]['age'].values[0]
df_titanic['age'] =df_titanic.apply(lambda x: select_group_age_median(x) if np.isnan(x['age']) else x['age'],axis=1)

在这里插入图片描述
④ 模型预测填充
如果其他无缺失字段丰富,我们也可以借助于模型进行建模预测填充,将待填充字段作为Label,没有缺失的数据作为训练数据,建立分类/回归模型,对待填充的缺失字段进行预测并进行填充。
在这里插入图片描述
最近距离邻法(KNN)

  • 先根据欧式距离或相关分析来确定距离具有缺失数据样本最近的 公式 个样本,将这 公式 个值加权平均/投票来估计该样本的缺失数据。

回归(Regression)

  • 基于完整的数据集,建立回归方程。对于包含空值的对象,将已知属性值代入方程来估计未知属性值,以此估计值来进行填充。当变量不是线性相关时会导致有偏差的估计,常用线性回归。

我们以 Titanic 案例中的 age 字段为例,讲解一下:

  • age 缺失量较大,这里我们用 sex、pclass、who、fare、parch、sibsp 六个特征构建随机森林模型,填充年龄缺失值。
    df_titanic_age = df_titanic[['age', 'pclass', 'sex', 'who','fare', 'parch', 'sibsp']]
    df_titanic_age = pd.get_dummies(df_titanic_age)
    df_titanic_age.head()
    
    # 乘客分成已知年龄和未知年龄两部分
    known_age = df_titanic_age[df_titanic_age.age.notnull()]
    unknown_age = df_titanic_age[df_titanic_age.age.isnull()]
    # y 即目标年龄
    y_for_age = known_age['age']
    # X 即特征属性值
    X_train_for_age = known_age.drop(['age'], axis=1)
    X_test_for_age = unknown_age.drop(['age'], axis=1)
    from sklearn.ensemble import RandomForestRegressor
    rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1)
    rfr.fit(X_train_for_age, y_for_age)
    # 用得到的模型进行未知年龄结果预测
    y_pred_age = rfr.predict(X_test_for_age)
    # 用得到的预测结果填补原缺失数据
    df_titanic.loc[df_titanic.age.isnull(), 'age'] = y_pred_age
    
    sns.distplot(df_titanic.age)
    

在这里插入图片描述

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

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

相关文章

TYWZOJ 礼品配对包装 题解

文章目录 题目描述输入格式输出格式样例样例输入样例输出 数据范围与提示思路与部分实现完整代码 题目描述 爱与愁大神在这家目标店买了 2 x 2x 2x 份礼物&#xff0c;打算分给班级同学。其中有 x x x 份黑礼品&#xff0c; x x x 份白礼品&#xff0c; 2 x 2 2x2 2x2 个空…

计网小题题库整理第一轮(面向期末基础)(3)

基础选择题的最后一章更新&#xff0c;看完期末75至少没问题~ 前情提要&#xff1a; 计网小题题库整理第一轮&#xff08;12期&#xff09; 一.选择题 1、 目前,最流行的以太网组网的拓扑结构是&#xff08; C &#xff09;。 A&#xff09; 总线结构 B&#xff09; 环…

如何能够在发现问题和提问的时候一并带出自己的解决方案

1. 充分理解问题&#xff1a; 在提出问题之前&#xff0c;确保你已经完全理解了问题的本质。从不同的角度分析问题&#xff0c;确保没有遗漏任何重要的信息或者上下文。 2. 进行自我调查和研究&#xff1a; 在向他人寻求帮助之前&#xff0c;尝试自己解决问题。利用网络资源…

Go学习第十三章——Gin(入门与路由)

Go web框架——Gin&#xff08;入门与路由&#xff09; 1 Gin框架介绍1.1 基础介绍1.2 安装Gin1.3 快速使用 2 路由2.1 基本路由GET请求POST请求 2.2 路由参数2.3 路由分组基本分组带中间件的分组 2.4 重定向 1 Gin框架介绍 github链接&#xff1a;https://github.com/gin-gon…

从零开始搭建Prometheus+grafana服务器组件监控系统

服务器及相关组件监控 本文档主要记录了常用企业级服务器及各种组件的监控手段和监控部署方案&#xff0c;使企业可以实时感知服务器组件的健康状态&#xff0c;并在服务器或组件出现异常时及时做出反应。 本方案采用的Prometheusgrafana的方式实现对服务器及各种组件的监控&am…

【前端】NodeJS核心知识点整理

1.Node.js入门案例 1.1.什么是Node.js JS是脚本语言&#xff0c;脚本语言都需要一个解析器才能运行。对于写在HTML页面里的JS&#xff0c;浏览器充当了解析器的角色。而对于需要独立运行的JS&#xff0c;NodeJS就是一个解析器。 每一种解析器都是一个运行环境&#xff0c;不但…

C/C++数据结构之深入了解线性表:顺序表、单链表、循环链表和双向链表

线性表是一种基本的数据结构&#xff0c;它在计算机科学中起着至关重要的作用。线性表用于存储一系列具有相同数据类型的元素&#xff0c;这些元素之间存在顺序关系。在C/C中&#xff0c;我们可以使用各种方式来实现线性表&#xff0c;其中包括顺序表、单链表、循环链表和双向链…

基于白鲸优化算法BWO优化的VMD-KELM光伏发电短期功率预测MATLAB代码(含详细算法介绍)

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; VMD适用于处理非线性和非平稳信号&#xff0c;例如振动信号、生物信号、地震信号、图像信号等。它在信号处理、振动分析、图像处理等领域有广泛的应用&#xff0c;特别是在提取信号中的隐含信息和去除噪声方面…

无头浏览器自动化:Puppeteer 帮你释放效能 | 开源日报 No.64

facebook/react Stars: 209.5k License: MIT React是一个用于构建用户界面的JavaScript库。它具有以下优势和特点&#xff1a; 声明式&#xff1a;React使得创建交互式UI变得轻松。您可以为应用程序中的每个状态设计简单视图&#xff0c;当数据发生更改时&#xff0c;React会…

Postman日常操作

一.Postman介绍 1.1第一个简单的demo 路特斯&#xff08;英国汽车品牌&#xff09;_百度百科 (baidu.com) 1.2 cookie 用postman测试需要登录权限的接口时&#xff0c;会被拦截&#xff0c;解决办法就是每次请求接口前&#xff0c;先执行登录&#xff0c;然后记住cookie或者to…

ChineseChess5 2023.10.28

中国象棋残局&#xff1a;黑双卒单车压境解棋

iphone备份后怎么转到新手机,iphone备份在哪里查看

iphone备份会备份哪些东西&#xff1f;iphone可根据需要备份设备数据、应用数据、苹果系统等。根据不同的备份数据&#xff0c;可备份的数据类型不同&#xff0c;有些工具可整机备份&#xff0c;有些工具可单项数据备份。本文会详细讲解苹果手机备份可以备份哪些东西。 一、ip…

婚礼的魅力

昨日有幸被邀请去当伴郎&#xff0c;虽然是替补&#xff0c;即别人鸽了&#xff0c;过去救急&#xff0c;但总归是去起作用。 婚礼的魅力&#xff0c;感受到了&#xff0c;满满的仪式感&#xff0c;紧凑的流程&#xff0c;还有不断的拍照&#xff0c;做视频&#xff0c;留下美好…

接口测试到底怎么做,5分钟时间看完这篇文章彻底搞清楚

01、通用的项目架构 02、什么是接口 接口&#xff1a;服务端程序对外提供的一种统一的访问方式&#xff0c;通常采用HTTP协议&#xff0c;通过不同的url&#xff0c;不同的请求类型&#xff08;GET、POST&#xff09;&#xff0c;不同的参数&#xff0c;来执行不同的业务逻辑。…

2.Vue — 模板语法、数据绑定、el与data的写法、数据代理

文章目录 一、模板语法1.1 插值语法1.2指令语法 二、数据绑定语法2.1 单向数据绑定2.2 双向数据绑定 三、el与data的两种写法3.1 el3.2 data 四、数据代理4.1 Object.defineProperty4.2 Vue数据代理4.2.1 展示数据代理4.2.2 Vue数据代理 一、模板语法 root容器里面的代码被称为…

Ajax学习笔记第二天

喜欢的东西太贵了&#xff0c;我一咬牙&#xff0c;狠下心决定不喜欢了&#xff01; 【一.GET请求】 【1.1 URL即信息】 我们知道php的相关运算都是在服务器端进行的&#xff0c;此时我们要考虑一个问题&#xff0c;如何将要计算的数字带给服务器&#xff1f;我们可以通过UR…

如何能在项目具体编码实现之前能尽可能早的发现问题并解决问题

在项目的具体编码实现之前尽可能早地发现并解决问题&#xff0c;可以大大节省时间和资源&#xff0c;提高项目的成功率。以下是一些策略和方法&#xff1a; 1. 明确需求和预期&#xff1a; 确保所有的项目需求都是清晰和明确的。需求模糊不清是项目失败的常见原因之一。与利益…

java - IDEA IDE - 设置字符串断点

文章目录 java - IDEA IDE - 设置字符串断点概述笔记END java - IDEA IDE - 设置字符串断点 概述 IDE环境为IDEA2022.3 在看一段序列化的代码, 想找出报错抛异常那个点, 理解一下代码实现. 因为序列化代码实现在第三方jar包中, 改不了(只读的). 根本数不清第几次才会开始报…

vue3基础流程

目录 1. 安装和创建项目 2. 项目结构 3. 主要文件解析 3.1 main.js 3.2 App.vue 4. 组件和Props 5. 事件处理 6. 生命周期钩子 7. Vue 3的Composition API 8. 总结和结论 响应式系统&#xff1a; 组件化&#xff1a; 易于学习&#xff1a; 灵活性&#xff1a; 社…

Ubuntu 23.10(Mantic Minotaur)正式发布,支持Linux 6.5和GNOME 45

导读Canonical 近日正式发布了 Ubuntu 23.10&#xff08;Mantic Minotaur&#xff09;操作系统&#xff0c;其中包含一些最新的 GNU/Linux 技术、改进的硬件支持以及许多其他变化。 Ubuntu 23.10 采用了最新的 Linux 6.5 内核系列&#xff0c;并为 Ubuntu 桌面和服务器增强了 z…