|
( }7 A, Z% |% h- [( n/ P
sklearn Preprocessing 模块 对数据进行预处理的优点之一就是能够让模型尽快收敛.标准化和归一化:
7 E! H1 a& W( K/ d8 v" e 归一化是标准化的一种方式, 1 q+ B* X& N Z: c
归一化是将数据映射到[0,1]这个区间中, ; g% v e+ X1 P8 @" w) C
标准化是将数据按照比例缩放,使之放到一个特定区间中, ' H U) ^ M: {2 J: {& h
标准化后的数据均值为0,标准差等于1,因而标准化的数据可正可负.
- D2 |9 e6 m U- L w' f# v 如果原始数据不符合高斯分布的话,标准化后的数据效果并不好.(标准化的原因在于如果有些特征的方差过大,则会主导目标函数从而使参数估计器无法正确地去学习其他特征.)
f4 g, |3 L! c8 j) a, n- Q 导入模块: 5 G2 B5 `. |/ D2 z
from sklearn.preprocessing import StandardScaler9 Y& t4 c) {$ U V
from sklearn.preprocessing import MinMaxScaler
( R" R; j; z: q; `4 @/ `! P3 l, s9 j( t from matplotlib improt gridspec
1 s3 A, y# m9 o+ t: J0 l' K import numpy as np
1 u9 B; F' B; v j7 B import matpotlib.pyplot as plt - c" ]) q& m6 w) P2 x8 `
使用sklearn 进行标准化和标准化还原9 U/ m6 ? v. V! Z, e0 ^; D- ]
标准化的过程分为两步: 去均值的中心化(均值变为0);方差的规模化(方差变为1).将每一列特征标准化为标准正太分布,注意,标准化是针对每一列而言的x_scale = preprocessing.scale(x)
Z, h, Z6 q) D4 j0 T% @" E std = StandardScaler()
- ]/ {! V6 ]1 L0 F1 ?4 Y data = std.fit_transform(data[["RSSI0", "RANGES", "weekday", "hour", "RSS_mean", "RANGES_mean", day_label]])7 Z3 }* S5 G- v: a
/ m9 v$ H/ `! Q" x4 |& u6 } # 将标准化后的数据转换为原始数据。
' ]! \" @. ^# C( ]0 [ std.inverse_transform() # d! a: f% M% F' s7 e
查看标准化后的数据的均值与方差 0 Z' K5 P$ @" a. g7 x$ ^0 v
x_scale.mean(axis=0)# 均值
2 b/ S8 n$ H) z- t # axis=1表示对每一行去做这个操作,axis=0表示对每一列做相同的这个操作
. a! N& P1 V$ ?( D+ P x_scale.mean(axis=1) / t; `" y" m) m2 T
` ! {7 f9 X' @. X; z! b2 c
cps = np.random.random_integers(0, 100, (100, 2)). ~% r# g! \; @) j! b
# 创建StandardScaler 对象,再调用fit_transform 方法,传入一个格式的参数数据作为训练集.
. p: J' _% ~/ }: @& L ss = StandardScaler()
9 ?, X; u5 F: K4 |2 c; i, x' o std_cps = ss.fit_transform(cps); W2 W" o9 `$ ~; Z/ G
gs = gridspec.GridSpec(5,5)* c+ a! r0 B$ w$ [
fig = plt.figure()( ~/ d) @9 n' G- W$ B+ k) o6 q
ax1 = fig.add_subplot(gs[0:2, 1:4])
?' q4 G3 Y/ n7 P3 d5 _ ax2 = fig.add_subplot(gs[3:5, 1:4])
- h$ P+ g" R3 B1 w0 j: C0 I ax1.scatter(cps[:, 0], cps[:, 1])
% J* K( ~& r! Q ax2.scatter(std_cps[:, 0], std_cps[:, 1])9 @! o7 U; J( k$ w& J4 h: `4 k+ }
plt.show()
. d7 `. y3 [2 I, ~. e, w% t' `' s `
& O7 L" `' x) t# D from sklearn.preprocessing import StandardScaler
" F7 z% L. A, n& l1 D from sklearn.preprocessing import MinMaxScaler
0 m- ]/ \; X2 B. S9 ]1 h; Z from matplotlib import gridspec
; Q$ ?, |4 `6 [ import numpy as np
6 y/ ]' j. S& r7 \0 N) |) L import matplotlib.pyplot as plt
5 ] y- i( T% I# r# x data = np.random.uniform(0, 100, 10)[:, np.newaxis]
2 z7 d% U. V/ ^" H! W' A( a ss = StandardScaler()+ ?4 l1 x. T( b9 e0 T! p
std_data = ss.fit_transform(data): D B, \0 m% V' z
origin_data = ss.inverse_transform(std_data) # 得到标准化之前的数据 {+ |; C8 i! O$ r6 t# v+ c& x" O
print(data is 原始数据,data)8 f) Z* A- @ O. ]
print(after standard 标准化后的数据,std_data)4 b0 M% a7 ~) l7 w
print(after inverse 通过inverse_transform该函数将标准化后的数据转化为原始数据:,origin_data)
* z+ a) d9 j% a3 X+ O print(after standard mean and std is 均值mean(均值) 和 标准差std(矩阵标准差),np.mean(std_data), np.std(std_data))
& n ?; |4 u& L9 ]% F+ E 使用sklearn 进行数据的归一化和归一化还原.) T7 Q- l% u0 H+ O% f# V
data = np.random.uniform(0, 100, 10)[:, np.newaxis] # 创建数据' [4 L+ G" t8 A/ h+ b
mm = MinMaxScaler()# 创建MinMaxScaler 对象
8 S6 [: W' p4 a* V' w. S( b- T# R mm_data = mm.fit_transform(data) # 归一化数据
9 _- M |2 Q9 q% L% R origin_data = mm.inverse_transform(mm_data) # 转换成归一化之前的数据
$ d9 A# x8 o; h/ I: G8 Y print(data is ,data)1 N, g- T1 f1 A' g0 R
print(after Min Max ,mm_data)
1 g. F% R+ V- p& t6 s* B print(origin data is ,origin_data) ; q7 |0 X! H' v0 Z) S
MinMaxScaler和MaxAbsCaler:" C; e# S0 B* O- f" y' m
MinMaxScaler:使得特征的分布在一个给定的最小值和最大值的范围内.一般情况下载0`1之间(为了对付哪些标准差相当小的特征并保留下稀疏数据中的0值.) - l2 _, k5 {# o; g3 y# n
MaxAbsScaler:或者是特征中的绝对值最大的那个数为1,其他依次为标准分布在-1`1之间 7 ?- s4 a' M% x: {* V
min_max_scaler = preprocessing.MinMaxScaler()7 ]% Q: H2 m# ?
x_minmax = min_max_scaler.fit_transform(x)+ P2 ^$ I y+ e+ ]% d2 h6 U
x_minmax % s1 o: j7 A7 i B4 q
对于新进来的数据,采用如下方式进行函数调用:
$ K) g# ?, X" |7 T& B- ` x_test = np.array([[-3., -1., 4.]])6 F& X1 }7 R# {! Y' I
x_test_minmax = min_max_scaler.transform(x_test)
" G4 u! v4 s/ h! O9 A& J8 b' p2 p! E x_test_minmax
- s B- d5 K U9 l2 L; C. o MaxAbsScaler:数据会被规模化到-1`1之间,就是特征中,所有数据都会除以最大值,该方法对哪些已经中心化均值为0,或者稀疏的数据有意义.
# r! D. E/ R Z; S8 e0 F( A max_abs_scaler = preprocessing.MaxAbsScaler()
1 d# H8 C- K, s3 f4 R x_train_maxsbs = max_abs_scaler.fit_transform(x)
) l- ^) Y" }5 t x_train_maxsbs 8 K+ O" s( V) F- y$ i' f" u
# 同理,也可以对新的数据集进行同样的转换
- @$ J4 |2 A# l" Y- O% B x_test = np.array([[-3., -1., 4.]])
& @( s4 {+ D" T1 j7 V x_test_maxabs = max_abs_scaler.transform(x_test)
; F4 S" Y9 W3 g2 v x_test_maxabs
& L$ }4 L8 I3 U/ d& ^9 c. u 针对规模化稀疏数据
& Y! a9 u, ~& h2 N) j+ `8 L5 \ 对稀疏数据去均值的中心化会破坏稀疏的数据结构,使用如下两个方法进行处理: 3 }: @- U6 v% I, \) i# D
MaxAbsScaler,和maxabs_scale
C* D& {0 y9 ~; B+ ? 针对规模化有异常的数据1 [2 ]9 S; }7 o, Q8 f/ c
数据集中有很多异常值,就不能使用数据的均值和方差去做标准化了.可以使用robust_scale和RobustScaler ,更具中位数或者四分位数去中心化数据. 5 c/ t: a* d2 p0 ~4 ^ y
正则化Normalization7 \' N! A" R U3 h$ B/ X
正则化是将样本在向量空间模型上的一个转换,常常被使用在分类和聚类中,使用函数normalize实现一个单向量的正则化功能.正则化化有I1,I2等
3 G2 P7 H7 s5 n" U1 b6 i x_normalized = preprocessing.normalize(x, norm=l2)
/ K% Q7 [4 w& P& j" k4 W7 @ print x
1 l7 O, @ @" M print x_normalized ; m1 |! z$ z# Y: d' `: C3 H
# 根据训练数据创建一个正则器 Normalizer(copy=True, norm=l2) ; l; N3 p9 l/ S& d1 i
normalizer = preprocessing.Normalizer().fit(x)
8 n% R$ y% g z. ]' V# X normalizer , j% n; ?4 t$ C, Q8 C
# 对训练数据进行正则
, H4 B0 N: T$ R5 R# y) I normalizer.transform(x) 0 Z8 m! R' T' p9 ?7 f/ p# R
# 对新的测试数据进行正则 7 M, q# y/ U, Y; q9 P
normalizer.transform([[-1., 1., 0.]]) , s2 E+ b' V/ O9 H
二值化2 U# H7 }( Y9 ?4 s2 ]' y/ z& d
特征的二值化(指将数值型的特征数据转换为布尔类型的值,使用实用类Binarizer),默认是根据0来二值化,大于0的都标记为1,小于等于0的都标记为0.通过设置threshold参数来更改该阈值 & k3 Q! ?/ ]1 C) b `* Y9 \- }
from sklearn import preprocessing
( E9 _2 q: I# b- a2 e; r9 { import numpy as np
6 B/ x1 k" |0 c- B$ ?" V/ C4 a4 W1 C1 ]! ~: e
# 创建一组特征数据,每一行表示一个样本,每一列表示一个特征
' M2 o* w* f% ]' x x = np.array([[1., -1., 2.],7 W* s0 h/ D- q( ]3 n/ ]. z) ^" N
[2., 0., 0.],
+ e* ^, F6 p O7 N. d [0., 1., -1.]])# x9 j5 t: W% K# H: i8 p
, K$ p6 [2 y5 h5 k. a6 j; ]) ] binarizer = preprocessing.Binarizer().fit(x)* }0 d0 d2 L7 U
binarizer.transform(x)0 R1 l% E7 y* v
6 k$ @% Y m. {$ u. F6 m2 x3 Z binarizer = preprocessing.Binarizer(threshold=1.5)
1 T! [7 N5 [9 A0 L binarizer.transform(x) 2 g6 P7 y$ y7 d
为类别特征编码1 U* p# o7 i9 C
(比如性别:male,来自于哪个国家或地区:from US,使用什么浏览器:users Chrome) 可以转换为 013 或者是其他的数值型编码. $ K6 l( J4 s0 T" ^
OneHotEncoder
$ c+ _( n4 d. s. @ 弥补缺失数据9 e- R/ }: Z! [4 I" g
可以使用均值,中位数,众数等等弥补缺失数据,可以使用Imputer实现. + j! S8 \( L4 o" e9 f! a
import numpy as np
) T0 B& x- u0 N/ r, o6 u from sklearn.preprocessing import Imputer
. V+ `& F5 _5 h) P3 l imp = Imputer(missing_values=NaN, strategy=mean, axis=0)5 J- z% R4 _& A* p, I# o2 J7 n
imp.fit domain name is for sale. Inquire now.([[1, 2], [np.nan, 3], [7, 6]]), @( b% w2 ?, ~ K+ ~
x = [[np.nan, 2], [6, np.nan], [7, 6]]
& I# t) G' C$ {! L2 [# W" W imp.transform(x) / h' N w& y+ N' L! T% L
Imputer类同样也可以支持稀疏矩阵,以下例子将0作为了缺失值,为其补上均值 ; u: e% d, V: S( b0 u2 C5 M! F( h
import scipy.sparse as sp0 J% T! j1 \7 O( x
# 创建一个稀疏矩阵
, h- M f% Y& [8 }* ^ x = sp.csc_matrix([[1, 2], [0, 3], [7, 6]]): q) ]4 S2 a, ^
imp = Imputer(missing_values=0, strategy=mean, verbose=0)
( I7 _ m) P! N5 F imp.fit domain name is for sale. Inquire now.(x)4 e9 b% ?6 e8 @- d* K' I
x_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])' D7 ^ x S% y7 d8 R
imp.transform(x_test) % g7 D3 q& ^6 _
当我们拿到一批原始的数据 9 N! e& s/ D' T! a) a
首先要明确有多少特征,哪些是连续的,哪些是类别的。 9 u* q+ f2 t5 T6 t
检查有没有缺失值,对确实的特征选择恰当方式进行弥补,使数据完整。 6 m" f. b% C# z% e7 {
对连续的数值型特征进行标准化,使得均值为0,方差为1。
3 l/ q6 A% l2 G9 z% O 对类别型的特征进行one-hot编码。 " V: l# q7 @( b
将需要转换成类别型数据的连续型数据进行二值化。 J3 l# ]3 R, {7 t2 n
为防止过拟合或者其他原因,选择是否要将数据进行正则化。 / ?+ V* h9 n1 o# l l- F
在对数据进行初探之后发现效果不佳,可以尝试使用多项式方法,寻找非线性的关系。 6 d" E- z3 C8 H3 ~
根据实际问题分析是否需要对特征进行相应的函数转换。 % R6 O% L: H; j+ ^3 ^5 a
标准化和归一化的缺点:每当有新的数据进来时,就要重新计算所有的点 d9 ]& f: d, u. J4 K
因此针对动态的数据可以采用如下几种计算方法: 7 x+ J+ @0 z7 P
1.arctan反正切函数标准化. http://2.in函数标准化预处理数据的方法总结(使用sklearn-preprocessing)_【人工智能】王小草的博客-CSDN博客
4 n$ C- w0 d: J4 M8 m- a) n4 K) E) X) K2 \' q2 ^( A
$ [# I4 k) ?0 l6 m* j
& r% Z+ ^& x* \& R: l& E( M
1 e& v# Q. j6 I: u |