Kaggle翻译,第十六天:机器学习进阶 3/7

类别型变量 —— 中级机器学习 3/7

数据集中往往有许多非数字的数据,我们来看看怎么使用他们。
在本课中你教会学到:什么是类别型变量,还有三种处理他们的方法。

简介

  • 类别型变量只接受一小部分特定的值:
    • 想象一个问题,它问你多久吃一次早餐,有四个选项:“从不”,“很少”,“几乎每天”,“每天”。在这个例子中,数据就是分类别的,因为答案被限制在一个分类的集合中。
    • 如果人们回答一个关于他们轿车的牌子的调查时,回答将落在“本田”,“丰田”,“福特”。那么在这个例子中,数据依旧是分类别的。
  • 如果你未经加工就将这些数据输入到大多数Python写成的机器学习模型时,这些模型会报错。本科就来比较一下三种处理该情况的方法。

三大法宝

  1. 删除分类变量
    最简单的方法就是将他们从数据集中剔除出去。该方法仅限该列不含有有用信息的情况。
  2. 依次编码
    将各个选项依次编上不同的整数号码。
    • 这个方法本身要求选项有一定的顺序:“从不”(0)< “很少”(1)< “几乎每天”(2) < “每天”(3).
    • 在上面的例子使用这个方法就很合理,因为这几个选项毋庸置疑的有特定顺序。但是不是所有的分类变量都有一个清晰的顺序来 依次编码。对于树形模型(像决策树和随机森林)他们都可以很好的使用依次编码后的数据。
  3. 一位热编码
    它会创建多个列来表示可选项在原数据中是否存在。举个例子:
    • 原数据集中,“颜色”是一个分类变量,有三个值:“红”,“红”,“黄”,“绿”。一位热编码说的是,将每个选项都创建一列,然后行数与原数据集相同。当原数据是“红”时,我们在“红”这一列下标记为1;选“黄”,在对应位置写1;选“绿”,在对应位置写1,以此类推。
    • 于依次编码不同,一位热编码不会依据分类的顺序。因此,你可以将该方法使用在哪些分类没有明显顺序的情境中(红没有比黄多还是少)。我们将这些没有明显顺序的分类变量称为 名义变量
    • 一位热编码在分类变量可选值较多时表现并不好(所以,你一般不会对有15个可选项的分类变量使用这个方法)。

案例

  • 我们还是使用墨尔本房价的数据集。
  • 照例,我们还是跳过了数据加载的代码,详见之前的课程。
  • 我们来看看数据集的前几行:
X_train.head()
  • 下面,我们来获得一个有分类变量的列表。
  • 我们使用检查每列的数据类型(dtype)来实现。object数据类型表明某一列的数据有文本类型(理论上还会有别的类型,但是我们现在不关心那些)。在这个数据集中,带有文本类型的列表明他们就是分类变量。
# Get list of categorical variables
s = (X_train.dtypes == 'object')
object_cols = list(s[s].index)

print("Categorical variables:")
print(object_cols)
Categorical variables:
['Type', 'Method', 'Regionname']

定义一个评估方法的函数

  • 我们来定义一个函数score_dataset()来比较三种方法在处理分类变量时的表现,该函数返回一个随机森林的平均绝对误差(MAE),我们想要MAE越低越好!
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error

# Function for comparing different approaches
def score_dataset(X_train, X_valid, y_train, y_valid):
    model = RandomForestRegressor(n_estimators=100, random_state=0)
    model.fit(X_train, y_train)
    preds = model.predict(X_valid)
    return mean_absolute_error(y_valid, preds)

方法一得分(删除分类变量)

  • 我们使用select_dtypes()函数来删掉object类型的列
drop_X_train = X_train.select_dtypes(exclude=['object'])
drop_X_valid = X_valid.select_dtypes(exclude=['object'])

print("MAE from Approach 1 (Drop categorical variables):")
print(score_dataset(drop_X_train, drop_X_valid, y_train, y_valid))
MAE from Approach 1 (Drop categorical variables):
175703.48185157913

方法二得分(依次编码)

  • Scikit-learn有一个类OrdinalEncoder它能够获得依次编码,我们通过循环所有的分类变量,将OrdinalEncoder应用于每一列。
from sklearn.preprocessing import OrdinalEncoder

# Make copy to avoid changing original data 
label_X_train = X_train.copy()
label_X_valid = X_valid.copy()

# Apply ordinal encoder to each column with categorical data
ordinal_encoder = OrdinalEncoder()
label_X_train[object_cols] = ordinal_encoder.fit_transform(X_train[object_cols])
label_X_valid[object_cols] = ordinal_encoder.transform(X_valid[object_cols])

print("MAE from Approach 2 (Ordinal Encoding):") 
print(score_dataset(label_X_train, label_X_valid, y_train, y_valid))
MAE from Approach 2 (Ordinal Encoding):
165936.40548390493
  • 在上面的代码块中,每一列我们为不同的值都随机设置了一个不同的整数。这是一个常见的方式,他要比设置一个特定值要简单。但是可想而知,如果我们为所有的有序变量设置一些有意义的标记值,获得的模型表现会更好。
    方法三得分(一位热编码)
  • 我们使用scikit-learn中的OneHotEncoder类来获得一位热编码的值。其中有许多参数你可以设置来自定义他的编码方式。
    • 我们设置handle_unknown='ignore'来避免验证集中的数据包含训练集中没有的选项。
    • 设置sparse=False来保证我们获得的列中数据时为numpy 数组,而非稀疏矩阵。
  • 编码时我们只需要将我们想热编码的列使用一位热编码就可以了。在本例中我们对X_train[object_cols]编码,由于object_cols包含了所有的分类变量,所以我们将所有的分类变量都使用了一位热编码。
from sklearn.preprocessing import OneHotEncoder

# Apply one-hot encoder to each column with categorical data
OH_encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
OH_cols_train = pd.DataFrame(OH_encoder.fit_transform(X_train[object_cols]))
OH_cols_valid = pd.DataFrame(OH_encoder.transform(X_valid[object_cols]))

# One-hot encoding removed index; put it back
OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index

# Remove categorical columns (will replace with one-hot encoding)
num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)

# Add one-hot encoded columns to numerical features
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)

print("MAE from Approach 3 (One-Hot Encoding):") 
print(score_dataset(OH_X_train, OH_X_valid, y_train, y_valid))
MAE from Approach 3 (One-Hot Encoding):
166089.4893009678

哪个方法得分最高呢?

  • 在本例中,删除分类列表表现最差,因为他的MAE最高。对于另外两个方法呢,MAE都差不多,所以无论选择哪个方法都没有对模型训练产生有意义的提升。
  • 总之,热编码方法三通常表现最好,而删除分类变量法方法一表现最差,但是也要因数据集而异。

总结

真实世界充满了分类变量。你要是知道了如何处理这些常见的变量,你将会成为一个高效的数据科学家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值