我想使用多个PMMLS来将数据转换和模型应用分开。以下是我正在使用的代码。我这样做是因为我想对我的数据进行某种缩尾处理。
train_stats = {}
continous_domains = []
for cont in con_vars:
# REMOVE -1 values to not distort the quantiles
cont_val = np.asarray(train_data_sub[train_data_sub[cont] != -1][cont])
_95 = np.percentile(cont_val[~np.isnan(cont_val)], 95)
_05 = np.percentile(cont_val[~np.isnan(cont_val)], 5)
_50 = np.percentile(cont_val[~np.isnan(cont_val)], 50)
train_stats[cont] = [_05, _50, _95]
continous_domains.append(
([cont], [
ContinuousDomain(
missing_values = [-1],
missing_value_treatment="as_value",
missing_value_replacement= _50,
outlier_treatment ='as_extreme_values',
low_value = _05,
high_value = _95,
dtype = float
)
]))
data_mapper = DataFrameMapper(continous_domains, df_out=True)
data_mapper.fit(train_data_sub)
data_mapper.transform(train_data_sub)
pmml_pipeline = PMMLPipeline(steps = [
('DataframeMapper', data_mapper)])
path_name = f"Trafo_{str(datetime.now().strftime('%Y_%m_%d_%H-%M'))}.pmml"
sklearn2pmml(pmml_pipeline, path_name, debug=True)
它有点工作,但返回的 .pmml 文件仅包含数据字典,没有设置的高/低值等规范。
有趣的是,当我将 LogisticRegression 放入管道中时,我得到了一个看起来正确的 PMML,但那里我只有两个输出,实际上我只想从 Dataframe Mapper 获取所有转换后的值。
有人可以帮我吗?真的很难找到解决方案。
非常感谢您并致以诚挚的问候
保罗
返回的.pmml文件仅包含数据字典,不包含设置的高/低值等规范
域规范存储在 PMML 文档内的两个位置。
首先,某些输入值是否有效的决定被编码到
/PMML/DataDictionary/DataField
元素中。例如,指定“Sepal.Length”仅接受 [4.3, 7.9]
范围内的值:
<DataField name="Sepal_Length" displayName="Sepal length in cm" optype="continuous" dataType="double">
<Interval closure="closedClosed" leftMargin="4.3" rightMargin="7.9"/>
</DataField>
其次,决定任何给定模型应如何处理预分类的输入值(即有效/无效/缺失)。这被编码到
/PMML/<Model>/MiningSchema/MiningField
元素中。例如,指定不允许无效值和缺失值:
<MiningSchema>
<MiningField name="Sepal_Length" invalidValueTreatment="returnInvalid" missingValueTreatment="returnInvalid"/>
</MiningSchema>
您的管道不包含模型对象,因此实际上没有地方可以存储域规范的第二部分。
有趣的是,当我将 LogisticRegression 放入管道中时,我得到了一个看起来正确的 PMML,但我只有两个输出......
SkLearn2PMML 包执行 PMML 优化,其中未使用的字段声明将被自动删除,以减轻人类和计算机的认知工作。
看起来您的
LogisticRegression
模型对象仅使用两个输入字段。
您可以尝试将
LogisticRegression
替换为使用所有输入字段的其他模型类型。一些“贪婪”算法(例如随机森林)可能很合适。
TLDR:您无法将
ContinuousDomain
等域装饰器与实际模型对象分开。如果您想在多个管道中使用预先安装的域装饰器,那么您应该将它们存储为 Pickle 或 Dill 数据格式的纯 Python 对象。或者,生成一些实用函数(并将其打包为 Python 库),您可以方便地导入和激活。