经典机器学习模型(八)梯度提升树GBDT详解

经典机器学习模型(八)梯度提升树GBDT详解

Boosting、Bagging和Stacking是集成学习(Ensemble Learning)的三种主要方法。

Boosting是一族可将弱学习器提升为强学习器的算法,不同于Bagging、Stacking方法,Boosting训练过程为串联方式,弱学习器的训练是有顺序的,每个弱学习器都会在前一个学习器的基础上进行学习,最终综合所有学习器的预测值产生最终的预测结果。

我们之前详细介绍过提升方法中的AdaBoost算法。今天,我们继续来了解下另一种提升方法—梯度提升树GBDT。

传统机器学习(六)集成算法(2)—Adaboost算法原理

1 GBDT原理详解

1.1 初识GBDT

GBDT(Gradient Boosting Decision Tree),全名叫梯度提升决策树,是一种迭代的决策树算法,它通过构造一组弱的学习器(树),并把多颗决策树的结果累加起来作为最终的预测输出。该算法将决策树与集成思想进行了有效的结合。

GBDT的原理很简单

  • 所有弱分类器的结果相加等于预测值。
  • 每次都以当前预测为基准,下一个弱分类器去拟合残差(预测值与真实值之间的误差)
  • GBDT的弱分类器使用的是树模型。
  • 注意:实际上每个决策树拟合的都是负梯度,只是当损失函数是均方损失时,负梯度刚好是残差,所以其实残差只是负梯度的一种特例而已,我们后面会详细说明。

下图是一个非常简单的帮助理解的示例,我们用GBDT去预测年龄:

  • 第一个弱分类器(第一棵树)预测一个年龄(如20岁),计算发现误差有10岁;
  • 第二棵树预测拟合残差,预测值6,计算发现差距还有4岁;
  • 第三棵树继续预测拟合残差,预测值3,发现差距只有1岁了;
  • 第四课树用1岁拟合剩下的残差,完成。
  • 最终,四棵树的结论加起来,得到30岁这个标注答案。

在这里插入图片描述

1.2 梯度下降和梯度提升

1.2.1 梯度下降

梯度下降法,我们都比较熟悉。不妨思考这样一个问题,梯度下降法中,为什么在负梯度方向函数值下降最快?

我们目标就是证明负梯度方向函数值下降最快。
假设我们现在处于函数 f ( x ) f(x) f(x)的一个点上,这个点的坐标为 x ⃗ = ( x 1 , x 2 , . . . , x n ) \vec{x}=(x_1,x_2,...,x_n) x =(x1,x2,...,xn),此时函数值为 f ( x ⃗ ) f(\vec{x}) f(x )

让我们假设一个下降的方向,这个方向是随机的,我们设这个方向是 l ⃗ = ( l 1 , l 2 , . . . , l n ) \vec{l}=(l_1,l_2,...,l_n) l =(l1,l2,...,ln),那么我们沿着 l ⃗ \vec{l} l 下降的意思就是,我们下一步将来到 f ( x ⃗ + l ⃗ ) 。 f(\vec{x}+\vec{l}) 。 f(x +l )

根据多元函数的一阶泰勒展开公式,我们有:
f ( x ⃗ + l ⃗ ) = f ( x ⃗ ) + ∑ k = 1 n ∂ f ∂ x k l k + o ( ∣ ∣ x ∣ ∣ n ) f(\vec{x}+\vec{l})=f(\vec{x})+\sum_{k=1}^n \frac{\partial f}{\partial x_k}l_k + o(||x||^n) f(x +l )=f(x )+k=1nxkflk+o(∣∣xn)
f ( x ⃗ + l ⃗ ) − f ( x ⃗ ) f(\vec{x}+\vec{l})-f(\vec{x}) f(x +l )f(x )就是移动后函数值的变化量,也就是说,只要这个值小于零,我们的函数值就在变小。而只要我们可以证明当 l ⃗ \vec{l} l 取到梯度的负方向时这个值小于零且绝对值最大,那么我们就证明了我们的目标。
而 f ( x ⃗ + l ⃗ ) − f ( x ⃗ ) = ∑ k = 1 n ∂ f ∂ x k l k + o ( ∣ ∣ x ∣ ∣ n ) 自变量变化值极小的时候 ( ∣ ∣ l ⃗ ∣ ∣ 极小 ) ,我们可以忽略 o ( ∣ ∣ x ∣ ∣ n ) 而f(\vec{x}+\vec{l})-f(\vec{x})=\sum_{k=1}^n \frac{\partial f}{\partial x_k}l_k + o(||x||^n)\\ 自变量变化值极小的时候(||\vec{l}|| 极小),我们可以忽略o(||x||^n) f(x +l )f(x )=k=1nxkflk+o(∣∣xn)自变量变化值极小的时候(∣∣l ∣∣极小),我们可以忽略o(∣∣xn)
我们现在仅剩的问题就是如何找到一个方向,使得 ∑ k = 1 n ∂ f ∂ x k l k \sum_{k=1}^n \frac{\partial f}{\partial x_k}l_k k=1nxkflk小于零且绝对值最大。

  • 我们观察这个式子,它其实是两个向量的数量积,我们知道当两个向量的夹角为0或180度时,该数量积的绝对值取得最大值。
  • 而最后一个小于零的条件很容易满足,我们只需要让 l ⃗ = − g r a d f ⃗ \vec{l}=-\vec{grad_f} l =gradf 。这样的话,对于这两个向量来说,他们的每一个维度都互为对方的相反数,因此他们的数量积一定不可能大于零,在实际情况下,他们甚至一直小于零。
  • 到这里,我们就证明了当且仅当 l ⃗ \vec{l} l 的方向是负梯度方向时,函数值下降最快。
  • 因此,使用梯度下降法时为了让函数值下降最快,在参数更新时候就需要沿着负梯度方向更新。

在梯度下降法中,我们经常用 θ 表示参数。 f ( x ⃗ + l ⃗ ) = f ( x ⃗ ) + ∑ k = 1 n ∂ f ∂ x k l k + o ( ∣ ∣ x ∣ ∣ n ) 可以表示为: f ( θ k + 1 ) ≈ f ( θ k ) + ∂ f ( θ k ) ∂ θ k ( θ k + 1 − θ k ) = f ( θ k ) + ∂ f ( θ k ) ∂ θ k ∇ θ 当 ∇ θ = − g r a d f ⃗ = − ∂ f ( θ k ) ∂ θ k 时,下降最快 因此,参数迭代公式 θ k + 1 = θ k + η ∇ θ = θ k − η ∂ f ( θ k ) ∂ θ k 在梯度下降法中,我们经常用\theta表示参数。\\ f(\vec{x}+\vec{l})=f(\vec{x}) + \sum_{k=1}^n \frac{\partial f}{\partial x_k}l_k + o(||x||^n)\\ 可以表示为:f(\theta_{k+1}) \approx f(\theta_{k})+\frac{\partial f(\theta_k)}{\partial \theta_k}(\theta_{k+1}-\theta_k)\\ =f(\theta_{k})+\frac{\partial f(\theta_k)}{\partial \theta_k}\nabla\theta\\ 当\nabla\theta=-\vec{grad_f}=-\frac{\partial f(\theta_k)}{\partial \theta_k}时,下降最快 \\ 因此,参数迭代公式\theta_{k+1}=\theta_k + \eta \nabla\theta =\theta_k - \eta\frac{\partial f(\theta_k)}{\partial \theta_k} 在梯度下降法中,我们经常用θ表示参数。f(x +l )=f(x )+k=1nxkflk+o(∣∣xn)可以表示为:f(θk+1)f(θk)+θkf(θk)(θk+1θk)=f(θk)+θkf(θk)θθ=gradf =θkf(θk)时,下降最快因此,参数迭代公式θk+1=θk+ηθ=θkηθkf(θk)

补充以下泰勒展开公式:

在这里插入图片描述

1.2.2 梯度提升原理推导

我们利用一阶泰勒展开公式,对损失函数进行泰勒展开:

在这里插入图片描述

在优化 L ( y , F t ( x ) ) L(y,F_t(x)) L(y,Ft(x))的时候:
函数更新公式: F t ( x ) = F t − 1 ( x ) − a t ∂ L ( y , F t − 1 ( x ) ) ∂ F t − 1 ( x ) 即 T t ( x ) = − a t ∂ L ( y , F t − 1 ( x ) ) ∂ F t − 1 ( x ) 所以需要当前的学习器来学习负梯度,这里和 G B D T 中差了一个 a 。 函数更新公式:F_t(x)=F_{t-1}(x)-a_t\frac{\partial L(y,F_{t-1}(x))}{\partial F_{t-1}(x)}\\ 即T_t(x)=-a_t\frac{\partial L(y,F_{t-1}(x))}{\partial F_{t-1}(x)}\\ 所以需要当前的学习器来学习负梯度,这里和GBDT中差了一个a。 函数更新公式:Ft(x)=Ft1(x)atFt1(x)L(y,Ft1(x))Tt(x)=atFt1(x)L(y,Ft1(x))所以需要当前的学习器来学习负梯度,这里和GBDT中差了一个a
当我们的损失函数为平方损失时候, L ( y , f ( x ) ) = ( y − f ( x ) ) 2 L(y,f(x))=(y-f(x))^2 L(y,f(x))=(yf(x))2,此时学习器要学习的负梯度为:
G B D T 中忽略 a t , 那么 T t ( x ) = − ∂ L ( y , F t − 1 ( x ) ) ∂ F t − 1 ( x ) 这里为了求导方便,损失函数加上 1 2 = − ∂ 1 2 ( y − f ( x ) ) 2 ∂ f ( x ) f ( x ) = f t − 1 ( x ) = y − f t − 1 ( x ) GBDT中忽略a_t,那么T_t(x)=-\frac{\partial L(y,F_{t-1}(x))}{\partial F_{t-1}(x)}\\ 这里为了求导方便,损失函数加上\frac{1}{2} \\ =-\frac{\partial \frac{1}{2}(y-f(x))^2}{\partial f(x)}_{f(x)=f_{t-1}(x)}\\ =y-f_{t-1}(x) GBDT中忽略at,那么Tt(x)=Ft1(x)L(y,Ft1(x))这里为了求导方便,损失函数加上21=f(x)21(yf(x))2f(x)=ft1(x)=yft1(x)
y − f t − 1 ( x ) y-f_{t-1}(x) yft1(x)刚好是残差,因此每个决策树拟合的都是负梯度,只是当损失函数是均方损失时,负梯度刚好是残差,所以其实残差只是负梯度的一种特例而已。

1.2.3 梯度下降VS梯度提升

  • 我们已经通过一阶泰勒展开证明了负梯度方向是下降最快的方向。

  • 我们熟悉的梯度下降法是在参数空间中优化。对于最终的最优解 θ ∗ \theta^* θ,是由初始值 θ 0 \theta_0 θ0经过T次迭代之后得到的。

设 θ 0 = − ∂ L ( θ ) ∂ θ 0 ,那么 θ ∗ 表示为 θ ∗ = ∑ t = 0 T a t ∗ [ − ∂ L ( θ ) ∂ θ ] θ = θ t − 1 [ − ∂ L ( θ ) ∂ θ ] θ = θ t − 1 表示 θ 在 θ t − 1 处泰勒展开式的一阶导数 设\theta_0= -\frac{\partial L(\theta)}{\partial \theta_0},那么\theta^*表示为 \\ \theta^*=\sum_{t=0}^T a_t * [-\frac{\partial L(\theta)}{\partial \theta}]_{\theta=\theta_{t-1}} \\ [-\frac{\partial L(\theta)}{\partial \theta}]_{\theta=\theta_{t-1}}表示\theta在\theta_{t-1}处泰勒展开式的一阶导数 θ0=θ0L(θ),那么θ表示为θ=t=0Tat[θL(θ)]θ=θt1[θL(θ)]θ=θt1表示θθt1处泰勒展开式的一阶导数

  • 函数空间中,我们也可以借鉴梯度下降的思想,进行最优函数的搜索。对于模型的损失函数 L ( y , F ( x ) ) L(y,F(x)) L(y,F(x)),为了能求出最优的函数 F ∗ ( x ) F^*(x) F(x),我们首先也设置初始值 F 0 ( x ) = f 0 ( x ) F_0(x)=f_0(x) F0(x)=f0(x)

  • 以函数 F ( x ) F(x) F(x)为一个整体,与梯度下降法的更新过程一致,假设经过T次迭代得到最优函数 F ∗ ( x ) F^*(x) F(x)
    F ∗ ( x ) = ∑ t = 0 T f t ( x ) 其中 , f t ( x ) = a t [ − ∂ L ( y , F ( x ) ) ∂ F ( x ) ] F ( x ) = F t − 1 ( x ) F^*(x)=\sum_{t=0}^Tf_t(x) \\ 其中,f_t(x)=a_t[-\frac{\partial L(y,F(x))}{\partial F(x)}]_{F(x)=F_{t-1}(x)} F(x)=t=0Tft(x)其中,ft(x)=at[F(x)L(y,F(x))]F(x)=Ft1(x)

  • 可以看到,这里的梯度变量是一个函数,是在函数空间上求解,而我们以前梯度下降算法是在多维参数空间中的负梯度方向,变量是参数

    • 为什么是多维参数,因为一个机器学习模型中可以存在多个参数。
    • 而这里的变量是函数,更新函数通过当前函数的负梯度方向来修正模型,使模型更优,最后累加的模型为近似最优函数

在这里插入图片描述

  • Gradient Boosting算法在每一轮迭代中,首先计算出当前模型在所有样本上的负梯度,然后以该值为目标训练一个新的弱分类器进行拟合并计算出该弱分类器的权重,最终实现对模型的更新。

梯度提升和梯度下降的区别和联系:

  • 两者都是在每一轮迭代中,利用损失函数相对于模型的负梯度方向的信息来对当前模型进行更新

  • 只不过在梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参数的更新。

  • 而在梯度提升中,模型并不需要进行参数化表示,而是直接定义在函数空间中,从而大大扩展了可以使用的模型种类。

  • 梯度提升Gradient Boosting是Boosting中的一大类算法,它的思想借鉴于梯度下降法,其基本原理是根据当前模型损失函数的负梯度信息来训练新加入的弱分类器,然后将训练好的弱分类器以累加的形式结合到现有模型中。采用决策树(通常为CART树)作为弱分类器的Gradient Boosting算法被称为GBDT。

在这里插入图片描述

1.3 几个容易混淆的概念

1.3.1 梯度提升和提升树算法

  • 提升树利用加法模型与前向分歩算法实现学习的优化过程。
  • 当损失函数是平方误差损失函数指数损失函数时,每一步优化是很简单的。
  • 但对一般损失函数而言,往往每一步优化并不那么容易。针对这一问题,Freidman提出了梯度提升(gradient boosting)算法。这是利用损失函数的负梯度在当前模型的值 [ − ∂ L ( y , F ( x ) ) ∂ F ( x ) ] F ( x ) = F t − 1 ( x ) [-\frac{\partial L(y,F(x))}{\partial F(x)}]_{F(x)=F_{t-1}(x)} [F(x)L(y,F(x))]F(x)=Ft1(x)作为提升树算法中残差的近似值,拟合一个梯度提升模型。

1.3.2 梯度提升和GBDT

  • 采用决策树作为弱分类器的Gradient Boosting算法被称为GBDT,GBDT中使用的决策树通常为CART。
  • GBDT使用梯度提升(Gradient Boosting)作为训练方法。
  • Gradient Boosting是Boosting中的一大类算法,其中包括:GBDT(Gradient Boosting Decision Tree)、XGBoost(eXtreme Gradient Boosting)、LightGBM (Light Gradient Boosting Machine)和CatBoost(Categorical Boosting)等。

  • XGBoost原理可以参考知乎文章(写的相当细致):深入理解XGBoost

  • 回归树可以利用集成学习中的Boosting框架改良升级得到提升树,提升树再经过梯度提升算法改造就可以得到GBDT算法,GBDT再进一步可以升级为XGBoost、LightGBM或者CatBoost。

1.4 GBDT回归算法

1.4.1 相关算法

  • 当我们采用的基学习器是决策树时,那么梯度提升算法就具体到了梯度提升决策树。

  • GBDT算法又叫MART(Multiple Additive Regression),是一种迭代的决策树算法。

  • GBDT算法可以看成是 M M M棵树组成的加法模型:

在这里插入图片描述

回归问题的提升树算法

我们在初识GBDT中就是使用下面的算法,所用损失函数为均方差损失。

在这里插入图片描述

GBDT梯度提升算法

  • 当损失函数是平方误差损失函数指数损失函数时,每一步优化是很简单的。
  • 但对一般损失函数而言,往往每一步优化并不那么容易。针对这一问题,Freidman提出了梯度提升(gradient boosting)算法。

《统计学习方法》中的所写梯度提升算法如下图:

在这里插入图片描述

上图中一棵树T(x)换成了公式表达,书中解释如下:

在这里插入图片描述

1.4.2 GBDT的回归任务常见的损失函数

对于GBDT回归模型,sklearn中实现了四种损失函数

  • 均方差’ls’。默认是均方差’ls’。一般来说,如果数据的噪音点不多,用默认的均方差’ls’比较好。
  • 绝对损失’lad’
  • Huber损失’huber’,如果是噪音点较多,则推荐用抗噪音的损失函数’huber’。
  • 分位数损失’quantile’。而如果我们需要对训练集进行分段预测的时候,则采用’quantile’。

在这里插入图片描述

在这里插入图片描述

2 GBDT算法案例

《统计学习方法》中例8.2给出一个求解回归问题的提升树模型案例。

一个更加复杂的回归问题的案例:GBDT算法原理以及实例理解

GBDT做二分类案例详解:【完善版】深入理解GBDT二分类算法

GBDT做多分类案例详解:深入理解GBDT多分类算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/537711.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java基础第十课——类与对象(1)

前面二白的九讲属于Java基础方面的内容,总体来说偏基础和简单,能完成的操作也有限,有兴趣的同学可以写一写相关的管理系统,后面二白也会上传一些自己敲的小系统,下面就要开始Java面对对象的知识内容了,从这…

ZGC的介绍

背景 在jdk17中已经将ZGC从实验性产品升级到正式产品功能,达到亚毫秒级停顿,毫不留情地将parallel和G1拉开了数量级的差别,无论是平均停顿还是最大停顿时间都能毫不费劲地控制在10ms内。 《深入理解Java虚拟机》在书中这样定义:Z…

Fast-lio2运行时如何显示轨迹线

修改对应设备的.yaml文件,以velodyne为例: 将 path_en参数改为true即可,运行其他设备,修改对应的参数

FME学习之旅---day24

我们付出一些成本,时间的或者其他,最终总能收获一些什么。 高级地理数据库 教程:地理数据库转换 上述教程包括 如何使用 Esri 模板地理数据库 该内容在FME学习之旅day19 已经学习过 使用地理数据库属性域:编写编码属性域 属…

【SpringBoot整合系列】SpringBoot整合FastDFS(一)

目录 FastDFSFastDFS特点相关概念的介绍Tracker ServerStorage Server FastDFS环境搭建【CentOS 7】环境准备安装gcc和libevent上传安装包安装libfastcommon安装FastDFS拷贝配置文件到指定位置tracker配置storage配置client测试上传文件安装fastdfs-nginx-module模块到nginx第一…

Java基础入门--第十二章--多线程

多线程 12.1 进程与进程12.1.1 进程12.1.2 线程 12.2 线程的创建12.2.1 继承Thread类创建多线程12.2.2 实现Runnable接口创建多线程12.2.3 实现Callable接口创建多线程12.2.4 Thread类与Runnable接口实现多线程的对比12.2.5 后台线程 12.3 线程的生命周期及状态转换12.4 线程操…

springboot整合shiro之——拦截路径

简介Shiro: 1.基本功能 身份认证、授权、加密、会话管理 Web支持、缓存、多线程、测试、允许一个用户假装为另一个用户的身份进行访问、记住我 2. 执行过程 分为五步: Subject 用户主体:请求的发起者,即访问应用的用户 Security Manager 安…

在一台恢复测试机器上验证oracle备份有效性

一 目的 定期将生产环境oracle数据库恢复到一台测试环境数据库服务器上,以验证备份是否有效,是否能正常恢复。 二 环境 这里以恢复orcl1库为例,计划在orcl这个实例上进行恢复测试。 三 实验步骤 3.1 在目标端创建和源端一样的备份目录 ①…

公众号小程序二合一分销商城源码系统 带完整的安装代码包以及搭建教程

互联网的快速发展,微信小程序和公众号成为了企业推广与营销的重要工具。为了更好地满足企业的需求,罗峰给大家分享一款公众号小程序二合一分销商城源码系统,该系统集成了小程序和公众号的双重功能,旨在为企业提供更加便捷、高效的…

SpringMVC:搭建第一个web项目并配置视图解析器

👉需求:用spring mvc框架搭建web项目,通过配置视图解析器达到jsp页面不得直接访问,实现基本的输出“hello world”功能。👩‍💻👩‍💻👩‍💻 1 创建web项目 1…

数字IC/FPGA——锁存器/触发器/寄存器

本文主要介绍以下几点: 什么是触发器和锁存器门电路和触发器的区别什么是电平钟控触发器电平钟控触发器触发器和锁存器的区别触发器的分类方式:逻辑功能、触发方式、电路结构、存储数据原理、构成触发器的基本器件寄存器利用移位寄存器实现串并转换或并…

采集主机环境业务日志最佳实践

前言 随着信息技术的飞速发展,主机环境业务越来越复杂,产生的日志数据也呈爆炸式增长。日志数据作为记录系统运行状态、用户行为以及异常事件的重要信息,对于业务分析、故障排查和安全审计等方面具有不可替代的作用。然而,传统的…

简洁易用的记账小程序——微点记账 增加一个新功能

文章目录 背景功能介绍水印相机首页介绍所需权限水印相机功能定位切换拍摄闪光分享 总结 背景 前面已经介绍过了这个小 程 序——微点记账 最近有朋友反馈,能不能出一个水印相机的小程序?很想为小伙伴分忧,但是鉴于小 程 序也需要备 案&…

2024妈妈杯数学建模B题思路-甲骨文智能识别中原始拓片单字自动分割与识别研究

# 1 赛题 B 题 甲骨文智能识别中原始拓片单字自动分割与识别研究 甲骨文是我国目前已知的最早成熟的文字系统,它是一种刻在龟甲或 兽骨上的古老文字。甲骨文具有极其重要的研究价值,不仅对中国文明的 起源具有重要意义,也对世界文明的研究有着…

避坑指南: “低代码开发平台”怎么选看这篇!附案例参考

从事TOB行业 9 年,深入体验过 10 余款低代码产品。 下面基于我的个人认知给大家讲一讲: 低代码开发平台该如何选?从哪些维度可以判断低代码平台适合你的企业?多家企业采用低代码平台的实践案例! 目前市面上有超过 2…

大数据dolphinscheduler 本地容器化安装

Minio 容器安装 docker run -p 9000:9000 -p 9090:9090 --name minio -d -e "MINIO_ACCESS_KEYminioadmin" -e "MINIO_SECRET_KEYminioadmin" -v D:\SF\DOCKER\minio\data:/data -v D:\SF\DOCKER\minio\config:/root/.minio minio/minio server /da…

LeetCode---392周赛

题目列表 3105. 最长的严格递增或递减子数组 3106. 满足距离约束且字典序最小的字符串 3107. 使数组中位数等于 K 的最少操作数 3108. 带权图里旅途的最小代价 一、最长的严格递增或递减子数组 按照题目要求进行模拟即可,这里提供两者思路: 1、两次…

AI赋能校园管理,打造平安智慧校园解决方案

背景: 2020年教育部办公厅印发《教育系统安全专项整治三年行动实施方案》,文中要求,学校在所辖范围内组织开展安全专项整治三年行动,健全完善安全责任体系,建立风险管控和隐患治理的安全防控体系,开展消防等…

tRPC架构设计简单理解

互联网发展早期,业务场景差异大,试错迭代速度很快。这导致其后台服务使用的语言技术栈、开发框架、通信协议、服务治理系统、运维平台等或多或少存在差异。 业务发展到一定阶段后,跨业务合作越来越多,组织架构调整也愈发频繁。技…

局域网管理软件哪个好?局域网电脑管理系统实践案例

之前有一个公司案例,是这样的: 公司名称:智慧科技有限公司 背景: 智慧科技有限公司是一家拥有数百名员工的中型企业,随着业务的快速发展,公司面临着网络管理上的挑战。 员工在日常工作中需要频繁地访问…