python - 列表元素的相似性

标签 python python-3.x algorithm list

我有十个列表,我想获得它们的“相似性”。这是我的输入:

data = [
    ['RuntimeInMinutes', 'EpisodeNumber', 'Genres', 'ReleaseDate', 'SeasonNumber', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales'], 
    ['RuntimeInMinutes', 'EpisodeNumber', 'Genres', 'ReleaseDate', 'SeasonNumber', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales'], 
    ['RuntimeInMinutes', 'Genres', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', '_StudioName', 'Type', 'LanguageOfMetadata', 'ReleaseDate', 'Studio', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'TVSeriesID', 'Locales', 'EpisodeNumber', 'Name', 'Synopsis', 'Products', 'SeasonNumber', 'Platform'], 
    ['RuntimeInMinutes', 'EpisodeNumber', 'Genres', 'ReleaseDate', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'LanguageOfMetadata', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales'], 
    ['RuntimeInMinutes', 'EpisodeNumber', 'Genres', 'ReleaseDate', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales'], 
    ['RuntimeInMinutes', 'Genres', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', '_StudioName', 'Type', 'LanguageOfMetadata', 'ReleaseDate', 'Studio', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'TVSeriesID', 'Locales', 'EpisodeNumber', 'Name', 'Synopsis', 'Products', 'SeasonNumber', 'Platform'], 
    ['RuntimeInMinutes', 'EpisodeNumber', 'Genres', 'ReleaseDate', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales'], 
    ['RuntimeInMinutes', 'ReleaseDate', 'Genres', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales'], 
    ['RuntimeInMinutes', 'EpisodeNumber', 'Genres', 'ReleaseDate', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales'], 
    ['RuntimeInMinutes', 'EpisodeNumber', 'Genres', 'ReleaseDate', 'Name', 'Platform', 'PlatformID', 'BaseURL', 'Languages', 'ArtworkURL', 'Synopsis', 'TVSeriesID', 'Products', '_NetworkName', 'ReleaseYear', '_ContentProviderName', 'Studio', '_StudioName', 'Type', 'Locales']
]

我目前的方法是将这些值的集合的长度与总长度进行比较。所以在上面它将是:

>>> len(set(data))/len(data)
0.5

然而,这非常粗略,因为我想得到一个不是“全有或全无”的相似性。换句话说,类似于概念上的相似性,上面可能有 98% 的相似性(很抱歉,如果我无法准确解释我在这里想要的东西——但我的意思是评估相似性不仅仅是列表本身,而是其元素的相似性。

最佳答案

看看 datasketch library及其 MinHash 数据结构。这是基于 Jaccard Similarity对于集合,这只是交集(它们的共同点)除以并集(所有可能的元素)。

这是一个例子:

from datasketch import MinHash

data1 = ['minhash', 'is', 'a', 'probabilistic', 'data', 'structure', 'for',
        'estimating', 'the', 'similarity', 'between', 'datasets']
data2 = ['minhash', 'is', 'a', 'probability', 'data', 'structure', 'for',
        'estimating', 'the', 'similarity', 'between', 'documents']

m1, m2 = MinHash(), MinHash()
for d in data1:
    m1.update(d.encode('utf8'))
for d in data2:
    m2.update(d.encode('utf8'))
print("Estimated Jaccard for data1 and data2 is", m1.jaccard(m2))

如果你的集合很大,给你一个相似度的估计。否则,只需使用内置的集合操作:

s1 = set(data1)
s2 = set(data2)
actual_jaccard = float(len(s1.intersection(s2)))/float(len(s1.union(s2)))
print("Actual Jaccard for data1 and data2 is", actual_jaccard)

如果您想获取两个以上集合的 Jaccard 相似度,只需计算成对比较并取所有值的平均值(平均值):

from datasketch import *
import itertools
minhash_data = list()
for element in data:
    m = MinHash()
    for d in element:
        m.update(d.encode('utf-8'))
    minhash_data.append(m)

jaccard_sims = list()
for pair in itertools.combinations(minhash_data, 2):
    jaccard_sims.append(pair[0].jaccard(pair[1]))

average = sum(jaccard_sims) / float(len(jaccard_sims))
print("Average Jaccard similarity: {}".format(average))

Average Jaccard similarity: 0.9512152777777778

关于python - 列表元素的相似性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54599246/

相关文章:

python - Python 的 splat 运算符是……在某一时刻吗?

Python - 将单词分为 3 组

algorithm - 表示小无符号整数的最有效位格式

java - 我在反转这个链表的一部分时做错了什么?

python:如何从自然语言文件中提取记录,只有分隔符是记录开头的 5 个字符

python - Pandas 数据框值相等测试

python-3.x - 根据列名中的匹配字符串对 pandas 单元格(字符串)进行排序

python - python中的方法链延迟执行

python-3.x - 为什么我的 python 不适用于 seaborn

algorithm - 从字符串对中查找未知排列