python3机器学习——sklearn0.19.1版本——数据处理(一)(数据标准化、tfidf、独热编码)

一、数据预处理基础知识点

链接:https://www.zhihu.com/question/29316149/answer/110159647

通过特征提取,我们能得到未经处理的特征,这时的特征可能有以下问题:

  • 不属于同一量纲:即特征的规格不一样,不能够放在一起比较。无量纲化可以解决这一问题。
  • 信息冗余:对于某些定量特征,其包含的有效信息为区间划分,例如学习成绩,假若只关心“及格”或不“及格”,那么需要将定量的考分,转换成“1”和“0”表示及格和未及格。二值化可以解决这一问题。
  • 定性特征不能直接使用:某些机器学习算法和模型只能接受定量特征的输入,那么需要将定性特征转换为定量特征。最简单的方式是为每一种定性值指定一个定量值,但是这种方式过于灵活,增加了调参的工作。通常使用哑编码的方式将定性特征转换为定量特征:假设有N种定性值,则将这一个特征扩展为N种特征,当原始特征值为第i种定性值时,第i个扩展特征赋值为1,其他扩展特征赋值为0。哑编码的方式相比直接指定的方式,不用增加调参的工作,对于线性模型来说,使用哑编码后的特征可达到非线性的效果
  • 存在缺失值:缺失值需要补充。
  • 信息利用率低:不同的机器学习算法和模型对数据中信息的利用是不同的,之前提到在线性模型中,使用对定性特征哑编码可以达到非线性的效果。类似地,对定量变量多项式化,或者进行其他的转换,都能达到非线性的效果。

  我们使用sklearn中的preproccessing库来进行数据预处理,可以覆盖以上问题的解决方案。


二、无量钢化——数据标准化

无量纲化使不同规格的数据转换到同一规格。常见的无量纲化方法标准化区间缩放法

标准化的前提特征值服从正态分布,标准化后,其转换成标准正态分布。

区间缩放法利用了边界值信息,特征的取值区间缩放到某个特点的范围,例如[0, 1]等。

Standardization即标准化,尽量将数据转化为均值为零,方差为一的数据,形如标准正态分布(高斯分布)

关于高斯分布,文章链接为:http://blog.csdn.net/u010182633/article/details/45694437

实际中我们会忽略数据的分布情况,仅仅是通过改变均值来集中数据,然后将非连续特征除以他们的标准差。

sklearn中 scale函数提供了简单快速的singlearray-like数据集操作。

Standardization, or mean removal and variance scaling:标准化,均值去除和按方差比例缩放。

数据集的标准化:当个体特征太过或明显不遵从高斯正态分布时,标准化表现的效果较差。

实际操作中,经常忽略特征数据的分布形状,移除每个特征均值,划分离散特征的标准差,从而等级化,进而实现数据中心化。scale函数可实现数据的均值为0,方差为1,代码如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

from sklearn import preprocessing
import numpy as np

X = np.array([[1.,-1.,2.],[2.,0.,0.],[0.,1.,-1.]])
X_scaled = preprocessing.scale(X)

print("========X==========")
print(X)
print("========X_scaled==========")
print(X_scaled)
print("========mean==========")
#scale函数可实现数据的均值为0,方差为1
print(X_scaled.mean(axis=0))    #按列计算均值
print("========var==========")
print(X_scaled.var(axis=0))     #按列计算方差

#运行结果:
========X==========
[[ 1. -1.  2.]
 [ 2.  0.  0.]
 [ 0.  1. -1.]]
========X_scaled==========
[[ 0.         -1.22474487  1.33630621]
 [ 1.22474487  0.         -0.26726124]
 [-1.22474487  1.22474487 -1.06904497]]
========mean==========
[ 0.  0.  0.]
========var==========
[ 1.  1.  1.]

python3机器学习——sklearn0.19.1版本——数据处理(一)(数据标准化、tfidf、独热编码)_第1张图片


1、StandardScaler

标准化需要计算特征的均值和标准差,公式表达为:,使用preproccessing库的

StandardScaler类对数据进行标准化。

Python: sklearn库中数据预处理函数fit_transform()和transform()的区别详见博客链接:


http://blog.csdn.net/quiet_girl/article/details/72517053


python3机器学习——sklearn0.19.1版本——数据处理(一)(数据标准化、tfidf、独热编码)_第2张图片

python3机器学习——sklearn0.19.1版本——数据处理(一)(数据标准化、tfidf、独热编码)_第3张图片

python3机器学习——sklearn0.19.1版本——数据处理(一)(数据标准化、tfidf、独热编码)_第4张图片

#2.StandardScaler
from sklearn.preprocessing import StandardScaler

X1 = [[1,2,3,2],
      [4,5,7,9],
      [8,7,4,3],
      [5,9,4,2],
      [1,4,7,8]]

ss = StandardScaler()   #引入标准化的方法,要有数据的均值和方差
ss.fit(X1)    #用标准化的方法进行训练数据集X1(fit),得到标准化方法中的参数
#ss = StandardScaler.fit(X1)   等价于上面两句
print(ss)
print("========mean_==========")
print(ss.mean_)
print("========var_==========")
print(ss.var_)

print("===transform实现标准化转换===")
print(ss.transform(X1))

#fit与transform结合成一句
print("===fit_transform训练并标准化转换===")
X1_train = ss.fit_transform(X1)
print(X1_train)

#运行结果:
StandardScaler(copy=True, with_mean=True, with_std=True)
========mean_==========
[ 3.8  5.4  5.   4.8]
========var_==========
[ 6.96  5.84  2.8   9.36]
===transform实现标准化转换===
[[-1.06133726 -1.40693001 -1.19522861 -0.91520863]
 [ 0.0758098  -0.16552118  1.19522861  1.37281295]
 [ 1.59200589  0.66208471 -0.5976143  -0.58834841]
 [ 0.45485883  1.4896906  -0.5976143  -0.91520863]
 [-1.06133726 -0.57932412  1.19522861  1.04595272]]
===fit_transform训练并标准化转换===
[[-1.06133726 -1.40693001 -1.19522861 -0.91520863]
 [ 0.0758098  -0.16552118  1.19522861  1.37281295]
 [ 1.59200589  0.66208471 -0.5976143  -0.58834841]
 [ 0.45485883  1.4896906  -0.5976143  -0.91520863]
 [-1.06133726 -0.57932412  1.19522861  1.04595272]]

注:1)若设置with_mean=False 或者 with_std=False,则不做centering 或者scaling处理。

2)scale和StandardScaler可以用于回归模型中的目标值处理


2、MinMaxScaler


将数据特征缩放至某一范围(scalingfeatures to a range),被称为“区间缩放法”,常见的一种为利用两个最值进行缩放。即:另一种标准化方法是将数据缩放至给定的最小值与最大值之间,通常是0与1之间,可用MinMaxScaler实现者将最大的绝对值缩放至单位大小,可用MaxAbsScaler实现。公式表达为:

使用这种标准化方法的原因是,有时数据集的标准差非常非常小,有时数据中有很多很多零(稀疏数据),

需要保存住0元素。


from sklearn.preprocessing import MinMaxScaler

X = [[1,2,3,2],
      [4,5,7,9],
      [8,7,4,3],
      [5,9,4,2],
      [1,4,7,8]]

mms = MinMaxScaler()
mms.fit(X)
print(mms)
print("最大值",mms.data_max_)
print("最小值",mms.data_min_)

print("===区间缩放,返回值为缩放到[0, 1]区间的数据===")
print(mms.transform(X))

#与上面最后一句等价
# mms_fit = mms.fit_transform(X)
# print(mms_fit)

#运行结果:
MinMaxScaler(copy=True, feature_range=(0, 1))
最大值 [ 8.  9.  7.  9.]
最小值 [ 1.  2.  3.  2.]
===区间缩放,返回值为缩放到[0, 1]区间的数据===
[[ 0.          0.          0.          0.        ]
 [ 0.42857143  0.42857143  1.          1.        ]
 [ 1.          0.71428571  0.25        0.14285714]
 [ 0.57142857  1.          0.25        0.        ]
 [ 0.          0.28571429  1.          0.85714286]]

3、Normalizer——归一化

标准化与归一化的区别:

标准化是依照特征矩阵的列处理数据,其通过求z-score的方法,将样本的特征值转换到同一量纲下。

归一化是依照特征矩阵的行处理数据,其目的在于样本向量在点乘运算或其他核函数计算相似性时,

拥有统一的标准,也就是说都转化为“单位向量”。使用preproccessing库的Normalizer类对数据进行归一化


官方文档翻译:

sklearn.preprocessing.Normalizer(norm=’l2’, copy=True)

norm:可以为l1、l2或max,默认为l2

若为l1时,样本各个特征值除以各个特征值的绝对值之和

若为l2时,样本各个特征值除以各个特征值的平方之和

若为max时,样本各个特征值除以样本中特征值最大的值


归一化的过程是将每个样本缩放到单位范数(每个样本的范数为1),如果后面要使用如二次型(点积)或者其它核方法计算两个样本之间的相似性这个方法会很有用。

Normalization主要思想是对每个样本计算其p-范数,然后对该样本中每个元素除以该范数,这样处理的结果是使得每个处理后样本的p-范数(l1-norm,l2-norm)等于1。

        p-范数的计算公式:||X||p=(|x1|^p+|x2|^p+...+|xn|^p)^1/p

该方法主要应用于文本分类和聚类中。例如,对于两个TF-IDF向量的l2-norm进行点积,就可以得到这两个向量的余弦相似性。TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术TF意思是词频(Term Frequency),IDF意思是逆向文件频率(Inverse Document Frequency)。



#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

from sklearn.preprocessing import Normalizer

X = [[1,2,3,2],
      [4,5,7,9],
      [8,7,4,3],
      [5,9,4,2],
      [1,4,7,8]]

nm = Normalizer()
nm.fit(X)
#nm = Normalizer().fit(X)     #等价于上面两句
print(nm)
print("norm",nm.norm)

nm1 = nm.fit_transform(X)
print("=======fit_transform=======")
print(nm1)

#print(nm.transform(X))       #等价于上面两句

#运行结果:
Normalizer(copy=True, norm='l2')
norm l2
=======fit_transform=======
[[ 0.23570226  0.47140452  0.70710678  0.47140452]
 [ 0.30588765  0.38235956  0.53530338  0.6882472 ]
 [ 0.68100522  0.59587957  0.34050261  0.25537696]
 [ 0.4454354   0.80178373  0.35634832  0.17817416]
 [ 0.0877058   0.35082321  0.61394061  0.70164642]]

总结:数据标准化的意义

(1)消除量纲的影响

(2)对于数据分布不均匀的影响(比如:某列数据跟其他差距很大)

(3)数据标准化用哪个方法没有评价标准,一般数值类型的数据用StandardScalerMinMaxScaler,

对文本数据类型用Normalizer(归一化)。


三、sigmoid函数

python3机器学习——sklearn0.19.1版本——数据处理(一)(数据标准化、tfidf、独热编码)_第5张图片

Logistic函数的表示形式如下:


它的函数图像如下,由于函数图像很像一个“S”型,所以该函数又叫 sigmoid 函数。


满足的性质:

1.对称性,关于(0,0.5)中心对称

在逻辑回归logistic中,将大于0.5的值映射为1,小于0.5映射为0,成为一个分类的问题。


四、文本数据的处理——TF-IDF

TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术

TF意思是词频(Term Frequency),即:某个词条在文本中出现的次数。

如果某个词很重要,它应该在这篇文章中多次出现。于是,我们进行"词频"(Term Frequency,缩写为TF)统计。

IDF意思是逆向文件频率(Inverse Document Frequency),即:一个词条的重要性。

用统计学语言表达,就是在词频的基础上,要对每个词分配一个"重要性"权重。最常见的词("的"、"是"、"在")给予最小的权重,较常见的词("中国")给予较小的权重,较少见的词("蜜蜂"、"养殖")给予较大的权重。

这个权重叫做"逆文档频率"(Inverse Document Frequency,缩写为IDF),它的大小与一个词的常见程度成反比

知道了"词频"(TF)和"逆文档频率"(IDF)以后,将这两个值相乘,就得到了一个词的TF-IDF值

某个词对文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的几个词,就是这篇文章的关键词


该算法的步骤为:

第一步,计算词频


考虑到文章有长短之分,为了便于不同文章的比较,进行"词频"标准化。


或者


第二步,计算逆文档频率。

这时,需要一个语料库(corpus),用来模拟语言的使用环境。


如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数(以e为底数)。

第三步,计算TF-IDF。


可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。
所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。

TF-IDF算法的优点是简单快速,结果比较符合实际情况。缺点是,单纯以"词频"衡量一个词的重要性,不够全面,

有时重要的词可能出现次数并不多。而且,这种算法无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的。(一种解决方法是,对全文的第一段和每一段的第一句话,给予较大的权重。)还可以用TF-IDF结合余弦相似性,衡量文档之间的相似程度

(文章链接:http://www.ruanyifeng.com/blog/2013/03/cosine_similarity.html)。


sklearn.feature_extraction.text.TfidfVectorizer:可以把一大堆文档转换成TF-IDF特征的矩阵

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

from sklearn.feature_extraction.text import TfidfVectorizer

text1 = [
    "this is python",
    "this is sample",
    "anaconda sklearn is good"
]

text2 = [
    "this is another",
    "today is sunny",
    "lr randomforest is model"
]

tfidf = TfidfVectorizer()
tf = tfidf.fit_transform(text2)     #训练并转换

print(tfidf.get_feature_names)
print(tfidf.get_stop_words)     #停止词
print("====TF-IDF特征的矩阵====")
print(tf.toarray())
print("====输出的各个文本各个词的TF-IDF值=====")
print(tf)

#运行结果:
, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), norm='l2', preprocessor=None, smooth_idf=True,
        stop_words=None, strip_accents=None, sublinear_tf=False,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True,
        vocabulary=None)>
, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), norm='l2', preprocessor=None, smooth_idf=True,
        stop_words=None, strip_accents=None, sublinear_tf=False,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True,
        vocabulary=None)>
====TF-IDF特征的矩阵====
[[ 0.65249088  0.38537163  0.          0.          0.          0.
   0.65249088  0.        ]
 [ 0.          0.38537163  0.          0.          0.          0.65249088
   0.          0.65249088]
 [ 0.          0.32274454  0.54645401  0.54645401  0.54645401  0.          0.
   0.        ]]
====输出的各个文本各个词的TF-IDF值=====
  (0, 6)	0.652490884513
  (0, 1)	0.385371627466
  (0, 0)	0.652490884513
  (1, 1)	0.385371627466
  (1, 7)	0.652490884513
  (1, 5)	0.652490884513
  (2, 1)	0.32274454218
  (2, 2)	0.546454011634
  (2, 4)	0.546454011634
  (2, 3)	0.546454011634

五、离散的特征数据——独热编码(也称为:哑编码)

定性特征不能直接使用:

某些机器学习算法和模型只能接受定量特征的输入,那么需要将定性特征转换为定量特征。最简单的方式是为每一种定性值指定一个定量值,但是这种方式过于灵活,增加了调参的工作。通常使用哑编码的方式将定性特征转换为定量特征:假设有N种定性值,则将这一个特征扩展为N种特征,当原始特征值为第i种定性值时,第i个扩展特征赋值为1,其他扩展特征赋值为0。哑编码的方式相比直接指定的方式,不用增加调参的工作,对于线性模型来说,使用哑编码后的特征可达到非线性的效果

使用preproccessing库的OneHotEncoder类对数据进行独热编码/哑编码.


举个例子:

在机器学习任务中,对于如性别“male”和“female这样的特征,通常我们需要对其进行特征数字化。

有如下的三个特征属性:
  • 性别:["male","female"]
  • 国家:["US""China","England"]
  • 城市:["Beijing","London","NewYork","Shanghai"]
对于 某一个样本,如[" male ", " China " " Shanghai " ],我们需要将这个分类值的特征数字化,最直接的方法,我们可以采用 序列化的方式:[0,1,3] 。但是这样的特征处理并不能直接放入机器学习算法中。

可以采用One-Hot编码的方式对上述的样本“["male","China""Shanghai"]”编码,“male”则对应着[1,0],同理"China"对应着[0,1,0],"Shanghai"对应着[0,0,0,1]。则完整的特征数字化的结果为:[1,0,0,1,0,0,0,0,1]


代码实现如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:ZhengzhengLiu

#独热编码/哑编码
from sklearn.preprocessing import OneHotEncoder

#X为训练的数据,按列看,每列中的四个数字表示每个特征可能的取值范围,
# 即每个特征的可能的取值个数

X = [[0,0,3],
    [1,1,0],
    [0,2,1],
    [1,0,2]]

enc = OneHotEncoder()   #创建独热编码方法
enc.fit(X)            #训练
print(enc.n_values_)    #打印每一维数据可能的取值个数
print(enc.feature_indices_)

print("======独热编码=====")
enc1 = enc.transform(X).toarray()
enc2 = enc.transform([[0,1,3]]).toarray()

print(enc1)
print("===============================")
print(enc2)

#运行结果:
[2 3 4]
[0 2 5 9]
======独热编码=====
[[ 1.  0.  1.  0.  0.  0.  0.  0.  1.]
 [ 0.  1.  0.  1.  0.  1.  0.  0.  0.]
 [ 1.  0.  0.  0.  1.  0.  1.  0.  0.]
 [ 0.  1.  1.  0.  0.  0.  0.  1.  0.]]
===============================
[[ 1.  0.  0.  1.  0.  0.  0.  0.  1.]]




你可能感兴趣的:(机器学习)