博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[scikit-learn] 特征二值化
阅读量:6896 次
发布时间:2019-06-27

本文共 2853 字,大约阅读时间需要 9 分钟。

1.首先造一个测试数据集

#coding:utf-8import numpyimport pandas as pdfrom sklearn.preprocessing import OneHotEncoderfrom sklearn.preprocessing import LabelEncoderfrom sklearn.preprocessing import LabelBinarizerfrom sklearn.preprocessing import MultiLabelBinarizerdef t2():    testdata = pd.DataFrame({'pet': ['chinese', 'english', 'english', 'math'],                         'age': [6 , 5, 2, 2],                         'salary':[7, 5, 2, 5]})    print testdatat2()

这里我们把 petagesalary 都看做类别特征,所不同的是 age 和 salary 都是数值型,而 pet 是字符串型。我们的目的很简单: 把他们全都二值化,进行 one-hot 编码

2. 对付数值型类别变量

对 age 进行二值化很简单,直接调用 OneHotEncoder

OneHotEncoder(sparse = False).fit_transform(testdata.age) # testdata.age 这里与 testdata[['age']]等价

然而运行结果是 array([[ 1.,  1.,  1.,  1.]]),这个结果是错的,从 Warning 信息中得知,原因是 sklearn 的新版本中,OneHotEncoder 的输入必须是 2-D array,而 testdata.age 返回的 Series 本质上是 1-D array,所以要改成

OneHotEncoder(sparse = False).fit_transform(testdata[['age']])

我们得到了我们想要的:

array([[ 0.,  1.,  0.],        [ 0., 0., 1.], [ 1., 0., 0.], [ 1., 0., 0.]])

可以用同样的方法对 salary 进行 OneHotEncoder, 然后将结果用 numpy.hstack() 把两者拼接起来得到变换后的结果

import numpyresult1 = OneHotEncoder(sparse = False).fit_transform(testdata[['age']])    result2 = OneHotEncoder(sparse=False).fit_transform(testdata[['salary']])    final_output = numpy.hstack((result1,result2))    print final_output

不过这样的代码略显冗余,既然 OneHotEncoder() 可以接受 2-D array 输入,那我们可以写成这样

result = OneHotEncoder(sparse = False).fit_transform( testdata[['age', 'salary']])
结果为
array([[ 0.,  1.,  0.,  0., 1., 0.], [ 0., 0., 1., 0., 0., 1.], [ 1., 0., 0., 1., 0., 0.], [ 1., 0., 0., 1., 0., 0.]])

有时候我们除了得到最终编码结果,还想知道结果中哪几列属于 age 的二值化编码,哪几列属于 salary 的,这时候我们可以通过 OneHotEncoder() 自带的 feature_indices_ 来实现这一要求,比如这里 feature_indices_ 的值是[0, 3, 6],表明 第[0:3]列是age的二值化编码,[3:6]是salary的。更多细节请参考 sklearn 文档,

3. 对付字符串型类别变量

遗憾的是OneHotEncoder无法直接对字符串型的类别变量编码,也就是说OneHotEncoder().fit_transform(testdata[['pet']])这句话会报错(不信你试试)。已经有很多人在 stackoverflow 和 sklearn 的 github issue 上讨论过这个问题,但目前为止的 sklearn 版本仍没有增加OneHotEncoder对字符串型类别变量的支持,所以一般都采用曲线救国的方式:

  • 方法一 先用 LabelEncoder() 转换成连续的数值型变量,再用 OneHotEncoder() 二值化

  • 方法二 直接用 LabelBinarizer() 进行二值化

然而要注意的是,无论 LabelEncoder() 还是 LabelBinarizer(),他们在 sklearn 中的设计初衷,都是为了解决标签 y 的离散化,而非输入 X, 所以他们的输入被限定为 1-D array,这恰恰跟 OneHotEncoder() 要求输入 2-D array 相左。所以我们使用的时候要格外小心,否则就会出现上面array([[ 1.,  1.,  1.,  1.]])那样的错误

# 方法一: LabelEncoder() + OneHotEncoder() a = LabelEncoder().fit_transform(testdata['pet']) OneHotEncoder( sparse=False ).fit_transform(a.reshape(-1,1)) # 注意: 这里把 a 用 reshape 转换成 2-D array # 方法二: 直接用 LabelBinarizer() LabelBinarizer().fit_transform(testdata['pet'])

这两种方法得到的结果一致,都是

array([[ 1.,  0.,  0.],        [ 0., 1., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])

正因为LabelEncoderLabelBinarizer设计为只支持 1-D array,也使得它无法像上面 OneHotEncoder 那样批量接受多列输入,也就是说LabelEncoder().fit_transform(testdata[['pet', 'age']])会报错。

转载于:https://www.cnblogs.com/Mrwan/p/7411447.html

你可能感兴趣的文章
Mockito 库、powermock扩展
查看>>
各版本JDK1.5-1.8新特性
查看>>
京东无界零售带来机遇,家电专卖店拉动实体经济,大学生的致富经
查看>>
中国物流能送到四海八荒,菜鸟年度排行榜告诉你都去了哪些地方
查看>>
从业界良心到疲态尽显 Netflix到底中了什么降头?
查看>>
OpenStack消亡?在企业落地为什么越来越难
查看>>
GitHub因Memcached漏洞遭遇DDoS攻击,专家称攻击会持续发生!
查看>>
湖南郴州与新疆托克逊特色年货节开幕
查看>>
快手音乐人计划:音乐人可以靠作品赚到真金白银
查看>>
使用Python一年多了,总结八个好用的Python爬虫技巧
查看>>
无人船成下一个全球研发热点,参与行业标准的「云洲智能」要做海洋上的"SpaceX"...
查看>>
13种数据分析思维
查看>>
3分钟搞掂Set集合
查看>>
如果再有人问你分布式 ID,这篇文章丢给他
查看>>
90% New Grads 都懵逼的面试轮次,这些应对“骚操作”请收好
查看>>
重磅 | PyTorch 0.4.0和官方升级指南,支持Windows
查看>>
http状态码是什么,有什么用,在哪里查看,分别代表什么意思?
查看>>
应用迁移至 Android P 操作指南
查看>>
用 CoordinatorLayout 处理滚动
查看>>
网络七层模型与四层模型区别
查看>>