Python案例如何用Scikit-learn做杰卡德相似

wen python案例 2

本文目录导读:

Python案例如何用Scikit-learn做杰卡德相似

  1. 基础杰卡德相似度计算
  2. 两两样本相似度计算
  3. 实际应用案例
  4. 处理不同类型的数据
  5. 性能优化和注意事项

我来详细介绍如何使用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)
  1. 推荐系统:基于用户行为相似度进行推荐
  2. 文本分析:文档相似度计算
  3. 生物信息学:基因序列相似度分析
  4. 社交网络:用户兴趣相似度
  5. 图像识别:特征二值化后比较

使用Scikit-learn的杰卡德相似度计算简单高效,特别适合处理二进制特征的数据。

抱歉,评论功能暂时关闭!