如何在结构化查询中使用 scikit-learn 模型?

Posted

技术标签:

【中文标题】如何在结构化查询中使用 scikit-learn 模型?【英文标题】:How to use scikit-learn model in structured query? 【发布时间】:2019-11-20 17:26:43 【问题描述】:

我正在尝试将使用 pickle 检索到的 scikit 模型应用于结构化流数据帧的每一行。

我尝试过使用 pandas_udf(版本代码 1),它给了我这个错误:

AttributeError: 'numpy.ndarray' object has no attribute 'isnull'

代码:

inputPath = "/FileStore/df_training/streaming_df_1_nh_nd/"
from pyspark.sql import functions as f
from pyspark.sql.types import *

data_schema = data_spark_ts.schema

import pandas as pd

from pyspark.sql.functions import col, pandas_udf, PandasUDFType   # User Defines Functions for Pandas Dataframe
from pyspark.sql.types import LongType

get_prediction = pandas_udf(lambda x: gb2.predict(x), IntegerType())


streamingInputDF = (
  spark
    .readStream                       
    .schema(data_schema)               # Set the schema of the JSON data
    .option("maxFilesPerTrigger", 1)  # Treat a sequence of files as a stream by picking one file at a time
    .csv(inputPath)
    .fillna(0)
    .withColumn("prediction", get_prediction( f.struct([col(x) for x in data_spark.columns]) ))
)

display(streamingInputDF.select("prediction"))

我也尝试过使用普通的 udf 而不是 pandas_udf,它给了我这个错误:

ValueError: Expected 2D array, got 1D array instead:
[.. ... .. ..]
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

我不知道如何重塑我的数据。

我尝试应用的模型是这样检索的:

#load the pickle
import pickle
gb2 = None

with open('pickle_modello_unico.p', 'rb') as fp:
  gb2 = pickle.load(fp)

它的规格是这样的:

GradientBoostingClassifier(criterion='friedman_mse', init=None,
              learning_rate=0.1, loss='deviance', max_depth=3,
              max_features=None, max_leaf_nodes=None,
              min_impurity_decrease=0.0, min_impurity_split=None,
              min_samples_leaf=1, min_samples_split=2,
              min_weight_fraction_leaf=0.0, n_estimators=300,
              n_iter_no_change=None, presort='auto', random_state=None,
              subsample=1.0, tol=0.0001, validation_fraction=0.1,
              verbose=0, warm_start=False)

任何帮助解决这个问题?

【问题讨论】:

scikit-learn 估计器不返回熊猫数据帧;他们返回numpy 数组。你的错误 AttributeError: 'numpy.ndarray' object has no attribute 'isnull' 是因为 numpy 数组没有方法 isnull()。请改用isnan() 我从不调用 isnull(),我应该调用 isnan()? 我怀疑正在发生的事情是 PySpark 对 pandas UDF 字段上的 fillna() 的调用在后台调用了一些与您的基础数据类型不符的 pandas 函数,但我需要确定的调试环境。 【参考方案1】:

我解决了从 pandas_udf 返回 pd.Series 的问题。

这是工作代码:

inputPath = "/FileStore/df_training/streaming_df_1_nh_nd/"
from pyspark.sql import functions as f
from pyspark.sql.types import *

data_schema = data_spark_ts.schema

import pandas as pd

from pyspark.sql.functions import col, pandas_udf, PandasUDFType   # User Defines Functions for Pandas Dataframe
from pyspark.sql.types import LongType

get_prediction = pandas_udf(lambda x: pd.Series(gb2.predict(x)), StringType())


streamingInputDF = (
  spark
    .readStream                       
    .schema(data_schema)               # Set the schema of the JSON data
    .option("maxFilesPerTrigger", 1)  # Treat a sequence of files as a stream by picking one file at a time
    .csv(inputPath)
    .withColumn("prediction", get_prediction( f.struct([col(x) for x in data_spark.columns]) ))
)

display(streamingInputDF.select("prediction"))

【讨论】:

以上是关于如何在结构化查询中使用 scikit-learn 模型?的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn RandomForestClassifier 中的特征重要性和森林结构如何相关?

scikit-learn 将每个叶节点的决策标签保存在其树结构中的啥位置?

如何在 scikit-learn(用于计算机视觉)中使用我自己的数据集?

scikit-learn 查询数据维度必须匹配训练数据维度

我应该如何在 Scikit-learn 中使用 RandomizedLogisticRegression?

如何在 scikit-learn 中使用交叉验证获得预测概率