# -*- coding: utf-8 -*- """ @contact: 微信 1257309054 @file: recommend_ncf.py @time: 2024/6/16 22:13 @author: LDC """ import os import django import joblib import numpy as np import pandas as pd import tensorflow as tf from sklearn.metrics import classification_report from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from keras.models import load_model os.environ["DJANGO_SETTINGS_MODULE"] = "course_manager.settings" django.setup() from course.models import * def get_all_data(): ''' 从数据库中获取所有物品评分数据 [用户特征(点赞,收藏,评论, 物品特征(收藏人数,点赞人数,浏览量,评分人数,平均评分) ] ''' # 定义字典列表 user_item_list = [] # 从评分表中获取所有课程数据 item_rates = RateCourse.objects.all().values('course_id').distinct() # 获取每个用户的评分数据 for user in User.objects.all(): user_rate = RateCourse.objects.filter(user=user) if not user_rate: # 用户如果没有评分过任何一本课程则跳过循环 continue data = {'User': f'user_{user.id}'} for br in item_rates: item_id = br['course_id'] ur = user_rate.filter(course_id=item_id) if ur: data[f'item_{item_id}'] = ur.first().mark # 对应课程的评分 else: data[f'item_{item_id}'] = np.nan # 设置成空 user_item_list.append(data) data_pd = pd.DataFrame.from_records(user_item_list) print(data_pd) return data_pd def get_data_vector(data): ''' 对矩阵进行向量化,便于神经网络学习 ''' user_index = data[data.columns[0]] data = data.reset_index(drop=True) data[data.columns[0]] = data.index.astype('int') scaler = 5 # 评分最高为5,把用户的评分归一化到0-1 df_vector = pd.melt(data, id_vars=[data.columns[0]], ignore_index=True, var_name='item_id', value_name='rate').dropna() df_vector.columns = ['user_id', 'item_id', 'rating'] df_vector['rating'] = df_vector['rating'] / scaler df_vector['user_id'] = df_vector['user_
时间: 2025-06-26 11:19:25 浏览: 19
### 基于 Django 和 TensorFlow 的推荐系统中的 NCF 模型数据预处理
构建基于 Django 和 TensorFlow 的推荐系统的重点之一在于数据的预处理和向量化。以下是关于如何针对 NCF (Neural Collaborative Filtering) 模型进行数据预处理的具体说明。
#### 数据准备阶段
在实际应用中,通常会有一个用户-物品交互矩阵作为输入数据源。这些数据可能来自数据库表或其他存储形式,在 Django 中可以通过 ORM 查询获取。假设存在一张记录用户行为的表格 `UserItemInteraction`,其中包含字段 `user_id`, `item_id`, 和其他辅助特征(如评分)。这部分可以利用 Django 的查询功能完成:
```python
from myapp.models import UserItemInteraction
interactions = UserItemInteraction.objects.values('user_id', 'item_id')
data_list = [(interaction['user_id'], interaction['item_id']) for interaction in interactions]
```
此代码片段提取了所有的 `(user_id, item_id)` 对并将其转换成列表结构以便后续操作[^1]。
#### 用户与项目 ID 映射
为了提高效率以及减少内存占用,应将原始字符串或者整数类型的 `user_id` 及 `item_id` 转化为连续编号的形式。这一步骤对于神经网络训练尤为重要因为它们期望接收数值化的张量而非离散对象。
```python
import numpy as np
from sklearn.preprocessing import LabelEncoder
users = [pair[0] for pair in data_list]
items = [pair[1] for pair in data_list]
user_encoder = LabelEncoder()
item_encoder = LabelEncoder()
encoded_users = user_encoder.fit_transform(users)
encoded_items = item_encoder.fit_transform(items)
# 将编码后的结果重新组合起来形成新的样本集
processed_data = list(zip(encoded_users, encoded_items))
```
上述过程通过 Scikit-Learn 提供的 `LabelEncoder` 类实现了从原生ID到索引位置的一一映射关系建立工作[^2]。
#### 构建负采样机制
由于大多数情况下正反馈远少于潜在可选商品数量,因此需要引入适当比例的虚假链接来扩充训练集合大小从而改善泛化性能表现。一种常见做法是在每次迭代过程中动态生成一定数量未发生过关联事件的商品实例加入当前批次当中去充当反面教材角色参与学习进程之中。
```python
def generate_negatives(user_item_set, num_negative=4):
all_items = set(range(len(item_encoder.classes_)))
negative_samples = []
for u,i in processed_data:
negatives = random.sample(all_items.difference({i}), k=num_negative)
negative_samples.extend([(u,neg) for neg in negatives])
return pd.DataFrame(processed_data + negative_samples, columns=['user','item'])
```
这里定义了一个函数用于批量生产指定倍率下的随机负面案例补充至最终版完整资料集中待用作下一步深度计算素材之需所求[^3]。
#### 向量化表示
最后一步就是把前面得到的结果进一步加工成为适合喂给深层架构使用的标准格式——即所谓的嵌入(embedding)层所需的密集矢量表达方式。TensorFlow/Keras API 提供了非常便捷的方法帮助开发者轻松达成这一目标:
```python
from tensorflow.keras.layers import Input, Embedding, Flatten, Concatenate, Dense
from tensorflow.keras.models import Model
num_users = len(np.unique(encoded_users))
num_items = len(np.unique(encoded_items))
embedding_size = 32
input_user = Input(shape=(1,))
input_item = Input(shape=(1,))
emb_layer_user = Embedding(num_users, embedding_size)(input_user)
emb_layer_item = Embedding(num_items, embedding_size)(input_item)
flat_emb_u = Flatten()(emb_layer_user)
flat_emb_i = Flatten()(emb_layer_item)
merged_vector = Concatenate()([flat_emb_u, flat_emb_i])
dense_output = Dense(64, activation='relu')(merged_vector)
output_layer = Dense(1, activation='sigmoid')(dense_output)
model = Model(inputs=[input_user, input_item], outputs=output_layer)
model.compile(optimizer="adam", loss="binary_crossentropy")
X_train = df[['user', 'item']].values
y_train = ... # Labels indicating positive or negative samples.
history = model.fit(X_train, y_train, epochs=5, batch_size=256)
```
以上展示了完整的端到端解决方案概述,涵盖了从原始日志解析直至搭建好可供调优优化的基础预测引擎为止的关键环节要点介绍[^4]。
---
阅读全文