来源 | AI小白入门
作者 | 文杰
编辑 | yuquanle
完整代码见:原文链接

本文介绍了集成学习中Boosting的代表算法Adaboost。首先介绍了Adaboost的Boosting思想:1)学习器的投票权重,2)更新样本权重,巧妙之处在于这两个权重的设计使得Adaboost如此优美。然后介绍了Adaboost的前向加法思想,即不断拟合上一次分类器的损失。最后以前向加法模型中的特例(二分类)导出Adaboost的指数损失理解,再次回归到Adaboost的学习器权重和样本更新权重为何如此设计。

Adaboost

Adaboost的Boosting理解

Adaboost是集成学习中Boosting方式的代表。多个基学习器其串行执行,下一个学习器基于上一个学习器的经验,通过调整样本的权重,使得上一个错分的样本在下一个分类器更受重视而达到不断提升的效果。

Adaboost集成多个学习器的关键在两点:

  1. 设置基学习器的权重:

    am=12log1−emema_{m}=\frac{1}{2}log\frac{1-e_{m}}{e_{m}}am​=21​logem​1−em​​

  2. 调整样本的权重:

    wm+1,i=wm,iZmexp(−amyiGm(xi))w_{m+1,i}=\frac{w_{m,i}}{Z_{m}}exp(-a_{m}y_{i}G_{m}(x_{i}))wm+1,i​=Zm​wm,i​​exp(−am​yi​Gm​(xi​))

相对随机森林的Bootstrap Sampling重采样技术,可以看出Adaboost的权重调整是有目的性,基于上一个学习器的经验,这也导致Adaboost在基学习器层是串行的。值得探讨的是权重为何如此设置?

Adaboost算法采用的基学习器是二值函数(二叉树)模型,当然Adaboost的核心是采用Boosting的思想。

下面先来看Adaboost算法的整个流程,后面分析Adaboost在设计上巧妙之处。

  • 输入:训练集:
    D={(x1y1),(x2,y2),…,(xN,yN)}D = \left \{(x_1y_1),(x_2,y_2),…,(x_N,y_N) \right \}D={(x1​y1​),(x2​,y2​),…,(xN​,yN​)},其中xi∈Rnx_i \in \mathbb{R}^nxi​∈Rn,yi∈{+1,−1}y_i \in \left \{+1,-1 \right \}yi​∈{+1,−1}

  • 输出:强学习器G(x)G(x)G(x)

  1. 初始化权值 :

    D1=w11,w12,…,w1ND_1 = {w_{11},w_{12},…,w_{1N}}D1​=w11​,w12​,…,w1N​,w1i=1N,i=1,2,…,Nw_{1i} = \frac{1}{N},i=1,2,…,Nw1i​=N1​,i=1,2,…,N

  2. 训练M个基学习器m=1,2...Mm=1,2...Mm=1,2...M:

    2.1 使用权值分布DmD_{m}Dm​与相应的基学习器算法得到第mmm个基学习器:

    Gm(x):xi→yiG_{m}(x):x_{i} \rightarrow y_{i}Gm​(x):xi​→yi​

    2.2 计算基学习器Gm(x)G_{m}(x)Gm​(x)的训练误差:

    em=P(Gm(xi)≠yi)=∑iNwmiI(Gm(xi)≠yi)/∑iNwmie_m = P(G_m(x_i) \ne y_i) = \sum_i^Nw_{mi}I(G_m(x_i) \ne y_i)/\sum_{i}^Nw_{mi}em​=P(Gm​(xi​)​=yi​)=∑iN​wmi​I(Gm​(xi​)​=yi​)/∑iN​wmi​

    2.3 计算基学习器的权重:

    如果em>12e_{m}>\frac{1}{2}em​>21​:am=0a_{m}=0am​=0,舍弃基学习器,样本权重更新与不更新一致;

    否则:am=12log⁡1−emema_m = \frac{1}{2} \log \frac{1-e_m}{e_m}am​=21​logem​1−em​​;

    2.4 更新样本的权重:

    Dm+1=(wm+1,1,....,wm+1,i,…,wm+1,N)D_{m+1} = ({w_{m+1,1},....,w_{m+1,i},…,w_{m+1,N}})Dm+1​=(wm+1,1​,....,wm+1,i​,…,wm+1,N​)

    其中:

    wm+1,i=wmiZmexp⁡(−amyiGm(xi))w_{m+1,i} = \frac{w_{mi}}{Z_m}\exp(-a_m y_i G_m(x_i))wm+1,i​=Zm​wmi​​exp(−am​yi​Gm​(xi​))

    这里ZmZ_{m}Zm​是归一化因子:

    Zm=∑iwmiexp⁡(−amyiGm(xi))Z_m = \sum_i w_{mi}\exp(-a_my_iG_m(x_i))Zm​=∑i​wmi​exp(−am​yi​Gm​(xi​))

    使得Dm+1D_{m+1}Dm+1​满足一个概率分布;

  3. 得到MMM个基学习器之后,将基学习器线性组合:

    f(x)=∑mamGm(x)f(x) = \sum_m a_mG_m(x)f(x)=∑m​am​Gm​(x)

  4. 得到最终的分类器:

    G(x)=sign(f(x))=sign(∑mamGm(x))G(x) = sign(f(x)) = sign(\sum_m a_mG_m(x))G(x)=sign(f(x))=sign(∑m​am​Gm​(x))

Adaboost算法流程基本与Boosting思想一致,特别之处在于权重的设计,下面分析一下:

  1. 基学习器的权重am=12log⁡1−emema_m = \frac{1}{2} \log \frac{1-e_m}{e_m}am​=21​logem​1−em​​,当0≤em≤120\leq e_{m}\leq\frac{1}{2}0≤em​≤21​,am≥0a_{m}\geq0am​≥0,且ama_{m}am​随eme_{m}em​的减小而增大,也就是说当基学习器的误差越小,权重越大。

  2. 样本权重更新公式可以表示如下:
    wm+1,i={1Zmwmie−am,Gm(xi)=yi1Zmwmieam,Gm(xi)≠yiw_{m+1,i} = \left \{ \begin{aligned} \frac{1}{Z_m} w_{mi}e^{-a_m} , G_m(x_i) = y_i \\ \frac{1}{Z_m} w_{mi}e^{a_m} \ , G_m(x_i) \ne y_i \end{aligned} \right. wm+1,i​=⎩⎪⎪⎨⎪⎪⎧​Zm​1​wmi​e−am​,Gm​(xi​)=yi​Zm​1​wmi​eam​ ,Gm​(xi​)​=yi​​
    也就是说正确分类yi=Gm(xi)y_{i}=G_{m}(x_{i})yi​=Gm​(xi​),那么−am<0-a_{m}<0−am​<0,正确分类的样本权重在上一次的基础上乘上一个小于1的因子而减小,反之,错分的样本的权重增大。

  3. MMM个基学习器在线性组合时,需要注意的是∑mam≠1\sum_m a_m \ne 1∑m​am​​=1,最终的f(x)=∑mamGm(x)f(x) = \sum_m a_mG_m(x)f(x)=∑m​am​Gm​(x)是一个[−∑mam,∑mam][-\sum_m a_m,\sum_m a_m][−∑m​am​,∑m​am​]区间的值,符号决定分类,绝对值表示分类一个确信度。

Adaboost的指数损失理解

Adaboost算法是前向分步加法算法的特例,以模型为加法模型,损失函数为指数函数的二类分类学习方法。考虑加法模型(additive model)
f(x)=∑mβmb(x;γm)f(x) = \sum_m \beta_mb(x; \gamma_m) f(x)=m∑​βm​b(x;γm​)
其中,b(x;γm)b(x; \gamma_m)b(x;γm​)为基函数,$\gamma_m 为基函数的参数,为基函数的参数,为基函数的参数,\beta_m$为基函数的权重,显然这是一个加法模型。

在给定训练集和损失函数L(y,f(x))L(y,f(x))L(y,f(x))的条件下,学习加法模型f(x)f(x)f(x)就是最小化损失函数的问题:
argmin⁡βm,γm∑i=1NL[yi,∑mβmb(xi;γm)]arg\min_{\beta_m, \gamma_m} \sum^N_{i=1}L \left [y_i,\sum_m \beta_mb(x_i; \gamma_m) \right ] argβm​,γm​min​i=1∑N​L[yi​,m∑​βm​b(xi​;γm​)]
当然,我们可以将加法模型看作一个复合函数,直接优化各个系数和基函数参数,但这样问题就变复杂了。

考虑前向分步算法,逐个优化每一个基函数和系数来逼近复合函数,这样问题就简化了。

具体的,每一步需要优化如下目标函数:
argmin⁡βm,γm∑i=1NL[yi,βmb(xi;γm)]arg\min_{\beta_m, \gamma_m} \sum^N_{i=1}L \left [y_i, \beta_mb(x_i; \gamma_m) \right ] argβm​,γm​min​i=1∑N​L[yi​,βm​b(xi​;γm​)]
按照这种分步策略,每步优化一个基函数和系数,我们有前向分步算法如下:

  • 输入:训练集:
    D={(x1y1),(x2,y2),…,(xN,yN)}D = \left \{(x_1y_1),(x_2,y_2),…,(x_N,y_N) \right \}D={(x1​y1​),(x2​,y2​),…,(xN​,yN​)},损失函数:L(y,f(x))L(y,f(x))L(y,f(x)),基函数{b(x;γ)}\{b(x;\gamma)\}{b(x;γ)}

  • 输出:加法模型f(x)f(x)f(x)

  1. 初始化f0(x)=0f_{0}(x)=0f0​(x)=0

  2. 学习MMM基函数和系数,从m=1,2,…Mm = 1,2,…Mm=1,2,…M

    2.1 极小化损失函数:

    βm,γm=argmin⁡β,γ∑iL(yi,fm−1(xi)+βb(xi;γ))\beta_m,\gamma_m=arg\min_{\beta,\gamma} \sum_iL(y_i,f_{m-1}(x_i)+ \beta b(x_i; \gamma))βm​,γm​=argminβ,γ​∑i​L(yi​,fm−1​(xi​)+βb(xi​;γ))

    2.2 更新:

    fm(x)=fm−1(x)+βmb(ai;γm)f_m(x) = f_{m-1}(x) + \beta_m b(a_i; \gamma_m)fm​(x)=fm−1​(x)+βm​b(ai​;γm​)

  3. 得到最终的加法模型:

    f(x)=fM(x)=∑mβmb(x,γm)f(x) = f_M(x) = \sum_m\beta_mb(x,\gamma_m)f(x)=fM​(x)=∑m​βm​b(x,γm​)

前向分步算法通过逐个优化基函数,逐渐弥补残差的思想完成MMM个基函数的学习。

回到Adaboost算法,Adaboost是前向分步加法模型的特例。特例在于Adaboost是二分类,且损失函数定义为指数损失和基函数定义为二分类函数。

  1. 指数损失函数:

    L(y,f(x))=−yexp(f(x))=exp(−yf(x)),y∈{−1,1}L(y,f(x)) = -yexp(f(x))=exp(-yf(x)),y\in\{ -1,1\}L(y,f(x))=−yexp(f(x))=exp(−yf(x)),y∈{−1,1}

  2. 基函数:

    Gm(x):xi→yi,yi∈{−1,1}G_{m}(x):x_{i} \rightarrow y_{i}, y_{i} \in \{-1,1\}Gm​(x):xi​→yi​,yi​∈{−1,1}

在Adaboost算法中,我们最终的强学习器为:
f(x)=∑mamGm(x)f(x) = \sum_ma_mG_m(x) f(x)=m∑​am​Gm​(x)
以第mmm步前向分步算法为例,第mmm个基函数为:
fm(x)=fm−1(x)+amGm(x)f_m(x) = f_{m-1}(x)+a_mG_m(x) fm​(x)=fm−1​(x)+am​Gm​(x)
其中fm−1(x)f_{m-1}(x)fm−1​(x)为:
fm−1(x)=fm−2(x)+am−1(x)Gm−1(x)=a1G1(x)+,…,+amGm(x)f_{m-1}(x) = f_{m-2}(x) +a_{m-1}(x)G_{m-1}(x) = a_1G_1(x) +,…,+a_mG_m(x) fm−1​(x)=fm−2​(x)+am−1​(x)Gm−1​(x)=a1​G1​(x)+,…,+am​Gm​(x)
根据前向分步算法得到ama_{m}am​和Gm(x)G_{m}(x)Gm​(x)使得fm(x)f_{m}(x)fm​(x)在训练集DDD上的指数损失最小,即:
am∗,Gm∗(x)=argmin⁡a,G∑iexp[−yi(fm−1(xi)+amGm(xi))]=argmin⁡am,Gm∑iexp[−yifm−1(xi)]⋅exp[−yiamGm(xi)]=argmin⁡am,Gm∑iwmiexp[−yiamGm(xi)]a^*_m,G^*_m(x) = arg \min_{a,G} \sum_i exp[-y_i(f_{m-1}(x_i) +a_mG_m(x_i))]\\ = arg \min_{a_m,G_m} \sum_i exp[-y_if_{m-1}(x_i)]\cdot exp[-y_ia_mG_m(x_i)]\\ =arg \min_{a_m,G_m} \sum_i w_{mi} exp[-y_ia_mG_m(x_i)] am∗​,Gm∗​(x)=arga,Gmin​i∑​exp[−yi​(fm−1​(xi​)+am​Gm​(xi​))]=argam​,Gm​min​i∑​exp[−yi​fm−1​(xi​)]⋅exp[−yi​am​Gm​(xi​)]=argam​,Gm​min​i∑​wmi​exp[−yi​am​Gm​(xi​)]
其中wm,i=exp[−yifm−1(xi)]w_{m,i}=exp[-y_if_{m-1}(x_i)]wm,i​=exp[−yi​fm−1​(xi​)],可以看出wm,iw_{m,i}wm,i​只与fm−1(x)f_{m-1}(x)fm−1​(x)有关,与当前的学习器无关。

由fm(x)=fm−1(x)+amGm(x)f_m(x) = f_{m-1}(x)+a_mG_m(x)fm​(x)=fm−1​(x)+am​Gm​(x),我们可以得出wm,iw_{m,i}wm,i​的另外一种表示:
wm,i=w(m−1,i)exp[−yiamGm(x)]w_{m,i} = w_{(m-1,i)} exp[-y_ia_mG_m(x)] wm,i​=w(m−1,i)​exp[−yi​am​Gm​(x)]
这也就是样本权重更新的表达式(未归一化)。

现在分析目标函数,首先看Gm∗(x)G_{m}^*(x)Gm∗​(x),因为am>0a_{m}>0am​>0,Gm(x)={−1,1}G_{m}(x)=\{-1,1\}Gm​(x)={−1,1},要使目标函数取到最小值,那么必然有:
Gm∗(x)=argmin⁡Gm∑iwmiI(yi≠Gm(xi))G^*_m(x) = arg\min_{G_m}\sum_i w_{mi}I(y_i \ne G_m(x_i)) Gm∗​(x)=argGm​min​i∑​wmi​I(yi​​=Gm​(xi​))
也就是说Gm∗(x)G_{m}^*(x)Gm∗​(x)是第mmm步使得样本加权训练误差最小的基分类器。将Gm∗(x)G_{m}^*(x)Gm∗​(x)带入目标函数有:
∑iwmiexp[−yiamGm(xi)]=∑yi=Gm(xi)wmie−am+∑yi≠Gm(xi)wmieam=∑yi=Gm(xi)wmie−am+∑yi≠Gm(xi)wmieam+∑yi≠Gm(xi)wmie−am−∑yi≠Gm(xi)wmie−am=e−am∑iwmi+(eam−e−am)∑yi≠Gm(xi)wmi\begin{aligned} & \ \ \ \sum_i w_{mi}exp[-y_ia_mG_m(x_i)] \\ &= \sum_{y_i = G_m(x_i)}w_{mi}e^{-a_m} + \sum_{y_i \ne G_m(x_i)}w_{mi}e^{a_m} \\ &= \sum_{y_i = G_m(x_i)}w_{mi}e^{-a_m}+ \sum_{y_i \ne G_m(x_i)}w_{mi}e^{a_m} +\sum_{y_i \ne G_m(x_i)}w_{mi}e^{-a_m} - \sum_{y_i \ne G_m(x_i)}w_{mi}e^{-a_m} \\ &=e^{-a_m} \sum_iw_{mi} + (e^{a_m} -e^{-a_m})\sum_{y_i \ne G_m(x_i)}w_{mi} \end{aligned} ​   i∑​wmi​exp[−yi​am​Gm​(xi​)]=yi​=Gm​(xi​)∑​wmi​e−am​+yi​​=Gm​(xi​)∑​wmi​eam​=yi​=Gm​(xi​)∑​wmi​e−am​+yi​​=Gm​(xi​)∑​wmi​eam​+yi​​=Gm​(xi​)∑​wmi​e−am​−yi​​=Gm​(xi​)∑​wmi​e−am​=e−am​i∑​wmi​+(eam​−e−am​)yi​​=Gm​(xi​)∑​wmi​​
上式对ama_mam​求导即可,使得倒数为000,即可得到 am∗a^∗_mam∗​ :
am∗=12log1−emema_m^* = \frac{1}{2}log \frac{1-e_m}{e_m} am∗​=21​logem​1−em​​
其中eme_{m}em​是第mmm个基分类器Gm(x)G_{m}(x)Gm​(x)的分类错误率:
em=∑yi≠Gm(xi)wmi∑iwmi=∑iwmiI(yi≠Gm(xi))e_m = \frac{\sum_{y_i \ne G_m(x_i)}w_{mi}}{\sum_iw_{mi} } = \sum_iw_{mi} I(y_i \ne G_m(x_i)) em​=∑i​wmi​∑yi​​=Gm​(xi​)​wmi​​=i∑​wmi​I(yi​​=Gm​(xi​))
最后来看Adaboost的权重调整,都是前向分步算法基于一个目标:
min⁡a,G∑iexp[−yi(fm−1(xi)+amGm(xi))]\min_{a,G} \sum_i exp[-y_i(f_{m-1}(x_i) +a_mG_m(x_i))] a,Gmin​i∑​exp[−yi​(fm−1​(xi​)+am​Gm​(xi​))]
可见一切设计都不是偶然,都是必然。Adaboost只是前向分步加法模型的特例,是GBDT的二分类特例,采用牛顿法求解版。

代码实战


vector<int> Classify(const Data data, int axis, double threshVal, string threshIneq) { vector<int> label; for(size_t i=0; i<data.size(); i++) { label.push_back(1); if(threshIneq=="lt") { if(data[i][axis]<=threshVal) label[i]=-1; } else { if(data[i][axis]>threshVal) label[i]=-1; } } return label; } Stump buildStump(const Data &data,vector<double> weight)
{ Stump stump; int i,j,k,l; double *errArr=(double *)malloc(sizeof(double)*data.size()); double minErr=MAX; double weightError=0; double *range=(double *)malloc(sizeof(double)*2); double rangemin,rangemax; double stepSize; int numSteps=data.size()/10; double threshVal; int label_index=data[0].size()-1; vector<int> label; string threshIneq[2]= {"lt","gt"}; for(i=0; i<data[0].size()-1; i++) //属性 { range=rangeSize(data,i); rangemin=range[0]; rangemax=range[1]; stepSize=(rangemax-rangemin)/numSteps; for(j=0; j<=numSteps; j++) //其实是numstep+1步 { threshVal=rangemin+stepSize*j; for(k=0; k<2; k++) //大于小于 { label=Classify(data,i,threshVal,threshIneq[k]); weightError=0; for(l=0; l<data.size(); l++) { errArr[l]=label[l]-data[l][label_index]>0?(label[l]-data[l][label_index])/2:-(label[l]-data[l][label_index])/2; weightError+=errArr[l]*weight[l]; } if(weightError<minErr) { minErr=weightError; for(l=0; l<data.size(); l++) { if(label[l]>0) stump.twosubdata.left.push_back(data[l]); else stump.twosubdata.right.push_back(data[l]); } stump.label=label; stump.bestIndex=i; stump.minErr=minErr; stump.threshVal=threshVal; stump.ltOrgt=threshIneq[k]; cout<<"minErr="<<minErr<<endl; stump.alpha=0.5*log((1-minErr)/minErr); } } } } return stump; }

更多AI、NLP干货资源请关注公众号:AI小白入门(ID: StudyForAI):

【机器学习】Adaboost相关推荐

  1. 机器学习——Adaboost 算法

    机器学习--Adaboost 算法 资料来源:<MATLAB 神经网络 43 个案例分析> Adaboost算法思想 Adaboost算法的基本思想是合并多个弱分类器来实现更为有效的分类. ...

  2. 机器学习-Adaboost 算法(集成学习)

    本文结构: 什么是集成学习? 为什么集成的效果就会好于单个学习器? 如何生成个体学习器? 什么是 Boosting? Adaboost 算法? 什么是集成学习 集成学习就是将多个弱的学习器结合起来组成 ...

  3. [机器学习] Adaboost原理及实现

    Boost   Adaboost(adaptive boosting)是一种集成学习算法,基于boosting的框架,因此首先简单说一下boosting算法.boosting算法主要的目的是将&quo ...

  4. 机器学习-AdaBoost(自适应提升算法)

    介绍 AdaBoost,是"Adaptive Boosting"(自适应增强)的缩写,是一种机器学习方法,由Yoav Freund和Robert Schapire于1995年提出. ...

  5. 六、(机器学习)-Adaboost提升树-二分类和多分类(最清晰最易懂)

    Adaboost提升树 一.bagging与boosting bagging即套袋法,通过对训练样本重新采样的方法得到不同的训练样本集,在这些新的训练样本集上分别训练学习器,最终合并每一个学习器的结果 ...

  6. 数据挖掘十大经典算法之——AdaBoost 算法

    数据挖掘十大经典算法系列,点击链接直接跳转: 数据挖掘简介及十大经典算法(大纲索引) 1. 数据挖掘十大经典算法之--C4.5 算法 2. 数据挖掘十大经典算法之--K-Means 算法 3. 数据挖 ...

  7. gbdt 算法比随机森林容易_机器学习(七)——Adaboost和梯度提升树GBDT

    1.Adaboost算法原理,优缺点: 理论上任何学习器都可以用于Adaboost.但一般来说,使用最广泛的Adaboost弱学习器是决策树和神经网络.对于决策树,Adaboost分类用了CART分类 ...

  8. 【机器学习实战】第7章 集成方法(随机森林和 AdaBoost)

    第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...

  9. 机器学习经典算法详解及Python实现--元算法、AdaBoost

    http://blog.csdn.net/suipingsp/article/details/41822313 第一节,元算法略述 遇到罕见病例时,医院会组织专家团进行临床会诊共同分析病例以判定结果. ...

  10. 机器学习 集成学习篇——python实现Bagging和AdaBOOST算法

    机器学习 集成学习篇--python实现Bagging和AdaBOOST算法 摘要 Bagging算法 Adaboost算法 摘要 本文通过python实现了集成学习中的Bagging和AdaBOOS ...

最新文章

  1. [转] 利用jemalloc分析内存泄漏
  2. android Activity布局初步(二)- 嵌套布局
  3. 2018-2019-2 20175328 《Java程序设计》第十一周学习总结
  4. poj 4468Spy(kmp算法)
  5. 中南大学王斌计算机学院,中南大学 信息科学与工程学院,长沙 410083
  6. 2012021401
  7. 格式化 SQL 来提高效率
  8. 【Java数据结构】Map与Set、搜索树、哈希表
  9. pythonnamedtuple定义类型_python - namedtuple和可选关键字参数的默认值
  10. JS屏蔽360浏览器代码
  11. 如何在Redhat7.4安装CDH6.2
  12. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 07课
  13. 设置电脑开机自启动软件,exe/jar均可
  14. mysql主从延迟设置
  15. PHP 判断变量是否定义、是否为空、是否为真
  16. 【优化预测】基于matlab布谷鸟算法优化SVM预测【含Matlab源码 1422期】
  17. Jzoj3780 Magical GCD
  18. Java 爬虫系列丨(一)爬虫介绍
  19. 【微信小程序】数据绑定
  20. 思科路由器交换机指示灯状态详解

热门文章

  1. echarts中折线图、柱状图之间的转换
  2. Delayed Adversarial Training with Non-Sequential Adversarial Epochs
  3. WPS文档怎样转换为图片
  4. Bugku旧平台crypto writeup
  5. 因果性与因果模型 | 中国人民大学哲学与认知科学明德讲坛
  6. 华为领衔,“5G+摄像头”拿下双影帝,多家国产手机凭借拍照入围MWC最佳演员...
  7. Navigating to current location (/user) is not allowed
  8. C++可视化和图表库
  9. 聚名:“虎虎酒”商标正在申请中,电视剧《赘婿》引商标注册热潮!
  10. 最新手机产业供应链汇总