-
Notifications
You must be signed in to change notification settings - Fork 539
/
Copy pathrun_dssm_negsampling.py
113 lines (87 loc) · 4.68 KB
/
run_dssm_negsampling.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import pandas as pd
from deepctr.feature_column import SparseFeat, VarLenSparseFeat
from deepmatch.models import *
from preprocess import gen_data_set, gen_model_input
from sklearn.preprocessing import LabelEncoder
from tensorflow.python.keras.models import Model
if __name__ == "__main__":
data = pd.read_csvdata = pd.read_csv("./movielens_sample.txt")
sparse_features = ["movie_id", "user_id",
"gender", "age", "occupation", "zip", "genres"]
SEQ_LEN = 50
negsample = 10
# 1.Label Encoding for sparse features,and process sequence features with `gen_date_set` and `gen_model_input`
feature_max_idx = {}
for feature in sparse_features:
lbe = LabelEncoder()
data[feature] = lbe.fit_transform(data[feature]) + 1
feature_max_idx[feature] = data[feature].max() + 1
user_profile = data[["user_id", "gender", "age", "occupation", "zip"]].drop_duplicates('user_id')
item_profile = data[["movie_id", "genres"]].drop_duplicates('movie_id')
user_profile.set_index("user_id", inplace=True)
user_item_list = data.groupby("user_id")['movie_id'].apply(list)
train_set, test_set = gen_data_set(data, SEQ_LEN, negsample)
train_model_input, train_label = gen_model_input(train_set, user_profile, SEQ_LEN)
test_model_input, test_label = gen_model_input(test_set, user_profile, SEQ_LEN)
# 2.count #unique features for each sparse field and generate feature config for sequence feature
embedding_dim = 32
user_feature_columns = [SparseFeat('user_id', feature_max_idx['user_id'], 16),
SparseFeat("gender", feature_max_idx['gender'], 16),
SparseFeat("age", feature_max_idx['age'], 16),
SparseFeat("occupation", feature_max_idx['occupation'], 16),
SparseFeat("zip", feature_max_idx['zip'], 16),
VarLenSparseFeat(SparseFeat('hist_movie_id', feature_max_idx['movie_id'], embedding_dim,
embedding_name="movie_id"), SEQ_LEN, 'mean', 'hist_len'),
VarLenSparseFeat(SparseFeat('hist_genres', feature_max_idx['genres'], embedding_dim,
embedding_name="genres"), SEQ_LEN, 'mean', 'hist_len'),
]
item_feature_columns = [SparseFeat('movie_id', feature_max_idx['movie_id'], embedding_dim),
SparseFeat('genres', feature_max_idx['genres'], embedding_dim)
]
# 3.Define Model and train
import tensorflow as tf
if tf.__version__ >= '2.0.0':
tf.compat.v1.disable_eager_execution()
else:
K.set_learning_phase(True)
model = DSSM(user_feature_columns, item_feature_columns, loss_type="logistic")
# model = FM(user_feature_columns,item_feature_columns)
model.compile(optimizer='adagrad', loss="binary_crossentropy")
history = model.fit(train_model_input, train_label,
batch_size=256, epochs=1, verbose=1, validation_split=0.0, )
# 4. Generate user features for testing and full item features for retrieval
test_user_model_input = test_model_input
all_item_model_input = {"movie_id": item_profile['movie_id'].values, "genres": item_profile['genres'].values}
user_embedding_model = Model(inputs=model.user_input, outputs=model.user_embedding)
item_embedding_model = Model(inputs=model.item_input, outputs=model.item_embedding)
user_embs = user_embedding_model.predict(test_user_model_input, batch_size=2 ** 12)
item_embs = item_embedding_model.predict(all_item_model_input, batch_size=2 ** 12)
print(user_embs.shape)
print(item_embs.shape)
# 5. [Optional] ANN search by faiss and evaluate the result
# test_true_label = {line[0]:[line[1]] for line in test_set}
#
# import numpy as np
# import faiss
# from tqdm import tqdm
# from deepmatch.utils import recall_N
#
# index = faiss.IndexFlatIP(embedding_dim)
# # faiss.normalize_L2(item_embs)
# index.add(item_embs)
# # faiss.normalize_L2(user_embs)
# D, I = index.search(user_embs, 50)
# s = []
# hit = 0
# for i, uid in tqdm(enumerate(test_user_model_input['user_id'])):
# try:
# pred = [item_profile['movie_id'].values[x] for x in I[i]]
# filter_item = None
# recall_score = recall_N(test_true_label[uid], pred, N=50)
# s.append(recall_score)
# if test_true_label[uid] in pred:
# hit += 1
# except:
# print(i)
# print("recall", np.mean(s))
# print("hr", hit / len(test_user_model_input['user_id']))