集成学习(思想)
一、集成学习简介
=================================== 集成学习 =========================================
0、集成学习的概念:集成学习的思想是将若干个学习器(分类器&回归器)组合之后产生一个 新学习器。
0.1、弱分类器(weak learner)指那些分类准确率只稍微好于随机猜 测的分类器(error rate < 0.5)。
1、理解:将多个子模型通过某种策略合并为一个集成模型,从外界看来 输入 ----> 输出 是一个模型的效果。
2、常见的集成思想:集成学习是一种思想,由于单个模型在训练的时候会有所偏向(欠拟合、过拟合等),即
单个模型训练测试的效果不够理想,我们可以训练多个子模型通过某种策略(Bagging、Bossting)集成在一起,通过所有子
模型的结果的合并效果作为模型的最终效果。
常见的有三种思想:① Bagging ② Bossting ③ Stacking
3、Bagging、Bossting思想:
一:Bagging(自举汇聚法)思想:
3.1、理解:类似“尺有所短寸有所长”这样的意思,每个模型有自己擅长的方向,也有自己模型缺陷的地方,说白点
就是说每个模型可能对于某些样本的取值情况会产生过拟合的情况,这个时候通过多个模型的融合,可以将一些过
拟合的情况进行缓解。
3.2、结构:他是一个并行结构。
3.3、目的:为了解决单个模型的过拟合问题。
二: 提升学习(Boosting)思想
3.1、理解:类似“三个臭皮匠赛过诸葛亮”,虽然每个子模型效果比较差,但是将多个子模型的效果合并,整个模
型的效果会比单个模型效果好。
3.2、结构:他是一个串行结构,
3.3、目的:为了解决单个模型的欠拟合问题。
4、集成学习的适用场景:
• 1. 弱分类器间存在一定的差异性,这会导致分类的边界不同,也就是说可能存在错 误。那么将多个弱分类器合并后,就可
以得到更加合理的边界,减少整体的错误率, 实现更好的效果;
• 2. 对于数据集过大或者过小,可以分别进行划分和有放回的操作产生不同的数据子 集,然后使用数据子集训练不同的分类
器,最终再合并成为一个大的分类器;
• 3. 如果数据的划分边界过于复杂,使用线性模型很难描述情况,那么可以训练多个 模型,然后再进行模型的融合;
• 4. 对于多个异构的特征集的时候,很难进行融合,那么可以考虑每个数据集构建一 个分类模型,然后将多个模型融合。
二、Bagging思想
1、Bagging的简介
1、Bagging方法的学习器可以是基本的算法模型,eg: Linear、Ridge、Lasso、 Logistic、Softmax、ID3、C4.5、
CART、SVM、KNN等。
2、Bagging方法常用于解决强学习器的过拟合问题,减少预测值的方差。
Bagging:
1、主要的目的:缓解过拟合。
2、Bagging思想步骤:
① 有放回抽取m次(必须和样本数量一致),并去重作为一个子数据集:
详情:做有放回的抽样,每次从原始数据集中有放回的抽取一条样本,假设原始数据集中存在100条样本,那么进行有放回
抽样100次,也就是会产生100条抽样样本数据,但是这100条样本数据中可能存在重复的数据,所以在做模型训练之前,需
要先将重复数据删除(其实是删除有放回抽样获得的子数据集索引的重复值),删除重复数据之后,用于模型训练的数据样
本数目一般情况下是小于等于100条的。
② 重复上述步骤s次,获取s个子数据集用s个子模型并行训练:
详情:通过这种有放回的抽样的方式产生S个子数据集,用这些子数据集分别训练模型(表示每个子模型训练用的数据是不
一样的(数量不一样、样本不一样),最后对s的子模型的结果进行合并。
3、Bagging适用场景:回归、分类模型的过拟合场景,Bagging 对子模型的类型(LinearRegression、Ridge、KNN、决策树...)
没有任何要求,但是要求所有的子模型类型相同。
4、Bagging集成学习的结果:
① 回归:Bagging的结果是对s个回归子模型效果的加权均值。
② 分类:Bagging的结果是对s个分类子模型效果的加权多票表决。
5、为什么Bagging可以解决过拟合问题:
由于Bagging思想是有放回的m次(m是样本数量)抽样并去重后所获得的子数据集(共获取s个子数据集),那么有可能有一
条样本(异常数据)存在第一个子模型的训练数据中,但是不存在其它的子模型中,如果这条数据为噪声异常样本,那么第一个
模型可能训练后会存在过拟合,但是其它模型对于类似这个数据的取值情况可能产生一个比较适合的预测值,将这些预测值融合
之后,可能缓解这个样本单个模型过拟合的情况。
NOTE: 因为做的是有放回的重采样,所以在原始数据中可能有部分数据是没有参与到模型训练的。这部分没有用于训练的数据就
叫做袋外数据,当模型训练好后,对于模型的效果评估,可以直接使用袋外数据进行评估,也就是指标 .oob_score()方法。
2、Bagging思想的算法
Bagging思想:有放回的重采样。
(1)随机森林(RandomForest)
特点:随机森林是决策树算法过拟合的解决方式。它是一个随机局部特征属性最优划分数据
注意:① 随机森林(两个随机)与 Bagging+决策树算法(一个随机)的区别
本质:由于RF是多个样本数据抽样数据集与对个随机特征属性局部最优划分数据,因此各个子模型不良效果相互抵消,即缓解决策树算
法的过拟合问题。
子模型划分数据的手段:CART决策树划分方法,即分类:条件熵最小/gini增益最大;回归:mse和最小)
子模型预测数据的手段:CART决策树预测方法,即分类:加权多票表决;回归:加权均值
RF预测结果:会使用多数投票或者求均 值的方式来统计最终的分类/回归结果
- 随机森林(两个随机)与Bagging(一个随机)+决策树算法的区别
1、须知:随机森林RF是集成学习Bagging思想的一种应用,Bagging集成学习的API本身对子模型的类型没有要求。
2、随机森林RF的本质:子模型是决策树的Bagging思想(并行结构)的集成学习,但它与普通的Bagging集成学习有些区别。
3、随机森林算法与普通Bagging思想集成学习区别:
特点:普通的Bagging集成学习决策树 仅仅随机有放回抽取m次样本获取一个子数据集,样本特征默认获取全部的样本特征
(全局最优划分),而随机深林是一个局部最优特征分割数据(区别于普通的Bagging决策树----全局最优特征分割数据)
• 1. 从原始样本集(n个样本)中用Bootstrap采样(有放回重采样)选出n个样本;真正用 于模型训练的是这抽取出来的样本去重之
后的数据集,也就是一般情况用户模型训 练的样本数目实际上不等于n,应该是小于n。
• 2. 使用抽取出来的子数据集(去重后的)来训练决策树;从所有属性中随机选择K个属 性,从K个属性中选择出最佳分割属性作为
----------------------- 即它是一个局部特征最优划分数据
节点来迭代的创建决策树
• 3. 重复以上两步m次,即建立m棵决策树;
• 4. 这m个决策树形成随机森林,通过投票表决结果决定数据属于那一类
- 随机森林与决策树的关系
随机森林是 决策树基于 Bagging 思想的一种扩展(区分与 普通Bagging+决策树的区别)
决策树:
决策树构建的时候,是选择基于训练数据最优(API默认全局)的划分方式对数据进行划分操作的,所以说最终的决策树模型一定是非常
契合训练数据的。也就是说有可能存在某个决策路径是满足训练数据,但是不满足测试数据/生产数据(过拟合)
NOTE: 在决策树中,如果多个样本落在同一个叶子节点,可以认为属于同一个类别(落在同一个节点的所有数据之间具有相似的特征属性)
随机森林: 随机森林是决策树算法过拟合的解决方式。
两个随机:
-1. 对于每个子模型而已,用于子模型的训练数据是随机的重采样产生的+去重
-2. 在每个子决策树构建的时候,每个判断节点的划分特征属性的选择是先从所有特征属性中随机出K个特征属性,然
后从这K个特征属性中获取出最优的特征属性作为当前节点的划分特征属性
NOTE: 每个划分节点的特征属性选择都是随机+局部最优。
对于随机森林简单来讲:
内部包含多个决策树,每个决策树构建的样本数据是不一样的,也就是每个子模型对于某些方面有效果比较好的预测,
所以一般用于解决过拟合。
- RF的推广算法
RF算法在实际应用中具有比较好的特性,应用也比较广泛,主要 应用在:分类、回归、特征转换、异常点检测等。常见的RF变种
算法如下:
• Extra Tree ------------ 子模型使用原数据集,且完全随机选取特征属性划分数据集
• Totally Random Trees Embedding(TRTE) ----------- 无监督学习特征工程(低维 >>>>>> 高维)
• Isolation Forest --------------- 检测异常点的算法
注意:这三种算法是RF算法的变种,他们是用Extra决策树作为子模型,这三种算法的划分数据的特征属性是完全随机的。
① Extra Tree 算法
Extra Tree是RF的一个变种,原理基本和RF一样,区别如下:
• 1. RF会随机重采样来作为子决策树的训练集,而Extra Tree每个子决策树采用 原始数据集训练;
------ s个子模型全部使用原始样本数据集
• 2. RF在选择划分特征点的时候会和传统决策树一样,会基于信息增益、信息 增益率、基尼系数、均方差等原则来选择最优特征值;
而Extra Tree会随机的 选择一个特征值来划分决策树。
------ 即Extra Tree算法完全随机选取特征属性划分数据集
• Extra Tree因为是随机选择特征值的划分点,这样会导致决策树的规模 一般大于RF所生成的决策树。也就是说Extra Tree模型的方
差相对于RF 进一步减少。在某些情况下,Extra Tree的泛化能力比RF的强。
Extra Tree 算法的适用场景:
为了解决决策树算法的过拟合问题,如果RF算法无法解决决策树算法的过拟合问题就是用该算法。
② Totally Random Trees Embedding(TRTE) ------------- 非监督学习
TRTE使用场景:
TRTE是一种非监督的数据转化方式。将低维的数据集映射到高维,从而让映射到 高维的数据更好的应用于分类回归模型。
TRTE算法使用原理:
TRTE算法的转换过程类似RF+KDTree算法的方法,建立T个决策树来拟合数据(是 类似KD-Tree一样基于特征属性的方差
选择划分特征)。当决策树构建完成后,数据 集里的每个数据在T个决策树中叶子节点的位置就定下来了,将位置信息转换为向
量就完成了特征转换操作。
③ Isolation Forest(IForest) ------------ 预测异常值的算法
预测方法:决策树叶节点离根节点越近,它是异常点的概率越大
- RF随机森林的优缺点:
• RF的主要优点:
• 1. 训练可以并行化,对于大规模样本的训练具有速度的优势;
• 2. 由于进行随机选择决策树划分特征列表,这样在样本维度比较高的时候,仍然具有比较 高的训练性能;
• 3. 给以给出各个特征的重要性列表;
• 4. 由于存在随机抽样,训练出来的模型方差小,泛化能力强,能够缓解过拟合的情况;
• 5. RF实现简单;
• 6. 对于部分特征的缺失不敏感。
• RF的主要缺点:
• 1. 在某些噪音比较大的特征上(数据特别异常情况),RF模型容易陷入过拟合;
• 2. 取值比较多的划分特征对RF的决策会产生更大的影响,从而有可能影响模型的效果。
三、Boosting思想
Boosting思想常常解决弱学习器的欠拟合问题,减少预测值的偏度
1、Boosting思想的简介
1、提升学习(Boosting)概念:是一种机器学习技术,可以用于回归和分类的问题,它每一步产生弱预测模型(如决策树),并加权
累加到总模型中;如果 每一步的弱预测模型的生成都是依据损失函数的梯度方式的,那么就称 为梯度提升(Gradient boosting);
2、适用模型:作用于 弱预测模型,分类与回归,对子模型类别没有要求,但要求子模型类别相同。
3、目的:解决欠拟合问题
4、常见的模型有:
• Adaboost
• Gradient Boosting(GBT/GBDT/GBRT)
2、Adaboost
3、GBDT
4、XGboost
四、API的使用方法
(1)Y标签编码
# 使用LabelEncoder对Y进行编码
le = LabelEncoder()
le.fit(Y)
Y = le.transform(Y)
print("Y中的类别:{}".format(le.classes_))
# print("反转恢复:{}".format(le.inverse_transform([0, 1])))
(2)BaggingAPI的用法
===========================Bagging 有分类也有回归 ======================================
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
algo = BaggingClassifier(base_estimator=knn, n_estimators=10,
max_samples=1.0, bootstrap=True,
max_features=0.5, bootstrap_features=False,
oob_score=True)
"""
def __init__(self,
base_estimator=None, 给定子模型对象,KNN,Ridge,决策树 ......
n_estimators=10, 给定子模型的数目
max_samples=1.0, 给定重采用的时候,子模型的训练数据样本数目占比;
--------- 注意:这里的是随机抽取百分比特征,也就是说各个子模型的子数据集的
特征是不同的,但之后的操作会将这些特征当做全局特征进行操作,因此要区分RF算法中每次构建节点都会重新随机从子数据抽取k个特征
局部最优化分子数据集。
max_features=1.0, 给定子模型训练的特征属性的数目占比
bootstrap=True, 给定样本采样的时候,是否进行重采样,True表示重采样
bootstrap_features=False, 给定特征属性采样的时候,是否进行重采样,True表示重采样
oob_score=False, 给定是否计算袋外的评估指标(回归中是R2,分类是准确率),True表示计算
warm_start=False,
n_jobs=None,
random_state=None,
verbose=0):
"""
- 实例代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
============================ Bagging + KNN =========================================
# 3. 构建模型
knn = KNeighborsClassifier(n_neighbors=9)
algo = BaggingClassifier(base_estimator=knn, n_estimators=10,
max_samples=1.0, bootstrap=True,
max_features=0.5, bootstrap_features=False,
oob_score=True)
"""
def __init__(self,
base_estimator=None, 给定子模型对象,KNN,Ridge,决策树 ......
n_estimators=10, 给定子模型的数目
max_samples=1.0, 给定重采用的时候,子模型的训练数据样本数目占比
max_features=1.0, 给定子模型训练的特征属性的数目占比
bootstrap=True, 给定样本采样的时候,是否进行重采样,True表示重采样
bootstrap_features=False, 给定特征属性采样的时候,是否进行重采样,True表示重采样
oob_score=False, 给定是否计算袋外的评估指标(回归中是R2,分类是准确率),True表示计算
warm_start=False,
n_jobs=None,
random_state=None,
verbose=0):
"""
# 4. 模型训练
algo.fit(X, Y)
# 5. 看模型效果
Y_predict = algo.predict(X)
print("准确率:{}".format(algo.score(X, Y)))
print("训练数据上的分类报告:\n{}".format(classification_report(Y, Y_predict)))
# 查看一下Bagging属性
estimators_ = algo.estimators_
print("子模型:")
print(estimators_)
estimators_samples_ = algo.estimators_samples_
print("各个子模型的样本列表:")
print(estimators_samples_)
for samples_ in estimators_samples_:
print("{}-{}".format(np.size(samples_), np.size(np.unique(samples_))))
estimators_features_ = algo.estimators_features_
print("各个子模型的特征属性列表:")
print(estimators_features_)
print("袋外样本评估指标:{}".format(algo.oob_score_))
================================= Bagging + 线性回归 ===============================
import numpy as np
import pandas as pd
from sklearn.ensemble import BaggingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# 1. 加载数据
path = "../datas/household_power_consumption_1000.txt"
df = pd.read_csv(path, sep=';')
# df.info()
# 2. 数据的清洗
# 3. 根据需求和原始模型从原始的特征属性中获取特征属性矩阵X和目标属性矩阵Y
X = df.iloc[:, 2:4]
Y = df.iloc[:, 5]
# X.info()
# print(Y)
# 4. 数据的分割(划分为训练数据和测试数据)
"""
train_test_split: 功能将输入的集合转换为train数据集合和test数据集合,对于数据集中的元素类型以及元素之没有要求。
"""
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=28)
# x_train, x_test = X.iloc[:800, :], X.iloc[800:, :]
# y_train, y_test = Y[:800], Y[800:]
print("训练数据X的格式:{}, 以及X的数据类型:{}".format(x_train.shape, type(x_train)))
print("测试数据X的格式:{}, 以及X的数据类型:{}".format(x_test.shape, type(x_test)))
print("数据Y的格式:{}, 以及Y的数据类型:{}".format(y_train.shape, type(y_train)))
# 5. 特征工程
# 6. 模型对象的构建
lr = LinearRegression(fit_intercept=True)
algo = BaggingRegressor(lr, n_estimators=10, oob_score=True)
# 7. 模型对象的训练
algo.fit(x_train, y_train)
# 8. 模型效果评估
print("训练数据上模型的R2的值:{}".format(algo.score(x_train, y_train)))
print("测试数据上模型的R2的值:{}".format(algo.score(x_test, y_test)))
# 查看一下Bagging属性
estimators_ = algo.estimators_
print("子模型:")
print(estimators_)
estimators_samples_ = algo.estimators_samples_
print("各个子模型的样本列表:")
print(estimators_samples_)
for samples_ in estimators_samples_:
print("{}-{}".format(np.size(samples_), np.size(np.unique(samples_))))
estimators_features_ = algo.estimators_features_
print("各个子模型的特征属性列表:")
print(estimators_features_)
print("袋外样本评估指标:{}".format(algo.oob_score_))
(3)Bagging + 决策树 图形化
# 查看一下Bagging属性
estimators_ = algo.estimators_
print("子模型:")
print(estimators_)
k = 0
x_test = np.array([[4.9, 2.5, 4.7, 1.7]])
for estimator, features in zip(estimators_, algo.estimators_features_):
dot_data = tree.export_graphviz(decision_tree=estimator, out_file=None,
feature_names=features,
class_names=['1', '2', '3'],
rounded=True, filled=True,
special_characters=True
)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png("bagging_{}.png".format(k))
print((k, estimator.predict(x_test[:, features])))
k += 1
estimators_samples_ = algo.estimators_samples_
print("各个子模型的样本列表:")
# print(estimators_samples_)
(4) RF 算法 API
============================ RF 算法 有分类也有 回归
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pydotplus
from sklearn import tree
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
algo = RandomForestClassifier(n_estimators=5, oob_score=True, max_features='auto', max_depth=1, random_state=14)
"""
def __init__(self,
n_estimators='warn', 给定子模型数目
criterion="gini", 给定子模型决策树构建的纯度衡量指标,gini或者entropy
max_depth=None, 剪枝参数,限制树的深度 ------- max_depth一般不宜设置过大,把每个模型作为一个弱分类器
min_samples_split=2, 剪枝参数,
min_samples_leaf=1,剪枝参数,
min_weight_fraction_leaf=0.,
max_features="auto", 在决策树构建过程中,每个非叶子节点选择划分特征的时候,从多少个特征选择最优特征
max_leaf_nodes=None,剪枝参数,
min_impurity_decrease=0.,
min_impurity_split=None,
bootstrap=True, ----- 是否有放回的重采样
oob_score=False, ----- 是否用袋外数据
n_jobs=None,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None):
"""
# 4. 模型训练
algo.fit(X, Y)
- RF算法代码
======================= 基于RF算法的鸢尾花数据分类 =====================================
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pydotplus
from sklearn import tree
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
if __name__ == '__main__':
# 1. 加载数据
df = pd.read_csv('../datas/iris.data', header=None, names=['A', 'B', 'C', 'D', 'E'])
df.info()
"""
最终目的,是将X和Y转换为numpy数组的形式,并且值全部转换为数值型
-1. 因为需要获取X和Y,所以这里第一步从df中提取对应的X、Y, 并将X和Y转换为numpy数组
-2. 需要将Y中的字符串使用数字进行替换,eg:"Iris-setosa": 0, "Iris-versicolor": 1, "Iris-virginica": 2
"""
# 获取X和Y
columns = df.columns
X = np.array(df[columns[:-1]])
Y = np.array(df[columns[-1]])
# 使用LabelEncoder对Y进行编码
le = LabelEncoder()
le.fit(Y)
Y = le.transform(Y)
print("Y中的类别:{}".format(le.classes_))
# print("反转恢复:{}".format(le.inverse_transform([0, 1])))
# 2. 获取X的最后两列数据作为原始的特征属性X
# 按照索引获取所有行的最后两列的数据
X = X[:, :]
# print(X)
# 3. 构建模型
"""
def __init__(self,
n_estimators='warn', 给定子模型数目
criterion="gini", 给定子模型决策树构建的纯度衡量指标,gini或者entropy
max_depth=None, 剪枝参数,限制树的深度
min_samples_split=2, 剪枝参数,
min_samples_leaf=1,剪枝参数,
min_weight_fraction_leaf=0.,
max_features="auto", 在决策树构建过程中,每个非叶子节点选择划分特征的时候,从多少个特征选择最优特征
max_leaf_nodes=None,剪枝参数,
min_impurity_decrease=0.,
min_impurity_split=None,
bootstrap=True,
oob_score=False,
n_jobs=None,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None):
"""
algo = RandomForestClassifier(n_estimators=5, oob_score=True, max_features='auto', max_depth=1, random_state=14)
# 4. 模型训练
algo.fit(X, Y)
# 5. 看模型效果
Y_predict = algo.predict(X)
print("准确率:{}".format(algo.score(X, Y)))
print("训练数据上的分类报告:\n{}".format(classification_report(Y, Y_predict)))
# 查看一下Bagging属性
print("各个特征属性的重要性权重系数:{}".format(algo.feature_importances_))
estimators_ = algo.estimators_
print("子模型:")
print(estimators_)
k = 0
x_test = [[4.9, 2.5, 4.25, 1.68]]
for estimator in estimators_:
dot_data = tree.export_graphviz(decision_tree=estimator, out_file=None,
feature_names=['A', 'B', 'C', 'D'],
class_names=['1', '2', '3'],
rounded=True, filled=True,
special_characters=True
)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png("rf_{}.png".format(k))
print((k, estimator.predict(x_test)))
k += 1
if k >= 10:
break
print("最终预测值:{}".format(algo.predict(x_test)))
print("袋外样本评估指标:{}".format(algo.oob_score_))
# 查看样本落在那个叶子节点
print(x_test)
leafs = algo.apply(x_test)
print("样本落在叶子节点为:\n{}".format(leafs))
(5)ExtraTrees 算法的API ---------- 激进树
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pydotplus
from sklearn import tree
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
algo = ExtraTreesClassifier(n_estimators=100, max_features='auto', max_depth=5, random_state=14)
"""
n_estimators='warn',
criterion="gini",
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.,
max_features="auto",
max_leaf_nodes=None,
min_impurity_decrease=0.,
min_impurity_split=None,
bootstrap=False,
oob_score=False,
n_jobs=None,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None
"""
# 4. 模型训练
algo.fit(X, Y)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pydotplus
from sklearn import tree
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
if __name__ == '__main__':
# 1. 加载数据
df = pd.read_csv('../datas/iris.data', header=None, names=['A', 'B', 'C', 'D', 'E'])
df.info()
"""
最终目的,是将X和Y转换为numpy数组的形式,并且值全部转换为数值型
-1. 因为需要获取X和Y,所以这里第一步从df中提取对应的X、Y, 并将X和Y转换为numpy数组
-2. 需要将Y中的字符串使用数字进行替换,eg:"Iris-setosa": 0, "Iris-versicolor": 1, "Iris-virginica": 2
"""
# 获取X和Y
columns = df.columns
X = np.array(df[columns[:-1]])
Y = np.array(df[columns[-1]])
# 使用LabelEncoder对Y进行编码
le = LabelEncoder()
le.fit(Y)
Y = le.transform(Y)
print("Y中的类别:{}".format(le.classes_))
# print("反转恢复:{}".format(le.inverse_transform([0, 1])))
# 2. 获取X的最后两列数据作为原始的特征属性X
# 按照索引获取所有行的最后两列的数据
X = X[:, :]
# print(X)
# 3. 构建模型
"""
n_estimators='warn',
criterion="gini",
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.,
max_features="auto",
max_leaf_nodes=None,
min_impurity_decrease=0.,
min_impurity_split=None,
bootstrap=False,
oob_score=False,
n_jobs=None,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None
"""
algo = ExtraTreesClassifier(n_estimators=100, max_features='auto', max_depth=5, random_state=14)
# 4. 模型训练
algo.fit(X, Y)
# 5. 看模型效果
Y_predict = algo.predict(X)
print("准确率:{}".format(algo.score(X, Y)))
print("训练数据上的分类报告:\n{}".format(classification_report(Y, Y_predict)))
# 查看一下Bagging属性
print("各个特征属性的重要性权重系数:{}".format(algo.feature_importances_))
estimators_ = algo.estimators_
print("子模型:")
print(estimators_)
k = 0
x_test = [[4.9, 2.5, 4.25, 1.68]]
for estimator in estimators_:
dot_data = tree.export_graphviz(decision_tree=estimator, out_file=None,
feature_names=['A', 'B', 'C', 'D'],
class_names=['1', '2', '3'],
rounded=True, filled=True,
special_characters=True
)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png("extra_{}.png".format(k))
print((k, estimator.predict(x_test)))
k += 1
if k >= 10:
break
print("最终预测值:{}".format(algo.predict(x_test)))
(6)RandomTreesEmbedding 算法API
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pydotplus
from sklearn import tree
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomTreesEmbedding
from sklearn import metrics
algo = RandomTreesEmbedding(n_estimators=3, max_depth=2, random_state=14)
# 4. 模型训练
algo.fit(X, Y)
(7)IsolationForest 算法 API
import numpy as np
import matplotlib.pyplot as plt
import pydotplus
from sklearn import tree
from sklearn.ensemble import IsolationForest
#构建模型并训练
#contamination:允许有多少样本预测为异常样本,占比的一个值, 要求behaviour为old的时候生效。默认0.1 --> 如果修改这个参数不是特别的好
#当参数behaviour设置为new的时候,其实内部的阈值为0,决策函数值大于等于0表示正常样本,小于0表示异常样本
algo = IsolationForest(n_estimators=100, random_state=28, contamination=0.05, behaviour='new')
algo.fit(x_train) ------------ 不需要训练 Y
- IsolationForest 代码
import numpy as np
import matplotlib.pyplot as plt
import pydotplus
from sklearn import tree
from sklearn.ensemble import IsolationForest
# 认为正常的样本数据集中在(2,2)和(-2,-2)这两个点的附近
np.random.seed(28)
# 产生一个100*2的矩阵,每个元素值为服从标准正态分布的随机数(均值为0,标准差为1)
x = np.random.normal(size=(100, 2))
# 对x数据做一个缩进
x = 0.05 * x
# 移动中心点
x1 = x + 2
x2 = x - 2
# 合并两个数据得到最终的正常数据(200*2的形式)
x_train = np.vstack((x1, x2))
# 产生测试数据
x = 0.05 * np.random.normal(size=(20, 2))
x_test = np.vstack((x + 2, x - 2))
# 产生异常数据
x_outliers = np.random.uniform(low=-3.5, high=3.5, size=(20, 2))
# 构建模型并训练
# contamination:允许有多少样本预测为异常样本,占比的一个值, 要求behaviour为old的时候生效。默认0.1 --> 如果修改这个参数不是特别的好
# 当参数behaviour设置为new的时候,其实内部的阈值为0,决策函数值大于等于0表示正常样本,小于0表示异常样本
algo = IsolationForest(n_estimators=100, random_state=28, contamination=0.05, behaviour='new')
algo.fit(x_train)
# 预测(正常数据返回1,异常数据返回-1)
train_predict = algo.predict(x_train)
print(np.sum(train_predict == -1))
test_predict = algo.predict(x_test)
outliers_predict = algo.predict(x_outliers)
print("正常数据的预测值:{}".format(train_predict))
print("测试正常数据的预测值:{}".format(test_predict))
print("测试异常数据的预测值:{}".format(outliers_predict))
train_decision = algo.decision_function(x_train)
test_decision = algo.decision_function(x_test)
outliers_decision = algo.decision_function(x_outliers)
print("正常数据的预测值:\n{}".format(train_decision))
print("测试正常数据的预测值:\n{}".format(test_decision))
print("测试异常数据的预测值:\n{}".format(outliers_decision))
# 查看一下IsolationForest属性
estimators_ = algo.estimators_
print("子模型:")
print(estimators_)
k = 0
for estimator, features in zip(estimators_, algo.estimators_features_):
dot_data = tree.export_graphviz(decision_tree=estimator, out_file=None,
feature_names=features,
class_names=['1', '2', '3'],
rounded=True, filled=True,
special_characters=True
)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_png("isolation_{}.png".format(k))
k += 1
if k >= 1:
break
estimators_samples_ = algo.estimators_samples_
print("各个子模型的样本列表:")
# print(estimators_samples_)
for samples_ in estimators_samples_:
print("{}-{}".format(np.size(samples_), np.size(np.unique(samples_))))
# 可视化
t1 = np.linspace(-4, 4, 50)
t2 = np.linspace(-4, 4, 50)
x1, x2 = np.meshgrid(t1, t2) # 产生网格点的坐标
x_show = np.dstack((x1.flat, x2.flat))[0]
z = algo.decision_function(x_show)
z = z.reshape(x1.shape)
# 画等高线区域
# 第一个参数为横坐标的坐标值,第二个参数为纵坐标的坐标值,第三个参数为在这个点(横坐标、纵坐标)位置的数值
# 当这个数值越小的时候,在这里使用冷色调进行现实,如果值越大,使用暖色调现实。
# 要求三个参数的形状必须一致
plt.contourf(x1, x2, z, cmap=plt.cm.Blues_r)
plt.plot(x_train[:, 0], x_train[:, 1], 'ro')
plt.plot(x_test[:, 0], x_test[:, 1], 'go')
plt.plot(x_outliers[:, 0], x_outliers[:, 1], 'bo')
plt.xlim((-4, 4))
plt.ylim((-4, 4))
plt.show()
(8)adaboost
sklearn.ensemble.AdaBoostClassifier(base_estimator=None, n_estimators=50,
learning_rate=1.0, algorithm='SAMME.R', random_state=None)
base_estimator ------- 基础子模型的对象(子模型类型没有要求,默认基础子模型是决策树)
n_estimators ------- 子模型的数量
learning_rate ------- 学习率(防止子模型影响过多导致的过拟合问题)
algorithm
random_state
(9)GBDT
class sklearn.ensemble.GradientBoostingRegressor(loss='ls', learning_rate=0.1, n_estimators=100, subsample=1.0, criterion='friedman_mse', min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, min_impurity_split=1e-07, init=None, random_state=None, max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False, presort='auto')
'''
loss='ls', {‘ls’, ‘lad’, ‘huber’, ‘quantile’} ----- ls 平方误差(默认的损失函数),lad 绝对值误差
learning_rate=0.1, ------------- GBDT 学习率(为了防止模型学习能力过强导致过拟合)
n_estimators=100, ------------- 子模型的数目(实际上是回归决策树的数目)
subsample=1.0, ------------- 是否选取样本中百分比进行训练
criterion='friedman_mse', ------------- MSE(回归决策树选择特征属性划分数据的准则)
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.0,
max_depth=3, ------------- 回归树的深度,Boosting解决的弱学习器的欠拟合问题,因而深度需要设置小一些。
min_impurity_split=1e-07,
init=None,
random_state=None,
max_features=None, ------------- 是否随机选取特征属性中局部最优进行数据化分,详情见决策树或随机森林(RF)
alpha=0.9,
verbose=0,
max_leaf_nodes=None,
warm_start=False,
presort='auto'
'''
(10)XGboost 算法
from xgboost import XGBClassifier/XGBRegressor
class xgboost.XGBRegressor(max_depth=3, learning_rate=0.1, n_estimators=100, verbosity=1, silent=None,
objective='reg:linear', booster='gbtree', n_jobs=1, nthread=None, gamma=0, min_child_weight=1,
max_delta_step=0, subsample=1, colsample_bytree=1, colsample_bylevel=1, colsample_bynode=1, reg_alpha=0, reg_lambda=1,
scale_pos_weight=1,
base_score=0.5,
random_state=0, seed=None, missing=None, importance_type='gain', **kwargs)
'''
max_depth=3 ------------ 基础学习者的最大树深度
learning_rate=0.1 ---------- 学习率,防止过拟合
n_estimators=100 ---------- 子模型的个数
objective='reg:linear' ---------- 指定学习任务和相应的学习目标或要使用的自定义目标函数
subsample=1 ---------- 子采样占比
missing=None ---------- 数据中需要作为缺失值出现的值。如果为None,则默认为np.nan
random_state=0
'''
class xgboost.XGBClassifier(max_depth=3, learning_rate=0.1, n_estimators=100, verbosity=1, silent=None
, objective='binary:logistic', booster='gbtree', n_jobs=1, nthread=None, gamma=0, min_child_weight=1,
max_delta_step=0, subsample=1, colsample_bytree=1, colsample_bylevel=1, colsample_bynode=1,
reg_alpha=0, reg_lambda=1, scale_pos_weight=1, base_score=0.5, random_state=0, seed=None, missing=None, **kwargs)
总结
以线性回归算法为例:
-1. 线性回归算法是什么?线性回归基本原理是什么?构建原理是什么?
-2. 损失函数是什么?
-3. 什么是梯度下降?BGD、SGD、MBGD这三种有什么区别?
-4. 建议:基于最大似然估计到处最小二乘的损失函数的那个过程理解一下。
-5. 你觉得线性回归算法有什么局限性吗?那你觉得这个局限性怎么解决?
-6. 过拟合和欠拟合的解决方案
-7. L1正则和L2正则
一、集成学习是什么?集成学习基本原理是什么?构建原理是什么?
1、集成学习的概念:集成学习的思想是将若干个子学习器(分类器&回归器)通过某种策略(Bagging、Boosting)组合之
后产生一个新学习器,在外界看来,输入X ---> 输出Y是一个模型的效果。
2、集成学习的基本原理:
3、集成学习的构建原理:
3.1、Bagging:Bagging是一个并行结构
3、集成学习的优点:集成算法的成功在于保证弱分类器(欠拟合,Bissting思想)的多样性(Diversity)。而且集成不稳定的算法
(过拟合,Bagging思想)也能够得到一个比较明显的性能提升。
2、弱分类器(weak learner)指那些分类准确率只稍微好于随机猜 测的分类器(error rate < 0.5);