重生归来,我要成功 Python 高手--day34 集成学习
集成学习:通过多个模型的组合形成一个精度更高的模型,参与组成的模型成为弱学习器,训练时使用训练集依次训练这些弱学习器,对于未知的样本进行预测时,使用这些弱学习器联合进行预测
集成学习分为,bagging 思想 为并行 boosting 思想为串行
Bagging:并行构建多个独立的弱学习器,通过投票或平均来综合结果,以减少方差,
有放回的抽样产生不同的训练集,从而训练不同的学习器,通过平权投票,多数表决的方式,预测结果,弱学习器可以并行训练
代表算法:随机森林---增加特征的随机选择,进一步降低模型的相关性
优点:有效的减少过拟合,提高模型的稳定性,对异常值不敏感
缺点:对强学习器的效果提升有限,模型解释性差
Boosting:串行构建弱学习器,每个学习器专注于纠正之前学习器的错误以减少偏差,
每个新模型都会使用全部的原始数据进行训练,但会通过提高前一个模型预测错误样本的权重来让新的模型更关注这些预测错误的样本
代表算法:AdaBoost----通过调整样本权重关注错误样本
GDBT(梯度提升决策树):使用梯度下降思想来最小化损失函数
XGboost/lightGBM:GDBT的高效实现版本
优点:能有效的处理偏差,提高模型的精度
缺点:训练过程无法并行,速度较慢,容易过拟合,对异常值敏感
随机森林:训练:有放回的产生训练样本,随挑选n个特征 预测:平权投票,多数表决输出预测结果,默认的弱学习器是决策树
API:
import pandas as pd
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
from sklearn.ensemble import RandomForestClassifier #随机森林分类模型
# 获取数据
data_df=pd.read_csv('../../data/train - 副本.csv')
# 获取特征和标签
x=data_df[['Pclass','Sex','Age','SibSp','Parch']]
y=data_df['Survived']
# 对特征进行清洗,因为age列有空值,使用年龄的平均值进行填充
x['Age']=x['Age'].fillna(x['Age'].mean())
# 对性别列进行热编码
x=pd.get_dummies(x)
# 数据集的划分
x_trian,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=18)
# 数据进行标准化
t=StandardScaler()
x_trian=t.fit_transform(x_trian)
x_test=t.transform(x_test)
# 使用默认的随机森林参数
# 模型的创建
model1=RandomForestClassifier()
model1.fit(x_trian,y_train)
pred1=model1.predict(x_test)
print(f'模型的准确率是{accuracy_score(y_test,pred1)}')
# 增加默认参数实现
model2=RandomForestClassifier()
# 使用网格搜索
params={
'n_estimators':[100,200,300,400,500],
'max_depth':[5,6,7,8,9],
'random_state':[18,22,91,78,978]
}
gs_model2=GridSearchCV(model2,param_grid=params,cv=4)
gs_model2.fit(x_trian,y_train)
pred2=gs_model2.predict(x_test)
print(f'模型的准确率是{accuracy_score(y_test,pred2)}')
print(f'最佳参数:{gs_model2.best_params_}')
n_estimators=决策树的数量
max_depth=决策树的深度
random_state=随机种子
Adaboost算法:基于boosting思想实现的一种集成学习算法核心思想是通过逐步提高哪些被前一步的分类错误的样本的权重来训练一个强分类器

API:
import pandas as pd
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier # 决策树的api
from sklearn.ensemble import AdaBoostClassifier # AdaBoostClass分类模型
# 需要的列:
# 获取数据集
data=pd.read_csv('../../data/wine0501 - 副本.csv')
# 查询数据集的详细信息
# print(data.info())
# 使用Adaboost算法,一般用于二分类数据集
# 对数据集进行清洗Class label,过滤掉标签为1的数据集
# print(data['Class label'].unique())
# 一共有[1 2 3]这三种标签
# 过滤标签为1的列
data=data[data['Class label']!=1]
# 类别转化 (2,3)=>(0,1) 进行内容的替换
data['Class label']=data['Class label'].replace({2:0,3:1})
# print(data['Class label'])
#选择特征列和标签列
x=data[['Alcohol','Flavanoids','Total phenols','Color intensity','OD280/OD315 of diluted wines',' Proline']]
y=data['Class label']
# 标签编码器
"""
le=LabelEncoder()
y=le.fit_transform(y)
"""
# print(data.info())
# print(x.info())
# 数据集进行划分
x_train,x_test,y_train,y_test=train_test_split(x, y, test_size=0.2, random_state=66,stratify=y)
# 数据进行标准化
t=StandardScaler()
x_train=t.fit_transform(x_train)
x_test=t.transform(x_test)
# 单决策树模型的创建
model1 = DecisionTreeClassifier(max_depth=3)
# 模型的训练单决策树
model1.fit(x_train, y_train)
# 模型的测试
y_pred1 = model1.predict(x_test)
# 数据结果的输出
print(f'单决策树模型的准确率是{accuracy_score(y_test, y_pred1)}')
# Adaboost模型的创建
model2 = AdaBoostClassifier(estimator=model1,n_estimators=500,learning_rate=0.1,algorithm='SAMME')
# 模型的训练Adaboost-由500颗树组成
model2.fit(x_train, y_train)
# 模型的测试
y_pred2 = model2.predict(x_test)
# 数据结果的输出
print(f'Adaboost模型的准确率是{accuracy_score(y_test, y_pred2)}')
AdaBoostClassifier:参数 弱学习器(决策树对象) 弱学习器的个数 学习率 集成算法
BDT:残差提升树 通过拟合残差的思想来进行提升 残差=真实值-预测值
残差和误差的区别:
误差:真实值与理论模型预测值之间的差异(不可预测)
残差:实际观测值与拟合模型预测值的差异
例子:一个人100岁,第一次预测为80岁 残差就是20
第二次就以20为真实值,进行预测 这一次为16 残差为4
第三次就以4为真实值,进行预测 这一次为3.2 残差为0.8
这三次结果和为99.2 通过拟合残差可将多个弱学习器组成一个强学习器,这就是提升书的思想
GDBT:梯度提升树,利用损失函数的负梯度作为提升树算法中的残差近似值
通过负梯度(等价于残差)不断接近真实值
在梯度提升的过程中,每一轮构建的弱学习器:上一轮计算得到的负梯度,作为本轮弱学习器需要拟合的真实值,而本轮弱学习器对样本的预测,是通过子树的均值来实现的
梯度提升树的构建流程:
1.初始化弱学习器(目标值的均值作为预测值)
2.迭代构建学习器,每一个学习器拟合上一个学习器的负梯度
3.直到达到指定的学习器个数
4.当输入未知样本时,将所有弱学习器的输出作为结果组合起来作为强学习器的输出
平方损失=(左子树的负梯度-左子树负梯度的平均值)平方+(右子树的负梯度-右子树负梯度的平均值)平方
第一个决策树 :负梯度=真实-预测 然后当下一轮的目标值,对数据进行切分通过得到平方损失最小的当切分点得到第一个决策树
第二个决策树:目标值为上一轮的负梯度,预测值为负梯度的平均值,负梯度=真实-预测 对数据进行切分通过得到平方损失最小的当切分点得到第一个决策树
XGboost:极限梯度提升树构建模型的方式为:最小化训练数据的损失函数训练模型的复杂度较高容易过拟合,通过加入正则化提高对物质的测试数据的泛化性能
API:
import pandas as pd
import joblib
from sklearn.model_selection import train_test_split,GridSearchCV # 数据集的划分,网格搜索和交叉验证
from sklearn.model_selection import StratifiedKFold # 分层K折交叉验证,类似于网格搜索cv的折数
from collections import Counter # 统计标签个数
import xgboost as xgb # 极限梯度提升树
from sklearn.utils import class_weight # 平衡权重
from sklearn.metrics import accuracy_score
# 定义函数对数据集进行划分
def dm01_data_split():
df=pd.read_csv('../../data/红酒品质分类 - 副本.csv')
# 对特征和标签进行划分
x=df.iloc[:,:-1]
y=df.iloc[:,-1]-3
# 查看数据集的分布情况
print(f'数据集的分布情况{Counter(y)}')
# 数据集进行划分
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=22,stratify=y)
# 对划分的训练集和测试集进行保存
pd.concat([x_train,y_train],axis=1).to_csv('../../data/红酒品质分类_训练集',index=False)
pd.concat([x_test,y_test],axis=1).to_csv('../../data/红酒品质分类_测试集',index=False)
# 模型的训练
def dm02_model_train():
# 读取训练集数据集文件
data_train=pd.read_csv('../../data/红酒品质分类_训练集')
x_train = data_train.iloc[:, :-1] # 除了最后1列,取所有的特征
y_train = data_train.iloc[:, -1] # 最后1列是标签
# 读取测试集数据集文件
data_test=pd.read_csv('../../data/红酒品质分类_测试集')
x_test = data_test.iloc[:, :-1] # 除了最后1列,取所有的特征
y_test = data_test.iloc[:, -1] # 最后1列是标签
# 模型的创建,分类模型
model=xgb.XGBClassifier(
max_depth=5,# 树的最大深度
learning_rate=0.1, # 学习率
n_estimators=100,# 树的个数
random_state=24, # 随机种子
objective='multi:softmax'# 多分类问题
)
# 平衡权重
cw=class_weight.compute_sample_weight('balanced', y_train)
# 模型的训练
model.fit(x_train,y_train,sample_weight=cw)
# 模型的评估
print(f'模型的准确率是{model.score(x_test,y_test)}')
# 模型的保存
joblib.dump(model,'../../model/红酒品质分类.pkl')
print('模型保存成功')
# 模型的测试
def dm03_model_use():
# 读取测试数据
test_data = pd.read_csv('../../data/红酒品质分类_测试集')
x_test = test_data.iloc[:, :-1]
y_test = test_data.iloc[:, -1]
# 加载模型
model=joblib.load('../../model/红酒品质分类.pkl')
# 模型的训练
y_pred = model.predict(x_test)
# 模型的评估
print(f'模型的准确率是{accuracy_score(y_test,y_pred)}')
def dm04_model_ty():
# 读取训练集数据集文件
data_train = pd.read_csv('../../data/红酒品质分类_训练集')
x_train = data_train.iloc[:, :-1] # 除了最后1列,取所有的特征
y_train = data_train.iloc[:, -1] # 最后1列是标签
# 读取测试集数据集文件
data_test = pd.read_csv('../../data/红酒品质分类_测试集')
x_test = data_test.iloc[:, :-1] # 除了最后1列,取所有的特征
y_test = data_test.iloc[:, -1] # 最后1列是标签
# 加载模型
model = joblib.load('../../model/红酒品质分类.pkl')
# 模型参数调优
# max_depth = 5, # 树的最大深度
# learning_rate = 0.1, # 学习率
# n_estimators = 100, # 树的个数
# random_state = 24, # 随机种子
# objective = 'multi:softmax' # 多分类问题
params={
'max_depth': [8,10,12],
'n_estimators':[i for i in range(60,100,5)],
'learning_rate':[0.1,0.2,0.3,0.4],
'random_state':[18,22,23,21]
}
# 创建分层采样对象,参数 折数 参数 随机种子 参数 是否重新洗牌
skf=StratifiedKFold(n_splits=5,random_state=2,shuffle=True)
gs_model=GridSearchCV(model,param_grid=params,cv=skf)
# 模型的训练
gs_model.fit(x_train,y_train)
# 模型的预测
y_pre=gs_model.predict(x_test)
# 准确率
print(f'模型的准确率是{accuracy_score(y_test,y_pre)}')
# 最优超参组合
print(f'组合是{gs_model.best_params_}')
if __name__=='__main__':
# dm01_data_split()
# dm02_model_train()
# dm03_model_use()
dm04_model_ty()
更多推荐


所有评论(0)