- 数据矩阵:对象—属性结构:存放着数据对象
- 相异性矩阵:对象—对象结构:存放着对象之间的邻近度
一. 相异性矩阵(标称属性)
1.假设我们有表1中的样本数据
对象 标识符 | Length (数值的) | sort (序数的) | class (标称的) | T1 (二元的) | T2 (二元的) | T3 (二元的) | T4 (二元的) |
---|---|---|---|---|---|---|---|
0 | 10 | 1 | A | T | T | F | F |
1 | 6 | 3 | C | T | F | T | F |
2 | 8 | 2 | B | T | T | F | T |
3 | 10 | 1 | A | T | F | T | T |
计算标称属性的相异性矩阵,即下式
代码:
import numpy as np
import pandas as pd
def dir(dict, num):
'''
字典转换为相异性矩阵
:param dict: 标识符与属性对应的字典
:param num: 标识符数组
:return: 相异性矩阵
'''
data = [[0] * len(num) for i in range(len(num))]
for i in dict.keys():
for j in dict.keys():
if dict[i] == dict[j]:
data[i][j] = 0
else:
data[i][j] = 1
arr = np.tril(data, 0)
return arr
def cparr(filename):
'''
标称属性的相异性矩阵
:param filename: 数据集的相对地址
:return:
'''
df = pd.read_csv(filename)
df = pd.DataFrame(df) # .drop(labels=['class'],axis=1)
data_arr = np.array(df)
# for i in range(len(data_arr.T)):
num = data_arr[:, int(len(data_arr.T) - 1)]
data = [i for i in range(len(num))]
dit = dict(zip(data, num))
arr = dir(dit, num)
# arr=pd.DataFrame(arr)
arr = np.array(arr)
np.set_printoptions(threshold=np.inf)
# arr = pd.DataFrame(arr).to_string()
print('标称属性的相异性矩阵为:\n{}'.format(arr))
cparr('../data/1.csv')
运行结果及分析:
两个对象之间的相异性可以由不匹配率计算:,p——对象的总属性数,m——匹配的数目(对象 i,j取值相同的属性数),由于表1中只有一个属性为标称属性,则p=1,公式变为:,则对象 i 和 j 匹配 ,否则 。
运行结果图:
标称属性的相异性矩阵为: [[0 0 0 0] [1 0 0 0] [1 1 0 0] [0 1 1 0]] | 图1 相异性矩阵图 |
二. 相似性矩阵
1. 余弦相似度矩阵
1.建立矩阵
cos_arr = np.zeros((len(arr), len(arr)), float) # 余弦矩阵 长度为12*12 类型为float
2.计算余弦相似度
vector_a = np.mat(x) # 将向量转换为矩阵类型山
vector_b = np.mat(y)
num = float(vector_a * vector_b.T) # 求向量内积,行向量则A* B.Tψ
denom = np.linalg.norm(vector_a) * np.linalg.norm(vector_b)#计算两个点的欧几里得范数乘积4I
cos = num / denom # 求余弦值4
sim = 0.5 + 0.5 * cos# 归一化到[0,1]区间内
3.构建余弦相似度矩阵
for i in range(len(arr)):
for j in range(len(arr)):
cos_arr[i][j]=round(cos_sim1(arr[i], arr[j]), 4)
2. 欧氏距离相似度矩阵
1.建立矩阵
ed_arr = np.zeros((len(arr), len(arr)), float) # 余弦矩阵 长度为12*12 类型为float
2.计算欧氏距离相似度
num = 0
for i in range(len(a)):
num = num + (a[i] - b[i])**2
num = math.sqrt(num)
num = 1 / (1 + num)
3.构建欧氏距离相似度矩阵
for i in range(len(data)):
for j in range(len(data)):
ed_arr[i][j] = round(euclid_Distance(data[i], data[j]), 1)
3. 曼哈顿距离构建相似度矩阵
1.建立矩阵
md_arr = np.zeros((len(arr), len(arr)), float) # 余弦矩阵 长度为12*12 类型为float
2.计算曼哈顿距离相似度
num = 0
for i in range(len(a)):
num = num + abs(a[i] - b[i])
num = math.sqrt(num)
num = 1 / (1 + num)
3.构建曼哈顿距离相似度矩阵
for i in range(len(arr)):
for j in range(len(arr)):
md_arr[i][j] = round(Manhattan_Distance(arr[i], arr[j]), 1)
4.代码总合
import numpy as np
import pandas as pd
import math
np.set_printoptions(linewidth=300) # 控制输出屏幕
def readtxt(filename):
'''
读取txt中的数据
:param filename: txt文件的相对位置
:return: txt文件生成的数据矩阵data_arr
'''
# data=np.loadtxt(,dtype=np.int,delimiter=',')
df = pd.read_table(filename, delim_whitespace=True)
df = pd.DataFrame(df)
data_arr = np.array(df, dtype=float)
return data_arr
def cos_sim1(x, y):
'''
计算余弦相似度
:param x: 向量x
:param y: 向量Y
:return: 向量x和向量Y间余弦余弦相似度
'''
vector_a = np.mat(x) # 将向量转换为矩阵类型山
vector_b = np.mat(y)
num = float(vector_a * vector_b.T) # 求向量内积,行向量则A* B.Tψ
denom = np.linalg.norm(vector_a) * np.linalg.norm(vector_b) # 计算两个点的欧几里得范数乘积4I
cos = num / denom # 求余弦值4
sim = 0.5 + 0.5 * cos # 归一化到[0,1]区间内
return sim
def euclid_Distance(x, y):
'''
计算欧氏距离
:param x: 对象x
:param y: 对象y
:return: 对象x与对象y的欧氏距离
'''
num = 0
for i in range(len(x)):
num = num + (x[i] - y[i]) ** 2
num = math.sqrt(num)
num=1/(1+num)
return num
def Manhattan_Distance(x, y):
'''
计算曼哈顿距离
:param x: 对象x
:param y: 对象y
:return: 对象x与对象y的曼哈顿距离
'''
num = 0
for i in range(len(x)):
num = num + abs(x[i] - y[i])
num = 1 / (1 + num)
return num
def arr(data):
'''
创建矩阵
:param data: 数据矩阵
:return: 矩阵
'''
cos_arr = np.zeros((len(data), len(data)), float) # 余弦矩阵 长度为12*12 类型为float
ed_arr = np.zeros((len(data), len(data)), float) # 余弦矩阵 长度为12*12 类型为float
md_arr = np.zeros((len(data), len(data)), float) # 余弦矩阵 长度为12*12 类型为float
return cos_arr, ed_arr, md_arr
def cos(arr):
'''
构建余弦相似度矩阵,曼哈顿距离构建相似度矩阵
:param arr: 数据矩阵
:return: 余弦相似度矩阵,欧氏距离相似度矩阵,曼哈顿距离构建相似度矩阵
'''
n = int(4) # 保留小数的位数
for i in range(len(arr)):
for j in range(len(arr)):
cos_arr[i][j] = round(cos_sim1(arr[i], arr[j]), n)
ed_arr[i][j] = round(euclid_Distance(arr[i], arr[j]), n)
md_arr[i][j] = round(Manhattan_Distance(arr[i], arr[j]), n)
return cos_arr, ed_arr, md_arr
if __name__ == '__main__':
filename = '../data/Iris_Demo.txt'
data = readtxt(filename)
cos_arr, ed_arr, md_arr = arr(data) # 建立矩阵
cos(data)
print("余弦相似度矩阵:\n{}\n欧氏距离相似度矩阵:\n{}\n曼哈顿距离构建相似度矩阵:\n{}".format(cos_arr, ed_arr, md_arr))