1.算法的核心是要解决两个问题:①如何从数据表中找出最佳节点和最佳分枝?
②如何让决策树停止生长,防止过拟合?
流程:①实例化,建立评估模型对象;②通过模型接口训练模型;③通过模型接口提取需要的信息
在这个流程下,分类树对应的代码
from sklearn import tree #导入需要的模块 clf = tree.DecisionTreeClassifier() #实例化 clf = clf.fit(x_train,y_train) #用训练集数据训练模型 resule = clf.score(x_test,y_test) #导入测试集,从接口中调用需要的信息
2.分类树:参数criterion
1.不纯度:
衡量决策树找出最佳节点和最佳分支方法的标准。
不纯度越低,决策树对训练集的拟合越好。不纯度基于节点计算,树中的每个节点都会有一个不纯度,并且子节点的不纯度一定低于父节点的。
在同一个决策树上,叶子节点的不纯度一定是最低的。
criterion是用来决定不纯度的计算方法的,sklearn提供了两种选择:
①输入“entropy”,使用信息熵
②输入“gini”,使用基尼系数
3.建立一棵树
4.剪枝参数
剪枝策略对决策树影响巨大,正确的剪枝策略是优化决策树算法的核心
过拟合:在训练集上表现的很好,在测试集上却表现糟糕
①max_depth:限定树的最大深度,超过设定深度的树枝全部剪掉。最广泛运用的剪枝参数,在高纬度低样本量时非常有效。
②min_samples_leaf & min_samples_split:限定一个节点必须要包含至少min_samples_leaf,split个训练样本,否则分支不会发生。或者分支会朝着满足每个子节点都包含min_samples_leaf个样本去发生。
③max_features & min_impurity_decrease:max_features限制分支时考虑特征个数,超过限制个数的特征都会被舍弃。非常暴力。 min_impurity_decrease限制信息增益的大小,信息增益小于设定数值的分枝不会发生。
确定最优的剪枝参数:使用确定超参数的曲线来判断
5.重要属性和接口
sklearn中许多算法的接口都是相似的,比如之前用到的fit和score。
所有接口中要求输入X_train和X_test的部分,输入的特征矩阵必须至少是一个二维矩阵(最少有两个特征),sklearn不接受任何一维矩阵作为特征矩阵被输入。
#apply返回每个测试样本所在的叶子节点的索引
clf.apply(Xtest)
#predict返回每个测试样本的分类/回归结果
clf.predict(Xtest)
二、数据预处理和特征工程
1.数据的无量纲化可以是线性的也可以是非线性的。线性的无量纲化包括中心化处理和缩放处理。
数据归一化:当数据(x)按照最小值中心化后,再按极差缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间的过程。
2.我们用preprocessing.MinMaxScaler来实现这个功能。MinMaxScaler有一个重要参数,feature_range,控制我们希望把数据压缩到的范围内,默认值是[0,1]。
scaler = MinMaxScaler() #实例化scaler = scaler.fit(data) #fit,在这里本质是生成min(x)和max(x) result = scaler.transform(data) #通过接口导出结果 result result_ = scaler.fit_transform(data) #训练和导出结果一步达成 scaler.inverse_transform(result) #将归一化后的结果逆转 #使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]以外的范围中 data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]] scaler = MinMaxScaler(feature_range=[5,10]) #依然实例化 result = scaler.fit_transform(data) #fit_transform一步导出结果 result #当X中的特征数量非常多的时候,fit会报错并表示,数据量太大了我计算不了 #此时使用partial_fit作为训练接口 #scaler = scaler.partial_fit(data)
3.使用numpy来实现归一化
import numpy as np X = np . array ([[ - 1 , 2 ], [ - 0.5 , 6 ], [ 0 , 10 ], [ 1 , 18 ]]) # 归一化 X_nor = ( X - X . min ( axis = 0 )) / ( X . max ( axis = 0 ) - X . min ( axis = 0 )) X_nor # 逆转归一化 X_returned = X_nor * ( X . max ( axis = 0 ) - X . min ( axis = 0 )) + X . min ( axis = 0 ) X_returned
4.数据标准化:当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布)的过程。
from sklearn . preprocessing import StandardScaler data = [[ - 1 , 2 ], [ - 0.5 , 6 ], [ 0 , 10 ], [ 1 , 18 ]] scaler = StandardScaler () # 实例化 scaler . fit ( data ) #fit ,本质是生成均值和方差 scaler . mean_ # 查看均值的属性 mean_ scaler . var_ # 查看方差的属性 var_ x_std = scaler . transform ( data ) # 通过接口导出结果 x_std . mean () # 导出的结果是一个数组,用 mean() 查看均值 x_std . std () # 用 std() 查看方差 scaler . fit_transform ( data ) # 使用 fit_transform(data) 一步达成结果 scaler . inverse_transform ( x_std ) # 使用 inverse_transform 逆转标准化
5.填补缺失值
impute.SimpleImputerclass sklearn.impute.SimpleImputer ( missing_values=nan , strategy=’mean’ , fifill_value=None , verbose=0 , copy=True )在讲解随机森林的案例时,我们用这个类和随机森林回归填补了缺失值,对比了不同的缺失值填补 方式对数据的影响。这个类是专门用来填补缺失值的。它包括四个重要参数。
data . info () # 填补年龄 Age = data . loc [:, "Age" ]. values . reshape ( - 1 , 1 ) #sklearn 当中特征矩阵必须是二维 Age [: 20 ] from sklearn . impute import SimpleImputer imp_mean = SimpleImputer () # 实例化,默认均值填补 imp_median = SimpleImputer ( strategy = "median" ) # 用中位数填补 imp_0 = SimpleImputer ( strategy = "constant" , fill_value = 0 ) # 用 0 填补 imp_mean = imp_mean . fit_transform ( Age ) #fit_transform 一步完成调取结果 imp_median = imp_median . fit_transform ( Age ) imp_0 = imp_0 . fit_transform ( Age ) imp_mean [: 20 ] imp_median [: 20 ] imp_0 [: 20 ] # 在这里我们使用中位数填补 Age data . loc [:, "Age" ] = imp_median data . info () # 使用众数填补 Embarked Embarked = data . loc [:, "Embarked" ]. values . reshape ( - 1 , 1 ) imp_mode = SimpleImputer ( strategy = "most_frequent" ) data . loc [:, "Embarked" ] = imp_mode . fit_transform ( Embarked ) data . info ()用 Pandas 和 Numpy 进行填补其实更加简单
import pandas as pd data = pd . read_csv ( r"C:worklearnbettermicro-classweek 3 PreprocessingNarrativedata.csv" , index_col = 0 ) data . head () data . loc [:, "Age" ] = data . loc [:, "Age" ]. fillna ( data . loc [:, "Age" ]. median ()) #.fillna 在 Dataframe 里面直接进行填补 data . dropna ( axis = 0 , inplace = True ) #.dropna(axis=0) 删除所有有缺失值的行, .dropna(axis=1) 删除所有有缺失值的列 # 参数 inplace ,为 True 表示在原数据集上进行修改,为 False 表示生成一个复制对象,不修改 原数据,默认 False
6.处理分类型特征:编码与哑变量
为了让数据适应算法和库,我们必须将数据进行编码 ,即是说, 将文字型数据转换为数值型。 preprocessing.LabelEncoder :标签专用,能够将分类转换为分类数from sklearn . preprocessing import LabelEncoder y = data . iloc [:, - 1 ] # 要输入的是标签,不是特征矩阵,所以允许一维 le = LabelEncoder () # 实例化 le = le . fit ( y ) # 导入数据 label = le . transform ( y ) #transform 接口调取结果 le . classes_ # 属性 .classes_ 查看标签中究竟有多少类别 label # 查看获取的结果 label le . fit_transform ( y ) # 也可以直接 fit_transform 一步到位 le . inverse_transform ( label ) # 使用 inverse_transform 可以逆转 data . iloc [:, - 1 ] = label # 让标签等于我们运行出来的结果 data . head () #合并在一起写: from sklearn . preprocessing import LabelEncoder data . iloc [:, - 1 ] = LabelEncoder (). fit_transform ( data . iloc [:, - 1 ])preprocessing.OrdinalEncoder :特征专用,能够将分类特征转换为分类数值
from sklearn . preprocessing import OrdinalEncoder # 接口 categories_ 对应 LabelEncoder 的接口 classes_ ,一模一样的功能 data_ = data . copy () data_ . head () OrdinalEncoder (). fit ( data_ . iloc [:, 1 : - 1 ]). categories_ data_ . iloc [:, 1 : - 1 ] = OrdinalEncoder (). fit_transform ( data_ . iloc [:, 1 : - 1 ]) data_ . head ()preprocessing.OneHotEncoder :独热编码,创建哑变量
data . head () from sklearn . preprocessing import oneHotEncoder X = data . iloc [:, 1 : - 1 ] enc = OneHotEncoder ( categories = 'auto' ). fit ( X ) result = enc . transform ( X ). toarray () result # 依然可以直接一步到位,但为了给大家展示模型属性,所以还是写成了三步 OneHotEncoder ( categories = 'auto' ). fit_transform ( X ). toarray () # 依然可以还原 pd . Dataframe ( enc . inverse_transform ( result )) enc . get_feature_names () result result . shape #axis=1, 表示跨行进行合并,也就是将量表左右相连,如果是 axis=0 ,就是将量表上下相连 newdata = pd . concat ([ data , pd . Dataframe ( result )], axis = 1 ) newdata . head () newdata . drop ([ "Sex" , "Embarked" ], axis = 1 , inplace = True ) newdata . columns = [ "Age" , "Survived" , "Female" , "Male" , "Embarked_C" , "Embarked_Q" , "Embarked_S" ] newdata . head ()
7.处理连续型特征:二值化与分段
sklearn.preprocessing.Binarizer 根据阈值将数据二值化(将特征值设置为0 或 1 ),用于处理连续型变量。大于阈值的值映射为 1 ,而小于或等于阈 值的值映射为0 。默认阈值为 0 时,特征中所有的正值都映射到 1 。二值化是对文本计数数据的常见操作,分析人员 可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯 设置中的伯努利分布建模)。 将年龄二值化data_2 = data . copy () from sklearn . preprocessing import Binarizer X = data_2 . iloc [:, 0 ]. values . reshape ( - 1 , 1 ) # 类为特征专用,所以不能使用一维数组 transformer = Binarizer ( threshold = 30 ). fit_transform ( X ) transformerpreprocessing.KBinsDiscretizer 这是将连续型变量划分为分类变量的类,能够将连续型变量排序后按顺序分箱后编码。总共包含三个重要参数。
from sklearn . preprocessing import KBinsDiscretizer X = data . iloc [:, 0 ]. values . reshape ( - 1 , 1 ) est = KBinsDiscretizer ( n_bins = 3 , encode = 'ordinal' , strategy = 'uniform' ) est . fit_transform ( X ) # 查看转换后分的箱:变成了一列中的三箱 set ( est . fit_transform ( X ). ravel ()) est = KBinsDiscretizer ( n_bins = 3 , encode = 'onehot' , strategy = 'uniform' ) # 查看转换后分的箱:变成了哑变量 est . fit_transform ( X ). toarray ()



