测量二进制列表之间的相似性
Measuring similarity between binary lists
我有两个要比较的二进制列表。为了比较,我在每个对应值相等的地方求和并将其转换为百分比:
import numpy as np
l1 = [1,0,1]
l2 = [1,1,1]
print(np.dot(l1 , l2) / len(l1) * 100)
打印 66.666
所以在这种情况下,l1 和 l2 的接近度为 61.666。由于每个列表的相似性较低,因此接近度值会降低。
例如使用值:
l1 = [1,0,1]
l2 = [0,1,0]
returns 0.0
如何绘制描述l1
和l2
之间关系的l1
和l2
?是否有使用此方法测量二进制值之间相似性的名称?
使用散点图:
import matplotlib.pyplot as plt
plt.scatter( 'x', 'y', data=pd.DataFrame({'x': l1, 'y': l2 }))
产生:
但这没有意义吗?
更新:
"if both entries are 0, this will not contribute to your "相似度
使用下面更新的代码来计算相似性,这个更新的相似性度量在计算最终分数时包括相应的 0 值。
import numpy as np
l1 = [0,0,0]
l2 = [0,1,0]
print(len([a for a in np.isclose(l1 , l2) if(a)]) / len(l1) * 100)
其中 returns :
66.66666666666666
或者,对于相同或不同的列表,将下面的代码与度量 normalized_mutual_info_score
returns 1.0 一起使用,因此 normalized_mutual_info_score
不是合适的相似性度量 ?
from sklearn.metrics.cluster import normalized_mutual_info_score
l1 = [1,0,1]
l2 = [0,1,0]
print(normalized_mutual_info_score(l1 , l2))
l1 = [0,0,0]
l2 = [0,0,0]
print(normalized_mutual_info_score(l1 , l2))
打印:
1.0
1.0
不对,剧情没有意义。你所做的本质上是向量之间的内积。根据这个度量,l1
和 l2
应该是 3D 中的向量(在这种情况下)space,这衡量它们是否面向相同的相似方向并且具有相似的长度。输出是一个标量值,所以没有什么可绘制的。
如果您想显示每个组件的单独贡献,您可以做类似
的事情
contributions = [a==b for a, b in zip(l1, l2)]
plt.plot(list(range(len(contributions)), contributions)
但我仍然不确定这是否有意义。
import numpy as np
import matplotlib.pyplot as plt
def unpackbits(a, n):
''' Unpacks an integer `a` to n-length binary list. '''
return [a >> i & 1 for i in range(n-1,-1,-1)]
def similarity(a, b, n):
''' Similarity between n-length binary lists obtained from unpacking
the integers a and b. '''
a_unpacked = unpackbits(a, n)
b_unpacked = unpackbits(b, n)
return np.sum(np.isclose(a_unpacked, b_unpacked))/n
# Plot
n = 3
x = np.arange(2**n+1)
y = np.arange(2**n+1)
xx, yy = np.meshgrid(x, x)
z = np.vectorize(similarity)(yy[:-1,:-1], xx[:-1,:-1], n)
labels = [unpackbits(i, n) for i in x]
cmap = plt.cm.get_cmap('binary', n+1)
fig, ax = plt.subplots()
pc = ax.pcolor(x, y, z, cmap=cmap, edgecolor='k', vmin = 0, vmax=1)
ax.set_xticks(x + 0.5)
ax.set_yticks(y + 0.5)
ax.set_xlim(0, 2**n)
ax.set_ylim(0, 2**n)
ax.set_xticklabels(labels, rotation=45)
ax.set_yticklabels(labels)
cbar = fig.colorbar(pc, ax=ax, ticks=[i/n for i in range(n+1)])
cbar.ax.set_ylabel('similarity', fontsize=14)
ax.set_aspect('equal', adjustable='box')
plt.tight_layout()
plt.show()
我有两个要比较的二进制列表。为了比较,我在每个对应值相等的地方求和并将其转换为百分比:
import numpy as np
l1 = [1,0,1]
l2 = [1,1,1]
print(np.dot(l1 , l2) / len(l1) * 100)
打印 66.666
所以在这种情况下,l1 和 l2 的接近度为 61.666。由于每个列表的相似性较低,因此接近度值会降低。
例如使用值:
l1 = [1,0,1]
l2 = [0,1,0]
returns 0.0
如何绘制描述l1
和l2
之间关系的l1
和l2
?是否有使用此方法测量二进制值之间相似性的名称?
使用散点图:
import matplotlib.pyplot as plt
plt.scatter( 'x', 'y', data=pd.DataFrame({'x': l1, 'y': l2 }))
产生:
但这没有意义吗?
更新:
"if both entries are 0, this will not contribute to your "相似度
使用下面更新的代码来计算相似性,这个更新的相似性度量在计算最终分数时包括相应的 0 值。
import numpy as np
l1 = [0,0,0]
l2 = [0,1,0]
print(len([a for a in np.isclose(l1 , l2) if(a)]) / len(l1) * 100)
其中 returns :
66.66666666666666
或者,对于相同或不同的列表,将下面的代码与度量 normalized_mutual_info_score
returns 1.0 一起使用,因此 normalized_mutual_info_score
不是合适的相似性度量 ?
from sklearn.metrics.cluster import normalized_mutual_info_score
l1 = [1,0,1]
l2 = [0,1,0]
print(normalized_mutual_info_score(l1 , l2))
l1 = [0,0,0]
l2 = [0,0,0]
print(normalized_mutual_info_score(l1 , l2))
打印:
1.0
1.0
不对,剧情没有意义。你所做的本质上是向量之间的内积。根据这个度量,l1
和 l2
应该是 3D 中的向量(在这种情况下)space,这衡量它们是否面向相同的相似方向并且具有相似的长度。输出是一个标量值,所以没有什么可绘制的。
如果您想显示每个组件的单独贡献,您可以做类似
的事情contributions = [a==b for a, b in zip(l1, l2)]
plt.plot(list(range(len(contributions)), contributions)
但我仍然不确定这是否有意义。
import numpy as np
import matplotlib.pyplot as plt
def unpackbits(a, n):
''' Unpacks an integer `a` to n-length binary list. '''
return [a >> i & 1 for i in range(n-1,-1,-1)]
def similarity(a, b, n):
''' Similarity between n-length binary lists obtained from unpacking
the integers a and b. '''
a_unpacked = unpackbits(a, n)
b_unpacked = unpackbits(b, n)
return np.sum(np.isclose(a_unpacked, b_unpacked))/n
# Plot
n = 3
x = np.arange(2**n+1)
y = np.arange(2**n+1)
xx, yy = np.meshgrid(x, x)
z = np.vectorize(similarity)(yy[:-1,:-1], xx[:-1,:-1], n)
labels = [unpackbits(i, n) for i in x]
cmap = plt.cm.get_cmap('binary', n+1)
fig, ax = plt.subplots()
pc = ax.pcolor(x, y, z, cmap=cmap, edgecolor='k', vmin = 0, vmax=1)
ax.set_xticks(x + 0.5)
ax.set_yticks(y + 0.5)
ax.set_xlim(0, 2**n)
ax.set_ylim(0, 2**n)
ax.set_xticklabels(labels, rotation=45)
ax.set_yticklabels(labels)
cbar = fig.colorbar(pc, ax=ax, ticks=[i/n for i in range(n+1)])
cbar.ax.set_ylabel('similarity', fontsize=14)
ax.set_aspect('equal', adjustable='box')
plt.tight_layout()
plt.show()