一、决策树
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.SimpleImputer
class
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:\work\learnbetter\micro-class\week 3
Preprocessing\Narrativedata.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
)
transformer
preprocessing.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
()
|