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

文章目录

  • 引言
  • 特征工程
  • 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 snsdf_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.mzph.cn/news/121819.shtml

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

相关文章

技术资料MF74:将图像插入单元格注释

【分享成果&#xff0c;随喜正能量】须知往生净土&#xff0c;全仗信、愿。有信、愿&#xff0c;即未得三昧、未得一心不乱&#xff0c;亦可往生。且莫只以一心不乱&#xff0c;及得念佛三昧为志事&#xff0c;不复以信、愿、净念为事。。 我给VBA的定义&#xff1a;VBA是个人…

通过Vue自带服务器实现Ajax请求跨域(vue-cli)

通过Vue自带服务器实现Ajax请求跨域&#xff08;vue-cli&#xff09; 跨域 原理&#xff1a;从A页面访问到B页面&#xff0c;并且要获取到B页面上的数据&#xff0c;而两个页面所在的端口、协议和域名中哪怕有一个不对等&#xff0c;那么这种行为就叫跨域。注意&#xff1a;类…

[LaTeX] [数学符号] \mathbb{1}的各种替代方案:解决在 LaTeX 中输入黑板粗体的数字

[LaTeX] [数学符号] \mathbb{1}的各种替代方案&#xff1a;解决在 LaTeX 中输入黑板粗体的数字_latex mathbb-CSDN博客文章浏览阅读5w次&#xff0c;点赞36次&#xff0c;收藏80次。本文介绍如何在 LaTeX 中输入黑板粗体的数字。_latex mathbbhttps://blog.csdn.net/xovee/arti…

Android Studio 查看Framework源码

1、背景 安卓系统源码量很庞大&#xff0c;选择好的开发工具和方式去开发可以提升开发效率&#xff0c;常用的开发工具有Source Insight 、Visual Studio Code、Android Studio&#xff0c;vscode适合C和C代码开发&#xff0c;java层代码无法跳转和提示&#xff0c;因此&#…

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; 社…

Java中级面试题记录(四)

一面面试题 1.Innodb的行数据存储模式 https://baijiahao.baidu.com/s?id1775090633458928876&wfrspider&forpc 2.行数据包含哪些信息&#xff1f; https://baijiahao.baidu.com/s?id1775090633458928876&wfrspider&forpc 3.MySQL在进行存储VARCHAR的时…

DDOS版-超功能记事本 Ⅲ 8.8源码

DDOS版-超功能记事本 Ⅲ 8.8源码 下载地址&#xff1a;https://user.qzone.qq.com/512526231/main

goland无法调试问题解决

goland 无法调试问题解决 golang 版本升级后&#xff0c;goland 无法进行调试了 首先请看自己下载的版本是否有误 1.apple系 M系列芯片的 arm64版本 2.apple系 intel系列芯片的x86_64 3.windows系 intel解决如下&#xff1a; 查看gopath ericsanchezErics-Mac-mini gww-api…

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

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

【golang】Windows环境下Gin框架安装和配置

Windows环境下Gin框架安装和配置 我终于搞定了Gin框架的安装&#xff0c;花了两三个小时&#xff0c;只能说道阻且长&#xff0c;所以写下这篇记录文章 先需要修改一些变量&#xff0c;这就需要打开终端&#xff0c;为了一次奏效&#xff0c;我们直接设置全局的&#xff1a; …

大厂面试题-JVM中的三色标记法是什么?

目录 问题分析 问题答案 问题分析 三色标记法是Java虚拟机(JVM)中垃圾回收算法的一种&#xff0c;主要用来标记内存中存活和需要回收的对象。 它的好处是&#xff0c;可以让JVM不发生或仅短时间发生STW(Stop The World)&#xff0c;从而达到清除JVM内存垃圾的目的&#xff…

代码随想录Day31 贪心06 T738 单调递增的数字 T968监控二叉树

LeetCode T738 单调递增的数字 题目链接:738. 单调递增的数字 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 我们以332举例,题目要我们获得的是小于等于332的最大递增数字,我们知道这个数字要递增只能取299了,332 -- 329 --299 我们从后向前遍历,只要前一位大于后一位,我…

系统架构设计师之使用McCabe方法可以计算程序流程图的环形复杂度

系统架构设计师之使用McCabe方法可以计算程序流程图的环形复杂度

conda虚拟环境配置

命令行输入&#xff0c;conda -V 确定conda版本 创建自己的conda虚拟环境 activate 回车 conda create -n 名字 python版本号 执行命令 确认执行命令 输入y 创建完成 激活环境 conda activate 名字 进入python环境 python 退出 exit() conda deactive

Text Classification via Large Language Models

Abstract 表达大模型在文本分类上做的不好。 原因&#xff1a; 1、处理复杂语境时缺少推理能力。(e.g… 类比、讽刺) 2、限制学习的上下文的token数。 提出了自己的策略&#xff1a; ** Clue And Reasoning Prompting (CARP).线索与推理提示** 1、能用prompt找到clue(语境线索…

前端实现打印功能Print.js

前端实现打印的方式有很多种&#xff0c;本人恰好经历了几个项目都涉及到了前端打印&#xff0c;目前较为推荐Print.js来实现前端打印 话不多说&#xff0c;直接上教程 官方链接: Print.js官网 在项目中如何下载Print.js 使用npm下载&#xff1a;npm install print-js --sav…

抓取网页的含义和URL基本构成

抓取网页是指通过爬虫程序从互联网上获取网页的内容和数据。抓取网页是爬虫的核心功能之一&#xff0c;通过抓取网页&#xff0c;可以获取到网页中的文本、图片、链接等信息&#xff0c;用于后续的数据分析、挖掘和应用。 URL&#xff08;Uniform Resource Locator&#xff09…

muduo源码剖析之Buffer缓冲区类

简介 Buffer封装了一个可变长的buffer&#xff0c;支持廉价的前插操作&#xff0c;以及内部挪腾操作避免额外申请空间 使用vector作为缓冲区(可自动调整扩容) 设计图 源码剖析 已经编写好注释 buffer.h // Copyright 2010, Shuo Chen. All rights reserved. // http://c…

城市群(Megalopolis)/城际(inter-city)OD相关研究即Open Access数据集调研

文章目录 1 城市群/城际OD定义2 理论模型与分析方法2.1 重力模型 Gravity Model2.2 干预机会模型 Intervening Opportunities Model2.3 辐射模型 Radiation Model 3 Issues related to OD flows3.1 OD Prediction3.2 OD Forecasting3.3 OD Construction3.4 OD Estimation 4 OD …

PHP简单实现预定义钩子和自定义钩子

在PHP中&#xff0c;钩子&#xff08;Hooks&#xff09;是一种机制&#xff0c;允许开发人员在特定的时机插入自定义代码。通过使用钩子&#xff0c;开发人员可以在应用程序的特定事件发生时执行自定义的功能或逻辑 钩子有两种类型&#xff1a;预定义钩子和自定义钩子。 预定…