为什么要用不同的方法规范化数据?
现在又写数据拿到之后由于量纲不一样,或者要求的优化方向不一样,在后期进行一些权重或决策计算的时候,如果按照一种思路去规范化,往往可能会得到实际值和理论值恰恰相反的情景。
用个例子来解释一下上面这一段话,我要对多个学校的状况进行评估,评估的方面包括:逾期毕业率,研究生师生比例,科研经费。列出数据如下所示:
序号 | 逾期毕业率 | 研究生师生比例 | 科研经费(万元/年) | 人均专著 |
---|---|---|---|---|
1 | 4.3% | 5.5 | 5000 | 0.1 |
2 | 2.8% | 4.5 | 6000 | 0.2 |
3 | 3.6% | 10 | 10000 | 0.9 |
4 | 7.9% | 7 | 6000 | 1.2 |
5 | 0.5% | 8 | 1000 | 0.3 |
首先,规范一下符号,
- 记 A ( a i j ) 1 × n A(a_{ij})_{1\times n} A(aij)1×n矩阵为评级指标矩阵,在这里就是一个1x3的矩阵
- D ( d i j ) m × n D(d_{ij})_{m\times n} D(dij)m×n为实际的情况数据的矩阵,在这里就是表示上面的数据,为5x3的矩阵
- B ( b i j ) m × n B(b_{ij})_{m\times n} B(bij)m×n为 D D D规范化之后的矩阵。
由上述三个不同的指标我们分析发现,逾期毕业率越低越好,师生比例在某个区间内都行,人均专著,科研经费越高越好。如果我们要进行归一化处理。
如果使用:
b
i
j
=
a
i
j
/
∑
a
i
j
,
i
取
1
,
2
,
3
…
…
n
b_{ij} = a_{ij}/\sum a_{ij},i取1,2,3……n
bij=aij/∑aij,i取1,2,3……n
这种方法就非常的平均,但是也反应问题就是这个数越大,占比越高,很显然对于逾期毕业率这种指标并不好。
并且对于师生比这种师生比是
[
5
,
7
]
[5,7]
[5,7]之间我觉得都是可以,并没有任何区别。所以上述的数据处理方法是不合理的。
这时就需要更合理的规范数据的方法。
数据分类
根据数据的增长情况我们把数据分为三类:
- 效益性数据(越大越好)
- 成本型数据(越小越好)
- 区间型数据(在一个区间里面没差,在这个区间外别管大小都有问题)
规范化数据方法
线性规范
“最大为纲”的态度,
对于效益型数据:
b
i
j
=
a
i
j
/
a
j
m
a
x
b_{ij} =a_{ij}/a^{max}_j
bij=aij/ajmax
在效益型数据中,最好的就是1,最差的不一定为0,因为
a
i
j
a_{ij}
aij不一定为0
对于成本型数据:
b
i
j
=
1
−
a
i
j
/
a
j
m
a
x
b_{ij} = 1 - a_{ij}/a^{max}_j
bij=1−aij/ajmax
在成本型数据中,最差的为0,最好的不一定为1,同理。
将上述例子中的,科研经费和逾期毕业率规范一下,代码如下所示:
import numpy as np
#输入数据
funds_list = np.array([5000,6000,10000,6000,1000])
booknum_list = np.array([0.1,0.2,0.9,1.2,0.3])
overdue_list = np.array([4.3,2.8,3.6,7.9,0.5])
Combine_metrix = np.vstack((funds_list,booknum_list,overdue_list)) #数据垂直拼接,列合并
#规范化效益型数据
funds_list_mod = funds_list/Combine_metrix[0].max()
booknum_list_mod = booknum_list/Combine_metrix[1].max()
#规范成本型数据
overdue_list_mod = 1 - overdue_list/Combine_metrix[2].max()
#修正数据垂直拼接,列合并
Combine_metrix= np.vstack((funds_list_mod,booknum_list_mod,overdue_list_mod))
#结果
# [[0.5 0.6 1. 0.6 0.1] --经费规范化
# [0.08333333 0.16666667 0.75 1. 0.25] -- 出版物规范化
# [0.4556962 0.64556962 0.5443038 0. 0.93670886]] -- 预期毕业率规范化
标准0-1规划
标准0-1规划原则就是为了表现最差为0,最好为1这种现象。
对于效益性数据:
b
i
j
=
a
i
j
−
a
j
m
i
n
a
j
m
a
x
−
a
j
m
i
n
b_{ij} = \cfrac {a_{ij}-a^{min}_j}{a_j^{max}-a_j^{min}}
bij=ajmax−ajminaij−ajmin
对于成本型数据:
b
i
j
=
a
j
m
a
x
−
a
i
j
a
j
m
a
x
−
a
j
m
i
n
b_{ij} = \cfrac {a_{j}^{max}-a_{ij}}{a_j^{max}-a_j^{min}}
bij=ajmax−ajminajmax−aij
import numpy as np
#输入数据
funds_list = np.array([5000,6000,10000,6000,1000])
booknum_list = np.array([0.1,0.2,0.9,1.2,0.3])
overdue_list = np.array([4.3,2.8,3.6,7.9,0.5])
Combine_metrix = np.vstack((funds_list,booknum_list,overdue_list)) #数据垂直拼接,列合并
#规范化效益型数据
funds_list_mod = (funds_list - funds_list.min())/(funds_list.max()-funds_list.min())
booknum_list_mod = (booknum_list-booknum_list.min())/(booknum_list.max()-booknum_list.min())
#规范成本型数据
overdue_list_mod = (overdue_list.max() - overdue_list)/(overdue_list.max()-overdue_list.min())
#修正数据垂直拼接,列合并
Combine_metrix= np.vstack((funds_list_mod,booknum_list_mod,overdue_list_mod))
# 结果
# [[0.44444444 0.55555556 1. 0.55555556 0. ]
# [0. 0.09090909 0.72727273 1. 0.18181818]
# [0.48648649 0.68918919 0.58108108 0. 1. ]]
区间型属性规范化
对于在一个区间内合适的变量,我们通常会选择一个最优属性区间
[
a
0
,
a
∗
]
[a^0,a^*]
[a0,a∗]和一个最无法容忍的区间
[
a
′
,
a
′
′
]
[a^{'},a^{''}]
[a′,a′′]:
b
i
j
=
{
1
−
(
a
j
0
−
a
i
j
)
/
(
a
j
0
−
a
j
′
)
a
j
≤
a
i
j
≤
a
j
0
1
a
0
≤
a
i
j
≤
a
∗
1
−
(
a
i
j
−
a
j
∗
)
/
(
a
j
′
′
−
a
j
∗
)
a
j
∗
≤
a
i
j
≤
a
j
′
′
0
其
他
b_{ij} =\begin{cases} 1-(a^0_j-a_{ij})/(a^0_j-a^{'}_j) & a_j \le a_{ij}\le a_j^0\\ 1 &a^0\le a_{ij}\le a^{*} \\ 1-(a_{ij}-a_j^*)/(a^{''}_j-a^*_j) &a^*_j\le a_{ij}\le a^{''}_j \\ 0 &其他\\ \end{cases}
bij=⎩⎪⎪⎪⎨⎪⎪⎪⎧1−(aj0−aij)/(aj0−aj′)11−(aij−aj∗)/(aj′′−aj∗)0aj≤aij≤aj0a0≤aij≤a∗aj∗≤aij≤aj′′其他
代码如下所示:
import numpy as np
#导入数据
TaSRate = np.array([5.5,4.5,10,7,8])
#设置区间
interval = np.array([5,7])
notAllow = np.array([3,12])
#数据处理
TaSRate_mod = []
for t in TaSRate:
if t<= interval[0] and t>=notAllow[0]:
t = 1-(interval[0]-t)/(interval[0]-notAllow[0])
TaSRate_mod.append(t)
elif t<=interval[1] and t>=interval[0]:
t = 1
TaSRate_mod.append(t)
elif t<=notAllow[1] and t>=interval[1]:
t = 1 - (t-interval[1])/(notAllow[1]-interval[1])
TaSRate_mod.append(t)
else :
t = 0
TaSRate_mod.append(t)
TaSRate_mod = np.array(TaSRate_mod)
print(TaSRate_mod)
#结果
#[1. 0.75 0.4 1. 0.8 ]
标准化处理
标准化处理就非常简单了:
b
i
j
=
a
i
j
−
a
m
e
a
n
s
b_{ij} = \cfrac {a_{ij}-a_{mean}}{s}
bij=saij−amean
s
s
s为数组的方差,
a
m
e
a
n
a_{mean}
amean为数组的均值。
代码实现如下:
import numpy as np
#导入全部数据
funds_list = np.array([5000,6000,10000,6000,1000])
booknum_list = np.array([0.1,0.2,0.9,1.2,0.3])
overdue_list = np.array([4.3,2.8,3.6,7.9,0.5])
TaSRate = np.array([5.5,4.5,10,7,8])
#合并数据
Combine_metrix = np.vstack((funds_list,booknum_list,overdue_list,TaSRate))
for col in Combine_metrix:
mu = np.mean(col, axis=0)
sigma = np.std(col, axis=0)
#对应值替换
Combine_metrix[Combine_metrix == col] = (col - mu)/sigma
print(Combine_metrix)
#结果
#[[-0.2090199 0.1393466 1.53281263 0.1393466 -1.60248593]
# [-1.01913032 -0.78750979 0.8338339 1.52869548 -0.55588927]
# [ 0.1993504 -0.4236196 -0.09136893 1.69447841 -1.37884027]
# [-0.77981287 -1.29968811 1.55962573 0. 0.51987524]]