如何调整Azure ML端点输入变量以适配转换后特征列?
解决Azure Machine Learning端点输入架构不一致问题
问题背景
训练数据集包含unloadInDatetime、unloadOutDatetime这类仅未来可知的列,训练阶段通过Python脚本将原始数据转换为包含标签UnloadingTime和衍生特征的数据集。部署为推理端点后,尝试用以下8列作为输入测试时,出现「输入数据与架构不一致」错误:
toAddressCountryCodetoAddressPostCodeUnloadWeekdayUnloadMonthloadingMeterspayableWeightInTimename
核心原因
当前的转换脚本仅在输入包含unloadInDatetime和unloadOutDatetime时才会生成目标特征列,而推理阶段的输入不包含这两个列,导致脚本进入else分支,返回空DataFrame或未生成符合要求的列,与端点预期的输入架构不匹配。本质是训练阶段的特征工程逻辑和推理阶段的输入处理逻辑脱节。
解决方案
1. 拆分训练与推理的转换逻辑
将原脚本拆分为两个独立的转换函数:
- 训练函数:保留从原始列生成衍生特征和标签的逻辑,适配训练数据。
- 推理函数:直接接收目标输入列,仅做格式校验和统一处理(与训练时的转换规则对齐),适配推理场景。
2. 修改Azure ML脚本
替换原脚本为以下代码:
import pandas as pd def transform_training_data(df): # 训练数据转换逻辑:从原始列生成特征和标签 if 'unloadInDatetime' in df.columns and 'unloadOutDatetime' in df.columns: datetime_format = '%Y-%m-%d %H:%M:%S.%f' df['InDateTime'] = pd.to_datetime(df['unloadInDatetime'], format=datetime_format, errors='coerce') df['OutDateTime'] = pd.to_datetime(df['unloadOutDatetime'], format=datetime_format, errors='coerce') df['InTime'] = df['InDateTime'].dt.hour.astype(int) df['toAddressPostCode'] = df['toAddressPostCode'].str[:5] df['UnloadMonth'] = df['InDateTime'].dt.month df['UnloadWeekday'] = df['InDateTime'].dt.weekday + 1 df['UnloadingTime'] = (df['OutDateTime'] - df['InDateTime']).dt.total_seconds() / 60 df['UnloadingTime'] = df['UnloadingTime'].astype(int) df = df[(df['UnloadingTime'] > 5) & (df['UnloadingTime'] < 300)] df.reset_index(drop=True, inplace=True) df = df[['UnloadingTime', 'toAddressCountryCode', 'toAddressPostCode', 'UnloadWeekday', 'UnloadMonth', 'loadingMeters', 'payableWeight', 'InTime', 'name']] else: print("训练数据缺少unloadInDatetime或unloadOutDatetime列") return df def transform_inference_data(df): # 推理数据转换逻辑:直接处理目标输入列 required_cols = ['toAddressCountryCode', 'toAddressPostCode', 'UnloadWeekday', 'UnloadMonth', 'loadingMeters', 'payableWeight', 'InTime', 'name'] if all(col in df.columns for col in required_cols): # 对齐训练时的格式处理规则 df['toAddressPostCode'] = df['toAddressPostCode'].str[:5] # 确保数据类型与训练一致 df['UnloadWeekday'] = df['UnloadWeekday'].astype(int) df['UnloadMonth'] = df['UnloadMonth'].astype(int) df['InTime'] = df['InTime'].astype(int) df['loadingMeters'] = df['loadingMeters'].astype(float) df['payableWeight'] = df['payableWeight'].astype(float) else: missing_cols = [col for col in required_cols if col not in df.columns] print(f"推理数据缺少必要列:{', '.join(missing_cols)}") df = pd.DataFrame(columns=required_cols) return df def azureml_main(dataframe1=None, dataframe2=None): if dataframe1 is not None: # 根据输入列判断场景:训练/推理 if 'unloadInDatetime' in dataframe1.columns and 'unloadOutDatetime' in dataframe1.columns: df_transformed = transform_training_data(dataframe1) else: df_transformed = transform_inference_data(dataframe1) else: df_transformed = pd.DataFrame() return df_transformed, None
3. 重新部署并验证
- 将修改后的脚本重新发布到Azure ML端点。
- 在端点测试窗口输入指定的8列数据,确保每个列的数据类型与训练时一致(例如
UnloadWeekday为1-7的整数,InTime为0-23的整数)。 - 检查端点的输入架构:在Azure ML工作室确认端点的输入数据集列名、数据类型与目标输入列完全匹配。
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

