4.1 数据接口
4.1.1 数据格式
lightgbm
支持csv,tsv,libsvm
格式的输入数据文件。其中:- 可以包含标题
- 可以指定
label
列、权重列、query/group id
列 - 也可以指定一个被忽略的列的列表。
train_data = lgb.Dataset('train.svm.txt')
lightgbm
也支持numpy 2d array
以及pandas
对象。data = np.random.rand(500, 10) # 500 个样本, 每一个包含 10 个特征
label = np.random.randint(2, size=500) # 二元目标变量, 0 和 1
train_data = lgb.Dataset(data, label=label)
lightgbm
也支持scpiy.sparse.csr_matrix
:csr = scipy.sparse.csr_matrix((dat, (row, col)))
train_data = lgb.Dataset(csr)
lightgbm
可以通过Lightgbm
二进制文件来保存和加载数据。train_data = lgb.Dataset('train.bin')
train_data.save_binary('train2.bin')
创建验证集:(要求验证集和训练集的格式一致)
test_data = lgb.Dataset('test.svm', reference=train_data)
或者:
train_data = lgb.Dataset('train.svm.txt')
test_data = train_data.create_valid('test.svm')
lightgbm
中的Dataset
对象由于仅仅需要保存离散的数据桶,因此它具有很好的内存效率。但是由于
numpy array/pandas
对象的内存开销较大,因此当使用它们来创建Dataset
时,你可以通过下面的方式来节省内存:- 构造
Dataset
时,设置free_raw_data=True
- 在构造
Dataset
之后,手动设置raw_data=True
- 手动调用
gc
- 构造
categorical_feature
的支持:- 需要指定
categorical_feature
参数 - 对于
categorical_feature
特征,首选需要将它转换为整数类型,并且只支持非负数。如果转换为连续的范围更佳。
- 需要指定
4.1.2 Dataset
Dataset
: 由lightgbm
内部使用的数据结构,它存储了数据集。class lightgbm.Dataset(data, label=None, max_bin=None, reference=None, weight=None,
group=None, init_score=None, silent=False, feature_name='auto',
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'
,则使用DataFrame
的column names
- 如果数据源为
categorical_feature
: 一个字符串列表、整数列表、或者'auto'
。它指定了categorical
特征。默认为'auto'
- 如果是整数列表,则给定了
categorical
特征的下标 - 如果是字符串列表,在给定了
categorical
特征的名字。此时必须设定feature_name
参数。 - 如果是
'auto'
并且数据源为pandas DataFrame
,则DataFrame
的categorical
列将作为categorical
特征
- 如果是整数列表,则给定了
params
: 一个字典或者None
,指定了其它的参数。默认为None
free_raw_data
: 一个布尔值,指定是否在创建完Dataset
之后释放原始的数据。默认为True
调用
Dataset()
之后,并没有构建完Dataset
。 构建完需要等到构造一个Booster
的时候。
方法:
.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()
: 获取当前Dataset
的group
get_xxx()
等方法,都是调用的get_field()
方法来实现的- 返回值:一个
numpy array
,表示每个分组的size
。
- 返回值:一个
.set_group(group)
: 设置当前Dataset
的group
- 参数:
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)
: 设置当前Dataset
的reference
- 参数:
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
对象。
当你通过
Dataset()
来创建一个Dataset
对象的时候,它并没有真正的创建必要的数据(必要的数据指的是为训练、预测等准备好的数据),而是推迟到构造一个Booster
的时候。因为
lightgbm
需要构造bin mappers
来建立子树、建立同一个Booster
内的训练集和验证集(训练集和验证集共享同一个bin mappers
、categorical features
、feature 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.data
是ndarray
,则它们就是self.data.shape[0],self.data.shape[1]
示例:
x
import lightgbm as lgb
import numpy as np
class DatasetTest:
def __init__(self):
self._matrix1 = lgb.Dataset('data/train.svm.txt')
self._matrix2 = lgb.Dataset(data=np.arange(0, 12).reshape((4, 3)),
label=[1, 2, 3, 4], weight=[0.5, 0.4, 0.3, 0.2],
silent=False, feature_name=['a', 'b', 'c'])
def print(self,matrix):
'''
Matrix 构建尚未完成时的属性
:param matrix:
:return:
'''
print('data: %s' % matrix.data)
print('label: %s' % matrix.label)
print('weight: %s' % matrix.weight)
print('init_score: %s' % matrix.init_score)
print('group: %s' % matrix.group)
def run_method(self,matrix):
'''
测试一些 方法
:param matrix:
:return:
'''
print('get_ref_chain():', matrix.get_ref_chain(ref_limit=10))
# get_ref_chain(): {<lightgbm.basic.Dataset object at 0x7f29cd762f28>}
print('subset():', matrix.subset(used_indices=[0,1]))
# subset(): <lightgbm.basic.Dataset object at 0x7f29a4aeb518>
def test(self):
self.print(self._matrix1)
# data: data/train.svm.txt
# label: None
# weight: None
# init_score: None
# group: None
self.print(self._matrix2)
# data: [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
# label: [1, 2, 3, 4]
# weight: [0.5, 0.4, 0.3, 0.2]
# init_score: No
self.run_method(self._matrix2)
你要确保你的数据集的样本数足够大,从而满足一些限制条件(如:单个节点的最小样本数、单个桶的最小样本数等)。否则会直接报错。