Q:什么叫做数据归一化?
A:就是将所有数据映射到同一尺度。
Q:机器学习为什么要做数据归一化?
A:如下图,发现天数影响之差的平方比肿瘤大小之差的平方大的多得多,导致天数主导了计算结果。所以我们需要对数据进行处理,使得某一特征不能主导结果。
Q:数据归一化的方法有几种?各自有什么优缺点?
A:常用的有两种。
1. 最值归一化normalization
x-xmin
x =————————————————
scale xmax-xmin
适用于分布有明显边界的情况,受outlier影响较大,如分数,图像等,不适用于工资等没有明确边界的情况。
2. 均值方差归一化:standardization
x-xmenu
x =——————————————
scale S
即把所有数据归一到均值为0方差为1的分布中
适用于:数据分布没有明显边界,有可能存在极端数据值
Q:很好,如果使用均值方差归一法,对于测试数据是不是也要再次计算均值和方差?
A:不需要,不对,应该使用训练集的均值和方差。在真实情况下我们很难得到这两个参数,比如只有一个参数,如何求方差和均值呢?对数据的归一化也是算法的一部分。需要保存训练集得到的均值和方差。
1. 最值归一化和均值方差归一化
# 最值归一化
def normalization(x):
assert len(x) > 1, 'x need greater than one number'
assert x.ndim == 2, 'only deal ndim=2'
x=np.array(x,dtype=float)
features=x.shape[1]
for i in range(0,features):
x[:,i]=(x[:,i]-np.min(x[:,i]))/(np.max(x[:,i])-np.min(x[:,i]))
return x
# 均值方差归一化
def standardization(x):
assert len(x) > 1, 'x need greater than one number'
assert x.ndim == 2, 'only deal ndim=2'
x=np.array(x,dtype=float)
features = x.shape[1]
for i in range(0,features):
x[:,i]=(x[:,i]-np.mean(x[:,i]))/np.std(x[:,i])
return x
2. 使用iris数据进行数据归一化处理并返回使用KNN算法进行预测的准确度
import math
import numpy as np
from collections import Counter
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# 对均值方差归一化方法进行封装
class Standard(object):
def __init__(self):
self.mean_=None
self.scale_=None
def fit(self,x):
# fit步骤计算方差和均值
assert x.ndim==2,'The dimension of x must be 2'
self.mean_=np.array([np.mean(x[:,i]) for i in range(x.shape[1])])
self.scale_=np.array([np.mean(x[:,i]) for i in range(x.shape[1])])
return self
def transform(self,x):
# transform对x进行均值方差归一化
assert x.ndim==1,'The dimension of x must be 2'
assert self.mean_ is not None,'fit before transform'
assert x.shape[1]==len(self.mean_),'The feature number must be same'
result=np.empty(shape=x.shape,dtype=float)
for i in range(x.shape[1]):
result[:,i]=(x[:,i]-self.mean_[i])/self.scale_[i]
return result
# 利用sklearn中的均值归一化方法,对iris数据集进行数据归一化
# 使用sklearn中的train_test_spilt对数据集进行分割
#
# 1.导入数据
iris=datasets.load_iris()
# 2.分割训练数据集和测试数据集
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2)
# 3.对训练数据进行归一化处理
scaler=StandardScaler()
scaler.fit(x_train)
x_train=scaler.transform(x_train)
# 4.对测试数据进行归一化处理
x_test=scaler.transform(x_test)
# 5.进行KNN算法
from sklearn.neighbors import KNeighborsClassifier
knn_clf=KNeighborsClassifier(n_neighbors=3)
# 6.训练数据
knn_clf.fit(x_train,y_train)
# 7.进行比较
score=knn_clf.score(x_test,y_test)
print(score)