Groupby 在一列 pandas 数据帧上,并使用 GridsearchCv 使用通用 sklearn 管道训练每个组的特征和目标 (X, y)
Posted
技术标签:
【中文标题】Groupby 在一列 pandas 数据帧上,并使用 GridsearchCv 使用通用 sklearn 管道训练每个组的特征和目标 (X, y)【英文标题】:Groupby on one column of pandas dataframe, and train feature and target (X, y) of each group with a common sklearn pipeline using GridsearchCv 【发布时间】:2018-05-22 01:54:13 【问题描述】:我有一个具有以下结构的熊猫数据框:
pd.DataFrame("user_id": ['user_id1', 'user_id1', 'user_id1', 'user_id2', 'user_id2'],
'meeting': ['text1', 'text2', 'text3', 'text4', 'text5'], 'label': ['a,b', 'a', 'a,c', 'x', 'x,y' ])
共有 12 个 user_id。我有如下管道:
knn_tfidf = Pipeline([('tf_idf', TfidfVectorizer(stop_words='english')),
('model', OneVsRestClassifier(KNeighborsClassifier())])
一个参数网格如下:
param_grid_1 = 'tf_idf__max_df': (0.25, 0.5, 0.75),
'tf_idf__ngram_range': [(1, 1), (1, 2), (2,2) (1, 3)],
'model__estimator_n_neighbors' : [np.range(1,30)]
最后是 GridSearchCV:
Grid_Search_tune = GridSearchCV(knn_tfidf, param_grid_1, cv=2)
我需要为每个用户创建一个具有相应 X 和 y 值的模型。对于一个用户,我可以执行以下操作:
t = df[df.user_id == 'user_id1']
从 t 中提取 X 和 y。将 y 传递给一个 Multi labelBinarizer(),然后在实例化管道、param_grid 和 GridsearchCV 之后,我可以这样做:
Grid_Search_tune.fit(X, y)
为每个用户重复 12 次此操作是重复的。所以我遍历了分组的熊猫数据框。这是我所做的:
g = df.groupby('user_id')
for names, groups in g:
X = groups.meeting_subject.as_matrix()
labels = [x.split(', ') for x in groups.priority_label.tolist()]
mlb = MultiLabelBinarizer()
y = mlb.fit_transform(labels)
knn_tfidf = Pipeline([('tf_idf', TfidfVectorizer(stop_words='english')),
('model', OneVsRestClassifier(KNeighborsClassifier()))])
param_grid_1 = 'tf_idf__max_df': (0.25, 0.5, 0.75),
'tf_idf__ngram_range': [(1, 2), (2,2), (1, 3)], 'model__estimator__n_neighbors': np.arange(1,4)
Grid_Search_tune = GridSearchCV(knn_tfidf, param_grid_1, cv=2)
all_estimators = Grid_Search_tune.fit(X, y)
best_of_all_estimators = Grid_Search_tune.best_estimator_
print(best_of_all_estimators)
这给了我这样的输出:
user_id1
Pipeline(memory=None,
steps=[('tf_idf', TfidfVectorizer(analyzer=u'word', binary=False, decode_error=u'strict',
dtype=<type 'numpy.int64'>, encoding=u'utf-8', input=u'content',
lowercase=True, max_df=0.25, max_features=None, min_df=1,
ngram_range=(2, 2), norm=u'l2', preprocessor=None, smooth_idf=T...tric_params=None, n_jobs=1, n_neighbors=1, p=2,
weights='uniform'),
n_jobs=1))])
user_id2
Pipeline(memory=None,
steps=[('tf_idf', TfidfVectorizer(analyzer=u'word', binary=False, decode_error=u'strict',
dtype=<type 'numpy.int64'>, encoding=u'utf-8', input=u'content',
lowercase=True, max_df=0.25, max_features=None, min_df=1,
ngram_range=(1, 2), norm=u'l2', preprocessor=None, smooth_idf=T...tric_params=None, n_jobs=1, n_neighbors=1, p=2,
weights='uniform'),
n_jobs=1))])
以此类推,直到 user_id12 和相应的管道。我不知道这是否是正确的做法,从这里开始我迷路了。如果我这样做:
best_of_all_estimators.predict(['some_text_string'])
我得到了所有 12 个模型的预测。如何使用 for 循环变量 'names' 对我的模型进行键控或索引,这样当我这样做时:
str(raw_input('Choose user_id from above list:'))
假设我选择 user_id3 ,然后
str(raw_input('Enter text string:'))
我输入“一些随机字符串”。为属于 user_id3 的 X 和 y 训练的模型被拉起,并对该模型进行预测,而不是针对所有模型。此处链接了一个非常相似的问题。 training an ML model on selected parts of a data frame。我是初学者,我真的很挣扎!请,请帮助!提前致谢。
【问题讨论】:
【参考方案1】:显然 Pipeline 不支持更改样本数量,例如在 groupby 或其他聚合中。
这是一个类似的问题和可能的解决方法。
sklearn: Have an estimator that filters samples
【讨论】:
我已经编辑了这个问题,添加了一些代码,并链接到一个非常相似的问题。除了这里我没有使用 Spark,并且循环对我来说很好。请帮忙!谢谢。以上是关于Groupby 在一列 pandas 数据帧上,并使用 GridsearchCv 使用通用 sklearn 管道训练每个组的特征和目标 (X, y)的主要内容,如果未能解决你的问题,请参考以下文章
使用 pandas 在数据帧上执行 groupby,按计数排序并获取 python 中的前 2 个计数
在 pandas 数据帧上同时操作 groupby 和 resample?
Python/Pandas - 结合 groupby 平均值和最小值