sklearn处理分类型特征:编码与哑变量

我们刚才已经用OrdinalEncoder把分类变量Sex和Embarked都转换成数字对应的类别了。在舱门Embarked这一 列中,我们使用[0,1,2]代表了三个不同的舱门,然而这种转换是正确的吗?
我们来思考三种不同性质的分类数据:
1) 舱门(S,C,Q) 三种取值S,C,Q是相互独立的,彼此之间完全没有联系,表达的是S≠C≠Q的概念。这是名义变量。
2) 学历(小学,初中,高中) 三种取值不是完全独立的,我们可以明显看出,在性质上可以有高中>初中>小学这样的联系,学历有高低,但是学 历取值之间却不是可以计算的,我们不能说小学 + 某个取值 = 初中。这是有序变量。
3) 体重(>45kg,>90kg,>135kg) 各个取值之间有联系,且是可以互相计算的,比如120kg - 45kg = 90kg,分类之间可以通过数学计算互相转换。这 是有距变量。
然而在对特征进行编码的时候,这三种分类数据都会被我们转换为[0,1,2],这三个数字在算法看来,是连续且可以 计算的,这三个数字相互不等,有大小,并且有着可以相加相乘的联系。所以算法会把舱门,学历这样的分类特 征,都误会成是体重这样的分类特征。这是说,我们把分类转换成数字的时候,忽略了数字中自带的数学性质,所 以给算法传达了一些不准确的信息,而这会影响我们的建模。
类别OrdinalEncoder可以用来处理有序变量,但对于名义变量,我们只有使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息。
代码实现:

import pandas as pd
data=pd.read_csv(r"C:\Users\JYuXuAN\Desktop\sklearn\预处理数据\Narrativedata.csv", index_col=0)
Age = data.loc[:,"Age"].values.reshape(-1,1)
Embarked=data.loc[:,"Embarked"].values.reshape(-1,1)

from sklearn.impute import SimpleImputer
#用中位数填补Age,众数填补Embarked
data.loc[:,"Age"]=SimpleImputer(strategy="median").fit_transform(Age)
data.loc[:,"Embarked"]=SimpleImputer(strategy="most_frequent").fit_transform(Embarked)
print(data.info())
print("空值填补完毕...")

from sklearn.preprocessing import OneHotEncoder
#用数值替换字符串
X=data.iloc[:,1:-1]
enc=OneHotEncoder(categories='auto').fit(X)
result=enc.transform(X).toarray()
result=OneHotEncoder(categories='auto').fit_transform(X).toarray() #一步完成
#print(pd.DataFrame(enc.inverse_transform(result))) #还原
print(enc.get_feature_names()) # ※※※非常重要,各个体征的名称※※※
print("特征替换完毕...")

# axis=1表示跨行进行合并,也就是将表左右相连(我们需要横着看进行比较)
# axis=0表示将表上下相连
newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
newdata.drop(["Sex","Embarked"],axis=1,inplace=True) #inplace=Ture 不创建新的对象,在原对象基础上进行修改
newdata.columns = ["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
print(newdata.head(20))
print("表格重置...")
发布了90 篇原创文章 · 获赞 15 · 访问量 3173

猜你喜欢

转载自blog.csdn.net/qq_43656233/article/details/104025500