轻松掌握分类数据编码:初学者的视觉指南

2024年09月04日 由 alex 发表 55 0

什么是分类数据,为什么需要编码?

在进入数据集和编码方法之前,我们先来了解一下什么是分类数据,以及为什么在机器学习领域需要对其进行特殊处理。


什么是分类数据?

分类数据就像我们日常生活中使用的描述性标签。它代表的是可以归类的特征或品质。


为什么分类数据需要编码?

这里有一个问题:大多数机器学习算法就像挑食的人--它们只消化数字。它们无法直接理解 “晴天 ”与 “雨天 ”的不同。这就是编码的作用所在。这就好比把这些分类翻译成机器可以理解和使用的语言。


分类数据类型

并非所有类别都是相同的。我们通常有两种类型:

1. 名义: 这些类别没有固有顺序。

例如:“展望”(晴天、阴天、雨天)就是名义类别。这些天气条件之间没有自然的排序。

2. 顺序: 这些类别具有有意义的顺序。

例如:“温度”(很低、很低、很高、很高)是顺序性的。从最冷到最热有一个明显的递进过程。


2


为什么要关注正确编码?

  1. 它能保留数据中的重要信息。
  2. 它能极大地影响模型的性能。
  3. 不正确的编码会带来意想不到的偏差或关系。


试想一下,如果我们将 “晴天 ”编码为 1,将 “雨天 ”编码为 2,模型可能会认为雨天 “大于 ”晴天,而这并不是我们想要的!


既然我们已经了解了什么是分类数据以及为什么需要编码,那么让我们来看看我们的数据集,看看如何使用六种不同的编码方法来处理其中的分类变量。


数据集

让我们用一个简单的高尔夫球数据集来说明我们的编码方法(该数据集大部分是分类列)。该数据集记录了各种天气状况以及高尔夫球场的拥挤程度。


3


import pandas as pd
import numpy as np
data = {
    'Date': ['03-25', '03-26', '03-27', '03-28', '03-29', '03-30', '03-31', '04-01', '04-02', '04-03', '04-04', '04-05'],
    'Weekday': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
    'Month': ['Mar', 'Mar', 'Mar', 'Mar', 'Mar', 'Mar', 'Mar', 'Apr', 'Apr', 'Apr', 'Apr', 'Apr'],
    'Temperature': ['High', 'Low', 'High', 'Extreme', 'Low', 'High', 'High', 'Low', 'High', 'Extreme', 'High', 'Low'],
    'Humidity': ['Dry', 'Humid', 'Dry', 'Dry', 'Humid', 'Humid', 'Dry', 'Humid', 'Dry', 'Dry', 'Humid', 'Dry'],
    'Wind': ['No', 'Yes', 'Yes', 'Yes', 'No', 'No', 'Yes', 'No', 'Yes', 'Yes', 'No', 'Yes'],
    'Outlook': ['sunny', 'rainy', 'overcast', 'sunny', 'rainy', 'overcast', 'sunny', 'rainy', 'sunny', 'overcast', 'sunny', 'rainy'],
    'Crowdedness': [85, 30, 65, 45, 25, 90, 95, 35, 70, 50, 80, 45]
}
# Create a DataFrame from the dictionary
df = pd.DataFrame(data)


我们可以看到,我们有很多分类变量。我们的任务是对这些变量进行编码,以便机器学习模型可以利用它们来预测高尔夫球场的拥挤程度。


让我们开始吧。


方法 1:标签编码

标签编码法为分类变量中的每个类别分配一个唯一的整数。


常用用途: 它通常用于有明确分类顺序的序数变量,如教育水平(如小学、中学、大学)或产品评级(如 1 星、2 星、3 星)。


在我们的案例中: 我们可以对高尔夫数据集中的 “Weekday ”列使用标签编码。一周中的每一天都将被分配一个唯一的数字(例如,周一 = 0,周二 = 1 等)。但是,我们需要小心,因为这可能意味着周日(6)“大于 ”周六(5),这对我们的分析可能没有意义。


4


# 1. Label Encoding for Weekday
df['Weekday_label'] = pd.factorize(df['Weekday'])[0]


方法 2:单热编码

一热编码法为分类变量中的每个类别创建一个新的二进制列。


常用用途: 通常用于类别没有固有顺序的名义变量。在处理类别数量相对较少的变量时尤其有用。


在我们的案例中: 对于我们的 “Outlook ”列来说,单热编码是理想的选择。我们将创建三个新列: Outlook_sunny“、”Outlook_overcast “和 ”Outlook_rainy"。每一行都将在其中一列中输入 1,在其他列中输入 0,代表当天的天气状况。


5


# 2. One-Hot Encoding for Outlook
df = pd.get_dummies(df, columns=['Outlook'], prefix='Outlook', dtype=int)


方法 3:二进制编码

二进制编码法将每个类别表示为二进制数(0 和 1)。


常用用途: 通常在只有两个类别时使用,多用于 “是 ”或 “否 ”的情况。


在我们的案例中: 虽然我们的 “Windy ”列只有两个类别(是和否),但我们可以使用二进制编码来演示该技术。这将产生一个单独的二进制列,其中一个类别(如 “否”)表示为 0,另一个类别(“是”)表示为 1。


6


# 3. Binary Encoding for Wind
df['Wind_binary'] = (df['Wind'] == 'Yes').astype(int)


方法 4:目标编码

目标编码法将每个类别替换为该类别目标变量的平均值。


常用用途: 当分类变量和目标变量之间可能存在关系时,就会使用这种方法。对于具有合理行数的数据集中的高心数特征,这种方法尤其有用。


我们的案例中:我们可以使用 “拥挤度 ”作为目标,对 “湿度 ”列进行目标编码。多风 “列中的每个 ”干燥 “或 ”潮湿 "都将分别替换为潮湿天和干燥天的平均拥挤度。


7


# 4. Target Encoding for Humidity
df['Humidity_target'] = df.groupby('Humidity')['Crowdedness'].transform('mean')


方法 5:序数编码

序数编码法根据有序整数的固有顺序将其分配到序数类别中。


常用用途: 用于序数变量,在这种情况下,类别的顺序是有意义的,而且你想保留这种顺序信息。


在我们的案例中: 序数编码非常适合我们的 “温度 ”列。我们可以指定整数来表示顺序: 低 = 1,高 = 2,极端 = 3。这样就保留了温度类别的自然排序。


8


# 5. Ordinal Encoding for Temperature
temp_order = {'Low': 1, 'High': 2, 'Extreme': 3}
df['Temperature_ordinal'] = df['Temperature'].map(temp_order)


方法 6:循环编码

循环编码法将周期性的分类变量转换成两个数字特征,以保持变量的周期性。它通常使用正弦和余弦变换来表示周期模式。例如,对于 “月份 ”这一列,我们先将其数值化(1-12),然后创建两个新特征:


  • Month_cos = cos(2 π (m - 1) / 12)
  • Month_sin = sin(2 π (m - 1) / 12)


其中,m 是 1 到 12 之间的数字,代表 1 月到 12 月。


9


常用用途:它用于具有自然周期顺序的分类变量,如一周中的天数、一年中的月份或一天中的小时数。当类别之间的 “距离 ”很重要且环环相扣时,循环编码就特别有用(例如,12 月和 1 月之间的距离应该很小,就像其他连续月份之间的距离一样)。


在我们的案例中:在我们的高尔夫数据集中,最适合循环编码的列是 “月份 ”列。月份有明显的周期模式,每年都会重复。这对我们的高尔夫数据集特别有用,因为它可以捕捉到高尔夫活动中可能每年重复出现的季节性模式。下面是我们如何应用它:


10


# 6. Cyclic Encoding for Month
month_order = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
               'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
df['Month_num'] = df['Month'].map(month_order)
df['Month_sin'] = np.sin(2 * np.pi * (df['Month_num']-1) / 12)
df['Month_cos'] = np.cos(2 * np.pi * (df['Month_num']-1) / 12)


结论: 转变(和理解)的力量

就是这样!六种不同的分类数据编码方法,全部应用于我们的高尔夫球场数据集。现在,所有类别都转换成了数字!


11


分类编码代码总结


import pandas as pd
import numpy as np
# Create a DataFrame from the dictionary
data = {
    'Date': ['03-25', '03-26', '03-27', '03-28', '03-29', '03-30', '03-31', '04-01', '04-02', '04-03', '04-04', '04-05'],
    'Weekday': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
    'Month': ['Mar', 'Mar', 'Mar', 'Mar', 'Mar', 'Mar', 'Mar', 'Apr', 'Apr', 'Apr', 'Apr', 'Apr'],
    'Temperature': ['High', 'Low', 'High', 'Extreme', 'Low', 'High', 'High', 'Low', 'High', 'Extreme', 'High', 'Low'],
    'Humidity': ['Dry', 'Humid', 'Dry', 'Dry', 'Humid', 'Humid', 'Dry', 'Humid', 'Dry', 'Dry', 'Humid', 'Dry'],
    'Wind': ['No', 'Yes', 'Yes', 'Yes', 'No', 'No', 'Yes', 'No', 'Yes', 'Yes', 'No', 'Yes'],
    'Outlook': ['sunny', 'rainy', 'overcast', 'sunny', 'rainy', 'overcast', 'sunny', 'rainy', 'sunny', 'overcast', 'sunny', 'rainy'],
    'Crowdedness': [85, 30, 65, 45, 25, 90, 95, 35, 70, 50, 80, 45]
}
df = pd.DataFrame(data)
# 1. Label Encoding for Weekday
df['Weekday_label'] = pd.factorize(df['Weekday'])[0]
# 2. One-Hot Encoding for Outlook
df = pd.get_dummies(df, columns=['Outlook'], prefix='Outlook')
# 3. Binary Encoding for Wind
df['Wind_binary'] = (df['Wind'] == 'Yes').astype(int)
# 4. Target Encoding for Humidity
df['Humidity_target'] = df.groupby('Humidity')['Crowdedness'].transform('mean')
# 5. Ordinal Encoding for Temperature
temp_order = {'Low': 1, 'High': 2, 'Extreme': 3}
df['Temperature_ordinal'] = df['Temperature'].map(temp_order)
# 6. Cyclic Encoding for Month
month_order = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
               'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
df['Month_num'] = df['Month'].map(month_order)
df['Month_sin'] = np.sin(2 * np.pi * df['Month_num'] / 12)
df['Month_cos'] = np.cos(2 * np.pi * df['Month_num'] / 12)
# Select and rearrange numerical columns
numerical_columns = [
    'Date','Weekday_label',
    'Month_sin', 'Month_cos',
    'Temperature_ordinal',
    'Humidity_target',
    'Wind_binary',
    'Outlook_sunny', 'Outlook_overcast', 'Outlook_rainy', 
    'Crowdedness'
]
# Display the rearranged numerical columns
print(df[numerical_columns].round(3))


文章来源:https://towardsdatascience.com/encoding-categorical-data-explained-a-visual-guide-with-code-example-for-beginners-b169ac4193ae
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
写评论取消
回复取消