机器学习-周志华-个人练习11.3

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qilixuening/article/details/72331313

11.3 Relief算法是分别考察每个属性的重要性。试设计一个能考虑每一对属性重要性的改进算法。

首先,我们知道单属性对应的统计量计算公式如下:

δj=i(diff(xji,xji,nh)2+diff(xji,xji,nm)2)
上式中 xji , xji,nh , xji,nm 等都是标量,因此可以考虑将其变为向量 x⃗ j1,j2i , x⃗ j1,j2i,nh , x⃗ j1,j2i,nm . 其中 x⃗ j1,j2i=(xj1i,xj2i) ,同时令
δj1,j2=i[diff(x⃗ j1,j2i,x⃗ j1,j2i,nh)2+diff(x⃗ j1,j2i,x⃗ j1,j2i,nh)2]
j1,j2 均为离散变量时, diff(x⃗ j1,j2a,x⃗ j1,j2b)=(xj1axj1b,xj2axj2b) 中非零元的个数;当 j1,j2 中至少含有一个离散变量时, diff(x⃗ j1,j2a,x⃗ j1,j2b)=(xj1axj1b,xj2axj2b)2 . 由于所有属性均已归一化,因此 diff(x⃗ j1,j2a,x⃗ j1,j2b)2[0,2] , 而在实际计算过程中, diff(x⃗ j1,j1a,x⃗ j1,j1b)2[0,2] ,这显然没有意义,因此对所有对角元素,令:
δj1,j2=12diff(x⃗ j1,j1a,x⃗ j1,j1b)2=δj1,[0,1]

基于上述想法,采用与 11.1同样的算法,获取属性对的相关统计量矩阵,显然,此矩阵是对称方阵。由最后的相关统计量矩阵得可视化结果可见,主对角元素对应了各单属性的相关统计量,与11.1题的结果一致,而非对角元素中属性3(纹理)和属性1(根蒂)形成的属性对明显比单用属性3的效果更好,而不含“纹理”的属性对组合也能获得较好的表征效果。
代码如下:

# -*- coding: utf-8 -*-
# 特征选择方法:Relief,对于属性对
import numpy as np
import matplotlib.pyplot as plt

label = {0:'色泽', 1:'根蒂', 2:'敲声', 3:'纹理', 4:'脐部', 5:'触感', 6:'密度', 7:'含糖率'}
D = np.array([
    [1, 1, 1, 1, 1, 1, 0.697, 0.460, 1],
    [2, 1, 2, 1, 1, 1, 0.774, 0.376, 1],
    [2, 1, 1, 1, 1, 1, 0.634, 0.264, 1],
    [1, 1, 2, 1, 1, 1, 0.608, 0.318, 1],
    [3, 1, 1, 1, 1, 1, 0.556, 0.215, 1],
    [1, 2, 1, 1, 2, 2, 0.403, 0.237, 1],
    [2, 2, 1, 2, 2, 2, 0.481, 0.149, 1],
    [2, 2, 1, 1, 2, 1, 0.437, 0.211, 1],
    [2, 2, 2, 2, 2, 1, 0.666, 0.091, 0],
    [1, 3, 3, 1, 3, 2, 0.243, 0.267, 0],
    [3, 3, 3, 3, 3, 1, 0.245, 0.057, 0],
    [3, 1, 1, 3, 3, 2, 0.343, 0.099, 0],
    [1, 2, 1, 2, 1, 1, 0.639, 0.161, 0],
    [3, 2, 2, 2, 1, 1, 0.657, 0.198, 0],
    [2, 2, 1, 1, 2, 2, 0.360, 0.370, 0],
    [3, 1, 1, 3, 3, 1, 0.593, 0.042, 0],
    [1, 1, 2, 2, 2, 1, 0.719, 0.103, 0]])
m = len(D)

# 数据归一化
temp = D[:,:-1]
D[:,:-1] = (temp-np.min(temp,axis=0)) / np.ptp(temp, axis=0)

# 按照顺序保存各样本的nh和nm近邻
data = D[:,:-1]
nh_set, nm_set = [],[]
for i in range(m):
    data -= data[i,:]
    li = np.argsort(np.linalg.norm(data, axis=1))
    for order in range(1,m):  # li[0]代表其本身的id,因此索引应该从1开始
        if D[li[order],-1] == D[i,-1]:
            nh_set.append(li[order])
            break
    for order in range(1,m):  # li[0]代表其本身的id,因此索引应该从1开始
        if D[li[order],-1] != D[i,-1]:
            nm_set.append(li[order])
            break

# 计算相关统计量score矩阵
n = len(label)
score = np.zeros((n,n))  # 初始化为n*n的零矩阵
for attr1 in range(n):  # 对所有属性采用连续变量的计算公式进行计算
    for attr2 in range(n):
        for i in range(m):
            dif_nh = np.linalg.norm(data[i, [attr1,attr2]] - data[nh_set[i], [attr1,attr2]])
            dif_nm = np.linalg.norm(data[i, [attr1, attr2]] - data[nm_set[i], [attr1, attr2]])
            score[attr1,attr2] += dif_nm**2 - dif_nh**2
score[:-2,:-2] = 0  # 将统计量矩阵中离散属性对的统计量重置为0
for attr1 in range(n - 2):  # 计算离散属性对的统计量
    for attr2 in range(n - 2):
        for i in range(m):
            dif_nh = data[i, [attr1,attr2]] - data[nh_set[i], [attr1,attr2]]
            s_hit = np.sum(dif_nh != 0)
            dif_nm = data[i, [attr1, attr2]] - data[nm_set[i], [attr1, attr2]]
            s_miss = np.sum(dif_nm != 0)
            score[attr1,attr2] += s_miss - s_hit
for attr in range(n):  # 对角元素减半,因为在前面的计算中同一属性组成的属性对的统计量,实际上是单个对应属性统计量的2倍
    score[attr,attr] /= 2

# 可视化并保存
fig,ax = plt.subplots(1,1,figsize=(7,6))
l = [label[i] for i in range(n)]
f = ax.matshow(score)
for i in range(n):
    for j in range(n):
        ax.text(i,j,'{0:.1f}'.format(score[i,j]),ha='center',va='center',color='white',size=12)
ax.set_title('Attributes Matrix')
plt.colorbar(f,ax=ax)
plt.subplots_adjust(left=0.05, bottom=0.05, right=0.95)
plt.savefig(r'C:\...\1.png')

属性对的统计量矩阵如下:
可视化矩阵

猜你喜欢

转载自blog.csdn.net/qilixuening/article/details/72331313