数据预处理

本文总结了Scikit-learn中数据预处理方法,包括规范化、正则化、特征标准化等,并介绍了特征抽取与选择的技术,如VarianceThreshold、SelectKBest等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Scikit-learn使用总结

1 scikit-learn基础介绍

1.1 估计器(Estimator)

  
  估计器,很多时候可以直接理解成分类器,主要包含两个函数: 

  • fit():训练算法,设置内部参数。接收训练集和类别两个参数。   

  • predict():预测测试集类别,参数为测试集。

    大多数scikit-learn估计器接收和输出的数据格式均为numpy数组或类似格式。

1.2 转换器(Transformer)

  
  转换器用于数据预处理和数据转换,主要是三个方法: 

  • fit():训练算法,设置内部参数。

  • transform():数据转换。

  • fit_transform(): 合并fit和transform两个方法。

1.3 预处理

  主要在sklearn.preprcessing包下

规范化:

  • MinMaxScaler :最大最小值规范化,实现 min-max 标准化,标准化后,所有的属性的值都在feature_range区间内。

    原型:class sklearn.preprocessing.MinMaxScaler(feature_range=(0, 1), copy=True)

from sklearn.preprocessing import MinMaxScaler

X = [[1, 5, 1, 2, 10],
     [2, 6, 3, 2, 7],
     [3, 7, 5, 6, 4],
     [4, 8, 7, 8, 1]]
print("before transfom:",X)
scaler=MinMaxScaler(feature_range=(0,2))
scaler.fit(X)
print("min_ is:",scaler.min_)
print("scale_ is:",scaler.scale_)
print("data_max_ is:",scaler.data_max_)
print("data_min_ is:",scaler.data_min_)
print("data_range_ is:",scaler.data_range_)
print("after transform:",scaler.transform(X))
#### 结果 ####
before transfom: [[1, 5, 1, 2, 10], [2, 6, 3, 2, 7], [3, 7, 5, 6, 4], [4, 8, 7, 8, 1]]
min_ is: [-0.66666667 -3.33333333 -0.33333333 -0.66666667 -0.22222222]
scale_ is: [ 0.66666667  0.66666667  0.33333333  0.33333333  0.22222222]
data_max_ is: [  4.   8.   7.   8.  10.]
data_min_ is: [ 1.  5.  1.  2.  1.]
data_range_ is: [ 3.  3.  6.  6.  9.]
after transform: [[ 0.          0.          0.          0.          2.        ]
 [ 0.66666667  0.66666667  0.66666667  0.          1.33333333]
 [ 1.33333333  1.33333333  1.33333333  1.33333333  0.66666667]
 [ 2.          2.          2.          2.          0.        ]]
  • Normalizer : 将数据正则化,使每条数据各特征值的和为1,正则化后,每个样本的L2范数为1。

    原型:class sklearn.preprocessing.Normalizer(norm=’l2’, copy=True)

    norm:指定正则化方法

  • l1:采用L1范数正则化

  • l2:采用L2范数正则化

  • max:采用L∞范数正则化
from sklearn.preprocessing import Normalizer

X = [[1, 2, 3, 4, 5],
     [5, 4, 3, 2, 1],
     [1, 3, 5, 2, 4],
     [2, 4, 1, 3, 5]]

print("before transfom:",X)
normalizer = Normalizer(norm='l2')
print("after transform:",normalizer.transform(X))
#### 结果 ####
before transfom: [[1, 2, 3, 4, 5], [5, 4, 3, 2, 1], [1, 3, 5, 2, 4], [2, 4, 1, 3, 5]]
after transform: [[ 0.13483997  0.26967994  0.40451992  0.53935989  0.67419986]
 [ 0.67419986  0.53935989  0.40451992  0.26967994  0.13483997]
 [ 0.13483997  0.40451992  0.67419986  0.26967994  0.53935989]
 [ 0.26967994  0.53935989  0.13483997  0.40451992  0.67419986]]
  • MaxAbsScaler :实现属性绝对值最大值 标准化,将每个属性值除以该属性的绝对值中的最大值,标准化后,每个属性值得绝对值都在[0, 1]之间。

    原型:class sklearn.preprocessing.MaxAbsScaler(copy=True)

from sklearn.preprocessing import MaxAbsScaler

X = [[1, 5, 1, 2, 10],
     [2, 6, 3, 2, 7],
     [3, 7, 5, 6, 4],
     [4, 8, 7, 8, 1]]
print("before transfom:",X)
scaler = MaxAbsScaler()
scaler.fit(X)
print("scale_ is :",scaler.scale_)
print("max_abs_ is :",scaler.max_abs_)
print("after transform:",scaler.transform(X))
#### 结果 ####
before transfom: [[1, 5, 1, 2, 10], [2, 6, 3, 2, 7], [3, 7, 5, 6, 4], [4, 8, 7, 8, 1]]
scale_ is : [  4.   8.   7.   8.  10.]
max_abs_ is : [  4.   8.   7.   8.  10.]
after transform: [[ 0.25        0.625       0.14285714  0.25        1.        ]
 [ 0.5         0.75        0.42857143  0.25        0.7       ]
 [ 0.75        0.875       0.71428571  0.75        0.4       ]
 [ 1.          1.          1.          1.          0.1       ]]
  • StandardScaler : z-score标准化,为使各特征的均值为0,方差为1

    原型:class sklearn.preprocessing.StandardScaler(copy=True,with_mean=True,with_std=True)

from sklearn.preprocessing import StandardScaler

X = [[1, 5, 1, 2, 10],
     [2, 6, 3, 2, 7],
     [3, 7, 5, 6, 4],
     [4, 8, 7, 8, 1]]
print("before transfom:",X)
scaler = StandardScaler()
scaler.fit(X)
print("scale_ is :",scaler.scale_)
print("mean_ is :",scaler.mean_)
print("var_ is :",scaler.var_)
print("after transform:",scaler.transform(X))
#### 结果 ####
before transfom: [[1, 5, 1, 2, 10], [2, 6, 3, 2, 7], [3, 7, 5, 6, 4], [4, 8, 7, 8, 1]]
scale_ is : [ 1.11803399  1.11803399  2.23606798  2.59807621  3.35410197]
mean_ is : [ 2.5  6.5  4.   4.5  5.5]
var_ is : [  1.25   1.25   5.     6.75  11.25]
after transform: [[-1.34164079 -1.34164079 -1.34164079 -0.96225045  1.34164079]
 [-0.4472136  -0.4472136  -0.4472136  -0.96225045  0.4472136 ]
 [ 0.4472136   0.4472136   0.4472136   0.57735027 -0.4472136 ]
 [ 1.34164079  1.34164079  1.34164079  1.34715063 -1.34164079]]

编码:

  • Binarizer :为将数值型特征的二元化

    原型:class sklearn.preprocessing.Binarizerr(threshold=0.0, copy=True)

    threshold用于指定阈值,大于此阈值的数标记为1,小于此阈值的数为0

from sklearn.preprocessing import Binarizer

#class sklearn.preprocessing.Binarizer(threshold=0.0, copy=True)
#threshold用于指定阈值,大于此阈值的数标记为1,小于此阈值的数为0
X = [[1, 2, 3, 4, 5],
     [5, 4, 3, 2, 1],
     [3, 3, 3, 3, 3],
     [1, 1, 1, 1, 1]]
print("before transfom:",X)
binarizer = Binarizer(threshold=2.5)
print("after transform:",binarizer.transform(X))
#### 结果 ####
before transfom: 
[[1, 2, 3, 4, 5], 
[5, 4, 3, 2, 1], 
[3, 3, 3, 3, 3], 
[1, 1, 1, 1, 1]]
after transform: 
[[0 0 1 1 1]
 [1 1 1 0 0]
 [1 1 1 1 1]
 [0 0 0 0 0]]
  • OneHotEncoder :scikit-learn提供的OneHotEncoder能够实现数据独热码,特征用一个二进制数字来表示

    原型:class sklearn.preprocessing.OneHotEncoder(n_values=’auto’, categorical_features=’all’, sparse=True,handle_unknown=error”)

快速了解原理:

http://blog.clzg.cn/blog-1579109-884831.html

from sklearn.preprocessing import OneHotEncoder

X = [[1, 2, 3, 4, 5],
     [5, 4, 3, 2, 1],
     [3, 3, 3, 3, 3],
     [1, 1, 1, 1, 1]]
print("before transfom:",X)
encoder = OneHotEncoder(sparse=False)
encoder.fit(X)
print("active_features_:",encoder.active_features_)
print("feature_indices_:",encoder.feature_indices_)
print("n_values_:",encoder.n_values_)
print("after transform:",encoder.transform([[1,2,3,4,5]]))
#### 结果 ####
before transfom: 
[[1, 2, 3, 4, 5], 
[5, 4, 3, 2, 1], 
[3, 3, 3, 3, 3], 
[1, 1, 1, 1, 1]]
active_features_: [ 1  3  5  7  8  9 10 12 14 16 17 18 19 21 23 25]
feature_indices_: [ 0  6 11 15 20 26]
n_values_: [6 5 4 5 6]
after transform: 
[[ 1.  0.  0.  0.  1.  0.  0.  0.  1.  0.  0.  0.  1.  0.  0.  1.]]
  • LabelEncoder :把字符串类型的数据转化为整型
  • MultiLabelBinarizer :多标签二值化估计器,很多时候可以直接理解成分类器

1.4 特征

  *1.4.1 特征抽取*

  主要在sklearn.feature_extraction包下

  特征抽取是数据挖掘任务最为重要的一个环节,一般而言,它对最终结果的影响要高过数据挖掘算法本身。只有先把现实用特征表示出来,才能借助 数据挖掘的力量找到问题的答案。特征选择的另一个优点在于:降低真实世界的复杂度,模型比现实更容易操纵。
  一般最常使用的特征抽取技术都是高度针对具体领域的,对于特定的领域,如图像处理,在过去一段时间已经开发了各种特征抽取的技术,但这些技术在其他领域的应用却非常有限。

  • DictVectorizer: 将dict类型的list数据,转换成numpy array

  • FeatureHasher : 特征哈希,相当于一种降维技巧

  • image:图像相关的特征抽取

  • text: 文本相关的特征抽取

  • text.CountVectorizer:将文本转换为每个词出现的个数的向量

  • text.TfidfVectorizer:将文本转换为tfidf值的向量

  • text.HashingVectorizer:文本的特征哈希

    *1.5.2 特征选择*

    主要在sklearn.feature_selection包下

  特征选择的原因如下:

  (1)降低复杂度

  (2)降低噪音

  (3)增加模型可读性特征抽

过滤式特征提取

  • VarianceThreshold: 删除特征值的方差达不到最低标准的特征,当一个熟悉的方差小时,说明该特征的价值不大,不应该优选,应该删除。

    原型:class sklearn.feature_selection.VarianceThreshold(threshold=0.0)

    threshold:用于指定方差阈值,低于此阈值的方差应该被剔除

#根据特征方差,方差小则该属性的识别能力差
from sklearn.feature_selection import VarianceThreshold

X = [[100, 1, 2, 3],
     [100, 4, 5, 6],
     [100, 7, 8, 9],
     [100, 11, 12, 13]]
selector = VarianceThreshold(threshold=1)
selector.fit(X)
print("Variances is:", selector.variances_)  # 成员分别各属性的方差
print("After transform::", selector.transform(X)) 
print("The surport is:", selector.get_support(True)) #返回被选出的特征的下标
print("After reverse transform is:", selector.inverse_transform(selector.transform(X)))



  • SelectKBest : 返回在该统计指标上得分最高的k个最佳特征,(通过计算每个特征的某个统计指标,

    然后根据该指标来选取特征)

  • SelectPercentile :返回在该统计指标上得分最高的前K%个特征,(通过计算每个特征的某个统计指

    标,然后根据该指标来选取特征)

    原型:class sklearn.feature_selection.SelectKBest(score_func=f_classif, k=3)

    k:用于指定保留特征个数

    score_func:给出统计指标的函数,

      f_regression:基于线性回归分析来计算统计指标,适用于回归问题
      chi2:卡方统计量,适用于分类问题
      f_classif:方差分析,适用于分类问题

# 单变量特征提取
from sklearn.feature_selection import SelectKBest, f_classif

X = [[1, 2, 3, 4, 5],
     [5, 4, 3, 2, 1],
     [3, 3, 3, 3, 3],
     [1, 1, 1, 1, 1]]
y = [0, 1, 0, 1]
print("before transform:", X)
selector_2 = SelectKBest(score_func=f_classif, k=3)
selector_2.fit(X, y)
print("scores_ :", selector_2.scores_)
print("pvalues_ :", selector_2.pvalues_)
print("selected index", selector_2.get_support(True))
print("After transform:", selector_2.transform(X))



包裹式特征提取

  • RFE: 通过外部提供的一个学习器来选择特征,要求学习器学习的是特征的权重(通常使用SVM和广义线性模型)

    原型:class sklearn.feature_selection.RFE(estimator, n_features_to_select=None, step=1)

    estimator:通常使用SVM和广义线性模型

    n_features_to_select:指定要选出几个特征

  • 步骤:

    • 初始化集合运用学习器进行训练
    • 剔除其中权重特别小的特征
    • 重新训练直到筛选出特征数量满足条件
# RFE
from sklearn.feature_selection import RFE
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris

iris = load_iris()
X = iris.data
y = iris.target
estimator = LinearSVC()
selector = RFE(estimator=estimator, n_features_to_select=2)
selector.fit(X, y)
print("N_features ",selector.n_features_)
print("Support is ",selector.support_)
print("Ranking ", selector.ranking_)



  • RFECV : 执行一个交叉验证来寻找最优的剩余特征数量,因此不需要指定保留多少个特征

    原型:class sklearn.feature_selection.RFECV(estimator, cv=None, step=1)

    estimator:通常使用SVM和广义线性模型

    cv:交叉验证生成器,如果为整数k,则使用k折交叉验证

#RFECV
import numpy as np
from sklearn.feature_selection import RFECV
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris

iris = load_iris()
X = iris.data
y = iris.target
estimator = LinearSVC()
selector = RFECV(estimator=estimator, cv=3)
selector.fit(X, y)
print("N_features ",selector.n_features_)
print("Support is ",selector.support_)
print("Ranking ", selector.ranking_)
print("Grid Scores ",selector.grid_scores_)



嵌入式特征提取

  • SelectFromModel: 删除特征值的方差达不到最低标准的特征

    原型:class sklearn.feature_selection.SelectFromModel(estimator, threshold=None)

    threshold:用于指定阈值,低于此阈值的方差应该被剔除

#嵌入式特征选取from sklearn.feature_selection import SelectFromModel
import numpy as np
from sklearn.feature_selection import SelectFromModel
from sklearn.svm import LinearSVC
from sklearn.datasets import load_digits

digits = load_digits()
X = digits.data
y = digits.target
estimator = LinearSVC(penalty='l1', dual=False)
selector = SelectFromModel(estimator=estimator, threshold='mean') #阈值为'mean',表示特征重要性的均值
selector.fit(X, y)
selector.transform(X)
print("Threshold ",selector.threshold_)
print("Support is ",selector.get_support(indices=True))



 

数据预处理实战总结:


1、绘制箱型图判断数据是否有异常值

  运用Python的Pandas库中,读入数据,然后使用describe()函数查看数据的基本情况
  

import pandas as pd
import numpy as np
#文件地址
catering_sale = 'E:/PyCharm/MyPyCharm/Python_data_analysis/chapter3/demo/data/catering_sale.xls'
#pd.read_excel()用于读取文件
data = pd.read_excel(catering_sale, index_col=r'日期')

#数据描述,其中count可以得到非空值数
#运用data.describe与len对比得到空值个数
data.describe()
len(data)

# df.index 是获取行名称,对应后面的[0]取行号/通过以下方式
np.where(data.isnull())#可以获取NAN的行号,如下为14行
    (array([14], dtype=int64), array([0], dtype=int64))
data.index[np.where(data.isnull())[0]]#可以获取NAN的索引,如下为'2015-02-14'
    DatetimeIndex(['2015-02-14'], dtype='datetime64[ns]', name='日期', freq=None)

#绘制箱型图
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

plt.figure() #建立图像
p = data.boxplot(return_type='dict') #画箱线图,直接使用DataFrame的方法
x = p['fliers'][0].get_xdata() # 'flies'即为异常值的标签
y = p['fliers'][0].get_ydata()
y.sort() #从小到大排序,该方法直接改变原对象

#用annotate添加注释
#其中有些相近的点,注解会出现重叠,难以看清,需要一些技巧来控制。
#以下参数都是经过调试的,需要具体问题具体调试。
for i in range(len(x)): 
  if i>0:
    plt.annotate(y[i], xy = (x[i],y[i]), xytext=(x[i]+0.05 -0.8/(y[i]-y[i-1]),y[i]))
  else:
    plt.annotate(y[i], xy = (x[i],y[i]), xytext=(x[i]+0.08,y[i]))

plt.show() #展示箱线图


箱型图

  通过绘制箱型图可以筛选查看出异常数据,箱型图识别异常值的结果比较客观,在识别异常值方面有一定的优越性,超过上下界的数据为可疑的异常值,然后通过编写过滤程序,进行后续处理。
  


2、数据清洗

  运用拉格朗日插值法《python数据分析与挖掘实战P63》
  from scipy.interpolate import lagrange #导入拉格朗日插值函数

# -*- coding:utf-8 -*-
# __author__ = 'Administrator'

#拉格朗日插值代码
import pandas as pd #导入数据分析库Pandas
from scipy.interpolate import lagrange #导入拉格朗日插值函数

inputfile = '../data/catering_sale.xls' #销量数据路径
outputfile = '../text/sales.xls' #输出数据路径

data = pd.read_excel(inputfile) #读入数据
# print(data)
data[u'销量'][(data[u'销量'] < 400) | (data[u'销量'] > 5000)] = None #过滤异常值,将其变为空值

#自定义列向量插值函数
#s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
def ployinterp_column(s, n, k=5):
  y = s[list(range(n-k, n)) + list(range(n+1, n+1+k))] #取数
  y = y[y.notnull()] #剔除空值
  return lagrange(y.index, list(y))(n) #插值并返回插值结果

#逐个元素判断是否需要插值
for i in data.columns:
  for j in range(len(data)):
    if (data[i].isnull())[j]: #如果为空即插值。
      data[i][j] = ployinterp_column(data[i], j)

data.to_excel(outputfile) #输出结果,写入文件

  在进行插值之前会对数据进行异常值检查,数据大于5000以及数据小于400的会被过滤检测出来(通过第一步的箱型图得来),然后再使用拉格朗日插值法填补数据。
  很多情况下,要先分析异常值出现的可能原因,在判断异常值是否应该被舍弃,如果是正确的数据,可以直接在具有异常值的数据集上进行数据挖掘。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值