使⽤XGBoost之数据准备(LabelEncoder,OneHotEncode,处理缺失值)
由于其速度和性能,XGBoost是⼀种流⾏的梯度增强实现。
在内部,XGBoost模型将所有问题表⽰为仅以数值作为输⼊的回归预测建模问题。如果您的数据是另⼀种形式的,则必须将其准备成预期的格式。
在本⽂中,您将了解如何使⽤Python中的XGBoost库为梯度增强准备数据。
读完这篇⽂章你就会知道:
如何为分类编码字符串输出变量。
如何使⽤onehot准备分类输⼊变量。
如何使⽤XGBoost⾃动处理丢失的数据。
让我们开始吧。
标签编码字符串类值
鸢尾花分类问题是⼀个具有字符串类值的问题的例⼦。
这是⼀个预测问题,给定以厘⽶为单位的鸢尾花的测量值,其任务是预测给定的花属于哪个物种。
下⾯是原始数据集的⽰例。您可以了解关于这个数据集的更多信息,并从UCI机器学习存储库的原始数据。
5.1,3.5,1.4,0.2,Iris-tosa
被毒虫咬了怎么办4.9,3.0,1.4,0.2,Iris-tosa
4.7,3.2,1.3,0.2,Iris-tosa
4.6,3.1,1.5,0.2,Iris-tosa
5.0,3.6,1.4,0.2,Iris-tosa
XGBoost不能按原样对这个问题建模,因为它要求输出变量是数值的。
我们可以使⽤LabelEncoder轻松地将字符串值转换为整数值。这三个类值(鸢尾-tosa、鸢尾-versicolor、鸢尾-virginica)被映射到整数值(0,1,2)。
# encode string class values as integers
label_encoder = LabelEncoder()
label_encoder = label_encoder.fit(Y)
label_encoded_y = ansform(Y)
我们将标签编码器保存为⼀个单独的对象,这样我们就可以使⽤相同的编码⽅案转换训练数据集以及稍后的测试和验证数据集。
下⾯是⼀个完整的⽰例,演⽰如何加载iris数据集。注意,panda⽤于加载数据,以便处理字符串类值。
# multiclass classification
import pandas
出师表原文import xgboost
from sklearn import model_lection
ics import accuracy_score
from sklearn.preprocessing import LabelEncoder
# load data
data = ad_csv('iris.csv', header=None)
datat = data.values
# split data into X and y
X = datat[:,0:4]
Y = datat[:,4]
# encode string class values as integers
label_encoder = LabelEncoder()
label_encoder = label_encoder.fit(Y)
label_encoded_y = ansform(Y)
ed = 7
test_size = 0.33
underX_train, X_test, y_train, y_test = ain_test_split(X, label_encoded_y, test_size=test_size, random_state=ed)
# fit model no training data
model = xgboost.XGBClassifier()
劳动时间标准model.fit(X_train, y_train)
print(model)
# make predictions for test data
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
运⾏该⽰例将产⽣以下输出:
XGBClassifier(ba_score=0.5, colsample_bylevel=1, colsample_bytree=1,
gamma=0, learning_rate=0.1, max_delta_step=0, max_depth=3,连续相
min_child_weight=1, missing=None, n_estimators=100, nthread=-1,
objective='multi:softprob', reg_alpha=0, reg_lambda=1,
scale_pos_weight=1, ed=0, silent=True, subsample=1)
Accuracy: 92.00%
请注意XGBoost模型是如何配置为使⽤multi:softprob⽬标(softmax loss function的变体,⽤于建模类概率)⾃动对多类分类问题建模的。这表明,在内部,输出类被⾃动转换为⼀个one hot编码。
One Hot Encode Categorical Data
有些数据集只包含分类数据,例如乳腺癌数据集。
该数据集描述了乳腺癌活检的技术细节,预测任务是预测患者是否有癌症复发。
下⾯是原始数据集的⽰例。您可以在UCI机器学习存储库中了解关于此数据集的更多信息,并从下载CSV格式的数据集。
'40-49','premeno','15-19','0-2','yes','3','right','left_up','no','recurrence-events'
'50-59','ge40','15-19','0-2','no','1','right','central','no','no-recurrence-events'
'50-59','ge40','35-39','0-2','no','2','left','left_low','no','recurrence-events'
'40-49','premeno','35-39','0-2','yes','3','right','left_low','yes','no-recurrence-events'
'40-49','premeno','30-34','3-5','yes','2','left','right_up','no','recurrence-events'
我们可以看到所有9个输⼊变量都是分类的,并以字符串格式描述。该问题是⼀个⼆分类预测问题,输出类值也⽤字符串格式描述。
我们可以重⽤上⼀节中的相同⽅法,并将字符串类值转换为整数值,从⽽使⽤LabelEncoder对预测进
⾏建模。例如:
# encode string class values as integers
label_encoder = LabelEncoder()
label_encoder = label_encoder.fit(Y)
label_encoded_y = ansform(Y)
我们可以对X中的每个输⼊特性使⽤相同的⽅法,但这只是⼀个起点。
# encode string input values as integers
features = []
for i in range(0, X.shape[1]):
label_encoder = LabelEncoder()
feature = label_encoder.fit_transform(X[:,i])
features.append(feature)
encoded_x = numpy.array(features)
encoded_x = shape(X.shape[0], X.shape[1])
XGBoost可以假设每个输⼊变量的编码整数值都具有序号关系。例如,将“left-up”编码为0,将“left-low”编码为1的breast-quad变量具有整数形式的有意义的关系。在这种情况下,这个假设是不正确的。
相反,我们必须将这些整数值映射到新的⼆进制变量上,每个分类值对应⼀个新变量。
例如,breast-quad变量有以下值:
left-up
left-low
right-up
right-low
central
我们可以将其建模为5个⼆进制变量如下:
left-up, left-low, right-up, right-low, central
1,0,0,0,0
0,1,0,0,0
0,0,1,0,0
0,0,0,1,0
0,0,0,0,1
这叫做热编码。我们可以使⽤scikit-learn中的OneHotEncoder类对所有分类输⼊变量进⾏热编码。
我们可以在标签编码后对每个特性进⾏热编码。⾸先,我们必须将特征数组转换为⼀个⼆维的NumPy数组,其中每个整数值都是长度为1的特征向量。
feature = shape(X.shape[0], 1)
然后,我们可以创建OneHotEncoder并对特性数组进⾏编码。
onehot_encoder = OneHotEncoder(spar=Fal)
feature = onehot_encoder.fit_transform(feature)
最后,我们可以通过将⼀个热编码特性⼀个接⼀个地连接起来,并将它们作为新列(axis=2)添加上去,从⽽构建输⼊数据集。我们最终得到⼀个由43个⼆进制输⼊变量组成的输⼊向量。
# encode string input values as integers
encoded_x = None
吃香菇的好处for i in range(0, X.shape[1]):
香煎黄花鱼的做法label_encoder = LabelEncoder()
feature = label_encoder.fit_transform(X[:,i])
feature = shape(X.shape[0], 1)
onehot_encoder = OneHotEncoder(spar=Fal)
feature = onehot_encoder.fit_transform(feature)
if encoded_x is None:
encoded_x = feature
el:
encoded_x = atenate((encoded_x, feature), axis=1)
print("X shape: : ", encoded_x.shape)
理想情况下,我们可以尝试不使⽤⼀个热编码对某些输⼊属性进⾏编码,因为我们可以⽤显式的顺序关系对它们进⾏编码,例如第⼀个列age的值为“40-49”和“50-59”。如果您对扩展这个⽰例感兴趣,可以将其作为练习。
下⾯是带有标签和⼀个热编码输⼊变量和标签编码输出变量的完整⽰例。
# binary classification, breast cancer datat, label and one hot encoded
import numpy
from pandas import read_csv
from xgboost import XGBClassifier
del_lection import train_test_split
ics import accuracy_score
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# load data
data = read_csv('datats-uci-breast-cancer.csv', header=None)
datat = data.values
# split data into X and y
X = datat[:,0:9]
X = X.astype(str)
Y = datat[:,9]
# encode string input values as integers
encoded_x = None
for i in range(0, X.shape[1]):
label_encoder = LabelEncoder()
feature = label_encoder.fit_transform(X[:,i])追风筝的孩子
feature = shape(X.shape[0], 1)
onehot_encoder = OneHotEncoder(spar=Fal)
feature = onehot_encoder.fit_transform(feature)
if encoded_x is None:
encoded_x = feature
el:
encoded_x = atenate((encoded_x, feature), axis=1)
print("X shape: : ", encoded_x.shape)
# encode string class values as integers
label_encoder = LabelEncoder()
label_encoder = label_encoder.fit(Y)
label_encoded_y = ansform(Y)
# split data into train and test ts
ed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(encoded_x, label_encoded_y, test_size=test_size, random_state=ed)
# fit model no training data
model = XGBClassifier()
model.fit(X_train, y_train)
print(model)
# make predictions for test data
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
运⾏这个例⼦,我们得到以下输出:
('X shape: : ', (285, 43))
XGBClassifier(ba_score=0.5, colsample_bylevel=1, colsample_bytree=1,
gamma=0, learning_rate=0.1, max_delta_step=0, max_depth=3,
min_child_weight=1, missing=None, n_estimators=100, nthread=-1,
objective='binary:logistic', reg_alpha=0, reg_lambda=1,
scale_pos_weight=1, ed=0, silent=True, subsample=1)
Accuracy: 71.58%