Yelp 数据集进行用户画像, 使用聚类做推荐-yelp_academic_dataset_business.json:包含了Yelp商家信息的数据

时间:2024-10-31 07:34:00

特征工程

用户特征

可以从用户数据和评论数据中提取以下特征:

  • 基本信息: 用户 ID、姓名、注册时间、城市等。
  • 行为特征:
    • 评论数量
    • 平均评分
    • 最高评分和最低评分
    • 喜欢的商家类型(通过评论的商家类别)
# 示例:计算用户特征
user_profile = reviews.groupby('user_id').agg({
    'stars': ['count', 'mean', 'max', 'min'],
    'business_id': 'nunique'
}).reset_index()

user_profile.columns = ['user_id', 'review_count', 'average_stars', 'max_stars', 'min_stars', 'unique_business_count']
商家偏好
  • 用户喜欢的商家类型: 通过评论的商家类别统计用户的偏好。
# 示例:用户偏好商家类型
user_business_types = reviews.merge(business[['business_id', 'categories']], on='business_id')
user_business_types['categories'] = user_business_types['categories'].str.split(', ')
user_business_types = user_business_types.explode('categories')

user_preference = user_business_types.groupby('user_id')['categories'].agg(lambda x: x.value_counts().index[0]).reset_index()
user_preference.columns = ['user_id', 'preferred_category']

可视化用户画像

使用 Matplotlib 或 Seaborn 可视化用户特征:

import seaborn as sns
import matplotlib.pyplot as plt

# 示例:绘制用户评分分布
sns.histplot(user_profile['average_stars'], bins=5, kde=True)
plt.title('Average Stars Distribution')
plt.xlabel('Average Stars')
plt.ylabel('Frequency')
plt.show()

整理功能,优化代码并运行

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 加载数据
users = pd.read_json('yelp_academic_dataset_user.json', lines=True)
reviews = pd.read_json('yelp_academic_dataset_review.json', lines=True)
business = pd.read_json('yelp_academic_dataset_business.json', lines=True)

# 选择必要的列以减少内存使用
reviews = reviews[['user_id', 'stars', 'business_id']]
business = business[['business_id', 'categories']]

# 数据处理与特征工程
# 计算用户特征
user_profile = reviews.groupby('user_id').agg({
    'stars': ['count', 'mean', 'max', 'min'],
    'business_id': 'nunique'
}).reset_index()

user_profile.columns = ['user_id', 'review_count', 'average_stars', 'max_stars', 'min_stars', 'unique_business_count']

# 用户偏好商家类型
user_business_types = (
    reviews.merge(business, on='business_id')
    .assign(categories=lambda x: x['categories'].str.split(', '))
    .explode('categories')
)

# 处理可能为空的组
def get_most_common_category(x):
    if x.empty:
        return None  # 返回 None 或者一个默认值
    # 计算类别的最常见值
    counts = x.value_counts()
    if counts.empty:
        return None  # 如果没有值,返回 None
    return counts.idxmax()

user_preference = user_business_types.groupby('user_id')['categories'].agg(get_most_common_category).reset_index()
user_preference.columns = ['user_id', 'preferred_category']

# 可视化用户评分分布
plt.figure(figsize=(10, 6))
sns.histplot(user_profile['average_stars'], bins=5, kde=True)
plt.title('Average Stars Distribution')
plt.xlabel('Average Stars')
plt.ylabel('Frequency')

# 保存图像到当前目录
plt.savefig('average_stars_distribution.png')

# 显示图像(可选)
plt.show()

结果

进一步分析

  • 聚类分析: 使用 K-means 或其他聚类算法,根据用户特征将用户分为不同群体。根据用户画像,建立推荐系统为用户推荐商家。

使用scikit-learn进行训练

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
import joblib

# 加载数据
users = pd.read_json('yelp_academic_dataset_user.json', lines=True)
reviews = pd.read_json('yelp_academic_dataset_review.json', lines=True)
business = pd.read_json('yelp_academic_dataset_business.json', lines=True)

# 选择必要的列以减少内存使用
reviews = reviews[['user_id', 'stars', 'business_id']]
business = business[['business_id', 'categories']]

# 数据处理与特征工程
user_profile = reviews.groupby('user_id').agg({
    'stars': ['count', 'mean', 'max', 'min'],
    'business_id': 'nunique'
}).reset_index()

user_profile.columns = ['user_id', 'review_count', 'average_stars', 'max_stars', 'min_stars', 'unique_business_count']

# 进行 K-means 聚类
features = user_profile[['review_count', 'average_stars', 'max_stars', 'min_stars', 'unique_business_count']]
scaler = StandardScaler()
scaled_features = scaler.fit_transform(features)

# 应用 K-means
kmeans = KMeans(n_clusters=3, random_state=42)  # 选择3个集群
user_profile['cluster'] = kmeans.fit_predict(scaled_features)

# 保存模型和标准化器
joblib.dump(kmeans, 'kmeans_model.pkl')
joblib.dump(scaler, 'scaler.pkl')

# 保存用户聚类结果
user_profile.to_csv('user_profile_with_clusters.csv', index=False)

kmeans_model.pkl

  • 作用: 保存训练后的 K-means 聚类模型。
  • 内容: 包含了聚类中心、聚类标签和模型的其他参数。通过这个文件,你可以在不需要重新训练模型的情况下,使用已经训练好的模型进行预测。
  • 使用场景: 当你需要对新的用户数据进行聚类或获取已经聚类的用户群体时,加载这个文件即可。

scaler.pkl

  • 作用: 保存数据标准化器(StandardScaler)。
  • 内容: 包含了用于标准化特征的数据(均值和标准差)。在训练模型时,特征需要被标准化,以确保不同特征的尺度一致。
  • 使用场景: 当你需要对新的用户特征进行预处理时,可以加载这个文件使用相同的标准化参数,以确保新数据的标准化与训练数据一致。

使用模型预测推荐代码

import pandas as pd
import joblib

# 加载数据
reviews = pd.read_json('yelp_academic_dataset_review.json', lines=True)
business = pd.read_json('yelp_academic_dataset_business.json', lines=True)

# 加载训练好的模型和标准化器
kmeans = joblib.load('kmeans_model.pkl')
scaler = joblib.load('scaler.pkl')
user_profile = pd.read_csv('user_profile_with_clusters.csv')

# 基于聚类推荐商家
def recommend_business(user_id):
    # 获取用户的聚类
    user_cluster = user_profile[user_profile['user_id'] == user_id]['cluster'].values[0]
    
    # 找到同类用户
    cluster_users = user_profile[user_profile['cluster'] == user_cluster]['user_id']
    
    # 推荐该集群内其他用户高频评价的商家
    recommended_businesses = reviews[reviews['user_id'].isin(cluster_users)]['business_id'].value_counts().head(5)
    
    return recommended_businesses.index.tolist()

# 示例:为某个用户推荐商家
sample_user_id = user_profile['user_id'].iloc[0]
recommended_businesses = recommend_business(sample_user_id)

print(f"Recommended businesses for user {sample_user_id}: {recommended_businesses}")

返回推荐的business

Recommended businesses for user ---1lKK3aKOuomHnwAkAow: ['_ab50qdWOk0DdB6XOrBitw', 'ac1AeYqs8Z4_e2X5M3if2A', 'GXFMD0Z4jEVZBCsbPf4CTQ', 'ytynqOUb3hjKeJfRj5Tshw', 'oBNrLz4EDhiscSlbOl8uAw']