集成学习方法之随机森林
集成学习(Ensemble Learning)是一种通过组合多个分类器来提高预测性能的方法。主要分为三种类型:Bagging、Boosting和Stacking。以下是集成学习的基本步骤和概念:
1数据采样:从训练集中有放回地随机抽取多个子集。
2模型训练:在每个子集上训练一个子模型(例如决策树)。
3继承预测:对于分类问题,通过投票(选择得票最多的类别)来确定最终的预测结果。
随机森林是集成学习的一种应用。它通过构建多个决策树(通常称为基学习器或弱学习器),每棵树使用不同的数据和特征子集进行训练。最终,随机森林通过对所有决策树的预测结果进行投票来获得最终结果。随机森林不仅能提高预测精度,还能有效降低过拟合风险,并处理高纬度和大规模数据集。
1. 算法原理
-
随机性:
-
样本:每次从训练集T中有放回地随机抽取n个样本用于训练一个决策树。
-
特征:每棵树在训练时仅使用k(k<d)个随机选择的特征。
-
-
森林:由多个决策树组成的集成分类器,通过引入随机性生成多个不同的决策树。
-
优势:能够处理高维特征数据,无需降维,且通过平均或投票机制提高预测精度并控制过拟合。
2.API及其使用
class sklearn.ensemble.RandomForestClassifier n_estimators: int, default=100 森林中树木的数量(即决策树的数量)。增加树木数量通常会提高模型的性能,但也会增加计算复杂度和内存使用。 criterion: {"gini", "entropy"}, default="gini" 决策树的分裂标准: "gini":使用基尼不纯度(Gini impurity)来评估特征的分裂效果。 "entropy":使用信息增益(Information Gain)来评估特征的分裂效果。 max_depth: int, default=None 决策树的最大深度。限制树的深度可以防止过拟合。如果设置为 None,则树会被扩展到每个叶子节点包含最小样本数(由 min_samples_split 和 min_samples_leaf 控制)的条件下。
示例:坦尼克号乘客生存
import pandas as pd from sklearn.model_selection import train_test_split from skearn.freature_extraction import DictVectorizer from sklearn.tree import export_graphviz from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import GridSearchCV #加载数据 data=pd.read_csv('./src/titanic/titanic.csv') x=data[["pclass","age","sex"]] y=data["survived"] #数据处理 x["age"].fillna(x["age"].mean(),inplace=True)#缺失值处理 x=x.to_dict(orient="records")#转换成字典 #数据划分 x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=44) #字典特征抽取 transfer=DictVectorizer() x_train=transfer.fit_transform(x_train) x_test=transfer.transform(x_test) #预估器:网格搜索与交叉验证 model=RandomForestClassifier() predict={"n_estimators":[200,300,400,500,600],"max_depth":[5,6,7,8]} model=GridSearchCV(model,param_grid=predict,cv=3) #训练 model.fit(x_train,y_train) #模型评估 y_predict=model.predict(x_test) print("yield:\n",y_predict) print("直接比对真实值与预测值:\n",y_test==y_predict) #计算准确率 score=model.score(x_test,y_test) print("准确率:\n",score) print(model.best_estimator_) print(model.best_score_) print(model.cv_results_)
线性回归
标称型数据(Nominal Data)用于分类不同的类别,特点包括无序性、非数值性和多样性。例如,颜色、性别等分类数据。这类数据不能进行数学运算,适用于分类任务。
连续型数据(Continuous Data)是可测量的,具有明确的数值关系和距离,如温度、重量。其特点包括可测量性、无限可分性和支持数学运算。这类数据常用于回归分析和各种统计计算。
1.什么是回归?
回归的目的是预测数值型目标值 ( y )。最直接的方法是用输入 ( x ) 写出一个目标值 ( y ) 的计算公式。例如,要预测某机器学习的效果,可能使用如下公式:
y=0.015w1−0.69w2
这就是回归方程,其中 ( 0.015 ) 和 ( -0.69 ) 是回归系数。回归过程的核心在于求这些系数。一旦获得回归系数,预测值就可以通过将输入值乘以相应的系数并求和来得出。
2.线性回归
线性回归是机器学习中一种有监督学习的算法,回归问题主要关注的是因变量(需要预测的值)和一个或多个数值型的自变量(预测变量)之间的关系。
因变量:即目标变量,target,y 自变量:影响目标变量的因素:X_1,X_2...X_n (连续值或离散值) 因变量与自变量之间的关系:即模型,model
人工智能中的线性回归:数据集中,往往找不到一个完美的方程式来100%满足所有的y目标
我们就需要找出一个最接近真理的方程式
3.损失函数
用于衡量模型在训练集上的表现好坏,通常是一个非负数值,其值越小,表示模型的预测结果与真实结果之间的差距越小,即模型的表现越好。
数据: [[4.2, 3.8],[4.2, 2.7],[2.7, 2.4],[0.8, 1.0],[3.7, 2.8],[1.7, 0.9],[3.2, 2.9]]
我们假设 这个最优的方程是:
y=wx+b
这几条中,哪一条是比较好的呢?
有很多方式认为某条直线是最优的,其中一种方式:均方差
就是每个点到线的竖直方向的距离平方 求和 在平均 最小时 这条直接就是最优直线
总误差(也就是传说中的损失):
平均误差(总误差会受到样本点的个数的影响,样本点越多,该值就越大,所以我们可以对其平均化,求得平均值,这样就能解决样本点个数不同带来的影响)
这样就得到了传说中的损失函数:
4.多参数回归
参数回归通常涉及多个自变量(特征)和一个因变量(目标),例如房价预测、股票价格预测、天气预报等,并且可以使用多种回归模型来解决,如线性回归、岭回归、LASSO 回归等。
波士顿房价数据集包含了波士顿郊区的房屋信息,每个样本包含13个特征,以及一个目标值,即该地区的中位数房价。这些特征包括但不限于:
-
CRIM:城镇人均犯罪率
-
ZN:住宅用地超过2.5万平方英尺的比例
-
INDUS:城镇非零售商业用地比例
-
CHAS:虚拟变量,如果邻近查尔斯河则为1
-
NOX:一氧化氮浓度(每千万分之一)
-
RM:每个住宅的平均房间数
-
AGE:1940年前建造的自住单元比例
-
DIS:到波士顿五个就业中心的加权距离
-
RAD:径向公路的可达性指数
-
TAX:全额房产税率
-
PTRATIO:城镇师生比例
-
B:1000(Bk - 0.63)^2,其中Bk是黑人的比例
-
LSTAT:低社会地位人口的比例
目标是预测 MEDV
,即自住房屋的中位数价值(以千美元计)。
5.最小二乘法MSE
矩阵相关公式:
最小二乘法:
这就是传说中的最小二乘法公式
n为什么等于2,因为是一个常数,求最小值是n随便取哪个正数都不会影响w结果,但是n=2求导过程可以约掉前面的系数
1.二次方程导数为0时最小
2.先展开矩阵乘法
3.进行求导(注意X,y都是已知的,W是未知的)
4.令导数
5.矩阵没有除法,使用逆矩阵转化
第二种方式链式求导
内部函数:
外部函数:
其中
外部函数的导数:
内部函数的导数:
应用链式法则,我们得到最终的梯度:
API及其示例
sklearn.linear_model.LinearRegression()
最小二乘法线性回归,权重和偏置直接算出来的,不适合数据量大太
参数:
fit_intercept bool, default=True 是否计算此模型的截距(偏置)。如果设置为False,则在计算中将不使用截距(即,数据应中心化)。 属性: coef_ 回归后的权重系数 intercept_ 偏置
from sklearn.linear_model import LinearRegression import numpy as np data=np.array([[0,14,8,0,5,-2,9,-3,399],[-4,10,6,4,-14,-2,-14,8,-144],[-1,-6,5,-12,3,-3,2,-2,30],[5,-2,3,10,5,11,4,-8,126],[-15,-15,-8,-15,7,-4,-12,2,-395],[11,-10,-2,4,3,-9,-6,7,-87],[-14,0,4,-3,5,10,13,7,422],[-3,-7,-2,-8,0,-6,-5,-9,-309]]) x=data[:,0:-1] y=data[:,-1] model=LinearRegression(fit_intercept=False) model.fit(x,y) print("权重系数:\n",model.coef_) print("偏置:\n",model.intercept_) y_predict=model.predict([[-1,-6,5,-12,3,-3,2,-2],[5,-2,3,10,5,11,4,-8],[11,14,8,10,5,10,8,1] ]) print("预测值:\n",y_predict) print(f"评估得分:{model.score(x,y)}")
6.梯度下降
梯度下降概念
核心思想是通过迭代的方式逐步调整参数,使目标函数的值不断减小,直至达到局部或全局最小值。
目标函数:机器学习中,通常时损失函数或代价函数,衡量模型预测与实际值的差异。目标是找到一组参数,是目标函数的值最小。 梯度:梯度是一个向量,表示目标函数在某一点处的斜率,即各个方向上的变化率。梯度的方向指向了函数增长最快的方向。(梯度表示损失函数对于模型参数的偏导数) 迭代更新:梯度下降通过迭代的方式更新参数,每次更新都朝着梯度的负方向移动一定步长。
梯度下降步骤
-
初始化参数
-
计算梯度
-
更新参数
-
检查停止条件
详细步骤解释
1. 初始化参数
-
选择初始点:选择一组初始参数 w0。这可以是随机选择的,也可以是基于某些先验知识。
-
设置超参数:选择学习率 α和最大迭代次数 T。学习率 α 控制每次更新的步长,而最大迭代次数 T控制迭代的上限。
2. 计算梯度
-
目标函数:确定你要最小化的目标函数 J(w)。在机器学习中,这通常是损失函数或代价函数。
-
梯度:计算目标函数在当前参数 wt 处的梯度 ∇J(wt)。梯度是一个向量,表示目标函数在各个方向上的变化率。梯度的方向指向了函数值增加最快的方向。
3. 更新参数
-
梯度更新:根据梯度和学习率更新参数:
wt+1=wt−α∇J(wt)
这里的wt+1是更新后的参数,wt是当前参数,α是学习率∇J(wt)是目标函数在当前参数处的梯度。
4. 检查停止条件
-
停止条件:检查是否满足停止条件。常见的停止条件包括:
-
梯度接近零:当梯度的模长小于某个阈值(例如 ∥∇J(wt)∥<ϵ)时停止迭代。
-
达到最大迭代次数:当迭代次数达到预设的最大值时停止迭代。
-
变化量很小:当参数的变化量小于某个阈值时停止迭代,即 ∥wt+1−wt∥<δ。
-
梯度下降公式
示例:
假设我们的学习率 α=0.01α=0.01,并且我们的目标函数是 f(w)=12w2f(w)=21w2,那么梯度就是 f′(w)=wf′(w)=w。
-
初始化:w0=0.2
-
第一次更新:
-
计算梯度: f′(w0)=0.2
-
更新参数: w1=w0−αf′(w0)=0.2−0.01×0.2=0.2−0.002=0.198
-
-
第二次更新:
-
计算梯度: f′(w1)=0.198
-
更新参数: w2=w1−αf′(w1)=0.198−0.01×0.198=0.198−0.00198=0.19602
-
-
第三次更新:
-
计算梯度: f′(w2)=0.19602
-
更新参数: w3=w2−αf′(w2)=0.19602−0.01×0.19602=0.19602−0.0019602=0.1940598
-
依此类推,每一步都将使 ww 更接近于 0,即抛物线的最低点。
学习率
学习率(Learning Rate)是梯度下降算法中的一个重要超参数,它决定了每次迭代时参数更新的步长大小。选择合适的学习率对于模型的收敛速度和最终性能至关重要。学习率的选择不当可能会导致算法无法收敛,或者收敛速度非常缓慢。
学习率的作用
学习率 α 决定了每次梯度更新的幅度:
wt+1=wt−α∇J(wt)
-
如果学习率太大,步长可能会过大,导致参数更新跳跃过大,可能会越过最小值点,甚至导致发散。
-
如果学习率太小,虽然能更精细地逼近最小值点,但会导致收敛速度非常慢。
通常,学习率设置为小数值(如0.1、0.01、0.001等)是比较常见的做法。在实际应用中,我们可以使用以下策略来优化学习率的设置:
-
学习率衰减:随着迭代次数的增加,逐渐减小学习率,这样可以在接近最优点时使步长变小,从而提高模型的收敛精度,避免在最优点附近震荡。
-
自适应学习率优化算法:一些高级优化算法(如Adam、RMSprop等)可以自动调整学习率,根据梯度的历史信息来更新学习率,从而在训练过程中动态优化步长。
自己实现梯度下降
1.假设损失函数是只有一个w1特征的抛物线:
要求解抛物线最小值时的横坐标w1的值
import numpy as np import matplotlib.pyplot as plt def fn1(w):return (w-3.5)**2-4.5*w+20 w=np.linspace(1,10,100) plt.plot(w,fn1(w)) plt.show() np.random.seed(18) w1=np.random.randint(1,10) print("随机初始化一个w1:\n",w1) def fn2(w1):return 2*(w1-3.5)-4.5 #学习率 a=0.01 w2=w1-a*fn2(w1) print("沿着梯度方向的反方向更新后w2:",w2) w3=w2-a*fn2(w2) print("沿着梯度方向的反方向更新后w3:",w3)
sklearn梯度下降
-
批量梯度下降 (BGD, Batch Gradient Descent):
-
在每次更新参数时,使用整个训练集来计算梯度。
-
优点:每次参数更新都会朝着全局最小值的方向前进,因为它是基于所有数据点的梯度平均。
-
缺点:计算量大,尤其是在大数据集上,每次迭代都需要计算所有数据点的梯度;而且如果数据很大,则可能导致内存不足的问题。
-
-
小批量梯度下降 (MBGD, Mini-Batch Gradient Descent):
-
每次更新参数时,从训练集中随机选择一个小批量的数据子集(通常几十到几百个样本)来估计梯度。
-
优点:结合了BGD和平滑性的优势,并且计算效率比BGD高得多,因为它不需要使用全部数据;同时相比于SGD更加稳定。
-
缺点:需要选择合适的批量大小,而且在某些情况下可能仍然需要较大的内存来存储批量数据。
-
-
随机梯度下降 (SGD, Stochastic Gradient Descent):
-
每次更新参数时只使用单个训练样本来估计梯度。
-
优点:非常快,因为它只需要处理一个样本;适合于大规模数据集。
-
缺点:由于每次更新都仅基于一个样本,所以更新路径会更不稳定,可能会导致更多的波动,从而使得收敛过程更慢或者更难找到全局最小值。
-