4.1 数据接口

4.1.1 数据格式

  1. lightgbm 支持csv,tsv,libsvm 格式的输入数据文件。其中:

    • 可以包含标题
    • 可以指定label列、权重列、query/group id
    • 也可以指定一个被忽略的列的列表。
    1. train_data = lgb.Dataset('train.svm.txt')
  2. lightgbm 也支持numpy 2d array 以及 pandas 对象。

    1. data = np.random.rand(500, 10) # 500 个样本, 每一个包含 10 个特征
    2. label = np.random.randint(2, size=500) # 二元目标变量, 0 和 1
    3. train_data = lgb.Dataset(data, label=label)
  3. lightgbm 也支持scpiy.sparse.csr_matrix

    1. csr = scipy.sparse.csr_matrix((dat, (row, col)))
    2. train_data = lgb.Dataset(csr)
  4. lightgbm 可以通过Lightgbm 二进制文件来保存和加载数据。

    1. train_data = lgb.Dataset('train.bin')
    2. train_data.save_binary('train2.bin')
  5. 创建验证集:(要求验证集和训练集的格式一致)

    1. test_data = lgb.Dataset('test.svm', reference=train_data)

    或者:

    1. train_data = lgb.Dataset('train.svm.txt')
    2. test_data = train_data.create_valid('test.svm')
  6. lightgbm 中的 Dataset 对象由于仅仅需要保存离散的数据桶,因此它具有很好的内存效率。

    但是由于numpy array/pandas 对象的内存开销较大,因此当使用它们来创建Dataset 时,你可以通过下面的方式来节省内存:

    • 构造Dataset 时,设置free_raw_data=True
    • 在构造Dataset 之后,手动设置raw_data=True
    • 手动调用gc
  7. categorical_feature 的支持:

    • 需要指定categorical_feature 参数
    • 对于categorical_feature特征,首选需要将它转换为整数类型,并且只支持非负数。如果转换为连续的范围更佳。

4.1.2 Dataset

  1. Dataset: 由lightgbm 内部使用的数据结构,它存储了数据集。

    1. class lightgbm.Dataset(data, label=None, max_bin=None, reference=None, weight=None,
    2. group=None, init_score=None, silent=False, feature_name='auto',
    3. categorical_feature='auto', params=None, free_raw_data=True)
    • 参数:

      • data: 一个字符串、numpy array 或者 scipy.parse, 它指定了数据源。

        如果是字符串,则表示数据源文件的文件名。

      • label: 一个列表、1维的numpy array 或者None, 它指定了样本标记。默认为None

      • max_bin: 一个整数或者None, 指定每个特征的最大分桶数量。默认为None

        如果为None,则从配置文件中读取。

      • reference: 一个Dataset 或者 None。 默认为None

        如果当前构建的数据集用于验证集,则reference 必须传入训练集。否则会报告has different bin mappers

      • weight: 一个列表、1维的numpy array 或者None, 它指定了样本的权重。默认为None

      • group: 一个列表、1维的numpy array 或者None, 它指定了数据集的group/query size。默认为None

      • init_score: 一个列表、1维的numpy array 或者None, 它指定了Booster的初始score 。默认为None

      • silent: 一个布尔值,指示是否在构建过程中输出信息。默认为False

      • feature_name: 一个字符串列表或者'auto',它指定了特征的名字。默认为'auto'

        • 如果数据源为pandas DataFrame 并且feature_name='auto',则使用DataFramecolumn names
      • categorical_feature: 一个字符串列表、整数列表、或者'auto'。它指定了categorical 特征。默认为'auto'

        • 如果是整数列表,则给定了categorical 特征的下标
        • 如果是字符串列表,在给定了categorical 特征的名字。此时必须设定feature_name 参数。
        • 如果是'auto' 并且数据源为pandas DataFrame,则DataFramecategorical 列将作为categorical 特征
      • params: 一个字典或者None,指定了其它的参数。默认为None

      • free_raw_data: 一个布尔值,指定是否在创建完Dataset 之后释放原始的数据。默认为True

        调用Dataset() 之后,并没有构建完Dataset。 构建完需要等到构造一个Booster 的时候。

  2. 方法:

    • .construct(): 延迟初始化函数。它返回当前的Dataset 本身

    • .create_valid(data,label=None,weight=None,group=None,init_score=None,silent=False,params=None): 创建一个验证集(其格式与当前的Dataset 相同)

      • 参数:参考Dataset 的初始化函数
      • 返回值:当前的Dataset 本身
    • .get_field(field_name): 获取当前Dataset 的属性

      它要求Dataset 已经构建完毕。否则抛出Cannot get group before construct Dataset 异常。

      • 参数:field_name: 一个字符串,指示了属性的名字
      • 返回值:一个numpy array, 表示属性的值。如果属性不存在则返回None
    • .set_field(field_name,data): 设置当前Dataset 的属性

      • 参数:

        • field_name: 一个字符串,指示了属性的名字
        • data: 一个列表、numpy array 或者None,表示属性的值
    • .get_group(): 获取当前Datasetgroup

      get_xxx() 等方法,都是调用的 get_field() 方法来实现的

      • 返回值:一个numpy array,表示每个分组的size
    • .set_group(group): 设置当前Datasetgroup

      • 参数:group: 一个列表、numpy array 或者None,表示每个分组的size
    • .get_init_score(): 获取当前Dataset 的初始化score

      get_xxx() 等方法,都是调用的 get_field() 方法来实现的

      • 返回值:一个numpy array,表示Booster 的初始化score
    • .set_init_score(init_score): 设置Booster 的初始化score

      • 参数:init_score: 一个列表、numpy array 或者None,表示Booster的初始化score
    • .get_label(): 获取当前Dataset 的标签

      get_xxx() 等方法,都是调用的 get_field() 方法来实现的

      • 返回值:一个numpy array,表示当前Dataset 的标签信息
    • .set_label(label): 设置当前Dataset 的标签

      • 参数:label: 一个列表、numpy array 或者None,表示当前Dataset 的标签信息
    • .get_ref_chain(ref_limit=100): 获取Dataset 对象的reference 链。

      假设d 为一个Dataset 对象,则只要d.reference存在,则获取d.reference;只要d.reference.reference存在,则获取d.reference.reference

      • 参数:ref_limit: 一个整数,表示链条的最大长度
      • 返回值:一个Dataset 的集合
    • .set_reference(reference): 设置当前Datasetreference

      • 参数:reference: 另一个Dataset 对象,它作为创建当前Dataset 的模板
    • .get_weight(): 返回Dataset 中每个样本的权重

      get_xxx() 等方法,都是调用的 get_field() 方法来实现的

      • 返回值:一个numpy array,表示当前Dataset 每个样本的权重
    • .set_weight(weight): 设置Dataset 中每个样本的权重

      • 参数:weight: 一个列表、numpy array 或者None,表示当前Dataset 每个样本的权重
    • .num_data(): 返回Dataset 中的样本数量

    • .num_feature(): 返回Dataset 中的特征数量

    • .save_binary(filename): 以二进制文件的方式保存Dataset

      • 参数:filename: 保存的二进制文件的文件名
    • .set_categorical_feature(categorical_feature): 设置categorical 特征

      • 参数:categorical_feature: 一个字符串列表或者整数列表。给出了categorical 特征的名字,或者给出了categorical 特征的下标
    • .set_feature_name(feature_name): 设置特征名字

      • 参数:feature_name: 一个字符串列表。给出了特征名字
    • .subset(used_indices,params=None): 获取当前Dataset 的一个子集

      • 参数:

        • used_indices: 一个整数的列表,它给出了当前Dataset 中样本的下标。这些样本将构建子集
        • params: 一个字典或者None,给出了其它的参数。默认为None
      • 返回值:一个新的Dataset 对象。
  3. 当你通过 Dataset() 来创建一个 Dataset 对象的时候,它并没有真正的创建必要的数据(必要的数据指的是为训练、预测等准备好的数据),而是推迟到构造一个Booster 的时候。

    因为lightgbm 需要构造bin mappers 来建立子树、建立同一个Booster 内的训练集和验证集(训练集和验证集共享同一个bin mapperscategorical featuresfeature names)。所以Dataset 真实的数据推迟到了构造Booster 的时候。

    在构建Dataset 之前:

    • get_label()、get_weight()、get_init_score()、get_group(): 等效于self.label、self.weight、self.init_score、self.group

      此时调用 self.get_field(field) 会抛出异常:Cannot get group before construct Dataset

    • set_label()、set_weight()、set_init_score()、set_group(): 等效于self.label=xxx、self.weight=xxx、self.init_score=xxx、self.group=xxx

    • self.num_data()、self._num_feature() 可以从self.data 中获取。

      如果self.datandarray,则它们就是self.data.shape[0],self.data.shape[1]

  4. 示例:

    ​x

    1. import lightgbm as lgb
    2. import numpy as np
    3. class DatasetTest:
    4. def __init__(self):
    5. self._matrix1 = lgb.Dataset('data/train.svm.txt')
    6. self._matrix2 = lgb.Dataset(data=np.arange(0, 12).reshape((4, 3)),
    7. label=[1, 2, 3, 4], weight=[0.5, 0.4, 0.3, 0.2],
    8. silent=False, feature_name=['a', 'b', 'c'])
    9. def print(self,matrix):
    10. '''
    11. Matrix 构建尚未完成时的属性
    12. :param matrix:
    13. :return:
    14. '''
    15. print('data: %s' % matrix.data)
    16. print('label: %s' % matrix.label)
    17. print('weight: %s' % matrix.weight)
    18. print('init_score: %s' % matrix.init_score)
    19. print('group: %s' % matrix.group)
    20. def run_method(self,matrix):
    21. '''
    22. 测试一些 方法
    23. :param matrix:
    24. :return:
    25. '''
    26. print('get_ref_chain():', matrix.get_ref_chain(ref_limit=10))
    27. # get_ref_chain(): {<lightgbm.basic.Dataset object at 0x7f29cd762f28>}
    28. print('subset():', matrix.subset(used_indices=[0,1]))
    29. # subset(): <lightgbm.basic.Dataset object at 0x7f29a4aeb518>
    30. def test(self):
    31. self.print(self._matrix1)
    32. # data: data/train.svm.txt
    33. # label: None
    34. # weight: None
    35. # init_score: None
    36. # group: None
    37. self.print(self._matrix2)
    38. # data: [[ 0 1 2]
    39. # [ 3 4 5]
    40. # [ 6 7 8]
    41. # [ 9 10 11]]
    42. # label: [1, 2, 3, 4]
    43. # weight: [0.5, 0.4, 0.3, 0.2]
    44. # init_score: No
    45. self.run_method(self._matrix2)
  5. 你要确保你的数据集的样本数足够大,从而满足一些限制条件(如:单个节点的最小样本数、单个桶的最小样本数等)。否则会直接报错。