• 数据预处理和特征工程2-缺失值处理、分类型特征:编码与哑变量


    缺失值处理

    import pandas as pd
    data = pd.read_csv(r"E:\机器学习\sklearn学习\数据\Narrativedata.csv",index_col=0)
    #index_col=0 告诉它索引列是第0列首列
    data.head()
    #Embarked舱门
    data.info() #查看缺失情况
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    sklearn.impute.SimpleImputer (missing_values=nan, strategy=’mean’, fill_value=None, verbose=0,copy=True)

    #填补年龄
    Age = data.loc[:,"Age"].values.reshape(-1,1) #sklearn当中特征矩阵必须是二维
    
    #data.loc[:,"Age"]---由索引列+Age列的值组成
    #data.loc[:,"Age"].values 取出Age列的值
    data.loc[:,"Age"].values.shape
    #输出(891,)----只有一个数字,是一维的。即输出的数据只有一个方括号
    data.loc[:,"Age"].values.reshape(-1,1).shape
    #输出(891,1)----是二维的。即输出的数据有两个方括号
    #sklearn当中特征矩阵必须是二维
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    from sklearn.impute import SimpleImputer
    imp_mean = SimpleImputer() #实例化,默认均值填补
    imp_median = SimpleImputer(strategy="median") #用中位数填补
    imp_0 = SimpleImputer(strategy="constant",fill_value=0) #用0填补
    
    imp_mean = imp_mean.fit_transform(Age)
    #fit_transform一步完成调取结果
    imp_median = imp_median.fit_transform(Age)
    imp_0 = imp_0.fit_transform(Age)
    imp_mean[:20] #均值29.699填补的
    imp_median[:20] #中位数28填补的
    imp_0[:20] #0填补的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    #在这里我们使用中位数填补Age
    data.loc[:,"Age"] = imp_median
    data.info()
    #Age填补完成
    #使用众数填补Embarked
    Embarked = data.loc[:,"Embarked"].values.reshape(-1,1)
    
    imp_mode = SimpleImputer(strategy = "most_frequent")
    data.loc[:,"Embarked"] = imp_mode.fit_transform(Embarked)
    data.info()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    #BONUS:用Pandas和Numpy进行填补其实更加简单
    import pandas as pd
    data_ = pd.read_csv(r"E:\机器学习\sklearn学习\数据\Narrativedata.csv",index_col=0)
    data_.head()
    
    data_.loc[:,"Age"] = data_.loc[:,"Age"].fillna(data_.loc[:,"Age"].median())
    #.fillna 在DataFrame里面直接进行填补  -- 填充列.fillna(要填的值)
    
    data_.info()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    data_.dropna(axis=0,inplace=True)
    #.dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
    #参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False
    
    data_.info()
    #填充完成
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    编码,即,将文字型数据转换为数值型
    LabelEncoder :标签专用,能够将分类转换为分类数值

    #LabelEncoder :标签专用,能够将分类转换为分类数值
    
    from sklearn.preprocessing import LabelEncoder
    y = data_.iloc[:,-1] #要输入的是标签,不是特征矩阵,所以允许一维
    
    le = LabelEncoder() #实例化
    le = le.fit(y) #导入数据
    label = le.transform(y) #transform接口调取结果
    
    le.classes_ #属性.classes_查看标签中究竟有多少类别
    #三个类
    
    label #结果处理后显示,0,1,2
    le.fit_transform(y) #也可以直接fit_transform一步到位
    #等价于上面三步
    le.inverse_transform(label) #使用inverse_transform可以逆转
    
    #重新完整的代码,应该为:
    #如果不需要教学展示的话我会这么写:
    from sklearn.preprocessing import LabelEncoder
    data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    OrdinalEncoder :特征专用,能够将分类转换为分类数值

    特征矩阵,就强调不能导入一维数组了

    from sklearn.preprocessing import OrdinalEncoder
    #接口categories_对应LabelEncoder的接口classes_,一模一样的功能
    data_ = data.copy() #保护原本data不受覆盖
    data_.head()
    
    OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_ #一步到位
    #categories_作用同classes_ ,查看类别
    
    data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
    data_.head()  #性别0、1  舱门0,1,2 存活情况0,1,2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    OneHotEncoder:独热编码,创建哑变量

    考三种不同性质的分类数据:

    1) 舱门(S,C,Q)

    三种取值S,C,Q是相互独立的,彼此之间完全没有联系,表达的是S≠C≠Q的概念。这是名义变量。

    2) 学历(小学,初中,高中)

    三种取值不是完全独立的,我们可以明显看出,在性质上可以有高中>初中>小学这样的联系,学历有高低,但是学历取值之间却不是可以计算的,我们不能说小学 + 某个取值 = 初中。这是有序变量。

    3) 体重(>45kg,>90kg,>135kg)

    各个取值之间有联系,且是可以互相计算的,比如120kg - 45kg = 90kg,分类之间可以通过数学计算互相转换。有距变量

    然而在对特征进行编码的时候,这三种分类数据都会被我们转换为[0,1,2],这三个数字在算法看来,是连续且可以计算的,这三个数字相互不等,有大小,并且有着可以相加相乘的联系。
    所以算法会把舱门,学历这样的分类特征,都误会成是体重这样的分类特征。
    这是说,我们把分类转换成数字的时候,忽略了数字中自带的数学性质,所以给算法传达了一些不准确的信息,而这会影响我们的建模。

    名义变量,使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息

    舱门—名义变量–哑变量–独热编码OneHotEncoder

    体重—有距变量–编码

    data.head()
    from sklearn.preprocessing import OneHotEncoder
    X = data.iloc[:,1:-1]
    enc = OneHotEncoder(categories='auto').fit(X)  #实例化
    result = enc.transform(X).toarray()  #toarray()转化成数组
    result
    #sex变两列 ,仓号变3列
    
    #依然可以直接一步到位,但为了给大家展示模型属性,所以还是写成了三步
    OneHotEncoder(categories='auto').fit_transform(X).toarray()
    #依然可以还原
    pd.DataFrame(enc.inverse_transform(result))
    #还原成两列特征
    enc.get_feature_names()
    #给出每个哑变量对应的原本类值
    result
    result.shape
    
    #把生成的5列哑变量拼接data上去
    
    #axis=1,表示跨行进行合并,也就是将两表左右相连,如果是axis=0,就是将量表上下相连
    newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
    newdata.head()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    newdata.drop(["Sex","Embarked"],axis=1,inplace=True) #删除原本两特征列
    newdata.columns = ["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
    #重命名特征名字
    newdata.head()
    
    • 1
    • 2
    • 3
    • 4

    标签列:是否存活—用0,1表示

    把标签列设置成哑变量很少,因为用的分类算法,就已经把标签当分类型数值了

    对分类数据的处理到此结束

    处理连续型特征:二值化与分段

    二值化:
    根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。
    二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯设置中的伯努利分布建模)。

    #将年龄二值化
    data_2 = data.copy()
    from sklearn.preprocessing import Binarizer
    X = data_2.iloc[:,0].values.reshape(-1,1) #类为特征专用,所以不能使用一维数组
    transformer = Binarizer(threshold=30).fit_transform(X)
    transformer  #分为了小于30岁的与大于等于30的
    data_2.iloc[:,0]=transformer  #替换原本年龄列
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    分箱

    将连续型变量划分为分类变量的类
    n_bins 每个特征分箱的个数,默认为5 encode 编码方式,默认onehot strategy 定义箱宽的方式,默认quantite(uniform 等宽分箱;quantitle 等位分箱 ;kmeans聚类分箱)

    from sklearn.preprocessing import KBinsDiscretizer
    X = data.iloc[:,0].values.reshape(-1,1)
    est = KBinsDiscretizer(n_bins=3,encode='ordinal',strategy='uniform')
    est.fit_transform(X)
    #查看转换后分的箱;变成了一列中的三箱
    set(est.fit_transform(X).ravel())
    est = KBinsDiscretizer(n_bins=3,encode='onehot',strategy='uniform')
    #查看转换后分的箱;变成了哑变量
    est.fit_transform(X).ravel()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    安全测试概述和用例设计
    在 Python 中跨多个文件使用全局变量
    Android 使用Camera2 API 和 GLSurfaceView实现相机预览
    ASP.NET Core 6框架揭秘实例演示[03]:Dapr初体验
    Redis持久化RDB与AOF
    为什么网络掩码一定是255.255.255.0(/24)
    LCR 144. 翻转二叉树
    ubuntu按下del却出现空格(命令行下键盘错乱)
    精确率、准确率、召回率
    用低代码打造CRM系统 实现客户个性化管理
  • 原文地址:https://blog.csdn.net/Sun123234/article/details/127560022