数据挖掘与scikit-learn浅出

欢迎关注我的微信公众号AI_Engine

数据无量纲化

在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布的需求,这种需求统称为将数据“无量纲化”。譬如梯度和矩阵为核心的算法中,譬如逻辑回归,支持向量机,神经 网络,无量纲化可以加快求解速度;而在距离类模型,譬如K近邻,K-Means聚类中,无量纲化可以帮我们提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响。数据的无量纲化可以是线性的,也可以是非线性的。线性的无量纲化包括中心化(Zero-centered或者Meansubtraction)处理和缩放处理(Scale)。中心化的本质是让所有记录减去一个固定值,即让数据样本数据平移到某个位置。缩放的本质是通过除以一个固定值,将数据固定在某个范围之中,取对数也算是一种缩放处理。

  • 归一化 preprocessing.MinMaxScaler
    当数据x按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间。这个过程就叫做数据归一化(Normalization,又称Min-Max Scaling)。注意,Normalization是归一化,不是正则化,真正的正则化是regularization,不是数据预处理的一种手段。归一化之后的数据服从正态分布,公式如下:
    在这里插入图片描述
    在sklearn当中,我们使用preprocessing.MinMaxScaler来实现这个功能。MinMaxScaler有一个重要参数:feature_range,控制我们希望把数据压缩到的范围,默认是[0,1]。
result_ = scaler.fit_transform(data) # 训练和导出结果一步达成
scaler.inverse_transform(result)    # 将归一化后的结果逆转
# 使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]以外的范围中
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]] 
scaler = MinMaxScaler(feature_range=[5,10]) # 实例化
result = scaler.fit_transform(data) # fit_transform一步导出结果

当X中的特征数量非常多的时候,fit会报错。此时使用partial_fit作为训练接口

scaler = scaler.partial_fit(data)
  • 标准化 preprocessing.StandardScaler
    当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布),而这个过程,就叫做数据标准化(Standardization,又称Z-score normalization),公式如下:
    在这里插入图片描述
    在这里插入图片描述](https://img-blog.csdnimg.cn/2020020201191473.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNjMyNTYwMg==,size_16,color_FFFFFF,t_70)
from sklearn.preprocessing import StandardScaler 
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]

scaler = StandardScaler()  # 实例化
scaler.fit(data)          # fit,本质是生成均值和方差
scaler.mean_             # 查看均值的属性mean_
scaler.var_             # 查看方差的属性var_

x_std = scaler.transform(data)
x_std.mean() 
x_std.std()

scaler.fit_transform(data)
scaler.inverse_transform(x_std) # 使用inverse_transform逆转标准化

注意:对于StandardScaler和MinMaxScaler来说,空值NaN会被当做是缺失值,在fit的时候忽略,在transform的时候保持缺失NaN的状态显示。并且,尽管去量纲化过程不是具体的算法,但在fit接口中,依然只允许导入至少二维数组,一维数组导入会报错。通常来说,我们输入的X会是我们的特征矩阵,现实案例中特征矩阵不太可能是一维,所以不会存在这个问题。

  • StandardScaler和MinMaxScaler选哪个?
    看情况。大多数机器学习算法中,会选择StandardScaler来进行特征缩放,因为MinMaxScaler对异常值非常敏感。在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler往往是最好的选择。MinMaxScaler在不涉及距离度量、梯度、协方差计算以及数据需要被压缩到特定区间时使用广泛,比如数字图像处理中量化像素强度时,都会使用MinMaxScaler将数据压缩于[0,1]区间之中。建议先试试看StandardScaler,效果不好换MinMaxScaler。除了StandardScaler和MinMaxScaler之外,sklearn中也提供了各种其他缩放处理(中心化只需要一个pandas广播一下减去某个数就好了,因此sklearn不提供任何中心化功能)。比如,在希望压缩数据,却不影响数据的稀疏性时(不影响矩阵中取值为0的个数时),我们会使MaxAbsScaler;在异常值多,噪声非常大时,我们可能会选用分位数来无量纲化,此时使用RobustScaler。更多详情请参考以下列表。
    在这里插入图片描述
缺省值

机器学习和数据挖掘中所使用的数据,永远不可能是完美的。很多特征,对于分析和建模来说意义非凡,但对于实际收集数据的人却不是如此,因此数据挖掘之中,常常会有重要的字段缺失值很多,但又不能舍弃字段的情况。因此,数据预处理中非常重要的一项就是处理缺失值。

  • impute.SimpleImputer
    class sklearn.impute.SimpleImputer (missing_values=nan, strategy=’mean’, fill_value=None, verbose=0, copy=True)
    这个类是专门用来填补缺失值的。它包括四个重要参数:
参数含义&输入
missing_values告诉SimpleImputer,数据中的缺失值长什么样,默认空值np.nan
strategy我们填补缺失值的策略,默认均值。输入“mean”使用均值填补(仅对数值型特征可用)。输入“median"用中值填补(仅对数值型特征可用)。输入"most_frequent”用众数填补(对数值型和字符型特征都可用)。输入“constant"表示请参考参数“fill_value"中的值(对数值型和字符型特征都可用)
fill_value当参数startegy为”constant"的时候可用,可输入字符串或数字表示要填充的值,常用0
copy默认为True,将创建特征矩阵的副本,反之则会将缺失值填补到原本的特征矩阵中去。

但是!!!用Pandas和Numpy进行填补其实更加简单

import pandas as pd 
data = pd.read_csv(r"C:\work\learnbetter\micro-class\week 3 Preprocessing\Narrativedata.csv",index_col=0)

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

data.dropna(axis=0,inplace=True) 
# .dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列 
# 参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False
处理连续型特征:二值化与分桶
  • 二值化 sklearn.preprocessing.Binarizer

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

# 将年龄二值化
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)
  • 分桶 preprocessing.KBinsDiscretizer

这是将连续型变量划分为分类变量的类,能够将连续型变量排序后按顺序分箱后编码。总共包含三个重要参数:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IVE06kuc-1580577486057)(evernotecid://199A0999-284B-465C-AF36-D243A9FA840A/appyinxiangcom/18720816/ENResource/p779)]

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).toarray()

样本均衡

我们对不同类别的样本数量进行观察:

y = data.loc[:,'SeriousDlqin2yrs']
y.value_counts()

0    139382
1     10009

我们发现样本的分布其实是不均衡的,也就是所利用这些样本去训练模型,模型很有可能会更倾向于学习样本多的类别,所以我们应该对样本的均衡问题进行处理,这里使用的是smote和smoteenn方法。
smote原理:SMOTE算法的基本思想是对少数类样本进行分析并根据少数类样本人工合成新样本。
API:imblearn.over_sampling.SMOTE
实例:

def sample_process(data):
    x = data.iloc[:, data.columns != Config.lable_colname]
    y = data.iloc[:, data.columns == Config.lable_colname]
    sme = SMOTE(random_state=Config.seed)
    x, y = sme.fit_sample(x.values, y.values)
    return x, y

其实很简答对吧,但是smoten其实是有弊端的,那就是容易产生噪声,官方的解释是:SMOTE allows to generate samples. However, this method of over-sampling does not have any knowledge regarding the underlying distribution. Therefore, some noisy samples can be generated, e.g. when the different classes cannot be well separated. Hence, it can be beneficial to apply an under-sampling algorithm to clean the noisy samples. 这句话的中心思想其实是这样的:当两个类别的样本经过过采样之后,如果不能很好的进行分离(说明过采样后产生了噪声),那么此时进行欠采样对去噪是很有效的。也就是说,使用smoteenn可以进行过采样,并利用欠采样进行去噪,可谓神器。
smoteenn原理:如上述所示
API:imblearn.combine.SMOTEENN
实例:

def sample_process(data):
    x = data.iloc[:, data.columns != Config.lable_colname]
    y = data.iloc[:, data.columns == Config.lable_colname]
    smen = SMOTEENN(sampling_strategy=1, random_state=Config.seed)
    x, y = smen.fit_resample(x.values, y.values)
    return x, y

超简单,有木有。现在附上smoteenn的图片介绍,可能会更加生动:
在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值