Scikit learn scikit学习:有没有一种方法可以提供一个对象作为预测分类器功能的输入?

Scikit learn scikit学习:有没有一种方法可以提供一个对象作为预测分类器功能的输入?,scikit-learn,Scikit Learn,我计划在生产中使用sgdclassizer。其思想是在一些训练数据上训练分类器,使用cPickle将其转储到.pkl文件中,然后在脚本中重用它。然而,某些高基数字段本质上是分类的,并转化为一个热矩阵表示,可创建约5000个特征。现在,我为predict得到的输入只有其中一个特性,其余的都是零。当然,它还将包括除此之外的其他数字特征。从文档中可以看出,predict函数需要一个数组作为输入。是否有任何方法可以将输入转换为predict函数所期望的格式,而不必在每次训练模型时存储字段 更新 假设我的

我计划在生产中使用
sgdclassizer
。其思想是在一些训练数据上训练分类器,使用
cPickle
将其转储到
.pkl
文件中,然后在脚本中重用它。然而,某些高基数字段本质上是分类的,并转化为一个热矩阵表示,可创建约5000个特征。现在,我为predict得到的输入只有其中一个特性,其余的都是零。当然,它还将包括除此之外的其他数字特征。从文档中可以看出,
predict
函数需要一个数组作为输入。是否有任何方法可以将输入转换为
predict
函数所期望的格式,而不必在每次训练模型时存储字段

更新

假设我的输入包含3个字段:

{
  rate: 10, // numeric
  flagged: 0, //binary 
  host: 'somehost.com' // keeping this categorical
}
主机可以有大约5000个不同的值。现在,我将文件加载到熊猫数据帧中,使用
get_dummies
函数将主机字段转换为大约5000个新字段,这些字段是二进制字段

然后,我按模型进行训练,并使用
cPickle
存储它

现在,当我需要使用
predict
函数时,对于输入,我只有3个字段(如上所示)。然而,根据我的理解,predict端点需要一个向量数组,每个向量都应该有5000个字段

对于我需要预测的条目,我只知道该条目的一个字段,即主机本身的值

例如,如果我的输入是

{
  rate: 5,
  flagged: 1
  host: 'new_host.com'
}
我知道预测预期的字段应为:

{
  rate: 5,
  flagged: 1
  new_host: 1
}
但是如果我将其转换为矢量格式,我不知道要将新的_主机字段放在哪个索引中。另外,我事先不知道其他主机是什么(除非我在培训阶段将其存储在某个地方)


我希望我说得有道理。如果我做得不对,请告诉我。

你应该使用scikit学习变压器,而不是使用傻瓜。在这种情况下,这是有意义的。鉴于LabelBinarizer无法在管道中工作,这是实现您所需的一种方法:

binarizer = LabelBinarizer()
# fitting LabelBinarizer means it remembers all the columns it's seen
one_hot_data = binarizer.fit_transform(X_train[:, categorical_col])
# replace string column with one-hot representation
X_train = np.concatenate([np.delete(X_train, categorical_col, axis=1),
                          one_hot_data], axis=1)

model = SGDClassifier()
clf.fit(X_train, y)

pickle.dump(f, {'clf': clf, 'binarizer': binarizer})
然后在预测时间:

estimators = pickle.load(f)
clf = estimators['clf']
binarizer = estimators['binarizer']

one_hot_data = binarizer.transform(X_test[:, categorical_col])
X_test = np.concatenate([np.delete(X_test, categorical_col, axis=1),
                         one_hot_data], axis=1)
clf.predict(X_test)
我不知道放置新的\u主机字段的索引

对我来说,一个很好的方法是建立一个模型,然后用于训练和预测。这样,您就不必关心转换产生的任何输出的列索引:

# in training 
pipl = Pipeline(steps=[('binarizer', LabelBinarizer(),
                ('clf', SGDClassifier())])
model = pipl.train(X, Y)
pickle.dump(mf, model)

# in production
model = pickle.load(mf)
y = model.predict(X)
作为X,Y输入,您需要传递一个类似数组的对象。确保培训和测试的输入结构相同,例如

X = [[data.get('rate'), data.get('flagged'), data.get('host')]] 
Y = [[y-cols]] # your example doesn't specify what is Y in your data
更灵活:数据帧+管道

还可以很好地结合使用,因为它允许您对不同的列名使用不同的转换。例如

df = pd.DataFrame.from_dict(data)
mapper = DataFrameMapper([
        ('host', sklearn.preprocessing.LabelBinarizer()),
        ('rate', sklearn.preprocessing.StandardScaler())
])
pipl = Pipeline(steps=[('mapper', mapper), 
                       ('clf', SGDClassifier())])
X = df[x-cols]
y = df[y-col(s)]
pipl.fit()

请注意,
x-cols
y-col
分别是功能列和目标列的列表。

在最后一句话中:您从何处转换?您必须存储哪些字段?一些示例代码可能会有所帮助。@joc:用一个示例添加了一些细节您的第一个示例不会运行()--我怀疑第二个也不会,但我愿意更正!换言之,注意上面代码中的bug;我写这篇文章只是作为一个例子,没有尝试过。撇开玩笑不谈,我正以这种方式成功地使用LabelBinarizer。事实证明,第二个示例会起作用,因为它可以学习熊猫。通过对LabelBinarizer进行子分类并以类似的方式重写
fit
方法,您也应该能够让第一个开始工作。