|
. W7 M& j* d5 B
sklearn Preprocessing 模块 对数据进行预处理的优点之一就是能够让模型尽快收敛.标准化和归一化:
1 n! A/ a: N6 _, o- } 归一化是标准化的一种方式,
( H4 o& m: c- {+ `2 T1 }' J 归一化是将数据映射到[0,1]这个区间中,
# b" E3 {( t" n4 i" X 标准化是将数据按照比例缩放,使之放到一个特定区间中,
4 x% h* t/ D/ _0 M4 I" c( r1 f) ]. a) c 标准化后的数据均值为0,标准差等于1,因而标准化的数据可正可负. 7 }/ \; [' g$ _
如果原始数据不符合高斯分布的话,标准化后的数据效果并不好.(标准化的原因在于如果有些特征的方差过大,则会主导目标函数从而使参数估计器无法正确地去学习其他特征.)
+ f, n7 q& ?) p9 Q" A 导入模块:
4 t- z! L& m5 m; H! ^) w from sklearn.preprocessing import StandardScaler( t5 o% ?& Z0 {0 J
from sklearn.preprocessing import MinMaxScaler
V( I; b# n* { from matplotlib improt gridspec
" e. A! Y6 ~1 t7 ]9 [7 S# Y import numpy as np6 P! |0 R' Y! Q: c
import matpotlib.pyplot as plt & g# Q! N- b* f; X: [
使用sklearn 进行标准化和标准化还原% J4 q! I% Y6 b/ [/ G+ g
标准化的过程分为两步: 去均值的中心化(均值变为0);方差的规模化(方差变为1).将每一列特征标准化为标准正太分布,注意,标准化是针对每一列而言的x_scale = preprocessing.scale(x)
; O# f+ c ?0 B std = StandardScaler(); F! K9 |( a9 G2 \ t
data = std.fit_transform(data[["RSSI0", "RANGES", "weekday", "hour", "RSS_mean", "RANGES_mean", day_label]])
6 u S+ O3 x8 r% r4 {. ]4 L. i6 F, Y- K7 x( `2 x* S. t
# 将标准化后的数据转换为原始数据。
) V& ^9 K8 E6 P5 Y/ P" }% m6 S std.inverse_transform() , Z7 ]; f% d# i5 ?; f8 r
查看标准化后的数据的均值与方差 5 A! x% f5 L5 Z; U) @+ t# c
x_scale.mean(axis=0)# 均值
* j4 p6 S* }) t0 m3 ]/ u # axis=1表示对每一行去做这个操作,axis=0表示对每一列做相同的这个操作 ) j& ^* b) U; z% R/ _
x_scale.mean(axis=1) / t) p( M/ V- s3 E A& k
`
+ @$ h" _) h) Y cps = np.random.random_integers(0, 100, (100, 2))
+ G" V4 d4 a; q$ V& q R; b # 创建StandardScaler 对象,再调用fit_transform 方法,传入一个格式的参数数据作为训练集.9 T" M, h6 I3 e( T3 D
ss = StandardScaler()1 r5 {1 {) F6 @+ ^5 i2 A
std_cps = ss.fit_transform(cps). m- E& ~) |& g
gs = gridspec.GridSpec(5,5)
5 [( m, a& b4 W9 Z8 H fig = plt.figure()8 y" D ?% P: N+ t
ax1 = fig.add_subplot(gs[0:2, 1:4])
4 S& H" X$ \$ ^/ \ e8 S0 w! p ax2 = fig.add_subplot(gs[3:5, 1:4])6 \. H0 ?) f' y
ax1.scatter(cps[:, 0], cps[:, 1])
. R& W& A; Y% {3 M: x' S _: u2 u+ { ax2.scatter(std_cps[:, 0], std_cps[:, 1])6 @. V' o; C; o7 o+ Z: K- l
plt.show()
# e; \! E9 p& S; z( A5 Y/ V! H* X9 I% Q `
/ c( L5 A2 K+ x from sklearn.preprocessing import StandardScaler) ~ n7 T: ]/ r3 i/ x2 y
from sklearn.preprocessing import MinMaxScaler
( k( P3 j% W. a9 c, X7 r* A from matplotlib import gridspec. T0 Q2 `$ F, h
import numpy as np
2 `" c' {. ]1 `( }0 U) N7 N( ] import matplotlib.pyplot as plt: V* I2 F( K" p+ G3 N: U1 k0 C3 S) K
data = np.random.uniform(0, 100, 10)[:, np.newaxis]
$ ?% a4 L! _( F+ a ss = StandardScaler()
$ R' D* j' C7 w i# V9 o std_data = ss.fit_transform(data)5 N# B6 _# e4 k+ ~5 |6 D
origin_data = ss.inverse_transform(std_data) # 得到标准化之前的数据
5 o, y" l I( U% N% h print(data is 原始数据,data)( a( I# ^) [5 ~% D
print(after standard 标准化后的数据,std_data) v% r+ `# W& U
print(after inverse 通过inverse_transform该函数将标准化后的数据转化为原始数据:,origin_data)
8 v S( u4 y; h, p7 n' N# Q print(after standard mean and std is 均值mean(均值) 和 标准差std(矩阵标准差),np.mean(std_data), np.std(std_data))
/ s0 } \# B- j 使用sklearn 进行数据的归一化和归一化还原.
: C+ _9 z @( M+ S: M data = np.random.uniform(0, 100, 10)[:, np.newaxis] # 创建数据" ~6 H$ u9 a4 a9 D( {+ P( f5 h
mm = MinMaxScaler()# 创建MinMaxScaler 对象
f7 V1 d' u9 P( [- R) ^ mm_data = mm.fit_transform(data) # 归一化数据5 i2 [5 p& X4 _8 _/ K
origin_data = mm.inverse_transform(mm_data) # 转换成归一化之前的数据
: C0 Z( R4 E& Y print(data is ,data)
$ D% Q0 L( z, f$ j( R6 n9 ~- m print(after Min Max ,mm_data)2 j" e, Q$ j% ^
print(origin data is ,origin_data) 8 ]9 l( [" i) M V1 S
MinMaxScaler和MaxAbsCaler:
+ k% }$ @$ o: [5 g8 T* p MinMaxScaler:使得特征的分布在一个给定的最小值和最大值的范围内.一般情况下载0`1之间(为了对付哪些标准差相当小的特征并保留下稀疏数据中的0值.) ) N5 C: ~1 h$ X2 [
MaxAbsScaler:或者是特征中的绝对值最大的那个数为1,其他依次为标准分布在-1`1之间
( N+ L1 Z& M$ h8 n/ ]- X min_max_scaler = preprocessing.MinMaxScaler()
& E( b# Y$ Y; O6 Y x_minmax = min_max_scaler.fit_transform(x)3 o9 _1 O) j2 L6 |9 \* ~! z
x_minmax
$ ?& C* \$ K* r/ }8 Z. q! ]6 q& u 对于新进来的数据,采用如下方式进行函数调用:
- W4 G/ X4 {: }; K x_test = np.array([[-3., -1., 4.]]): M b8 V( K/ }9 j9 V( h
x_test_minmax = min_max_scaler.transform(x_test)
2 f7 ^. @/ ?0 ?: o$ a' y x_test_minmax
( v$ u0 a, {: A6 J3 T; ?: i MaxAbsScaler:数据会被规模化到-1`1之间,就是特征中,所有数据都会除以最大值,该方法对哪些已经中心化均值为0,或者稀疏的数据有意义.
6 T* D1 y; K- V3 | max_abs_scaler = preprocessing.MaxAbsScaler()6 I* `& U+ H' q8 R
x_train_maxsbs = max_abs_scaler.fit_transform(x)
: g$ M2 z+ R5 P4 ^2 E5 h% h x_train_maxsbs
% o9 ~' Z2 c8 s' [7 r # 同理,也可以对新的数据集进行同样的转换 / Z3 K/ i: |( \% u+ s6 b
x_test = np.array([[-3., -1., 4.]])3 g& _; r+ E! ]
x_test_maxabs = max_abs_scaler.transform(x_test)+ {/ Y5 H6 L2 Z- v/ {
x_test_maxabs
8 Q% o8 W6 a' x. O* [2 Z( n" Y 针对规模化稀疏数据, j% T a0 q- ]9 N0 H
对稀疏数据去均值的中心化会破坏稀疏的数据结构,使用如下两个方法进行处理:
, C+ [* |* E9 m$ m; @& K& ] MaxAbsScaler,和maxabs_scale . @+ W4 Y1 h$ a- g
针对规模化有异常的数据2 f& O Y' p7 m& d/ s9 T4 d: x
数据集中有很多异常值,就不能使用数据的均值和方差去做标准化了.可以使用robust_scale和RobustScaler ,更具中位数或者四分位数去中心化数据. ' o4 s T7 ~$ Z( c$ j! b3 R
正则化Normalization
6 n" f% t# _4 F# l, \- y0 z 正则化是将样本在向量空间模型上的一个转换,常常被使用在分类和聚类中,使用函数normalize实现一个单向量的正则化功能.正则化化有I1,I2等 * m* R# E4 M% g2 m" D$ V1 Q
x_normalized = preprocessing.normalize(x, norm=l2)( G1 F0 U6 ~+ v8 |
print x% {5 D9 i" A# J2 u5 j: f
print x_normalized
' c" |0 ~4 E, |9 r# K # 根据训练数据创建一个正则器 Normalizer(copy=True, norm=l2)
0 G) o# }# U: A9 @1 [( S normalizer = preprocessing.Normalizer().fit(x)$ E& k' P+ k7 c% ?; h( N
normalizer ! m" n) o5 y l: P1 t3 w* I
# 对训练数据进行正则
6 z: E: I$ `. U4 l, k" l0 @ normalizer.transform(x) 5 Y" H* @2 E- A' n% s' s0 A
# 对新的测试数据进行正则
7 T3 ]( e' U$ X. b u' Q normalizer.transform([[-1., 1., 0.]]) . C# C; ^& n1 }$ N7 a; O
二值化: U: O' ~# R. U, D# d: f. u
特征的二值化(指将数值型的特征数据转换为布尔类型的值,使用实用类Binarizer),默认是根据0来二值化,大于0的都标记为1,小于等于0的都标记为0.通过设置threshold参数来更改该阈值 $ B* z+ ^- e/ l
from sklearn import preprocessing/ d% J* O; k$ _ x; f! z# d
import numpy as np
) H- I( ^! G% ~* b6 E! V
8 M; n! i m4 d- |8 Z$ g; h # 创建一组特征数据,每一行表示一个样本,每一列表示一个特征
( Y1 P+ y' w0 B; d& ~/ I' X x = np.array([[1., -1., 2.],
- A& f1 c4 j! w; X [2., 0., 0.],
5 G+ `4 I) Z6 n9 }0 i [0., 1., -1.]])8 K2 c( m' W2 s" r
+ J Q6 E Z$ _0 L
binarizer = preprocessing.Binarizer().fit(x)
5 v! x) \* U" }1 b binarizer.transform(x)
/ M6 u6 s3 R. n0 I) x' y& A, ]% ^5 |. X3 W% U, j
binarizer = preprocessing.Binarizer(threshold=1.5)3 p2 R3 V& \7 v# s, h5 a4 C
binarizer.transform(x) 9 e5 a' j. T1 z" A* s2 J$ B8 s
为类别特征编码
' T6 o y- u( o, A (比如性别:male,来自于哪个国家或地区:from US,使用什么浏览器:users Chrome) 可以转换为 013 或者是其他的数值型编码. 3 f1 R. w2 E7 m! ?9 z, y
OneHotEncoder % v9 @ H9 h$ `( ?7 R! B- G: B. w* t
弥补缺失数据( t; S$ a8 U5 I- e. E: [
可以使用均值,中位数,众数等等弥补缺失数据,可以使用Imputer实现. ' A; h0 T4 ~& q" R/ z
import numpy as np
. O( G) T& _# v" A) `. |1 n from sklearn.preprocessing import Imputer
( O% G$ |6 B* m5 h imp = Imputer(missing_values=NaN, strategy=mean, axis=0)
" Y: H) F3 l* U/ ?/ U: r imp.fit domain name is for sale. Inquire now.([[1, 2], [np.nan, 3], [7, 6]])
# w4 }( Q i9 o. X x = [[np.nan, 2], [6, np.nan], [7, 6]]
% l2 c+ o1 h! w6 C imp.transform(x) ; R5 E( {! i0 X2 g5 {% ^
Imputer类同样也可以支持稀疏矩阵,以下例子将0作为了缺失值,为其补上均值
1 _7 l# h& d/ C9 A import scipy.sparse as sp
r% W5 g; s+ W3 o/ ]- S" | # 创建一个稀疏矩阵
0 L; l, K: k; d x = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
6 F% [" C0 w4 f: U6 y* X8 g imp = Imputer(missing_values=0, strategy=mean, verbose=0)! b% {) H$ Q( e
imp.fit domain name is for sale. Inquire now.(x); E6 u0 V8 N. U" t1 B# v5 v
x_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
9 e6 ]! y3 q- E4 H( T% @ imp.transform(x_test) 9 O# x: i+ I, D, O* Z* j: A7 D
当我们拿到一批原始的数据
1 y, L7 @1 x8 U3 r: y$ v7 Q2 |' U! C 首先要明确有多少特征,哪些是连续的,哪些是类别的。
" h/ K/ f/ g: S 检查有没有缺失值,对确实的特征选择恰当方式进行弥补,使数据完整。
' G# ]! G. g% Y v& A) t# @ 对连续的数值型特征进行标准化,使得均值为0,方差为1。
" [, r* _9 h8 L# x# b5 k, a# | 对类别型的特征进行one-hot编码。 ' ~3 n5 n$ i+ {3 f' r7 P/ G* @
将需要转换成类别型数据的连续型数据进行二值化。
+ K% Q) P4 a& X& `: e1 o5 V# L& | 为防止过拟合或者其他原因,选择是否要将数据进行正则化。
0 f% H8 e# c1 B 在对数据进行初探之后发现效果不佳,可以尝试使用多项式方法,寻找非线性的关系。
1 v3 a) C, m% B/ G$ F3 @7 E 根据实际问题分析是否需要对特征进行相应的函数转换。 ' C3 [7 M4 g# M: B2 g/ R
标准化和归一化的缺点:每当有新的数据进来时,就要重新计算所有的点
/ W# V; r- M8 C 因此针对动态的数据可以采用如下几种计算方法:
/ R) J% ~7 R! Q: c$ {: T 1.arctan反正切函数标准化. http://2.in函数标准化预处理数据的方法总结(使用sklearn-preprocessing)_【人工智能】王小草的博客-CSDN博客
" g6 o8 E3 e5 L3 w# {- @+ {: G+ k8 q% r/ c, L% p
) D+ \2 [6 [0 M( h# [
; Q( ~: v/ n |6 w- z- ]% C" E( r6 r4 z8 {
|