特征工程

一、数据预处理 Preprocessing & Impute

菜菜第3章

0. 所有工作进行前需先分训练集和测试集

#train_test_split可用于对dataframe、series分割
x_train,x_test,y_train,y_test,reac_train,reac_test = train_test_split(X, Y,REACTION_CenterFrag, test_size=0.3, random_state=420)

1. 描述性统计处理异常值及重复值

去除重复样本

df_descriptor.drop_duplicates(inplace = True)

观察1%和min、99%和max对比就大概知道有无异常值()以及看方差

如何处理异常值?
首先观察异常值出现的频率
如果异常值出现了1测,多数为输入错误或计算错误,直接删除
出现多次,需判断是否是认为输入错误
占>=10%,把异常值替换成非异常但是非干扰的项,比如用0替换,或把异常当缺失

x_train.describe([0.01,0.05,0.1,0.25,0.5,0.75,0.9,0.99]).T
x_test.describe([0.01,0.05,0.1,0.25,0.5,0.75,0.9,0.99]).T

在这里插入图片描述

2. 处理缺失值impute

如何处理缺失值
分类型变量:用众数填补
连续性变量:用均值填补
或用算法(随机森林填补)
实际应用中使用测试集的均值和众数对训练集、测试集的缺失值进行填补(这样做可以保证在测试集样本少到不具有统计意义时,仍可执行)

import pandas as pd
#dataframe类型填补年龄
Age = data.loc[:,"Age"].values.reshape(-1,1) 


2.1补上缺失值

方法1 (更简单)

import pandas as pd
data.loc[:,"Age"] = data.loc[:,"Age"].fillna(data.loc[:,"Age"].median())
#.fillna 在DataFrame里面直接进行填补

方法2

from sklearn.impute import SimpleImputer
imp_nagtive1 = SimpleImputer(strategy="constant",fill_value=-1) #用-1填补
imp_nagtive1= imp_0.fit_transform(Age)

#在这里我们使用用-1填补Age
data.loc[:,"Age"] = imp_nagtive1
2.2 删掉缺失值(只有几个缺失的)
data.dropna(axis=0,inplace=True)
#.dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
#参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False

3. 分别处理分类型变量和连续性变量

数据类型

在这里插入图片描述

3. 1处理分类型数据(非数值型)

在机器学习中,大多数算法,譬如逻辑回归,支持向量机SVM,k近邻算法等都只能够处理数值型数据,不能处理文字,在sklearn当中,除了专用来处理文字的算法,其他算法在fit的时候全部要求输入数组或矩阵,也不能够导入文字型数据(其实手写决策树和普斯贝叶斯可以处理文字,但是***sklearn中规定必须导入数值型***)。然而在现实中,许多标签和特征在数据收集完毕的时候,都不是以数字来表现的。比如说,学历的取值可以是[“小学”,“初中”,“高中”,“大学”],付费方式可能包含[“支付宝”,“现金”,“微信”]等等。在这种情况下,为了让数据适应算法和库,我们必须将数据进行编码,即是说,将文字型数据转换为数值型。
1 . 编码 (y–标签专用)
将分类转换为分类数值

from sklearn.preprocessing import LabelEncoder #标签专用,能够将分类转换为分类数值
data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1])
LabelEncoder().fit(data.iloc[:,-1]).classes_       #属性.classes_查看标签中究竟有多少类别

2 分类数值OrdinalEncoder(xn–特征专用)
将分类特征转换为分类数值

from sklearn.preprocessing import OrdinalEncoder
​
#接口categories_对应LabelEncoder的接口classes_,一模一样的功能
data_ = data.copy()
data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])

3 哑变量OneHotEncoder (用独热编码创建,xn–特征专用)

思考:

将分类特征转换为分类数值这种转换是正确的吗?

我们来思考三种不同性质的分类数据:

1) 舱门(S,C,Q)——只能用OneHotEncoder

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

2) 学历(小学,初中,高中)——可以用OrdinalEncoder处理

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

3) 体重(>45kg,>90kg,>135kg)——正常处理

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

非常重要

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

类别OrdinalEncoder可以用来处理有序变量,但对于名义变量,只有使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息

这样的变化,让算法能够彻底领悟,原来三个取值是没有可计算性质的,是“有你就没有我”的不等概念。在我们的数据中,性别和舱门,都是这样的名义变量。因此我们需要使用独热编码,将两个特征都转换为哑变量。

现实中处理分类数据,分类型变量是否要变为哑变量的实际情况:

  1. 进行独热编码前,如果分类数值类别超过25种,算法会自动认为是连续变量
  2. 独热编码后不一定效果好,可以用OrdinalEncoder先训练一下,看看效果,或对比一下。 因为哑变量后特征会变得特别多,计算负担变大,需要的样本量也会随之增大,很可能模型分类效果不好。 所以可以先普通编码一下看看分类效果。
数据

data = {
        '性别':['1','2','2','1','1'],
        '姓名':['小明','小红','小芳','大黑','张三'],
        '年龄':[20,21,25,24,29]}
df = pd.DataFrame(data,
               columns=['姓名','性别','年龄','职业'])

将某一列或n列转换为独热编码

from sklearn.preprocessing import OneHotEncoder
X = df.iloc[:,1].values.reshape(-1, 1) 
enc = OneHotEncoder(categories='auto').fit(X)
result = enc.transform(X).toarray()
#依然可以还原
pd.DataFrame(enc.inverse_transform(result))
#独热编码每列代表的类别
enc.get_feature_names()

array([‘x0_1’, ‘x0_2’], dtype=object)

#一步到位
OneHotEncoder(categories='auto').fit_transform(X).toarray()

合并独热编码和原数据

newdata = pd.concat([df,pd.DataFrame(result)],axis=1)

删除独热编码对应的原数据列

newdata.drop(["性别"],axis=1,inplace=True)

在这里插入图片描述

4. 无量纲化(可只对连续性变量处理)

??需要无量纲化的情况

  1. 原始数据不同维度的尺度(量纲)不一致时,need
  2. 在分类、聚类算法中,需要使用距离来度量相似性时,或使用PCA降维时,标准化(standardization,也叫Z-score)表现更好(数据均值为0,方差为1),实际上不改变分布
  3. !!!在希望压缩数据,却不影响数据的稀疏性时(不影响矩阵中取值为0的个数时),我们会使用归一化***MaxAbsScaler***!!!MinMaxScaler归一化到[0,1],MaxAbsScaler归一化到[-1,1]
  4. 这个评述对选标准化还是归一化缩放数据讲的非常好standardization or normalization
    在这里插入图片描述
from sklearn.preprocessing import StandardScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = StandardScaler()  
scaler.fit_transform(data)                          #使用fit_transform(data)一步达成结果
​
scaler.inverse_transform(x_std)                     #使用inverse_transform逆转标准化

tips:
对于StandardScaler和MinMaxScaler来说,空值NaN会被当做是缺失值,在fit的时候忽略,在transform的时候保持缺失NaN的状态显示。

二、 样本不平衡处理

好文章
1.怎样解决样本不平衡问题
2. 不平衡数据处理之SMOTE、Borderline SMOTE和ADASYN详解及Python使用
3.写了很多在数据层面和算法层面处理不平衡问题的方法的综述
4. imbalanced-learn API
5. 样本不均衡对模型的影响
6.讲了SMOTE算法
7. SMOTE算法伪代码和实现
样本不平衡是指在一组数据集中,标签中的某些类天生占有很大的比例或误分类的代价很高(想要捕捉出特定的类)。对不平衡数据集的求解可以分为数据级和算法级。数据级的方法改变了不平衡数据集的分布,然后将平衡数据集提供给学习器,以提高少数类别的检测率。算法层面的方法对现有的数据挖掘算法进行了修改,或提出了新的算法来解决不平衡问题。
方法1:
使用参数class_weight对样本标签进行一定的均衡,给少量的标签更多的权重,让模型偏向少数类。默认所有标签权重都相同,当需要对标签进行均衡时,使用‘’balanced‘’模式。
该方法在实际应用时,很难找出参数class_weight对模型分类结果的引导趋势,或画出学习曲线评估参数效果,很难用
方法2:
主流的是采样法,即通过重复样本的方式来平衡标签,可以进行上采样(增加少数类的样本)(better option),比如SMOTE,或下采样(减少多数类的样本,减少不能盲目减少,集成算法、先对样本聚类等步骤都是必要的)。
方法3:
GAN生成伪样本

三、 特征工程

数据预处理后,开始特征工程。
特征工程包括:
特征提取(feature extraction,从非结构化数据中提取新信息作为特征)
特征创造(feature creation, 现有特诊搞得组合计算)
特征选择(feature selection,选择出有意义,对模型有帮助的特征)
在这里插入图片描述

1. 特征选择

1 对于能理解的特征,先主观判断,可以删除毫不相关的特征
2. 无法依赖对目标理解来选择特征,可以用四种方法:过滤法、嵌入法、包装法、和降维算法。

(1)过滤法

主要目的是:在维持算法表现的前提下,帮助算法降低计算成本
主要对象:需要遍历特征或升维的算法

selector = VarianceThreshold(threshold=0.01)#threshold=0.01删除方差小于0.01的列,默认0
selector = selector.fit(x_train)
x_train_var_001 = selector.transform(x_train)
x_test_var_001 = selector.transform(x_test)

# 保留特征名称
select_name_index = selector.get_support(indices=True).tolist() 
x_train_var_001 = pd.DataFrame(x_train_var_001,columns = select_name_index)
x_test_var_001 = pd.DataFrame(x_test_var_001,columns = select_name_index)

在这里插入图片描述
3. 依赖对目标理解来选择特征
方差挑选完毕之后,我们就要考虑下一个问题:相关性了。我们希望选出与标签相关且有意义的特征,因为这样的特征能够为我们提供大量信息。如果特征与标签无关,那只会白白浪费我们的计算内存,可能还会给模型带来噪音。在sklearn当中,我们有三种常用的方法来评判特征与标签之间的相关性:卡方,F检验,互信息
(1) 相关性过滤(卡方过滤)

聚类算法的评价指标

菜菜聚类评价指标
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值