一文了解类别型特征的编码方法

640?wx_fmt=jpeg

来源:Unsplash,作者:an Rizzari

2019 年第 78 篇文章,总第 102 篇文章

目录:

  • 问题描述
  • 数据准备
  • 标签编码
  • 自定义二分类
  • one-hot 编码
  • 总结

问题描述

一般特征可以分为两类特征,连续型和离散型特征,而离散型特征既有是数值型的,也有是类别型特征,也可以说是字符型,比如说性别,是男还是女;职业,可以是程序员,产品经理,教师等等。

本文将主要介绍一些处理这种类别型特征的方法,分别来自 pandas 和 sklearn 两个常用的 python 库给出的解决方法,这些方法也并非是处理这类特征的唯一答案,通常都需要具体问题具体分析。

数据准备

参考文章:https://mlln.cn/2018/09/18/pandas%E6%96%87%E6%9C%AC%E6%95%B0%E6%8D%AE%E8%BD%AC%E6%95%B4%E6%95%B0%E5%88%86%E7%B1%BB%E7%BC%96%E7%A0%81%E7%9A%84%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/

采用 UCI 机器学习库的一个汽车数据集,它包括类别型特征和连续型特征,首先是简单可视化这个数据集的部分样本,并简单进行处理。

首先导入这次需要用到的 python 库:

import pandas as pd	
import numpy as np	
import pandas_profiling	
from sklearn.feature_extraction import DictVectorizer	
from sklearn.preprocessing import LabelEncoder, OneHotEncoder

接着加载数据:

# 定义数据的列名称, 因为这个数据集没有包含列名称	
headers = ["symboling", "normalized_losses", "make", "fuel_type", "aspiration",	"num_doors", "body_style", "drive_wheels", "engine_location",	"wheel_base", "length", "width", "height", "curb_weight",	"engine_type", "num_cylinders", "engine_size", "fuel_system",	"bore", "stroke", "compression_ratio", "horsepower", "peak_rpm",	"city_mpg", "highway_mpg", "price"]	# 读取在线的数据集, 并将?转换为缺失NaN	
df = pd.read_csv("http://mlr.cs.umass.edu/ml/machine-learning-databases/autos/imports-85.data",	header=None, names=headers, na_values="?" )	
df.head()[df.columns[:10]]

展示的前 10 列的 5 行数据结果如下:

640?wx_fmt=png

这里介绍一个新的数据分析库--pandas_profiling,这个库可以帮我们先对数据集做一个数据分析报告,报告的内容包括说明数据集包含的列数量、样本数量,每列的缺失值数量,每列之间的相关性等等。

安装方法也很简单:

pip install pandas_profiling

使用方法也很简单,用 pandas读取数据后,直接输入下列代码:

df.profile_report()

显示的结果如下,概览如下所示,看右上角可以选择有 5 项内容,下面是概览的内容,主要展示数据集的样本数量,特征数量(列的数量)、占用内存、每列的数据类型统计、缺失值情况等:

640?wx_fmt=png

这是一个很有用的工具,可以让我们对数据集有一个初步的了解,更多用法可以去查看其 github 上了解:

https://github.com/pandas-profiling/pandas-profiling

加载数据后,这里我们仅关注类别型特征,也就是 object 类型的特征,这里可以有两种方法来获取:

方法1:采用 pandas 提供的方法 select_dtypes:

df2 = df.select_dtypes('object').copy()	
df2.head()

方法2: 通过 bool 型的 mask 获取 object 类型的列

category_feature_mask = df.dtypes == object	
category_cols = df.columns[category_feature_mask].tolist()	
df3 = df[category_cols].copy()	
df3.head()

输出结果如下:

640?wx_fmt=png

因为包含一些缺失值,这里非常简单的选择丢弃的方法,但实际上应该如何处理缺失值也是需要考虑很多因素,包括缺失值的数量等,但这里就不展开说明了:

# 简单的处理缺失值--丢弃	
df2.dropna(inplace=True)

标签编码

第一种处理方法是标签编码,其实就是直接将类别型特征从字符串转换为数字,有两种处理方法:

  • 直接替换字符串
  • 转为 category 类型后标签编码

直接替换字符串,算是手动处理,实现如下所示,这里用 body_style 这列特征做例子进行处理,它总共有 5 个取值方式,先通过 value_counts方法可以获取每个数值的分布情况,然后映射为数字,保存为一个字典,最后通过 replace 方法进行转换。

640?wx_fmt=png

第二种,就是将该列特征转化为 category 特征,然后再用编码得到的作为数据即可:

640?wx_fmt=png

自定义二分类

第二种方法比较特别,直接将所有的类别分为两个类别,这里用 engine_type 特征作为例子,假如我们仅关心该特征是否为 ohc ,那么我们就可以将其分为两类,包含 ohc 还是不包含,实现如下所示:

640?wx_fmt=png

One-hot 编码

前面两种方法其实也都有各自的局限性

  • 第一种标签编码的方式,类别型特征如果有3个以上取值,那么编码后的数值就是 0,1,2等,这里会给模型一个误导,就是这个特征存在大小的关系,但实际上并不存在,所以标签编码更适合只有两个取值的情况;
  • 第二种自定义二分类的方式,局限性就更大了,必须是只需要关注某个取值的时候,但实际应用很少会这样处理。

因此,这里介绍最常用的处理方法--One-hot 编码

实现 One-hot 编码有以下 3 种方法:

  • Pandas 的 get_dummies
  • Sklearn 的 DictVectorizer
  • Sklearn 的 LabelEncoder+OneHotEncoder

Pandas 的 get_dummies

首先介绍第一种--Pandas 的 get_dummies,这个方法使用非常简单了:

640?wx_fmt=png

Sklearn 的DictVectorizer

第二种方法--Sklearn 的 DictVectorizer,这首先需要将 dataframe 转化为 dict 类型,这可以通过 to_dict ,并设置参数 orient=records,实现代码如下所示:

640?wx_fmt=png

Sklearn 的 LabelEncoder+OneHotEncoder

第三种方法--Sklearn 的 LabelEncoder+OneHotEncoder

首先是定义 LabelEncoder,实现代码如下,可以发现其实它就是将字符串进行了标签编码,将字符串转换为数值,这个操作很关键,因为 OneHotEncoder 是不能处理字符串类型的,所以需要先做这样的转换操作:

640?wx_fmt=png

接着自然就是进行 one-hot 编码了,实现代码如下所示:

640?wx_fmt=png

此外,采用 OneHotEncoder 的一个好处就是可以指定特征的维度,这种情况适用于,如果训练集和测试集的某个特征的取值数量不同的情况,比如训练集的样本包含这个特征的所有可能的取值,但测试集的样本缺少了其中一种可能,那么如果直接用 pandas 的get_dummies方法,会导致训练集和测试集的特征维度不一致了。

实现代码如下所示:

640?wx_fmt=png


总结

对于类别型特征,最常用的还是 one-hot 编码,但很多问题都是需要具体问题具体分析,仅仅 one-hot 编码并不一定可以解决所有的类别型特征问题,需要多实践多总结经验。

代码例子在:

https://github.com/ccc013/CodesNotes/blob/master/Data_analysis/category_features_process_notes.ipynb

或者点击左下方“阅读原文”查看。


参考

  • https://mlln.cn/2018/09/18/pandas%E6%96%87%E6%9C%AC%E6%95%B0%E6%8D%AE%E8%BD%AC%E6%95%B4%E6%95%B0%E5%88%86%E7%B1%BB%E7%BC%96%E7%A0%81%E7%9A%84%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/
  • https://blog.csdn.net/selous/article/details/72457476
  • https://towardsdatascience.com/encoding-categorical-features-21a2651a065c
  • https://www.cnblogs.com/zhoukui/p/9159909.html

欢迎关注我的微信公众号--算法猿的成长,或者扫描下方的二维码,大家一起交流,学习和进步!

640?wx_fmt=png

如果觉得不错,在看、转发就是对小编的一个支持!

推荐阅读:

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

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

相关文章

UNIX网络编程--读书笔记

会集中这段时间写UNIX网络编程这本书的读书笔记,准备读三本,这一系类的文章会不断更新,一直会持续一个月多,每篇的前半部分是书中讲述的内容,每篇文章的后半部分是自己的心得体会,文章中的红色内容是很重要…

react学习(6)----react样式多用内联

<div style{{ textAlign: center }}><Button type"primary" style{{ marginRight: 10px }}>保存</Button><Button>取消</Button><Button type"primary" style{{ marginLeft: 10px }}>发布</Button></div>…

如何用栈实现浏览器的前进和后退?

2019 年第 79 篇文章&#xff0c;总第 103 篇文章数据结构与算法系列的第四篇文章&#xff0c;前三篇文章&#xff1a;前言浏览器的前进和后退功能怎么用栈来实现呢&#xff1f;这里先介绍一下栈的定义和实现&#xff0c;并介绍它的一些常用的应用&#xff0c;最后再简单实现一…

iOS开发Objective-C基础之──多态

Objective-C语言是面向对象的高级编程语言&#xff0c;因此&#xff0c;它具有面向对象编程所具有的一些特性&#xff0c;即&#xff1a;封装性、继承性和多态性。 今天介绍一下Objective-C中的多态性。 一、什么是多态 多态&#xff1a;不同对象以自己的方式响应相同的消息的能…

react学习(7)----react转换值同render

{title: 状态,dataIndex: status,render: (text, row) > {let arr [, 未开始, 进行中, 已结束, 已作废];return <span>{arr[text]}</span>;},},

数据科学家令人惊叹的排序技巧

2019 年第 80 篇文章&#xff0c;总第 104 篇文章本文大约 7800 字&#xff0c;阅读大约需要20分钟原题 | Surprising Sorting Tips for Data Scientists作者 | Jeff Hale原文 | https://towardsdatascience.com/surprising-sorting-tips-for-data-scientists-9c360776d7e译者 …

删除Autorun.inf的方法

你的电脑的每个分区根目录都有一个autorun.inf的文件夹&#xff0c;查看属性是只读隐藏&#xff0c;且无法删除、无法取得权限!点进去&#xff0c;却显示的是控制面板的内容? 其实这个不是病毒&#xff0c;而是用来防病毒&#xff0c;一些系统封装工具本身就自带。下面教你删…

react学习(8)----数组方法fliter简介

filter() 方法创建一个新的数组&#xff0c;新数组中的元素是通过检查指定数组中符合条件的所有元素。 注意&#xff1a; filter() 不会对空数组进行检测。 注意&#xff1a; filter() 不会改变原始数组。

几个有趣的python技巧

2019 年第 82 篇文章&#xff0c;总第 106 篇文章标题 | python-is-cool作者 | chiphuyen原文 | https://github.com/chiphuyen/python-is-cool译者 | kbsc13("算法猿的成长"公众号作者)声明 | 翻译是出于交流学习的目的&#xff0c;欢迎转载&#xff0c;但请保留本文…

react学习(9)----react生命周期

react生命周期1.1.constructor() constructor()中完成了React数据的初始化&#xff0c;它接受两个参数 &#xff1a;props和context&#xff0c;当想在函数内部使用这两个参数时 &#xff0c;需使用super()传入这两个参数。 注意&#xff1a;只要使用了constructor()就必须写su…

TOP 命令

转自&#xff1a;top命令.http://www.cnblogs.com/wangkangluo1/archive/2012/04/18/2454993.html#stat.2013-05-25 top命令是Linux下常用的性能分析工具&#xff0c;能够实时显示系统中各个进程的资源占用状况&#xff0c;类似于Windows的任务管理器。下面详细介绍它的使用方法…

20191215周学习总结

最近会打算每周总结一下学习的内容&#xff0c;主要内容可能是看过的书的一些学习笔记、论文阅读、学习的知识点以及推荐一些文章。这周的学习包括&#xff1a;推荐系统的知识点整理机器学习的技巧学习linux下两台机器的ssh免密登陆方式书籍阅读效率方法推荐系统因为工作方向的…

玩转12306之系统登录

【申明&#xff1a;本文所涉及的技术和分析的目的都是为了学习和交流&#xff0c;任何人使用文中所提的技术或成果做出的违法事情与我无关&#xff0c;大家购买火车票还是去12306官网上去购买。】 从今天起&#xff0c;我开始分析12306网站的Http请求&#xff0c;以及编写一个客…

react学习(10)----react数组定义 从0开始 直接加个0下标空

{title: 状态,dataIndex: status,render: (text, row) > {let arr [, 未开始, 进行中, 已结束, 已作废];return <span>{arr[text]}</span>;},},

Nginx快速搭建和基本使用

2019年第 83 篇文章&#xff0c;总第 107 篇文章最近在工作中项目需要上线&#xff0c;所以也了解到关于一些部署上线的知识内容&#xff0c;Nginx 就是其中一个知识点&#xff0c;主要是可以用它来进行负载均衡&#xff0c;本文的目录如下&#xff1a;简介安装配置基本使用简介…

对于mysql的用户权限管理

转载链接&#xff1a;http://www.cnblogs.com/ymy124/archive/2012/05/23/2514196.html 1.新建用户 //登录MYSQL>mysql -u root -p>密码//创建用户mysql> insert into mysql.user(Host,User,Password) values(‘localhost’,jeecn’,password(‘jeecn’));//刷新系统权…

第二期周总结

第二期的周总结&#xff0c;这次学习的内容可能没有上次那么广泛&#xff0c;主要是因为这周我负责的模块需要测试并进行上线&#xff0c;所以主要学习了解的就是工程开发方面的内容&#xff0c;准确说是部署上线的内容&#xff0c;所以本周主要简单总结这次上线过程的一些内容…

react学习(12)-moment插件设置日期格式

<p>{moment(boothDetails.startTime).format(YYYY-MM-DD)}到{moment(boothDetails.endTime).format(YYYY-MM-DD)}</p>

AI知识点(1)--激活函数

2019年第 84 篇文章&#xff0c;总第 108 篇文章本文大约 5000 字&#xff0c;阅读大约需要 15 分钟AI知识点&#xff08;AI Knowledge&#xff09;系列第一篇文章--激活函数。本文主要的目录如下&#xff1a;激活函数的定义为什么需要激活函数常见的激活函数1. 激活函数的定义…

oracle分区

oracle 分区技术&#xff1a;使用分区技术&#xff0c;Oracle允许把一个大表分成几个部分&#xff0c;每部分叫一个分区&#xff0c;然后把每个部分放在不同的物理磁盘&#xff0c;以提高整个数据库的性能。分区技术的优点&#xff1a;1.分区技术使数据库的可管理性变得更加容易…