机器学习总结(17)-XGBoost

文章目录

  • lecture17:XGBoost(eXtreme Gradient Boosting)
  • 目录
    • 1. XGBoost的基本信息
    • 2. XGBoost与GBDT的异同点
    • 3. XGBoost的原理
        • 3.1定义树的复杂度
        • 3.2 分裂节点
        • 3.3 自定义损失函数
    • 4. XGBoost的使用

lecture17:XGBoost(eXtreme Gradient Boosting)

目录

1. XGBoost的基本信息

全称:eXtreme Gradient Boosting
作者:程天奇(华盛顿大学博士)
基础:GBDT
所属:boosting 迭代算法、树类算法
应用类型:分类和回归
优点:速度快,效果好,可以并行计算处理大量数据,支持多种语言,支持自定义损失函数,正则化,高度灵活性,缺失值处理,剪枝,内置交叉验证,在已有模型基础上继续训练等等
缺点:发布时间短,工业领域应用较少,需要检验

参考博客

2. XGBoost与GBDT的异同点

相同点:
xgboost是在GBDT的基础上对boosting算法进行的改进,内部决策树使用的是回归树,简单回顾GBDT如下:
在这里插入图片描述
注意

XGBoost和GBDT本质的思想都是一种残差学习方式,即当前的弱分类器的主要目标是学习上一个弱分类器的误差;最后,通过将所有的弱分类器集成在一起,组成一个混合模型,从而降低模型的方差和偏差。

不同点:
如果不考虑工程实现、解决问题上的一些差异,xgboost与gbdt比较大的不同就是目标函数的定义。如下图是XGBoost目标函数的定义:
在这里插入图片描述
注意从目标函数的表达式可以看出,XGBoost的目标函数主要分为:加入一颗新树后模型的误差,正则化项和一个常数项;其中模型误差项,可以将加入的新树看成∆X,然后对L函数求泰勒展开,就得到最下面的公式了,从最下面的公式可以看出,目标函数中的损失项包括:上一颗树所在模型的损失,当前加入新树后模型的一阶导数和加入新树后的二阶导数。XGBoost利用泰勒展开三项,做一个近似,我们可以很清晰地看到,最终的目标函数只依赖于每个数据点的在误差函数上的一阶导数和二阶导数。正则化项包括对当前新加入的树叶子结点个数的约束(L1正则化项)和当前新加入树的叶子结点的权重的约束(L2正则化项)。

3. XGBoost的原理

对于上面给出的目标函数,我们可以进一步化简

3.1定义树的复杂度

对于f的定义做一下细化,把树拆分成结构部分q和叶子权重部分w。下图是一个具体的例子。结构函数q把输入映射到叶子的索引号上面去,而w给定了每个索引号对应的叶子分数是什么
在这里插入图片描述
定义这个复杂度包含了一棵树里面节点的个数,以及每个树叶子节点上面输出分数的L2模平方。

当然这不是唯一的一种定义方式,不过这一定义方式学习出的树效果一般都比较不错。下图还给出了复杂度计算的一个例子

在这里插入图片描述
在这种新的定义下,我们可以把目标函数进行如下改写,其中I被定义为每个叶子上面样本集合
在这里插入图片描述
g是一阶导数,h是二阶导数

在这里插入图片描述
注意

在上面的公式中,由于误差项中的第一项是上一个树所在模型的误差,与当前新加入的树无关,所以为一个常数,与目标函数的优化(优化的目标是找到一颗最佳的树(f(t)),将误差降低)无关,可以省略,于是误差项变成了一阶导数和二阶导数之和;由于最终的样本都会划分到每个叶子节点上,所以可以将最开始的样本的遍历换成叶子结点的遍历,从而可以和正则化项中的L2项进行合并,得到最终的公式如上图。
在这里插入图片描述

3.2 分裂节点

论文中给出了两种分裂节点的方法

(1)贪心法
每一次尝试去对已有的叶子加入一个分割,且每次分割的目标就是使得损失函数最小
在这里插入图片描述
注意:

XGBoost和决策树的构造准则不同,它不在基于gini系数或者熵,而是通过比较划分前和划分后对模型的损失(之前推到的那个目标函数)的影响,来选出最佳的树节点的划分。

对于每次扩展,我们还是要枚举所有可能的分割方案,如何高效地枚举所有的分割呢?我假设我们要枚举所有x < a 这样的条件,对于某个特定的分割a我们要计算a左边和右边的导数和
在这里插入图片描述
我们可以发现对于所有的a,我们只要做一遍从左到右的扫描就可以枚举出所有分割的梯度和GL和GR。然后用上面的公式计算每个分割方案的分数就可以了。

观察这个目标函数,大家会发现第二个值得注意的事情就是引入分割不一定会使得情况变好,因为我们有一个引入新叶子的惩罚项。优化这个目标对应了树的剪枝, 当引入的分割带来的增益小于一个阀值的时候,我们可以剪掉这个分割。大家可以发现,当我们正式地推导目标的时候,像计算分数和剪枝这样的策略都会自然地出现,而不再是一种因为heuristic(启发式)而进行的操作了。

**下面是论文中的算法 **
在这里插入图片描述
(2)近似算法:

主要针对数据太大,不能直接进行计算

3.3 自定义损失函数

(1)常用损失函数
在这里插入图片描述
(2)一阶导数和二阶导数的推到:
在这里插入图片描述

4. XGBoost的使用

(1)官方代码

#!/usr/bin/python
import numpy as np
import xgboost as xgb
###
# advanced: customized loss function
#
print ('start running example to used customized objective function')dtrain = xgb.DMatrix('../data/agaricus.txt.train')
dtest = xgb.DMatrix('../data/agaricus.txt.test')# note: for customized objective function, we leave objective as default
# note: what we are getting is margin value in prediction
# you must know what you are doing
param = {'max_depth': 2, 'eta': 1, 'silent': 1}
watchlist = [(dtest, 'eval'), (dtrain, 'train')]
num_round = 2# user define objective function, given prediction, return gradient and second order gradient
# this is log likelihood loss
def logregobj(preds, dtrain):labels = dtrain.get_label()preds = 1.0 / (1.0 + np.exp(-preds))grad = preds - labelshess = preds * (1.0-preds)return grad, hess# user defined evaluation function, return a pair metric_name, result
# NOTE: when you do customized loss function, the default prediction value is margin
# this may make builtin evaluation metric not function properly
# for example, we are doing logistic loss, the prediction is score before logistic transformation
# the builtin evaluation error assumes input is after logistic transformation
# Take this in mind when you use the customization, and maybe you need write customized evaluation function
def evalerror(preds, dtrain):labels = dtrain.get_label()# return a pair metric_name, result# since preds are margin(before logistic transformation, cutoff at 0)return 'error', float(sum(labels != (preds > 0.0))) / len(labels)# training with customized objective, we can also do step by step training
# simply look at xgboost.py's implementation of train
bst = xgb.train(param, dtrain, num_round, watchlist, logregobj, evalerror)

(2)XGBoost调参
通用参数
这些参数用来控制XGBoost的宏观功能。

  • booster[默认gbtree]
    • 选择每次迭代的模型,有两种选择:gbtree:基于树的模型 ; gbliner:线性模型
  • silent[默认0]
    • 当这个参数值为1时,静默模式开启,不会输出任何信息。
    • 一般这个参数就保持默认的0,因为这样能帮我们更好地理解模型
  • nthread[默认值为最大可能的线程数]
    • 这个参数用来进行多线程控制,应当输入系统的核数。
    • 如果你希望使用CPU全部的核,那就不要输入这个参数,算法会自动检测它。

还有两个参数,XGBoost会自动设置,目前你不用管它。接下来咱们一起看booster参数

booster参数
尽管有两种booster可供选择,我这里只介绍tree booster,因为它的表现远远胜过linear booster,所以linear booster很少用到

  • eta[默认0.3]
    • 和GBM中的 learning rate 参数类似。
    • 通过减少每一步的权重,可以提高模型的鲁棒性。
    • 典型值为0.01-0.2。
  • min_child_weight[默认1]
    • 决定最小叶子节点样本权重和。
    • 和GBM的 min_child_leaf 参数类似,但不完全一样。XGBoost的这个参数是最小样本权重的和,而GBM参数是最小样本总数。
    • 这个参数用于避免过拟合。当它的值较大时,可以避免模型学习到局部的特殊样本。
    • 但是如果这个值过高,会导致欠拟合。这个参数需要使用CV来调整。
  • max_depth[默认6]
    • 和GBM中的参数相同,这个值为树的最大深度
    • 这个值也是用来避免过拟合的。max_depth越大,模型会学到更具体更局部的样本。
    • 需要使用CV函数来进行调优。
    • 典型值:3-10
  • max_leaf_nodes
    • 树上最大的节点或叶子的数量。
    • 可以替代max_depth的作用。因为如果生成的是二叉树,一个深度为n的树最多生成n^2个叶子
    • 如果定义了这个参数,GBM会忽略max_depth参数。
  • gamma[默认0]
    • 在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。Gamma指定了节点分裂所需的最小损失函数下降值。
    • 这个参数的值越大,算法越保守。这个参数的值和损失函数息息相关,所以是需要调整的。
  • max_delta_step[默认0]
    • 这参数限制每棵树权重改变的最大步长。如果这个参数的值为0,那就意味着没有约束。如果它被赋予了某个正值,那么它会让这个算法更加保守。
    • 通常,这个参数不需要设置。但是当各类别的样本十分不平衡时,它对逻辑回归是很有帮助的。
    • 这个参数一般用不到,但是你可以挖掘出来它更多的用处
  • subsample[默认1]
    • 和GBM中的subsample参数一模一样。这个参数控制对于每棵树,随机采样的比例。
    • 减小这个参数的值,算法会更加保守,避免过拟合。但是,如果这个值设置得过小,它可能会导致欠拟合。
    • 典型值:0.5-1
  • 典型值:0.5-1
    • 和GBM里面的max_features参数类似。用来控制每棵随机采样的列数的占比(每一列是一个特征)。
    • 典型值:0.5-1
  • colsample_bylevel[默认1]
    • 用来控制树的每一级的每一次分裂,对列数的采样的占比。
    • 我个人一般不太用这个参数,因为subsample参数和colsample_bytree参数可以起到相同的作用。但是如果感兴趣,可以挖掘这个参数更多的用处。
  • lambda[默认1]
    • 权重的L2正则化项。(和Ridge regression类似)。
    • 这个参数是用来控制XGBoost的正则化部分的。虽然大部分数据科学家很少用到这个参数,但是这个参数在减少过拟合上还是可以挖掘出更多用处的
  • alpha[默认1]
    • 权重的L1正则化项。(和Lasso regression类似)。
    • 可以应用在很高维度的情况下,使得算法的速度更快。
  • scale_pos_weight[默认1]
    • 在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。

学习目标参数
这个参数用来控制理想的优化目标和每一步结果的度量方法。

  • objective[默认reg:linear]
    这个参数定义需要被最小化的损失函数。最常用的值有:
    • binary:logistic 二分类的逻辑回归,返回预测的概率(不是类别)。
    • multi:softmax 使用softmax的多分类器,返回预测的类别(不是概率)。
      • 在这种情况下,你还需要多设一个参数:num_class(类别数目)。
    • multi:softprob 和multi:softmax参数一样,但是返回的是每个数据属于各个类别的概率。
  • eval_metric[默认值取决于objective参数的取值]
    • 对于有效数据的度量方法。
    • 对于回归问题,默认值是rmse,对于分类问题,默认值是error。
    • 典型值有:
      在这里插入图片描述
  • seed(默认0)
    • 随机数的种子
    • 设置它可以复现随机数据的结果,也可以用于调整参数

(3)Python中对XGBoost的使用

  • 任务:二分类,存在样本不均衡问题(scale_pos_weight参数可以加快训练速度)
def xgboost_predict():import xgboost as xgb#xgboost start heredtest = xgb.DMatrix(test_x)dval = xgb.DMatrix(val_x , label = val_y)dtrain = xgb.DMatrix(x,label = y)params = {'booster':'gbtree','silent':1 ,#设置成1则没有运行信息输出,最好是设置为0.#'nthread':7,# cpu 线程数 默认最大'eta': 0.007, # 如同学习率'min_child_weight':3, # 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言#,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。#这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。'max_depth':6, # 构建树的深度,越大越容易过拟合'gamma':0.1,  # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。'subsample':0.7, # 随机采样训练样本'colsample_bytree':0.7, # 生成树时进行的列采样 'lambda':2,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。#'alpha':0, # L1 正则项参数#'scale_pos_weight':1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。#'objective': 'multi:softmax', #多分类的问题#'num_class':10, # 类别数,多分类与 multisoftmax 并用'seed':1000, #随机种子#'eval_metric': 'auc'}watchlist = [(dval,"val"),(dtrain,"train")] xgboost_model = xgb.train(params , dtrain , num_boost_round = 3000 , evals = watchlist)#xgboost_model.save_model("./xgboost.model")#predict the test setxgboost_predict_y = xgboost_model.predict(dtest , ntree_limit = xgboost_model.best_ntree_limit)
  • DART:将dropput思想引入XGBoost
import xgboost as xgb
# read in data
dtrain = xgb.DMatrix('demo/data/agaricus.txt.train')
dtest = xgb.DMatrix('demo/data/agaricus.txt.test')
# specify parameters via map
param = {'booster': 'dart','max_depth': 5, 'learning_rate': 0.1,'objective': 'binary:logistic', 'silent': True,'sample_type': 'uniform','normalize_type': 'tree','rate_drop': 0.1,'skip_drop': 0.5}
num_round = 50
bst = xgb.train(param, dtrain, num_round)
# make prediction
# ntree_limit must not be 0
preds = bst.predict(dtest, ntree_limit=num_round)
  • XGBoost在sklearn中的例子:
from sklearn.model_selection import train_test_split
from sklearn import metrics
from  sklearn.datasets import make_hastie_10_2
import xgboost as xgb
#记录程序运行时间
import time start_time = time.time()
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size测试集合所占比例#xgb矩阵赋值
xgb_train = xgb.DMatrix(X_train, label=y_train)
xgb_test = xgb.DMatrix(X_test,label=y_test)##参数
params={
'booster':'gbtree',
'silent':1 ,#设置成1则没有运行信息输出,最好是设置为0.
#'nthread':7,# cpu 线程数 默认最大
'eta': 0.007, # 如同学习率
'min_child_weight':3, 
# 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
#,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
#这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
'max_depth':6, # 构建树的深度,越大越容易过拟合
'gamma':0.1,  # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。
'subsample':0.7, # 随机采样训练样本
'colsample_bytree':0.7, # 生成树时进行的列采样 
'lambda':2,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
#'alpha':0, # L1 正则项参数
#'scale_pos_weight':1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。
#'objective': 'multi:softmax', #多分类的问题
#'num_class':10, # 类别数,多分类与 multisoftmax 并用
'seed':1000, #随机种子
#'eval_metric': 'auc'
}plst = list(params.items())
num_rounds = 100 # 迭代次数watchlist = [(xgb_train, 'train'),(xgb_test, 'val')]#训练模型并保存
# early_stopping_rounds 当设置的迭代次数较大时,early_stopping_rounds 可在一定的迭代次数内准确率没有提升就停止训练
model = xgb.train(plst, xgb_train, num_rounds, watchlist,early_stopping_rounds=100)#model.save_model('./model/xgb.model') # 用于存储训练出的模型
print("best best_ntree_limit",model.best_ntree_limit)y_pred = model.predict(xgb_test,ntree_limit=model.best_ntree_limit)
print('error=%f' % (  sum(1 for i in range(len(y_pred)) if int(y_pred[i]>0.5)!=y_test[i]) /float(len(y_pred))))  
#输出运行时长
cost_time = time.time()-start_time
print("xgboost success!",'\n',"cost time:",cost_time,"(s)......")```

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++基础学习(01)--(介绍,环境配置,基本语法,注释)

文章目录目录一. c介绍二. c开发环境到的配置三. c基本语法四. c注释目录 一. c介绍 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言&#xff0c;支持过程化编程、面向对象编程和泛型编程。 C 被认为是一种中级语言&#xff0c;它综合了高级语言和低…

《Head First设计模式》读书笔记_第一章

策略模式 例&#xff1a;设计一个模拟鸭子游戏&#xff0c;游戏中有各种鸭子&#xff0c;一边戏水一边嘎嘎叫。 所以学习设计模式前&#xff0c;我们最先想到的就是设置一个超类&#xff0c;并让其他子类去继承这个类&#xff0c;UML图如下&#xff1a; * * 但是&#xff0…

C++基础学习(02)--(数据类型,变量类型,变量作用域,常量,修饰符类型)

文章目录目录一. 数据类型C 中的数据类型typedefenumeration枚举类型c中变量类型二.变量作用域三.常量四.修饰符类型目录 一. 数据类型 C 中的数据类型 使用编程语言进行编程时&#xff0c;需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着&a…

c++基础学习(03)--(存储类,运算符,循环,判断)

文章目录目录一.存储类二.运算符三.循环whilefor四.判断目录 一.存储类 可见static存储类修饰之后&#xff0c;i的值没有从头开始&#xff0c;而是从上一次的结果中保留下来 #include <iostream>using namespace std; class Data { public:Data(){}~Data(){}void show()…

皇后问题

八皇后问题是一个以国际象棋为背景的问题&#xff1a;如何能够在 88 的国际象棋棋盘上放置八个皇后&#xff0c;使得任何一个皇后都无法直接吃掉其他的皇后&#xff1f;为了达到此目的&#xff0c;任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的…

c++基础学习(04)--(函数、数字、数组、字符串)

文章目录目录1.函数2.数字3.字符串4.数组目录 1.函数 #include <iostream> #include <limits>using namespace std;void swap(int *x , int *y);int main(){int a 100 , b200;cout<<"交换前:"<<"a is :"<<a<<"…

【精品计划0】蓝桥杯 摔手机

原题描述&#xff1a; x星球的居民脾气不太好&#xff0c;但好在他们生气的时候唯一的异常举动是&#xff1a;摔手机。 各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试&#xff0c;并且评定出一个耐摔指数来&#xff0c;之后才允许上市流通。 …

数据结构课上笔记15

图的存储 多重链表&#xff1a;完全模拟图的样子&#xff0c;每个节点内的指针都指向该指向的节点。 节点结构内指针数为度 缺点&#xff1a;浪费空间、不容易操作 数组表示法&#xff08;邻接矩阵表示法&#xff09; 可用两个数组存储。其中一个 一维数组存储数据元素&#…

c++基础学习(05)--(指针,引用)

文章目录目录1.指针2.引用目录 1.指针 #include <iostream>using namespace std;int main () {int var1;char var2[10];cout << "var1 变量的地址&#xff1a; ";cout << &var1 << endl;cout << "var2 变量的地址&#xff…

由旅行商问题认识何为状态压缩

动态规划 动态规划(dynamic programming)是运筹学的一个分支&#xff0c;是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时&#xff0c;提出了著名的最优化原理(pri…

c++基础学习(06)--(时间,输入输出,数据结构)

文章目录目录1.时间2.输入输出数据结构目录 1.时间 当前日期和时间 下面的实例获取当前系统的日期和时间&#xff0c;包括本地时间和协调世界时&#xff08;UTC&#xff09;。 #include <iostream> #include <ctime>using namespace std;int main( ) {// 基于当前…

Abstract Self-Balancing Binary Search Tree

二叉搜索树 二叉查找树&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又&#xff1a;二叉搜索树&#xff0c;二叉排序树&#xff09;它或者是一棵空树&#xff0c;或者是具有下列性质的二叉树&#xff1a; 若它的左子树不空&#xff0c;则左子树上所有结…

AVL Tree

前言 希望读者 了解二叉搜索树 了解左旋右旋基本操作 https://blog.csdn.net/hebtu666/article/details/84992363 直观感受直接到文章底部&#xff0c;有正确的调整策略动画&#xff0c;自行操作。 二叉搜索树 二叉查找树&#xff08;Binary Search Tree&#xff09;&a…

c++基础学习(07)--(类)

文章目录目录类与对象1.类成员函数2.类访问修饰符3.构造函数与析构函数4.拷贝构造函数5. 友元函数6.内联函数7.this指针8.指向类的指针9.类的静态成员目录 类与对象 #include <iostream>using namespace std;class Box {public:double length; // 长度double breadth;…

c++基础学习(08)--(继承、重载、多态、虚函数)

文章目录目录1.继承2.重载3.多态 && 虚函数目录 1.继承 #include <iostream>using namespace std;// 基类 class Shape {public:void setWidth(int w){width w;}void setHeight(int h){height h;}protected:int width;int height; };// 派生类 class Rectang…

图的应用

1. 图的应用总览 在数据结构中图的应用很广泛&#xff0c;本文主要从以下四个方面介绍&#xff1a; ①最小生成树&#xff1a;给定一个无向网络&#xff0c;在该网的所有生成树中&#xff0c;使得各边权数之和最小的那棵生成树称为该网的最小生成树&#xff0c;也叫最小代价…

c++基础学习(09)--(数据抽象、数据封装、接口)

文章目录目录1.数据抽象2.数据封装3.抽象接口类目录 1.数据抽象 数据抽象&#xff1a;就是把它当做黑箱子使用&#xff0c;内部实现与外部接口分开 C类实现数据抽象&#xff0c;如sort()函数&#xff0c;ostream的cout对象 #include <iostream> using namespace std…

c++基础学习(10)--(文件、流、异常处理、动态内存、命名空间)

文章目录目录1.文件和流2.异常处理3.动态内存4.命名空间目录 1.文件和流 注意 文件打开方式中的in和out都是相对于内存&#xff08;计算机&#xff09;而言的&#xff0c;计算机读取文件&#xff0c;是将数据从磁盘中的文件读入到内存中&#xff0c;所以用的是in #include &…

数据结构和算法(02)---字符串(c++)

文章目录目录一.c风格的字符串与操作函数1.c风格字符串2.c风格字符串处理函数二.c中的字符串与操作函数1.c中的string类2.string类的基本操作3.string类的操作汇总目录 数据结构&#xff1a; 逻辑结构&#xff1a;数组&#xff0c;栈&#xff0c;队列&#xff0c;字符串&#x…

如何学习数据结构和算法——大佬文章汇总

第一篇 第二篇、 作者&#xff1a;左程云 我分别说一下国内和国外的行情。 国内的话&#xff0c;一般来讲&#xff0c;工资高的公司在面试时算法和数据结构题目的比重较大&#xff0c;工资一般的公司比重较小。当然同样公司的不同岗位&#xff0c;要求也会不同&#xff0c;…