基于列的sklearn分层抽样

28

我有一个相当大的CSV文件,其中包含亚马逊评论数据,我将其读入pandas数据框中。我想将数据拆分为80-20(训练-测试),但在这样做时,我希望确保拆分的数据比例地代表一列值(类别)的价值,即所有不同的评论类别都在训练和测试数据中按比例呈现。

数据如下:

**ReviewerID**       **ReviewText**        **Categories**       **ProductId**

1212                   good product         Mobile               14444425
1233                   will buy again       drugs                324532
5432                   not recomended       dvd                  789654123 

我正在使用下面的代码来实现这个功能:

import pandas as pd
Meta = pd.read_csv('C:\\Users\\xyz\\Desktop\\WM Project\\Joined.csv')
import numpy as np
from sklearn.cross_validation import train_test_split

train, test = train_test_split(Meta.categories, test_size = 0.2, stratify=y)

它会给出以下错误

NameError: name 'y' is not defined

因为我对Python相对较新,所以我无法弄清我错在哪里或者这段代码是否会根据列类别分层。当我从train-test split中移除stratify选项和categories列时,它似乎能够正常工作。

感激不尽,希望得到任何帮助。


1
train_test_split 中使用 y 之前,您尚未定义它。 - Quazi Marufur Rahman
2
你需要先定义变量y。从sklearn页面上看,stratify:类似于数组或None(默认为None) 如果不是None,则使用此作为标签数组以分层方式拆分数据。因此,y必须是您正在使用的标签。 - nEO
类别是你的 Y,你需要将数据(X 和 Y)分开。你现在没有对数据进行任何拆分。 - nEO
下面是添加的解决方案 - nEO
4个回答

39
    >>> import pandas as pd
    >>> Meta = pd.read_csv('C:\\Users\\*****\\Downloads\\so\\Book1.csv')
    >>> import numpy as np
    >>> from sklearn.model_selection import train_test_split
    >>> y = Meta.pop('Categories')
    >>> Meta
        ReviewerID      ReviewText  ProductId
        0        1212    good product   14444425
        1        1233  will buy again     324532
        2        5432  not recomended  789654123
    >>> y
        0    Mobile
        1     drugs
        2       dvd
        Name: Categories, dtype: object
    >>> X = Meta
    >>> X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.33, random_state=42, stratify=y)
    >>> X_test
        ReviewerID    ReviewText  ProductId
        0        1212  good product   14444425

如果有多列需要分层,怎么办?例如分类1和分类2。有没有一种方法可以在多个列上进行分层,而不仅仅是一个列? - Ankhnesmerira

14

sklearn.model_selection.train_test_split

stratify:数组或None(默认为None)

如果不是None,则会以分层方式拆分数据,使用此作为类别标签。

根据API文档,你可以尝试像这样使用:X_train、X_test、y_train、y_test = train_test_split(Meta_X, Meta_Y, test_size=0.2, stratify=Meta_Y)

Meta_XMeta_Y应该由您适当地分配(我认为基于您的代码,Meta_Y应该是Meta.categories)。


4

我不确定为什么没有人提到StratifiedShuffleSplit。

from sklearn.model_selection import StratifiedShuffleSplit
split = StratifiedShuffleSplit(n_splits=10, test_size=0.2, random_state=42)
for train_index, test_index in split.split(df, df['Categories']):
    strat_train_set = df.loc[train_index]
    strat_test_set = df.loc[test_index]

有关文档请参阅StratifiedShuffleSplit


1

你不需要使用 sklearn - 而是使用 DataFrame.groupbyDataFrame.sample

df.groupby([cols]).apply(lambda f: f.sample(frac=ratio))

注意:您可能还需要在此之后使用reset_index(drop=True)重新设置索引。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接