Я строю простую систему рекомендаций книг , чтобы изучать методы и технику на местах. Мой dataFrame выглядит следующим образом (упрощенный пример):
type username product publishing_dt
0 access 45michael 63767 2020-01-01
1 access 7762hc 84325 2018-04-03
2 access adrian12 997165 2016-02-01
3 access kerrigan 5467 2020-01-24
4 access kerrigan 78921 2019-11-03
5 access kerrigan 86833 2020-02-04
6 access kerrigan 130365 2020-02-10
7 access yvera 76863 2019-10-04
8 order 45michael 76863 2019-10-04
9 order 45michael 86833 2020-02-04
10 order 45michael 130365 2020-02-10
11 order alicia7 130365 2020-02-10
12 order angel8 86217 2017-01-06
13 order john5 86833 2020-02-04
14 order john5 130365 2020-02-10
15 order kerrigan 76863 2019-10-04
Где type указывает, была ли это покупка (заказ) или это был простой просмотр файла книги (доступ) , username - это идентификатор пользователя, который совершил покупку или получил доступ к файлу книги, product - это идентификатор книги, которую пользователь приобрел или получил доступ, и publishing_dt дата выпуска рассматриваемой книги.
Мои исходные данные имеют такую форму: (35207, 10), есть 10 столбцов, так как есть больше полей, таких как: число - если тип является доступом, это указывает, сколько раз пользователь обращался к файлу, модель - если это печатная книга или электронная книга, жанры - указывает различные жанры каждой книги, order_date - если тип является заказом, это указывает дату, когда был сделан заказ, цена - сколько стоит книга ...
Я только что показал в примере DataFrame поля, которые, на мой взгляд, более важны для этой проблемы.
Мой оригинальный подход к индикаторам т. е. если я хочу получить рекомендации для элементов (для рекомендаций на основе элементов) или рекомендации для пользователей (чтобы я мог проверить заказанные ими книги и рекомендовать их другим пользователям). Я построил новый столбец (число) в кадре данных следующим образом:
order_df = order_df.groupby(['type','username','product', 'publishing_dt']).size().reset_index(name='count')
order_df['count'] = order_df['type'].apply(lambda x: 1 if x == 'orderline' else 0)
, который присваивает 1, если пользователь купил книгу, или 0, если он не сделал (если это доступ, пользователь не купил книгу), поэтому значения матрицы, которую я использую для алгоритма KNN, имеют элементов в виде строк (в случае рекомендации по элементам), имен пользователей в виде столбцов и значения ячеек это 1 или 0 в зависимости от покупок.
Вот так выглядит моя функция:
def knn_based(item, amount, df):
# Check which matrix has to be built
if type(item) == int:
# Construct matrix with products as index, as an item is being requested
order_products=df.pivot_table(values='count', index='product', columns='username')
else:
# Construct matrix with usernames as index, as an username is being requested
order_products=df.pivot_table(values='count', index='username', columns='product')
# NaN values are replaced by 0
order_products=order_products.fillna(0)
# Transform matrix-dataframe into scipy sparse matrix
order_products_matrix=csr_matrix(order_products.values)
# Specify KNN values
model_knn=NearestNeighbors(metric='cosine', algorithm='brute')
# Fit the algorithm with the scipy matrix
model_knn.fit(df)
# Get the index location of the item/username referenced
query_index = df.index.get_loc(item)
distances, indices = model_knn.kneighbors(df.iloc[query_index,:].values.reshape(1,-1), n_neighbors=6)
I ' я спрашиваю некоторую помощь по как выбрать k для алгоритма, я использую 6, так как это было число, которое было указано в примере, которому я следовал, но с количеством данных, которые у меня есть, я не Не думаю, что это хороший выбор, у меня есть 8830 уникальных продуктов (книги) и 12420 уникальных пользователей , и это должно быть способным расти больше.
Я использую Sklearn для KNN, так как он был прост в использовании, я также проверил Surprise Library, но не был Если кто-то знает, как я на самом деле хотел бы это знать, то можно реализовать его.
Итак, мои вопросы:
- , как правильно выбрать k для количества данных Я имею? (8830 книг, 12420 пользователей)
- Может кто-нибудь подсказать мне, как использовать Surprise для этой проблемы?
- Как я могу использовать KNN для выполнения рекомендаций на основе элементов? (По жанру, цене, ...)