|
6 e1 |' k1 K, p7 d$ ]3 i" |, H% u
sklearn Preprocessing 模块 对数据进行预处理的优点之一就是能够让模型尽快收敛.标准化和归一化:
0 v0 w; p ~- P0 A& n 归一化是标准化的一种方式, . E- e3 a; y7 ~; B' V
归一化是将数据映射到[0,1]这个区间中,
( C* v% D9 N$ v 标准化是将数据按照比例缩放,使之放到一个特定区间中,
; V' T5 Y3 h4 x/ B6 h6 W 标准化后的数据均值为0,标准差等于1,因而标准化的数据可正可负. ; e! ]4 p2 `: ]$ p+ o) W
如果原始数据不符合高斯分布的话,标准化后的数据效果并不好.(标准化的原因在于如果有些特征的方差过大,则会主导目标函数从而使参数估计器无法正确地去学习其他特征.) 0 C& j, p* @. {5 Z% l- d9 f
导入模块:
9 \: } [" W( ?- [3 {! i% L from sklearn.preprocessing import StandardScaler
. @5 y. Q0 u- g0 j from sklearn.preprocessing import MinMaxScaler
- Z- N' X+ z1 U( L2 y( H2 X( j3 V from matplotlib improt gridspec" @3 _5 J8 k: }1 u, q
import numpy as np2 v' O2 P- |/ _
import matpotlib.pyplot as plt ; s0 i, A* e5 S2 t
使用sklearn 进行标准化和标准化还原" r' c8 \8 X& X+ {9 f: ?2 k9 K: [
标准化的过程分为两步: 去均值的中心化(均值变为0);方差的规模化(方差变为1).将每一列特征标准化为标准正太分布,注意,标准化是针对每一列而言的x_scale = preprocessing.scale(x) . k+ J. z6 ~( M' ^
std = StandardScaler()
; r3 G$ n7 Z' ?9 |1 q: L5 \/ [( j data = std.fit_transform(data[["RSSI0", "RANGES", "weekday", "hour", "RSS_mean", "RANGES_mean", day_label]])9 ~, z. X6 g; U( l6 p+ g& ~
6 ~+ H w) Y2 P9 q- y
# 将标准化后的数据转换为原始数据。
. [( G! @- a/ |0 m std.inverse_transform() ) ?* I8 }- c4 @' S
查看标准化后的数据的均值与方差
/ Z, Q6 w: l. \ x_scale.mean(axis=0)# 均值
3 u: ~' A2 Z3 F # axis=1表示对每一行去做这个操作,axis=0表示对每一列做相同的这个操作 / c) @2 I. n0 q% O1 M' }/ {1 `
x_scale.mean(axis=1)
6 Y* C; b- T" ?& Y ` ! v( w( E, n8 M% u& C
cps = np.random.random_integers(0, 100, (100, 2))
4 o* G/ u5 V2 E, x% s/ x # 创建StandardScaler 对象,再调用fit_transform 方法,传入一个格式的参数数据作为训练集.
+ O8 M6 E9 a9 n$ `8 J. ] ss = StandardScaler()
7 y6 B" p- d/ L& ?2 T std_cps = ss.fit_transform(cps)
, W- Y! f K& l9 F# x/ V1 k gs = gridspec.GridSpec(5,5)
7 X3 w3 f& Q" i# c- O9 K' F5 Q$ K: Y fig = plt.figure() n+ o1 m: v6 s. K% Q
ax1 = fig.add_subplot(gs[0:2, 1:4]); ~5 ~" z& p1 W& ^6 w8 b
ax2 = fig.add_subplot(gs[3:5, 1:4]): x7 M+ s1 I h& G# x
ax1.scatter(cps[:, 0], cps[:, 1])
" a* r& p$ C6 }( u$ k* e ax2.scatter(std_cps[:, 0], std_cps[:, 1])% l5 S& {& f+ m$ H8 ^. i
plt.show() 0 i* M2 _& Z4 Y6 [
`
6 m8 o- y( S& Y# o( S from sklearn.preprocessing import StandardScaler
y9 f0 `5 i e1 w9 @5 _6 W! v from sklearn.preprocessing import MinMaxScaler9 Q& w9 p, P8 l9 m. a
from matplotlib import gridspec8 U9 I) B. V) ?
import numpy as np
/ x* l5 C% e; U( a import matplotlib.pyplot as plt9 R- o0 j( b2 Z# M* v: S
data = np.random.uniform(0, 100, 10)[:, np.newaxis]
6 x4 l) R; c+ ]" e4 m# Z8 W ss = StandardScaler()- R8 t. Z. D* \2 f
std_data = ss.fit_transform(data)0 g& @4 a/ o; W5 W/ @( ?
origin_data = ss.inverse_transform(std_data) # 得到标准化之前的数据* g6 Y j7 s$ l8 p; E% V
print(data is 原始数据,data)
/ i9 _$ a4 `8 U: l R8 b0 V! e% j) I7 x print(after standard 标准化后的数据,std_data)
3 F/ \6 ]& v' A. h print(after inverse 通过inverse_transform该函数将标准化后的数据转化为原始数据:,origin_data)
# c9 d' v; c; h9 P% b/ Q% ?- Q y print(after standard mean and std is 均值mean(均值) 和 标准差std(矩阵标准差),np.mean(std_data), np.std(std_data))
( N; E& E& `: x- {1 Z$ t 使用sklearn 进行数据的归一化和归一化还原.
, P+ V* b$ J" h y' `- v- K data = np.random.uniform(0, 100, 10)[:, np.newaxis] # 创建数据
- w( E/ j2 d9 t0 W) v# }* @' e5 \0 v mm = MinMaxScaler()# 创建MinMaxScaler 对象# o9 S" J8 @8 q" s; R
mm_data = mm.fit_transform(data) # 归一化数据, p# Y9 f2 G5 E8 k+ X
origin_data = mm.inverse_transform(mm_data) # 转换成归一化之前的数据
3 y: e, H3 d* l* L% T' `. G print(data is ,data)
5 f* M0 g; O( N print(after Min Max ,mm_data)
. A: ], z6 W' g/ ~& W0 h print(origin data is ,origin_data)
8 v/ v) |2 h8 D8 p0 c( w MinMaxScaler和MaxAbsCaler:
/ a1 i# q$ b/ b# H& Y MinMaxScaler:使得特征的分布在一个给定的最小值和最大值的范围内.一般情况下载0`1之间(为了对付哪些标准差相当小的特征并保留下稀疏数据中的0值.)
0 X1 `8 O' U* D1 `1 Z$ C9 J' F MaxAbsScaler:或者是特征中的绝对值最大的那个数为1,其他依次为标准分布在-1`1之间 # a* d6 H) X; q7 c
min_max_scaler = preprocessing.MinMaxScaler()/ d$ V3 Q% t9 n
x_minmax = min_max_scaler.fit_transform(x)
# R" _0 K. J Y: W x_minmax 3 R( n& V" [ b# G6 U$ Z
对于新进来的数据,采用如下方式进行函数调用:
a4 o/ b, w3 i8 Q/ w x_test = np.array([[-3., -1., 4.]])
2 x/ g W" R* ]3 x! l x_test_minmax = min_max_scaler.transform(x_test)+ O% A6 g5 O5 x3 k: ]3 @. V" d
x_test_minmax
Z+ d, L$ S t6 b MaxAbsScaler:数据会被规模化到-1`1之间,就是特征中,所有数据都会除以最大值,该方法对哪些已经中心化均值为0,或者稀疏的数据有意义. + _, ]/ x+ g: Q2 l
max_abs_scaler = preprocessing.MaxAbsScaler()' {1 ^( Y8 N; D" g0 Q6 k! o o7 F
x_train_maxsbs = max_abs_scaler.fit_transform(x)( V! G4 o a1 G- p' i' r9 ~
x_train_maxsbs * j" C8 T8 `9 T( e5 K0 g
# 同理,也可以对新的数据集进行同样的转换
2 I( N5 `2 a4 F. c1 F/ T5 ` x_test = np.array([[-3., -1., 4.]])0 Z: C) Q5 s- W8 J
x_test_maxabs = max_abs_scaler.transform(x_test)# O" F, B; ?3 s
x_test_maxabs 5 r+ `7 P9 W2 |2 S ~
针对规模化稀疏数据/ q* z* Z: H: W5 }( M; n
对稀疏数据去均值的中心化会破坏稀疏的数据结构,使用如下两个方法进行处理:
/ ?: m+ f% U) P: r1 m MaxAbsScaler,和maxabs_scale
% _1 y6 K. M* s/ D8 D3 | 针对规模化有异常的数据
. u" d3 f7 l% ]" l z4 U+ \ 数据集中有很多异常值,就不能使用数据的均值和方差去做标准化了.可以使用robust_scale和RobustScaler ,更具中位数或者四分位数去中心化数据.
7 v0 L" f1 B8 U4 Z) w8 W 正则化Normalization
$ Q! F, p6 ]/ x/ z8 w ~ 正则化是将样本在向量空间模型上的一个转换,常常被使用在分类和聚类中,使用函数normalize实现一个单向量的正则化功能.正则化化有I1,I2等
. o3 G/ W# K/ X/ V x_normalized = preprocessing.normalize(x, norm=l2)
" _) A1 D8 a. T6 }/ P+ p print x
1 x0 I/ i# k# r' ? print x_normalized + }* N- j Y" s2 G$ `; p& h
# 根据训练数据创建一个正则器 Normalizer(copy=True, norm=l2)
, Y2 L1 Y* J) b9 o normalizer = preprocessing.Normalizer().fit(x)
# P$ R; E9 u6 Q" A1 {) f normalizer
8 q0 j' T: `; r* u$ j! R' H # 对训练数据进行正则
1 c, G8 |" K8 H2 Y normalizer.transform(x)
1 \: a4 Z9 t% ?9 ? # 对新的测试数据进行正则 - |" P+ @; }: p
normalizer.transform([[-1., 1., 0.]])
* \: p+ ]0 K- v* F" L 二值化5 H. |) a; E! R' e# ~9 n# J
特征的二值化(指将数值型的特征数据转换为布尔类型的值,使用实用类Binarizer),默认是根据0来二值化,大于0的都标记为1,小于等于0的都标记为0.通过设置threshold参数来更改该阈值 ( d- J: \& F" @: h% j2 `
from sklearn import preprocessing$ b4 R" D% ]' R" S; s
import numpy as np
5 O# q# W) V) v' J! s3 C9 }! M0 Z9 X# |) f
# 创建一组特征数据,每一行表示一个样本,每一列表示一个特征
3 v8 \- j# N3 M4 A, I x = np.array([[1., -1., 2.],% ~3 b2 V V) h1 j- }+ ]) C
[2., 0., 0.],( d- J" U. {8 U: w! z
[0., 1., -1.]])3 g n, H- e' U( `& O6 a
( M* V9 C2 s% s% ^( }
binarizer = preprocessing.Binarizer().fit(x)
6 S d F; O' k5 J' t binarizer.transform(x)' }4 x9 K* U6 x. X
4 k$ U3 ~/ a$ Z/ [" k
binarizer = preprocessing.Binarizer(threshold=1.5)
. s8 r9 a3 k8 Z" d. g binarizer.transform(x)
# ~( j G. w4 I* g 为类别特征编码
6 l7 F1 j K! k( {( H (比如性别:male,来自于哪个国家或地区:from US,使用什么浏览器:users Chrome) 可以转换为 013 或者是其他的数值型编码. . w+ V" G" v4 P- x" b5 C, j# R
OneHotEncoder
' d6 r" D. J2 W& c5 R, o 弥补缺失数据+ h9 l" n: s- S! Q
可以使用均值,中位数,众数等等弥补缺失数据,可以使用Imputer实现. * h3 F( X7 {+ G. `
import numpy as np
/ ~* t0 J8 S4 i. E from sklearn.preprocessing import Imputer8 C. q- _" a, R3 U6 }, Q, H% A( r
imp = Imputer(missing_values=NaN, strategy=mean, axis=0)
: I% C6 t. {' @8 | imp.fit domain name is for sale. Inquire now.([[1, 2], [np.nan, 3], [7, 6]])8 G; @) `; U$ ]
x = [[np.nan, 2], [6, np.nan], [7, 6]]+ K* ~$ Q1 ?1 J0 @ l
imp.transform(x)
1 C, S9 t" u* ]/ f* p, x; { Imputer类同样也可以支持稀疏矩阵,以下例子将0作为了缺失值,为其补上均值
# ?3 z( g6 ~; X2 N import scipy.sparse as sp
6 K% T$ ^' Q" o9 p6 h( A # 创建一个稀疏矩阵0 O3 @2 c2 O" T g; R8 ?
x = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
% `! ?3 ]3 m1 P$ J. r9 {* @ imp = Imputer(missing_values=0, strategy=mean, verbose=0)
! W7 R/ f a) N7 M imp.fit domain name is for sale. Inquire now.(x)
\& C2 W" {6 l1 H( L x_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]]): j& y- {5 \/ w, E- t
imp.transform(x_test) 3 r/ Q8 _* R: F1 L( ~/ U
当我们拿到一批原始的数据 % d& d& S6 e: n
首先要明确有多少特征,哪些是连续的,哪些是类别的。
4 y( J z0 |. ?. s( g' u 检查有没有缺失值,对确实的特征选择恰当方式进行弥补,使数据完整。
3 f& o& M4 R. Z5 a 对连续的数值型特征进行标准化,使得均值为0,方差为1。 $ T, D5 y6 E: n f' E" A& O9 s: F, t
对类别型的特征进行one-hot编码。
r2 D+ R: ~) M$ ] 将需要转换成类别型数据的连续型数据进行二值化。 0 I! k% R' ^ j' f6 v2 \9 I; Q
为防止过拟合或者其他原因,选择是否要将数据进行正则化。 * I4 N3 L6 s0 V3 f+ q
在对数据进行初探之后发现效果不佳,可以尝试使用多项式方法,寻找非线性的关系。 ! n- X, F/ V8 h; Q( W7 W( N5 Y) M/ K. ?& p' X
根据实际问题分析是否需要对特征进行相应的函数转换。
6 w1 J* |# }8 |% C 标准化和归一化的缺点:每当有新的数据进来时,就要重新计算所有的点 " U5 L+ ~) Z6 d# \' n$ {' R0 X
因此针对动态的数据可以采用如下几种计算方法:
$ Z7 d3 v# t5 m 1.arctan反正切函数标准化. http://2.in函数标准化预处理数据的方法总结(使用sklearn-preprocessing)_【人工智能】王小草的博客-CSDN博客
$ Z& K" }$ N% ]1 l4 \- q$ l' V. z5 g- c/ s* R4 @6 J
7 l) P$ c4 U" k4 H4 C# @) ~" Z+ U+ i* O
/ H" a& _ V9 w0 x
|