文章原创,最近更新:2018-08-9
本章节的主要内容是:
重点介绍项目案例1: 优化约会网站的配对效果中的归一化处理
。
1.KNN项目案例介绍:
项目案例1:
优化约会网站的配对效果
项目概述:
1)海伦使用约会网站寻找约会对象。经过一段时间之后,她发现曾交往过三种类型的人: 不喜欢的人、魅力一般的人、 极具魅力的人。
2)她希望: 1. 工作日与魅力一般的人约会 2. 周末与极具魅力的人约会 3. 不喜欢的人则直接排除掉。现在她收集到了一些约会网站未曾记录的数据信息,这更有助于匹配对象的归类。
开发流程:
- 收集数据:提供文本文件
- 准备数据:使用 Python 解析文本文件
- 分析数据:使用 Matplotlib 画二维散点图
- 训练算法:此步骤不适用于 k-近邻算法
- 测试算法:使用海伦提供的部分数据作为测试样本。
测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。 - 使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。
数据集介绍
海伦把这些约会对象的数据存放在文本文件 datingTestSet2.txt (数据来源于《机器学习实战》第二章 k邻近算法)中,总共有 1000 行。
本文使用的数据主要包含以下三种特征:每年获得的飞行常客里程数,玩视频游戏所耗时间百分比,每周消费的冰淇淋公升数。其中分类结果作为文件的第四列,并且只有3、2、1三种分类值。datingTestSet2.csv文件格式如下所示:
飞行里程数 | 游戏耗时百分比 | 冰淇淋公升数 | 分类结果 |
---|---|---|---|
40920 | 8.326976 | 0.953952 | 3 |
14488 | 7.153469 | 1.673904 | 2 |
26052 | 1.441871 | 0.805124 | 1 |
数据在datingTestSet2.txt文件中的格式如下所示:
2.归一化处理相关代码
本章节的主要内容是:归一化处理,归一化是为了让数据都处于[0,1]之间
def autoNorm(dataSet):
"""
归一化特征值,消除属性之间量级不同导致的影响
dataSet: 数据集
return: 归一化后的数据集normDataSet,ranges和minVals即归一化的数据集,最小值与极差
归一化公式:
Y = (X-Xmin)/(Xmax-Xmin)
其中的 min 和 max 分别是数据集中的最小特征值和最大特征值。该函数可以自动将数字特征值转化为0到1的区间。
"""
# 找出样本集中每列属性的最小值
minVals= dataSet.min(0)
# 找出样本集中每列属性的最大值
maxVals= dataSet.max(0)
# 每列最大最小值之间的极差
ranges=maxVals-minVals
# 创建与样本集一样大小的零矩阵
normDataSet=np.zeros(np.shape(dataSet))
# 获得样本集的行的维度
m=dataSet.shape[0]
# 样本集中的元素与最小值组成的矩阵
normDataSet=dataSet-np.tile(minVals,(m,1))
# 将最小值之差除以范围组成矩阵
normDataSet=normDataSet/np.tile(ranges,(m,1))
return normDataSet, ranges, minVals
测试代码及其结果如下:
import kNN
normMat, ranges, minVals = kNN.autoNorm(datingDataMat)
normMat
Out[53]:
array([[ 0.44832535, 0.39805139, 0.56233353],
[ 0.15873259, 0.34195467, 0.98724416],
[ 0.28542943, 0.06892523, 0.47449629],
...,
[ 0.29115949, 0.50910294, 0.51079493],
[ 0.52711097, 0.43665451, 0.4290048 ],
[ 0.47940793, 0.3768091 , 0.78571804]])
ranges
Out[54]: array([ 9.12730000e+04, 2.09193490e+01, 1.69436100e+00])
minVals
Out[55]: array([ 0. , 0. , 0.001156])
用一组小数据来模拟以上每一行的源代码代码,具体如下:
dataSet = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
dataSet
Out[20]:
array([[ 1. , 1.1],
[ 1. , 1. ],
[ 0. , 0. ],
[ 0. , 0.1]])
minVals = dataSet.min(0)
minVals
Out[22]: array([ 0., 0.])
maxVals = dataSet.max(0)
maxVals
Out[24]: array([ 1. , 1.1])
ranges = maxVals - minVals
ranges
Out[26]: array([ 1. , 1.1])
normDataSet = np.zeros(np.shape(dataSet))
normDataSet
Out[30]:
array([[ 0., 0.],
[ 0., 0.],
[ 0., 0.],
[ 0., 0.]])
m = dataSet.shape[0]
m
Out[32]: 4
np.tile(minVals, (m,1))
Out[34]:
array([[ 0., 0.],
[ 0., 0.],
[ 0., 0.],
[ 0., 0.]])
normDataSet = dataSet - np.tile(minVals, (m,1))
normDataSet
Out[36]:
array([[ 1. , 1.1],
[ 1. , 1. ],
[ 0. , 0. ],
[ 0. , 0.1]])
np.tile(ranges, (m,1))
Out[37]:
array([[ 1. , 1.1],
[ 1. , 1.1],
[ 1. , 1.1],
[ 1. , 1.1]])
normDataSet = normDataSet/np.tile(ranges, (m,1))
normDataSet
Out[39]:
array([[ 1. , 1. ],
[ 1. , 0.90909091],
[ 0. , 0. ],
[ 0. , 0.09090909]])
3.特征归一化的了解
3.1归一化相关概念
机器学习中,提取某个样本特征的过程,叫特征工程
。
同一个样本,可能具备不同类型的特征,各特征的数值大小范围不一致。所谓特征归一化
,就是将不同类型的特征数值大小变为一致的过程。
3.2特征归一化的意义
- 各特征之间的大小范围一致,才能使用距离度量等算法
- 加速梯度下降算法的收敛
- 在SVM算法中,一致化的特征能加速寻找支持向量的时间
- 不同的机器学习算法,能接受的输入数值范围不一样
3.3归一化的方法
- min-max标准化(Min-Max Normalization)(线性函数归一化)
- 定义:也称为离差标准化,是对原始数据的线性变换,使得结果映射到0-1之间。
- 本质:把数变为【0,1】之间的小数。
- 转换函数:(X-Min)/(Max-Min)
- 如果想要将数据映射到-1,1,则将公式换成:(X-Mean)/(Max-Min)
其中:max为样本数据的最大值,min为样本数据的最小值,Mean表示数据的均值。
缺陷:当有新数据加入时,可导致max和min的变化,需要重新定义。
举个小案例,具体如下:
假设有4个样本及他们的特征如下
样本 | 特征1 | 特征2 |
---|---|---|
1 | 10001 | 2 |
2 | 16020 | 4 |
3 | 12008 | 6 |
4 | 13131 | 8 |
可见归一化前,特征1和特征2的大小不是一个数量级。归一化后,特征变为
样本 | 特征1 | 特征2 |
---|---|---|
1 | 0 | 0 |
2 | 1 | 0.33 |
3 | 0.73 | 0.67 |
4 | 0.81 | 1 |
解析:
以下例说明计算过程
样本 | 特征1 | 特征2 |
---|---|---|
1 | 10001 | 2 |
2 | 16020 | 4 |
3 | 12008 | 6 |
4 | 13131 | 8 |
X.max | 16020 | 8 |
X.min | 10001 | 2 |
归一化的过程如下,假设归一化后的矩阵为S
- S11=(10001-10001)/(16020-10001)=0
- S21=(16020-10001)/(16020-10001)=1
- S31=(12008-10001)/(16020-10001)=0.333444
- S41=(13131-10001)/(16020-10001)=0.52002
- S12=(2-2)/(8-2)=0
- S22=(4-2)/(8-2)=0.33
- S32=(6-2)/(8-2)=0.6667
- S42=(8-2)/(8-2)=1
学习参考链接:详解特征归一化
- 0均值标准化(Z-score standardization)
- 定义:这种方法给与原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化。经过处理的数据符合标准正态分布,即均值为0,标准差为1.
- 本质:把有量纲表达式变成无量纲表达式。
- 转换函数:(X-Mean)/(Standard deviation)
其中,Mean为所有样本数据的均值。Standard deviation为所有样本数据的标准差。
举个小案例,具体如下:
样本 | 特征1 | 特征2 |
---|---|---|
1 | 10001 | 2 |
2 | 16020 | 4 |
3 | 12008 | 6 |
4 | 13131 | 8 |
列均值 | 12790 | 5 |
列标准差 | 2175.96 | 2.236 |
归一化的过程如下,假设归一化后的矩阵为S
- S11=(10001-12790)/2175.96=-1.28173
- S21=(16020-12790)/2175.96=1.484
- S31=(12008-12790)/2175.96=-0.35938
- S41=(13131-12790)/2175.96=0.1567
- S12=(2-5)/2.236=-1.342
- S22=(4-5)/2.236=-0.447
- S32=(6-5)/2.236=0.447
- S42=(8-5)/2.236=1.3416
总结
本文详细介绍了min-max标准化和0均值标准化的计算过程。有这个过程可以看出:
- 当我们需要将特征值都归一化为某个范围[a,b]时,选min-max标准化
- 当我们需要归一化后的特征值均值为0,标准差为1,选0均值标准化
学习参考链接:机器学习-数据归一化方法(Normalization Method)
4.相关知识点
知识点1:python numpy中数组.min()和.max()
- 数组.min()
import numpy as np
a = np.array([[1,5,3],[4,2,6]])
print(a.min()) #无参,所有中的最小值
print(a.min(0)) # axis=0; 每列的最小值
print(a.min(1)) # axis=1;每行的最小值
输出结果如下:
1
[1 2 3]
[1 2]
- 数组.max()
import numpy as np
a = np.array([[1,5,3],[4,2,6]])
print(a.max()) #无参,所有中的最大值
print(a.max(0)) # axis=0; 每列的最大值
print(a.max(1)) # axis=1;每行的最大值
输出结果如下:
6
[4 5 6]
[5 6]
知识点2:python: numpy--函数 shape用法
shape函数它的功能是查看矩阵或者数组的维数。
举个小案例:
- 建立一个3×3的单位矩阵e, e.shape为(3,3),表示3行3列,第一维的长度为3,第二维的长度也为3
import numpy as np
a=np.eye(3)
a
Out[7]:
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
a.shape
Out[8]: (3, 3)
- 建立一个一维矩阵b, b.shape 为矩阵的长度
b=np.array([1,2,3,4])
b.shape
Out[11]: (4,)
#可以简写
np.shape([1,2,3,4])
Out[12]: (4,)
- 建立一个4×2的矩阵c, c.shape[1] 为第一维的长度,c.shape[0] 为第二维的长度。
c=np.array([[1,1],[1,2],[1,3],[1,4]])
c
Out[15]:
array([[1, 1],
[1, 2],
[1, 3],
[1, 4]])
c.shape
Out[16]: (4, 2)
c.shape[0]
Out[17]: 4
c.shape[1]
Out[18]: 2
知识点3:array中的tile()函数
举了一个小案例,具体可以参见如下案例:
import numpy as np
dataSet = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
dataSet
Out[47]:
array([[ 1. , 1.1],
[ 1. , 1. ],
[ 0. , 0. ],
[ 0. , 0.1]])
inX=np.array([0,1])
inX
Out[49]: array([0, 1])
dataSetSize=dataSet.shape[0]
dataSetSize
Out[51]: 4
tile(inX, (dataSetSize,1))
Out[53]:
array([[0, 1],
[0, 1],
[0, 1],
[0, 1]])
diffMat=tile(inX, (dataSetSize,1))-group
diffMat
Out[55]:
array([[-1. , -0.1],
[-1. , 0. ],
[ 0. , 1. ],
[ 0. , 0.9]])
网友评论