首页 > 解决方案 > 电影推荐系统:预计会看到 2 个数组,但得到了以下 1 个数组的列表

问题描述

我对机器学习完全陌生,我一直在尝试使用 keras 制作电影推荐系统,我一直在关注在线教程,但我不明白为什么会出现以下错误:ValueError: Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 arrays: [array([[130767], [ 110]], dtype=int32)]... 我知道它有一些东西与输入形状有关,但我一直在寻找 6 个连续小时,但我仍然无法理解出了什么问题,任何帮助将不胜感激,非常感谢 =)

import numpy as np
import pandas as pd
import os
from os import path
import matplotlib.pyplot as plt
from keras.models import Model
from keras.models import load_model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from keras.layers import Input, Reshape, Dot
from keras.layers.embeddings import Embedding
from keras.optimizers import Adam
from keras.regularizers import l2
from keras.layers import Add, Activation, Lambda
PATH = './ml-20m/'

ratings = pd.read_csv(PATH + 'ratings.csv')
# print(ratings.head(n=10))

movies = pd.read_csv(PATH + 'movies.csv')
# print(movies.head(n=10))

g = ratings.groupby('userId')['rating'].count()
top_users = g.sort_values(ascending=False)[:15]

g = ratings.groupby('movieId')['rating'].count()
top_movies = g.sort_values(ascending=False)[:15]

top_r = ratings.join(top_users, rsuffix='_r', how='inner', on='userId')
top_r = top_r.join(top_movies, rsuffix='_r', how='inner', on='movieId')
# print(pd.crosstab(top_r.userId, top_r.movieId, top_r.rating, aggfunc=np.sum))

user_enc = LabelEncoder()
ratings['user'] = user_enc.fit_transform(ratings['userId'].values)
n_users = ratings['user'].nunique()

item_enc = LabelEncoder()
ratings['movie'] = item_enc.fit_transform(ratings['movieId'].values)
n_movies = ratings['movie'].nunique()
ratings['rating'] = ratings['rating'].values.astype(np.float32)
min_rating = min(ratings['rating'])
max_rating = max(ratings['rating'])

X = ratings[['user', 'movie']].values
y = ratings['rating'].values
X = X[:90003]
y = y[:90003]
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.1, random_state=42)

n_factors = 50
X_train_array = [X_train[:, 0], X_train[:, 1]]
X_test_array = [X_test[:, 0], X_test[:, 1]]


def RecommenderV1(n_users, n_movies, n_factors):
    user = Input(shape=(1,))
    u = Embedding(n_users, n_factors, embeddings_initializer='he_normal',
                  embeddings_regularizer=l2(1e-6))(user)
    u = Reshape((n_factors,))(u)

    movie = Input(shape=(1,))
    m = Embedding(n_movies, n_factors, embeddings_initializer='he_normal',
                  embeddings_regularizer=l2(1e-6))(movie)
    m = Reshape((n_factors,))(m)

    x = Dot(axes=1)([u, m])
    model = Model(inputs=[user, movie], outputs=x)
    opt = Adam(lr=0.001)
    model.compile(loss='mean_squared_error', optimizer=opt)
    return model


model = RecommenderV1(n_users, n_movies, n_factors)
# model.summary()

if(os.path.exists('recommendation_model.h5')):
    model = load_model('recommendation_model.h5')
else:
    history = model.fit(x=X_train_array, y=y_train, batch_size=64, epochs=10,verbose=1, validation_data=(X_test_array, y_test))
    model.save("recommendation_model.h5")
    # plt.plot(history.history['loss'])
    # plt.xlabel("Epochs")
    # plt.ylabel('Training Error')
while(True):
    # text = input("Please enter your input\n")
    # numbers = text.split(' ')
    # userID = int(numbers[0])
    # movieID = int(numbers[1])
    # inputArray = np.array((np.array(userID), np.array(movieID)))
    # test_val = np.array(([userID], [movieID]))
    # userID = np.array(130767)
    # movieID = np.array(110)
    inArr = np.array([[130767], [110]], np.int32)
    print(inArr.shape)
    result = model.predict(inArr)
    print(result)
    # print(test_val)
    # print(inputArray.shape)
    print('---------------------------------------------------------')

标签: pythonkeras

解决方案


据我了解,模型需要一个包含两个 numpy 数组的列表,而您将单个 numpy 数组传递给模型。我认为您应该更改inArr = np.array([[130767], [110]], np.int32)inArr = [np.array([130767]),np.array([110]),这样现在您将在列表中传递两个 numpy 数组而不是一个数组.
希望能帮助到你。


推荐阅读