机器学习基础知识——标签化

特征编码:

在数据挖掘中,一些算法可以直接计算分类变量,比如决策树模型,但是需多算法不能直接处理分类变量,他们的输入和输出都是数值型数据。因此。把分类变量转换成数值型数据是必要的,这样我们就引入了独热编码和哑编码。比较常用的是对逻辑回归中的连续变量做离散化处理,然后对离散特征进行独热编码或哑编码,这样就可以使模型具有较强的非线性能力。

我闷举几个例子

# python 算法 不支持 分类变量
from sklearn.tree import DecisionTreeClassifier

X = ['a','a','b','b']
y = [0,0,1,1]

Dtree = DecisionTreeClassifier()
Dtree.fit(np.array(X).reshape(-1,1),y)    # X 必须是二维数组


# 得到结果证明不能处理非数值型数据
ValueError: could not convert string to float: 'a'

但是

X = ['1','1','2','2']
y = [0,0,1,1]

Dtree = DecisionTreeClassifier()
Dtree.fit(np.array(X).reshape(-1,1),y)    # X 必须是二维数组

# 这个就可以,虽然X里面是非数值型数据,但是这种类型,决策树会帮我们自动转换

在python里,非数值型数据无法进行处理,但是在其他工具里,决策树会自动将非数值型数据惊醒映射

字符串类型的数据转换为数值型数据的方法:

方法一:

标签化处理:最简单的处理方法,直接把分类变量映射成数字,具体原理就是将分类变量放入一个数组,去重之后变量的下标就将其映射为对应的数值,具体方法如下:

from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import LabelEncoder

X = ['男','男','女','女']
y = [0,0,1,1]

le = LabelEncoder()
X_encode = le.fit_transform(X)
print(le.classes_)   # 可以查看其映射的顺序
print(X_encode)

Dtree = DecisionTreeClassifier()
Dtree.fit(np.array(X_encode).reshape(-1,1),y)    # X 必须是二维数组


# 运行结果:
# ['女','男']
# [1 1 0 0]

如果数据变成二维数据,标签化必须一列一列进行处理

# 假设有一个二维数组
data = np.array([['apple', 'red'],
                 ['banana', 'yellow'],
                 ['orange', 'orange']])

# 创建一个LabelEncoder对象
label_encoder = LabelEncoder()

# 对每一列进行编码
encoded_data = []
for column in range(data.shape[1]):  #shape 返回一个包含两个元素的元组,其中第一个元素表示行数,第二个元素表示列数。因此,data.shape[1] 表示获取 data 的列数。
    encoded_column = label_encoder.fit_transform(data[:, column])  # 表示选择所有的行,而column表示选择第column列。因此,data[:, column]将返回一个一维数组,其中包含了data中第column列的所有元素。
    encoded_data.append(encoded_column)
    
# 将编码后的列合并为一个新的二维数组
encoded_data = np.array(encoded_data).T

print(encoded_data)

方法二:

我们可以用pandas中的factorize方法进行,不过其返回值为二元组,写回时应该注意

X = pd.DataFrame(['男','男','女','女'],columns=['col1'])
y = [0,0,1,1]

data = X['col1'].factorize()
print(data)


# (array([0, 0, 1, 1], dtype=int64), Index(['男', '女'], dtype='object'))
# 这是一个二元组array([0, 0, 1, 1], dtype=int64)是第零个元素,Index(['男', '女'], dtype='object')是第一个元素

X['col1'] = X['col1'].factorize()[0]
#所以我们写回时要选择第0个值写回

#    col1
# 0     0
# 1     0
# 2     1
# 3     1

方法三:

map方法可以手动指定将分类变量映射为什么数值。缺点是:分类变量过多时,一个个指定确实烦

X = pd.DataFrame(['男','男','女','女'],columns=['col1'])
y = [0,0,1,1]

print(X['col1'].map({'男':100,'女':200}))

# 0    100
# 1    100
# 2    200
# 3    200
# Name: col1, dtype: int64
# 这个数据是可以直接写回的

前三种方法都是简单的映射,其映射为数值型数据后就会产生一定的排序。因此我们引出独热编码的概念

独热编码:

例如:学校有三家食堂A,B,C这是属于无序变量,但是我们在数据预处理时,很容易将其映射为1,2,3.这样就为其赋予了有序的特征,因此我们可以将其映射为100,010,001.针对这种情况,独热编码就比较合适。但是如果分类特别多时,独热编码就会生成很多列来表示,会造成维度的扩张,且会产生稀疏矩阵,有用的信息并不多,在建模时,会造成过拟合。

第一种方法就是get.dumies

dic = {'id':['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
       'class':['1', '1', '1', '1', '2', '2', '2', '2', '3', '3'],
       'score1':[50, 60, 80, 90, 78, 92, 34, 92, 75, 34],
       'score2':[18, 19,36, 90, 57, 88, 10, 55, 32, 66],
       'score3':[87, 67, 62, 90, 35, 78, 99, 65, 13, 15]}
df = pd.DataFrame(dic)
pd.get_dummies(df ,columns=['class'],dummy_na=False)   
# columns 是用来指定列的,不加的话就是全进行处理 dummy_na是用来处理确实值的,默认为False,即不管缺失值,设置为True,则表示为确实值也进行数值化处理

第二种方法就是用sklearn里的第三方库(注意:这种方法处理时,分类变量里是不能出现缺失值的)

dic = {'id':['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
       'class':['1', '1', '1', '1', '2', '2', '2', '2', '3', '3'],
       'score1':[50, 60, 80, 90, 78, 92, 34, 92, 75, 34],
       'score2':[18, 19,36, 90, 57, 88, 10, 55, 32, 66],
       'score3':[87, 67, 62, 90, 35, 78, 99, 65, 13, 15]}
df = pd.DataFrame(dic)
from sklearn.preprocessing import OneHotEncoder
encode = OneHotEncoder(sparse_output=False)  # 里面参数是设置输出形式的,False比较好看,其他的我也不知道,我完了查一下

arr = encode.fit_transform(df)
print(arr)

sparse_output=True时,输出的编码结果是一个稀疏矩阵(SciPy库中的csr_matrix类型),这种格式占用内存更少,但需要额外的时间来访问和操作数据。

sparse_output=False时,输出的编码结果是一个普通的NumPy数组,这种格式占用更多的内存,但可以更快地访问和操作数据。

比较推荐用第一种方法

哑编码

python中并没有直接的哑编码,我们只能通过特定的方法去进行转换

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值