基于TensorFlow神经网络绘制情绪预测趋势线的问题排查
问题排查与代码修正
报错原因分析
- StandardScaler特征名警告:你用
StandardScaler拟合时传入的是带列名的DataFrame,但生成趋势线时传入的是无列名的numpy数组,两者格式不匹配触发警告。 - 输入验证失败:用户输入处理逻辑未正确校验数值转换,或输入维度与模型要求不符。
- 趋势线预测失败:绘制单特征趋势线时,未固定其他两个特征的取值(模型需要3个特征输入),导致输入维度错误。
修正后的完整代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt import tensorflow as tf from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split # 1. 数据读取与预处理 df = pd.read_csv('your_data.csv') # 替换为你的CSV文件路径 features = ['mean_sound', 'max_sound', 'min_sound'] target = 'average_mood' X = df[features] y = df[target] # 数据拆分与标准化 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # 2. 构建并训练TensorFlow神经网络 model = tf.keras.Sequential([ tf.keras.layers.Dense(32, activation='relu', input_shape=(3,)), tf.keras.layers.Dense(16, activation='relu'), tf.keras.layers.Dense(1) ]) model.compile(optimizer='adam', loss='mse', metrics=['mae']) model.fit(X_train_scaled, y_train, epochs=50, batch_size=8, validation_split=0.1, verbose=1) # 3. 用户输入处理函数 def get_user_prediction(): try: mean = float(input("输入mean_sound值: ")) max_val = float(input("输入max_sound值: ")) min_val = float(input("输入min_sound值: ")) # 构造带特征名的DataFrame,避免Scaler警告 user_input = pd.DataFrame([[mean, max_val, min_val]], columns=features) user_input_scaled = scaler.transform(user_input) prediction = model.predict(user_input_scaled, verbose=0)[0][0] print(f"预测的average_mood得分: {prediction:.2f}") except ValueError: print("Invalid input. Please enter numeric values.") except Exception as e: print(f"At least one prediction failed. Error: {str(e)}") # 4. 绘制单特征趋势线(神经网络生成) def plot_feature_trend(feature_name): # 固定其他两个特征为训练集的均值 other_features = [f for f in features if f != feature_name] fixed_vals = X_train[other_features].mean().values # 生成当前特征的取值范围(覆盖数据的min到max) feature_min = X_train[feature_name].min() feature_max = X_train[feature_name].max() feature_range = np.linspace(feature_min, feature_max, 100) # 构造完整的输入数据(带特征名的DataFrame) trend_data = [] for val in feature_range: row = {feature_name: val} for f, v in zip(other_features, fixed_vals): row[f] = v trend_data.append(row) trend_df = pd.DataFrame(trend_data) # 标准化后预测 trend_scaled = scaler.transform(trend_df) trend_predictions = model.predict(trend_scaled, verbose=0).flatten() # 绘制散点图+趋势线 plt.figure(figsize=(8,5)) plt.scatter(df[feature_name], df[target], label='原始数据', alpha=0.6) plt.plot(feature_range, trend_predictions, 'r-', linewidth=2, label='神经网络趋势线') plt.xlabel(feature_name) plt.ylabel('average_mood') plt.title(f'{feature_name} 与 average_mood 的关系') plt.legend() plt.grid(True) plt.show() # 运行示例 if __name__ == "__main__": # 绘制三个特征的趋势线 for feat in features: plot_feature_trend(feat) # 启动用户输入预测 get_user_prediction()
关键修正点
- 解决Scaler警告:所有预测输入(包括用户输入和趋势线数据)都用带特征名的DataFrame传递给
scaler.transform(),与拟合时的输入格式一致。 - 趋势线生成逻辑:绘制单个特征的趋势线时,固定另外两个特征为训练集的均值,确保模型接收的是3维输入(符合模型输入要求)。
- 输入验证优化:简化异常捕获逻辑,明确错误类型,同时保证用户输入的格式与模型要求匹配。
- 维度匹配:确保所有输入到模型的数据都是(None, 3)的形状,避免维度不匹配导致的预测失败。
内容的提问来源于stack exchange,提问作者Keilan Noonan Kessie
相关产品推荐
相关产品推荐

