机器学习实践/数据预处理/离散特征处理(1)

import pandas as pd 
df = pd.DataFrame([
            ['green', 'M', 10.1, 'class1'], 
            ['red', 'L', 13.5, 'class2'], 
            ['blue', 'XL', 15.3, 'class1']])
#numpy添加列表名称 (记下这种手法:先通过pd.DataFrame()添加数据,再用columns()补充列名)
df.columns = ['color', 'size', 'prize', 'class label']
df

先用比较简单的映射字典法来对离散属性进行处理

'''
把标签转换成数值型   这样的连续化将没有顺序关系的类别变成具有顺序关系0,1,2等,
同时也导致了不同类别之间的距离不相等,简单的用L1范式,0-1距离为1,0-2距离为2
'''

class_mapping = {label:idx for idx,label in enumerate(set(df['class label']))}



'''
df['class label'] 
输出:
0    class1
1    class2
2    class1
Name: class label, dtype: object 

set(df['class label'])
输出:
    {'class1', 'class2'}
是把df['class label']里面的数据装到一个集合里面,并且自动去除重复项


for idx,label in enumerate(set(df['class label'])):
    print(idx,label) 
输出:
0 class1
1 class2 
enumerate()作用是把遍历集合参数,返回序号和集合的数据项


class_mapping是键值对{label:idx}
class_mapping
输出:
{'class1': 0, 'class2': 1} 
''' 

df['class label'] = df['class label'].map(class_mapping)
'''
map(class_mapping)利用class_mapping键值对的数值去替换原本的离散属性
'''
df

 

 

#同上,应用映射字典的方法 将离散型属性转化成数值型属性

size_mapping = {'XL': 3,'L': 2,'M': 1}

color_mapping = {'green': (0,0,1),'red': (0,1,0),'blue': (1,0,0)}

df['size'] = df['size'].map(size_mapping)

df['color'] = df['color'].map(color_mapping)

df

#映射字典  还原数据的方法
#color_mapping.items() 返回的是键值对 比如 green,(0,0,1),其他的同理
inv_color_mapping = {v: k for k, v in color_mapping.items()}
inv_size_mapping = {v: k for k, v in size_mapping.items()}
inv_class_mapping = {v: k for k, v in class_mapping.items()}

#实际上就是  map的重复利用  键值对反过来而已
df['color'] = df['color'].map(inv_color_mapping)
df['size'] = df['size'].map(inv_size_mapping)
df['class label'] = df['class label'].map(inv_class_mapping)
df

 接下来利用sklearn对数据进行预处理

from sklearn.preprocessing import LabelEncoder

class_le = LabelEncoder()
#把传进去的属性转换成数字型属性,不是独热编码
df['class label'] = class_le.fit_transform(df['class label'])
df

反变换回去可以用这个函数 inverse_transform :

class_le.inverse_transform(df['class label'])
#输出:array(['class1', 'class2', 'class1'], dtype=object)

用scikit DictVectorizer一次性全部变换

使用 DictVectorizer将得到特征的字典

df.transpose().to_dict().values()#得到属性的字典

'''
输出:
dict_values([{'color': 'green', 'size': 'M', 'class label': 0, 'prize': 10.1}, {'color': 'red', 'size': 'L', 'class label': 1, 'prize': 13.5}, {'color': 'blue', 'size': 'XL', 'class label': 0, 'prize': 15.3}])
'''
#获取除了class_label属性以为的其他属性
feature = df.iloc[:, :-1]
from sklearn.feature_extraction import DictVectorizer
dvec = DictVectorizer(sparse=False)

X = dvec.fit_transform(feature.transpose().to_dict().values())
X
'''
输出:
array([[  0. ,   1. ,   0. ,  10.1,   0. ,   1. ,   0. ],
       [  0. ,   0. ,   1. ,  13.5,   1. ,   0. ,   0. ],
       [  1. ,   0. ,   0. ,  15.3,   0. ,   0. ,   1. ]])
'''

#可以调用 get_feature_names 来返回新的列的名字,其中0和1就代表是不是这个属性.
pd.DataFrame(X, columns=dvec.get_feature_names())

接下来是将离散类型转化成独热编码

#OneHotEncoder 必须使用整数作为输入,所以得先预处理一下

#先通过LabelEncoder()转化成正常的数值型属性
color_le = LabelEncoder()

df['color'] = color_le.fit_transform(df['color'])

from sklearn.preprocessing import OneHotEncoder

ohe = OneHotEncoder(sparse=False)

X = ohe.fit_transform(df['color'].values)
X
'''
输出:
array([[ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.]])
这里有一个问题 虽然生成独热编码 但是如何把这个编码 放到原本的数据里面???
'''

#另外 这里是先把文字属性转成数字属性,数字属性转成独热编码,通过LabelBinarizer可以实现一次性转化
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot=encoder.fit_transform(df['color'])
housing_cat_1hot
'''
输出:
array([[ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.]]) 
'''

利用pandas实现转化,不过这种算是独热编码嘛?

import pandas as pd
df = pd.DataFrame([
            ['green', 'M', 10.1, 'class1'], 
            ['red', 'L', 13.5, 'class2'], 
            ['blue', 'XL', 15.3, 'class1']])

df.columns = ['color', 'size', 'prize', 'class label']  

#Pandas库中同样有类似的操作,使用get_dummies也可以得到相应的特征
pd.get_dummies(df)

总结:数据预处理中的离散型数值的处理,主要有两种,一种是普通数值转换(实现方法有:1.手动之多映射字典,将其转化成数值型;2.利用sklearn 的LabelEncoder()),另一种是独热编码(实现方法有:sklean 的OneHotEncoder()和LabelBinarizer())

至于DictVectorizer()和pandas的get_dummies()方法,这种转化方法算是独热嘛??

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值