【python机器学习手册】第五章 处理分类数据

#5.1对没有内部顺序的nominal型分类特征编码
#单热编码 
#numpy
import numpy as np
from sklearn.preprocessing import LabelBinarizer,MultiLabelBinarizer
features=np.array([["Texas"],
                  ["California"],
                  ["Texas"],
                  ["Delaware"],
                  ["Texas"]])
one_hot=LabelBinarizer()#创建单热编码器
one_hot.fit_transform(features)#进行计算和转化
array([[0, 0, 1],
       [1, 0, 0],
       [0, 0, 1],
       [0, 1, 0],
       [0, 0, 1]])
one_hot.classes_#查看分类器使用的分类,使用classes_
array(['California', 'Delaware', 'Texas'], dtype='<U10')
one_hot.inverse_transform(one_hot.fit_transform(features))#进行逆转换,看看原来的分类名字叫啥
array(['Texas', 'California', 'Texas', 'Delaware', 'Texas'], dtype='<U10')
#pandas 通过设置虚拟变量的方法
import pandas as pd
pd.get_dummies(features[:,0])#设置虚拟变量,1就是有。0就是没有
CaliforniaDelawareTexas
0001
1100
2001
3010
4001
#多分类单热编码
multiclass_features=([["Texas","Florida"],
                    ["California","Alabama"],
                    ["Texas","Florida"],
                      ["Delware","Florida"],
                      ["Texas","Alabama"]])
muti_one_hot=MultiLabelBinarizer()#创建多分类单热编码器
muti_one_hot.fit_transform(multiclass_features)#进行计算和转化
array([[0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1],
       [0, 0, 1, 1, 0],
       [1, 0, 0, 0, 1]])
muti_one_hot.classes_#查看分类器的分类
array(['Alabama', 'California', 'Delware', 'Florida', 'Texas'],
      dtype=object)

#5.2对有顺序的ordinal分类特征编码
#使用映射的方法
import pandas as pd
dataframe=pd.DataFrame({"score":["low","low","medium","medium","high"]})#注意格式!数组的话features=np.array([])
dataframe#看看数据帧
score
0low
1low
2medium
3medium
4high
mapper={"low":1,#建立映射关系
       "medium":2,
       "high":3}
dataframe["score"].replace(mapper)#数据帧用replace,数据计算的时候喜欢用fit_transform
#这种情况默认是不同种类之间间隔相等
0    1
1    1
2    2
3    2
4    3
Name: score, dtype: int64
#不同分类之间间隔不等的时候,根据间距合理设置映射数值即可
mapper1={"low":1,#建立映射关系
       "medium":2.5,
       "high":5}
dataframe["score"].replace(mapper1)#映射替换
0    1.0
1    1.0
2    2.5
3    2.5
4    5.0
Name: score, dtype: float64

#5.3对特征字典编码
#把一个字典转换成一个特征矩阵(字典向量化)
from sklearn.feature_extraction import DictVectorizer#字典向量的意思
data_dict=[{"red":2,"blue":4},#列表和字典嵌套
          {"red":4,"blue":3},
          {"red":1,"yellow":2},
          {"red":2,"yellow":2}]
dictvectorizer=DictVectorizer(sparse=False)#创建字典向量化器,将字典量化成矩阵,不要量化成稀疏矩阵
features=dictvectorizer.fit_transform(data_dict)#计算转化
features#第一列为red,第二列为blue,第三列为yellow
array([[4., 2., 0.],
       [3., 4., 0.],
       [0., 1., 2.],
       [0., 2., 2.]])
names=dictvectorizer.get_feature_names()#名字提取
names
['blue', 'red', 'yellow']
df=pd.DataFrame(features,columns=names)
df
blueredyellow
04.02.00.0
13.04.00.0
20.01.02.0
30.02.02.0
df.values#数据帧转换为数组~
array([[4., 2., 0.],
       [3., 4., 0.],
       [0., 1., 2.],
       [0., 2., 2.]])

#5.4填充缺失的分类值
#用预测值来填充缺失值
#KNN分类器
from sklearn.neighbors import KNeighborsClassifier
X=np.array([[0,2.1,1.45],#创建一特征矩阵
           [1,1.18,1.33],#根据数据特征分两块,第一列是分类型的,其余列为数值型的
           [0,1.22,1.27],
           [1,-0.21,-1.19]])
X_nan=np.array([[np.nan,0.87,1.31],#创建一个有缺失值的矩阵
               [np.nan,-0.67,-0.22]])
#训练KNN分类器,最近k个观察值中位数为填充值
clf=KNeighborsClassifier(3,weights="distance")#3个近邻
#默认是uniform,参数可以是uniform、distance,也可以是用户自己定义的函数。
#uniform是均等的权重,就说所有的邻近点的权重都是相等的。distance是不均等的权重,距离近的点比距离远的点的影响大。
model=clf.fit(X[:,1:],X[:,0])#计算第二列之后所有列和第一列(根据数据特征分为两块分别计算)
impute_value=model.predict(X_nan[:,1:])#预测缺失值
X_nan_impute=np.hstack((impute_value.reshape(-1,1),X_nan[:,1:]))#并排连接,-1就是仅一航或者一列
np.vstack((X_nan_impute,X))#竖着连接,注意有两个括号
array([[ 0.  ,  0.87,  1.31],
       [ 1.  , -0.67, -0.22],
       [ 0.  ,  2.1 ,  1.45],
       [ 1.  ,  1.18,  1.33],
       [ 0.  ,  1.22,  1.27],
       [ 1.  , -0.21, -1.19]])
impute_value
array([0., 1.])
X_nan_impute
array([[ 0.  ,  0.87,  1.31],
       [ 1.  , -0.67, -0.22]])
#用特征中出现次数最多的值来填充缺失值
from sklearn.impute import SimpleImputer
X_complete=np.vstack((X_nan,X))#竖着连接,按照顺序连接
X_complete
array([[  nan,  0.87,  1.31],
       [  nan, -0.67, -0.22],
       [ 0.  ,  2.1 ,  1.45],
       [ 1.  ,  1.18,  1.33],
       [ 0.  ,  1.22,  1.27],
       [ 1.  , -0.21, -1.19]])
imputer=SimpleImputer(strategy="most_frequent")#建立一个自定义规则的填充器
#axis=0按列的方向处理
imputer.fit_transform(X_complete)#计算转化并缺失值
array([[ 0.  ,  0.87,  1.31],
       [ 0.  , -0.67, -0.22],
       [ 0.  ,  2.1 ,  1.45],
       [ 1.  ,  1.18,  1.33],
       [ 0.  ,  1.22,  1.27],
       [ 1.  , -0.21, -1.19]])
#5.5处理分布极度不均衡的数据
#最根本方法是收集更多的数据,如果不行就需要改变评估模型的衡量标准
#再不行的话考虑使用嵌入分类权重参数的模型、上采样、下采样
#随机森林分类
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
iris=load_iris()#一定要加括号
features=iris.data
target=iris.target
features=features[40:,:]#截取40行以后的数据
target=target[40:]#截取40以后的数据,只有一行所有没有“,:”
target=np.where((target==0),0,1)#where里的东西,前面是第一个标记数字
print(target)#查看不均衡的目标向量
print(features[:5,:])
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[[5.  3.5 1.3 0.3]
 [4.5 2.3 1.3 0.3]
 [4.4 3.2 1.3 0.2]
 [5.  3.5 1.6 0.6]
 [5.1 3.8 1.9 0.4]]
#1.创建带权重的随机森林分类器
weight={0:0.9,1:0.1}#0的权重为0.9,1的权重为0.1
rfc=RandomForestClassifier(class_weight=weight)
rfc.fit(features,target)
rfc.predict(features[:5,:])#只能根据样本数据来预测,不能根据标签预测
# n_estimators = 10,               弱学习器的最大迭代次数,太小,容易欠拟合,太大,又容易过拟合
# criterion = "gini",              衡量分裂质量的性能函数,默认是基尼不纯度,熵达到峰值的过程要相对慢一些。
# max_depth = None,                ★ 决策树最大深度,如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,
#                                  具体的取值取决于数据的分布。常用的可以取值10-100之间
# min_samples_split = 2,           ★ 内部节点再划分所需最小样本数。如果某节点的样本数少于min_samples_split,
#                                  则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。
#                                  如果样本量数量级非常大,则推荐增大这个值。
# min_samples_leaf = 1,            ★ 叶子节点最少样本数。如果样本量数量级非常大,则推荐增大这个值。
# min_weight_fraction_leaf = 0.,   叶子节点最小的样本权重和。
#                                  默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
# max_features = "auto",           ★ 最大特征数,
# max_leaf_nodes = None,           最大叶子节点数。限制最大叶子节点数,可以防止过拟合。
# min_impurity_decrease = 0.,      如果节点的分裂导致的不纯度的下降程度大于或者等于这个节点的值,那么这个节点将会被分裂
# min_impurity_split = None,       节点划分最小不纯度。
# bootstrap = True,                建立决策树时,是否使用有放回抽样
# oob_score = False,               建议用True,袋外分数反应了一个模型拟合后的泛化能力。
# n_jobs = 1,                      用于拟合和预测的并行运行的工作(作业)数量。如果值为-1,那么工作数量被设置为核的数量
# random_state = None,             是随机数生成器使用的种子; 如果是RandomState实例,random_state就是随机数生成器;
#                                  如果为None,则随机数生成器是np.random使用的RandomState实例
# verbose = 0,                     控制决策树建立过程的冗余度。
# warm_start = False,              当被设置为True时,重新使用之前呼叫的解决方案,用来给全体拟合和添加更多的估计器,
#                                  反之,仅仅只是为了拟合一个全新的森林。

array([0, 0, 0, 0, 0])
#2.创建带均衡分类权重的随机森林分类器
rfc1=RandomForestClassifier(class_weight="balanced")#balanced均衡
rfc1.fit(features,target)
rfc1.predict(features[:5,:])#只能根据样本数据来预测,不能根据标签预测
array([0, 0, 0, 0, 0])
#下采样
#从占多数的分类无放回的随机取出观测值
#创建一个观察值数量与占少数分类相同的子集
class0=np.where(target==0)[0]#where可以同时标记两个或者一个,0表示axis=0,竖着索引
class1=np.where(target==1)[0]
n0=len(class0)#先分类出来再查看每个分类的数量
n1=len(class1)
class1_downsampled=np.random.choice(class1,size=n0,replace=False)#replace表示是否重复抽样
np.hstack((target[class0],target[class1_downsampled]))
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值