多变量LSTM输入含字符串特征报错,求保留用户ID的解决方案
解决LSTM训练时的数值转换错误(保留UserID实现用户专属预测)
错误原因
你的输入特征X中包含字符串类型的UserID,导致NumPy数组的 dtype 为 object,而TensorFlow的LSTM层只能处理数值型张量,无法完成类型转换,因此抛出ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type int)。
解决方案:保留UserID的数值化处理
要实现用户专属预测,必须将UserID转换为模型可识别的数值类型,推荐两种编码方式:
1. 标签编码(适合用户数量较少的场景)
将每个唯一UserID映射为一个唯一整数,步骤如下:
- 用
LabelEncoder对UserID进行编码 - 修改序列生成函数,使用编码后的数值列构建输入特征
from sklearn.preprocessing import LabelEncoder import numpy as np import pandas as pd # 1. 对UserID做标签编码 le = LabelEncoder() df['UserID_encoded'] = le.fit_transform(df['UserID']) # 2. 修改序列转换函数,使用编码后的UserID和Points def df_to_seq_X_y(df, window_size=5): # 只取编码后的用户ID和Points列 df_as_np = df[['UserID_encoded', 'Points']].to_numpy() X = [] y = [] for i in range(len(df_as_np)-window_size): # 用原UserID判断是否为同一用户,避免编码后数值巧合相等的问题 if df['UserID'].iloc[i] == df['UserID'].iloc[i+window_size]: row = [r for r in df_as_np[i:i+window_size]] X.append(row) label = df_as_np[i+window_size][1] y.append(label) else: continue return np.array(X), np.array(y) # 生成训练/验证数据 X_train, y_train = df_to_seq_X_y(train_df) X_val, y_val = df_to_seq_X_y(val_df) # 验证数据类型:此时X的dtype应为int64/float32,而非object print(X_train.dtype) # 输出应为int64或类似数值类型
2. 嵌入层编码(适合用户数量庞大的场景)
如果用户数量很多,标签编码会让模型错误认为ID数值有大小关系,此时可以用嵌入层单独处理UserID,构建多输入模型:
from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, LSTM, Dense, Embedding, concatenate # 定义两个输入:用户ID序列、积分序列 user_input = Input(shape=(5,), name='user_id_input') points_input = Input(shape=(5,1), name='points_input') # 用户ID嵌入层:假设共有1000个唯一用户,嵌入维度设为8 user_embedding = Embedding(input_dim=1000, output_dim=8)(user_input) # 将嵌入后的用户ID序列与积分序列拼接 concatenated = concatenate([user_embedding, points_input], axis=-1) # LSTM层处理拼接后的序列 lstm_out = LSTM(64)(concatenated) dense1 = Dense(8, activation='relu')(lstm_out) output = Dense(1, activation='linear')(dense1) # 构建多输入模型 model = Model(inputs=[user_input, points_input], outputs=output) # 编译与训练 model.compile(loss=MeanSquaredError(), optimizer=Adam(0.0001), metrics=[RootMeanSquaredError()]) # 注意训练时要传入两个输入:用户ID序列和积分序列 model.fit( [X_train_user_ids, X_train_points], y_train, validation_data=([X_val_user_ids, X_val_points], y_val), epochs=10, callbacks=[cp1] )
验证修改效果
修改后重新生成X,确认其dtype为数值类型(如int64),再运行模型训练代码,即可解决张量转换错误。同时,编码后的UserID保留了用户的身份信息,模型可以学习到不同用户的积分变化规律,实现专属预测。
内容的提问来源于stack exchange,提问作者coumbs
相关产品推荐
相关产品推荐

