基于《python数据分析与数据运营》的总结与部分代码修正
很多算法包无法直接基于字符串做矩阵运算,例如Numpy以及基于Numpy的sklearn。
标志法:
独热编码转换后:
不使用男-1,女-2是因为1和2本身已经带有距离为1的差异,其他任意数字都有这样的差异,然而实际上男女是没有差异的。
代码实操
OneHotEncoder-独热编码:直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制
举例:三种颜色——红、黄、蓝,如果红=1,黄=2,蓝=3. 那么这样其实实现了标签编码,意味着机器可能会学习到“红<黄<蓝”,实际上我们并不想让他们有区别,而独热编码下三种颜色状态即三个比特即红色:1 0 0 ,黄色: 0 1 0,蓝色:0 0 1 。如此一来每两个向量之间的距离都是根号2,在向量空间距离都相等,所以这样不会出现偏序性,基本不会影响基于向量空间度量算法的效果。
优点:独热编码解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。
缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
df=pd.DataFrame({'id':[3566841,6541227,3512441],
'sex':['male','Female','Female'],
'level':['high','low','middle']})
df_new=df.copy()
for col_num,col_name in enumerate(df):#循环读出每个列的索引值和列名
col_data=df[col_name]#获得每列数据
col_dtype=col_data.dtype#获得每列dtype类型
if col_dtype=='object':#如果dtype类型是object(非数值型),执行条件
df_new=df_new.drop(col_name,1)#删除df数据框中要进行标志转换的列
value_sets=col_data.unique()#获取分类和顺序变量的唯一值域
for value_unique in value_sets:#读取分类和顺序变量中的每个值
col_name_new=col_name+'_'+value_unique#创建新的列名,使用“原标题+值”的方式命名
col_tmp=df.iloc[:,col_num]#获取原始数据列
new_col=(col_tmp==value_unique)#将原始数据列与每个值进行比较,相同的True,否则为False
df_new[col_name_new]=new_col#为最终结果集增加新列值
print(df_new)
df2=pd.DataFrame({'id':[3566841,6541227,3512441],
'sex':[1,2,2],
'level':[3,1,2]})
id_data=df2.values[:,1:]#获得ID列
transform_data=df2.values[:,1:]#指定要转换的列
enc=OneHotEncoder()#建立模型对象
df2_new=enc.fit_transform(transform_data).toarray()#标志转换
df2_all=pd.concat((pd.DataFrame(id_data),pd.DataFrame(df2_new)),axis=1)#组合为数据框
print(df2_all)
drop函数:
drop(['a'])
drop(['Ohio'], axis = 1)
drop函数默认删除行,列需要加axis = 1
drop('column_name',axis=1, inplace=True)
inplace可选参数手动设定为True(默认为False),那么原数组直接就被替换;inplace=False之后,原数组名对应的内存值并不改变,需要将新的结果赋给一个新的数组或者覆盖原数组的内存位置。