本文目录导读:

我来详细介绍如何使用Scikit-learn计算杰卡德相似度。
基础杰卡德相似度计算
使用pairwise_distances
import numpy as np
from sklearn.metrics import pairwise_distances
# 创建示例数据(二进制向量)
X = np.array([
[1, 0, 1, 1, 0], # 样本1
[1, 1, 0, 1, 0], # 样本2
[0, 1, 1, 0, 1], # 样本3
[1, 1, 1, 1, 1] # 样本4
])
# 计算杰卡德距离(1 - 杰卡德相似度)
jaccard_distances = pairwise_distances(X, metric='jaccard')
# 转换为杰卡德相似度
jaccard_similarity = 1 - jaccard_distances
print("杰卡德距离矩阵:")
print(jaccard_distances)
print("\n杰卡德相似度矩阵:")
print(jaccard_similarity)
两两样本相似度计算
使用自定义函数
from sklearn.metrics import jaccard_score
def jaccard_similarity_two_sets(set1, set2):
"""计算两个集合的杰卡德相似度"""
intersection = len(set1 & set2)
union = len(set1 | set2)
return intersection / union if union > 0 else 0
# 示例:用户购买记录
user1_bought = {'苹果', '香蕉', '牛奶', '面包'}
user2_bought = {'苹果', '牛奶', '鸡蛋', '可乐'}
user3_bought = {'面包', '牛奶', '薯片', '可乐'}
# 计算用户之间的相似度
users = [user1_bought, user2_bought, user3_bought]
user_names = ['用户A', '用户B', '用户C']
print("用户购买行为相似度:")
for i in range(len(users)):
for j in range(i+1, len(users)):
sim = jaccard_similarity_two_sets(users[i], users[j])
print(f"{user_names[i]} 与 {user_names[j]}: {sim:.3f}")
实际应用案例
文本相似度分析
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import pairwise_distances
# 示例文档
documents = [
"机器学习是人工智能的重要分支",
"深度学习是机器学习的一个分支",
"自然语言处理使用机器学习技术",
"计算机视觉是人工智能的重要领域"
]
# 转换为词袋模型
vectorizer = CountVectorizer(token_pattern=r'\w+')
X = vectorizer.fit_transform(documents)
# 计算杰卡德相似度
jaccard_dist = pairwise_distances(X.toarray(), metric='jaccard')
jaccard_sim = 1 - jaccard_dist
print("文档相似度矩阵(杰卡德相似度):")
print(np.round(jaccard_sim, 3))
商品推荐系统
from sklearn.metrics import pairwise_distances
import pandas as pd
# 模拟用户-商品购买矩阵
purchase_data = {
'用户1': [1, 0, 1, 1, 0, 1],
'用户2': [1, 1, 0, 1, 1, 0],
'用户3': [0, 1, 1, 0, 1, 1],
'用户4': [1, 0, 1, 0, 0, 1]
}
products = ['商品A', '商品B', '商品C', '商品D', '商品E', '商品F']
df = pd.DataFrame(purchase_data, index=products).T
# 计算用户间的杰卡德相似度
user_similarity = 1 - pairwise_distances(df, metric='jaccard')
# 创建相似度DataFrame
similarity_df = pd.DataFrame(
user_similarity,
index=['用户1', '用户2', '用户3', '用户4'],
columns=['用户1', '用户2', '用户3', '用户4']
)
print("用户相似度矩阵:")
print(similarity_df.round(3))
# 推荐函数
def recommend_items(user_name, df, similarity_df, top_n=2):
"""基于相似用户推荐商品"""
# 获取相似度最高的用户(排除自己)
similar_user = similarity_df[user_name].sort_values(ascending=False)
similar_user = similar_user[1:] # 排除自己
# 获取目标用户已购买的商品
user_items = set(df.columns[df.loc[user_name] == 1])
# 查找相似用户购买但目标用户未购买的商品
recommendations = []
for user in similar_user.index:
user_purchased = set(df.columns[df.loc[user] == 1])
new_items = user_purchased - user_items
recommendations.extend(new_items)
# 返回推荐列表
return list(set(recommendations))[:top_n]
# 测试推荐
user = '用户1'
recommendations = recommend_items(user, df, similarity_df)
print(f"\n给{user}推荐的商品:{recommendations}")
处理不同类型的数据
二值化数据后进行相似度计算
from sklearn.preprocessing import Binarizer
from sklearn.metrics import pairwise_distances
# 原始数值数据
data = np.array([
[3.5, 2.1, 5.0, 1.2],
[4.1, 1.8, 3.2, 2.5],
[2.0, 3.5, 1.0, 4.0]
])
# 二值化处理(大于阈值设为1,否则为0)
binarizer = Binarizer(threshold=2.5)
binary_data = binarizer.fit_transform(data)
print("原始数据:")
print(data)
print("\n二值化后数据:")
print(binary_data)
# 计算杰卡德相似度
jaccard_sim = 1 - pairwise_distances(binary_data, metric='jaccard')
print("\n二值化后的杰卡德相似度:")
print(np.round(jaccard_sim, 3))
性能优化和注意事项
import time
from sklearn.metrics import pairwise_distances
def compare_similarity_methods(X):
"""比较不同计算方法的性能"""
# 方法1:计算完整距离矩阵
start = time.time()
full_dist = pairwise_distances(X, metric='jaccard')
full_sim = 1 - full_dist
t1 = time.time() - start
# 方法2:只计算上三角
start = time.time()
n_samples = X.shape[0]
similarities = []
for i in range(n_samples):
for j in range(i+1, n_samples):
# 直接计算杰卡德相似度
intersection = np.sum(np.logical_and(X[i], X[j]))
union = np.sum(np.logical_or(X[i], X[j]))
sim = intersection / union if union > 0 else 0
similarities.append(sim)
t2 = time.time() - start
print(f"完整矩阵计算时间:{t1:.4f}秒")
print(f"循环计算时间:{t2:.4f}秒")
print(f"性能提升:{t2/t1:.2f}倍")
# 测试性能
np.random.seed(42)
test_data = np.random.randint(0, 2, size=(100, 50))
compare_similarity_methods(test_data)
- 推荐系统:基于用户行为相似度进行推荐
- 文本分析:文档相似度计算
- 生物信息学:基因序列相似度分析
- 社交网络:用户兴趣相似度
- 图像识别:特征二值化后比较
使用Scikit-learn的杰卡德相似度计算简单高效,特别适合处理二进制特征的数据。