DAY8 - 标签编码与连续变量处理

1.1 字典的简单介绍

我相信学过另一个专栏《从0开始学python》的朋友们应该不会太陌生。

如果忘了,回去看看便是,人生又不是每次都是考试。

当然,为了朋友们省懒,还是跟着我学长的教程走一遍吧。

目前我们只会用到映射这个用法,他需要传入的是字典,因为字典的键值对,键是唯一的,值可以重复。这很符合数据的特征是固定的,但是值可以变化这个特性。

所以后续想完成新的映射,直接修改字典的键值对即可。

提示: 字典是Python中非常重要的数据结构,在数据处理中经常用于映射和转换。

字典的性质:

  • 可变类型: 字典创建后可以修改、添加或删除键值对
  • 键的唯一性: 字典中的键必须是唯一的,重复的键会被覆盖
  • 键的不可变性: 键必须是不可变类型(如字符串、数字、元组),不能用列表做键
  • 值的任意性: 值可以是任何数据类型,可以重复
# 使用花括号创建字典
my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}

my_dict
{'name': 'Alice', 'age': 25, 'city': 'New York'}
# 访问字典中的值(查)
my_dict['name']  # 访问字典中的值
'Alice'
# 修改字典中的值(改)
my_dict['age'] = 26  # 修改年龄
my_dict
{'name': 'Alice', 'age': 26, 'city': 'New York'}
# 添加新的键值对(增)
my_dict['job'] = 'Engineer'  # 添加新键值对
my_dict
{'name': 'Alice', 'age': 26, 'city': 'New York', 'job': 'Engineer'}
# 删除键值对(删)
del my_dict['city']  # 删除city这个键值对
my_dict
{'name': 'Alice', 'age': 26, 'job': 'Engineer'}

好的进入正题

1.2 标签编码

之前介绍了离散数据 如果是不存在顺序,则采用独热编码,函数为pd.get_dummies()

现在介绍对于存在顺序和大小关系的离散特征,做好标签编码,借助dataframe的map函数即可实现

关键点: 标签编码适用于有序分类变量,可以保留变量之间的大小关系。

# 导入库并读取数据
import pandas as pd
data = pd.read_csv('E:\study\PythonStudy\python60-days-challenge-master\data.csv')
# 查看数据前几行
data.head()
IdHome OwnershipAnnual IncomeYears in current jobTax LiensNumber of Open AccountsYears of Credit HistoryMaximum Open CreditNumber of Credit ProblemsMonths since last delinquentBankruptciesPurposeTermCurrent Loan AmountCurrent Credit BalanceMonthly DebtCredit ScoreCredit Default
00Own Home482087.0NaN0.011.026.3685960.01.0NaN1.0debt consolidationShort Term99999999.047386.07914.0749.00
11Own Home1025487.010+ years0.015.015.31181730.00.0NaN0.0debt consolidationLong Term264968.0394972.018373.0737.01
22Home Mortgage751412.08 years0.011.035.01182434.00.0NaN0.0debt consolidationShort Term99999999.0308389.013651.0742.00
33Own Home805068.06 years0.08.022.5147400.01.0NaN1.0debt consolidationShort Term121396.095855.011338.0694.00
44Rent776264.08 years0.013.013.6385836.01.0NaN0.0debt consolidationShort Term125840.093309.07180.0719.00

1.2.1 Home Ownership特征编码

这里我们给Home Ownership来完成标签编码,实际上这个特征也可以独热编码,取决于你的理解。实际中,都试一下,谁训练出来的模型好选谁。

# 查看Home Ownership特征的分布
data["Home Ownership"].value_counts()
Home Ownership
Home Mortgage    3637
Rent             3204
Own Home          647
Have Mortgage      12
Name: count, dtype: int64

数据含义解读:

  • 住房抵押贷款(Home Mortgage): 3637 这个是有房贷,有房子
  • 租房(Rent): 3204 没房子
  • 拥有自有住房(Own Home): 647 这个没贷款,有房子,没房贷
  • 有贷款(Have Mortgage): 12 这个是有其他贷款,有房子,没房贷

上面这些翻译也不一定对,这是我个人对数据的理解。

按照贷款严重程度(抗风险能力),依次是: 自有住房 < 租房 < 有其他贷款 < 住房抵押贷款

所以按照这个逻辑来进行编码,数字越大表示负债压力越大。

# 定义映射字典
mapping = {
        "Own Home": 0,
        "Rent": 1,
        "Have Mortgage ": 2,
        "Home Mortgage": 3
    
}
data["Home Ownership"].head()
0         Own Home
1         Own Home
2    Home Mortgage
3         Own Home
4             Rent
Name: Home Ownership, dtype: object
# 应用映射并查看结果
data["Home Ownership"] = data["Home Ownership"].map(mapping)
data["Home Ownership"].head()
0    0.0
1    0.0
2    3.0
3    0.0
4    1.0
Name: Home Ownership, dtype: float64
# 查看Term特征的分布
data["Term"].value_counts()
Term
Short Term    5556
Long Term     1944
Name: count, dtype: int64

1.2.2 Term特征编码

对于字符串类型我们也要映射成整数类型,这里不要理解为标签编码或者独热编码

我们在复试班说过,二分类的问题不需要独热编码,比如性别这个特征,男女不需要变成2个特征(性别男、性别女)。因为他们二者自由度为1,如果是2个特征的话,性别男=1,那么性别女必定等于0。这样特征高度相关,没有价值。

此时这个特征的含义不是性别,而是:是否为男性,1是男性,0是非男。

记住: 三分类以上才涉及独热编码

# 对Term特征进行映射
# 定义映射字典
mapping = {
    "Short Term": 1,
    "Long Term": 0
}

# 进行映射
data["Term"] = data["Term"].map(mapping)
data["Term"].head()
0    1
1    0
2    1
3    1
4    1
Name: Term, dtype: int64

1.2.3 使用嵌套字典批量映射

实际上借助一个映射函数也可以实现上面2次编码

字典的键值对可以嵌套字典,这样可以把多个特征的映射规则集中管理,代码更简洁。

# 创建嵌套映射字典
import pandas as pd

# 重新读取数据
data = pd.read_csv("E:\study\PythonStudy\python60-days-challenge-master\data.csv")
# 嵌套映射字典
mapping = {
    "Term": {
        "Short Term": 1,
        "Long Term": 0
    },
    "Home Ownership": {
        "Rent": 0,
        "Own Home": 1,
        "Have Mortgage  ": 2,
        "Home Mortgage": 3
    }
}
# 访问嵌套字典
mapping["Term"] # 访问嵌套字典中的值,此时他又是一个字典
{'Short Term': 1, 'Long Term': 0}
# 批量应用映射
# 对 Home Ownership 列进行映射
data["Home Ownership"] = data["Home Ownership"].map(mapping["Home Ownership"])

# 对 Term 列进行映射
data["Term"] = data["Term"].map(mapping["Term"])

data.head()
IdHome OwnershipAnnual IncomeYears in current jobTax LiensNumber of Open AccountsYears of Credit HistoryMaximum Open CreditNumber of Credit ProblemsMonths since last delinquentBankruptciesPurposeTermCurrent Loan AmountCurrent Credit BalanceMonthly DebtCredit ScoreCredit Default
001.0482087.0NaN0.011.026.3685960.01.0NaN1.0debt consolidation199999999.047386.07914.0749.00
111.01025487.010+ years0.015.015.31181730.00.0NaN0.0debt consolidation0264968.0394972.018373.0737.01
223.0751412.08 years0.011.035.01182434.00.0NaN0.0debt consolidation199999999.0308389.013651.0742.00
331.0805068.06 years0.08.022.5147400.01.0NaN1.0debt consolidation1121396.095855.011338.0694.00
440.0776264.08 years0.013.013.6385836.01.0NaN0.0debt consolidation1125840.093309.07180.0719.00

1.3 连续变量的处理

归一化和标准化可以通过手写函数实现,也可以使用sklearn中的归一化和标准化函数。

为什么需要处理连续变量? 不同特征的量纲和数值范围差异很大,会影响模型训练效果,需要进行归一化或标准化处理。

1.3.1 归一化与标准化的区别

归一化: 将数据缩放到[0,1]区间
标准化: 将数据转换为均值为0,标准差为1的分布

# 手动实现归一化
# 对Annual Income列做归一化,手动构建函数实现
# 自行学习下如何创建函数,这个很简单很常用
def manual_normalize(data):
    """
    此函数用于对输入的数据进行归一化处理
    :param data: 输入的一维数据(如 Pandas 的 Series)
    :return: 归一化后的数据
    """
    min_val = data.min()
    max_val = data.max()
    normalized_data = (data - min_val) / (max_val - min_val)
    return normalized_data
data['Annual Income'] = manual_normalize(data['Annual Income'])
data['Annual Income'].head()
0    0.031798
1    0.086221
2    0.058771
3    0.064145
4    0.061260
Name: Annual Income, dtype: float64
# 使用sklearn进行归一化处理
# 借助sklearn库进行归一化处理

from sklearn.preprocessing import StandardScaler, MinMaxScaler
data = pd.read_csv("E:\study\PythonStudy\python60-days-challenge-master\data.csv")# 重新读取数据


# 归一化处理
min_max_scaler = MinMaxScaler() # 实例化 MinMaxScaler类,之前课上也说了如果采取这种导入函数的方式,不需要申明库名
data['Annual Income'] = min_max_scaler.fit_transform(data[['Annual Income']])

data['Annual Income'].head()
0    0.031798
1    0.086221
2    0.058771
3    0.064145
4    0.061260
Name: Annual Income, dtype: float64
# 使用sklearn进行标准化处理
# 标准化处理
data = pd.read_csv("E:\study\PythonStudy\python60-days-challenge-master\data.csv")# 重新读取数据
scaler = StandardScaler() # 实例化 StandardScaler
data['Annual Income'] = scaler.fit_transform(data[['Annual Income']])
data['Annual Income'].head()

    
0   -1.046183
1   -0.403310
2   -0.727556
3   -0.664078
4   -0.698155
Name: Annual Income, dtype: float64

更多推荐