我计划在制作中使用SGDClassifier
。我们的想法是在一些训练数据上训练分类器,使用cPickle
将其转储到.pkl
文件,然后在脚本中重复使用。然而,存在某些高基数字段,这些字段本质上是分类的并且被转换为一个热矩阵表示,其创建大约5000个特征。现在我获得的预测输入只有这些功能中的一个,其余的都是零。它还将包括除此之外的其他数字特征。从文档中可以看出,predict
函数需要一个数组数组作为输入。有没有什么方法可以将我的输入转换为predict
函数所期望的格式,而不必每次训练模型时都存储字段?
更新
所以,我们说我的输入包含3个字段:
{
rate: 10, // numeric
flagged: 0, //binary
host: 'somehost.com' // keeping this categorical
}
主机可以有大约5000个不同的值。现在我将文件加载到pandas数据帧,使用get_dummies
函数将主机字段转换为大约5000个新字段,这些字段是二进制字段。
然后我按模型训练并使用cPickle
存储它。
现在,当我需要使用predict
函数时,对于输入,我只有3个字段(如上所示)。然而,根据我的理解,预测端点将期望一组向量,并且每个向量应该具有那5000个字段。
对于我需要预测的条目,我只知道该条目的一个字段,它将是主机本身的值。
例如,如果我的输入是
{
rate: 5,
flagged: 1
host: 'new_host.com'
}
我知道预测所期望的字段应为:
{
rate: 5,
flagged: 1
new_host: 1
}
但是如果我把它翻译成矢量格式,我就不知道放置new_host字段的索引。此外,我事先并不知道其他主机是什么(除非我在培训阶段将其存储在某处)
我希望我有所作为。如果我做错了,请告诉我。
答案 0 :(得分:2)
我不知道放置new_host字段的索引
一个对我有用的好方法是构建一个pipeline,然后将其用于训练和预测。这样,您就不必关心转换产生的输出的列索引:
# 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
更灵活:Pandas DataFrame + Pipeline
还可以很好地使用Pandas DataFrame与sklearn-pandas
结合使用,因为它允许您对不同的列名称使用不同的转换。 E.g。
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(s)
分别是功能列和目标列的列表。
答案 1 :(得分:1)
你应该使用scikit-learn变换器而不是get_dummies。在这种情况下,LabelBinarizer是有道理的。看上去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)