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

来源:互联网 发布:js创建一个对象的方法 编辑:程序博客网 时间:2024/05/17 06:21

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 npimport matplotlib.pyplot as pltlabel = {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**2score[:-2,:-2] = 0  # 将统计量矩阵中离散属性对的统计量重置为0for 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_hitfor 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')

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

原创粉丝点击