百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

迁移学习用于供应链中的新品销量预测(一)

ztj100 2024-11-10 13:14 12 浏览 0 评论

背景


比如,虽然iphone12全新开售,没有历史数据可以用于预测,但是可以借鉴iphone11, iphone10的类似特征的sku,比如,同样max, pro max系列,同样内存档次(比如,今年的256G配置相当于去年的128G配置),使用类似老品的历史销售数据,这样模型可以学习的样本量就大多了。

算法思想





  • 因此,现在的目标是,设计一种基于boosting思想的迁移学习算法,来解决这一不通数据分布之间的分类学习问题。
  • 我们的基本思想是,尽管辅助训练数据和源训练数据或多或少会有些不同,但是辅助训练数据中应该还是会存在一部分比较适合用来训练一个有效的分类模型,并且适应测试数据。
  • 于是,我们的目标就是,从辅助训练数据中找出那些适合测试数据的实例,并将这些实例迁移到源训练数据的学习中去。
  • 因此,这是一个基于实例的迁移学习算法。





算法描述



Transfer AdaBoost,简称TrAdaBoost

AdaBoost和TrAdaBoost的区别在于对辅助训练数据的权重调整策略。

参考论文:

  • 戴文渊,基于实例和特征的迁移学习算法研究
  • 基于迁移学习的电力通信网异常站点业务数量预测,ISSN 1004?9037,CODEN SCYCE4Journal of Data Acquisition and Processing Vol. 34,No.3,May 2019,pp. 414-421
  • 算法描述



如果一个辅助训练数据被误分类,那么这个数据可能和源训练数据是矛盾的,


那么我们降低这个数据的权重,具体来说,就是给这个数据的权重乘上



  • 因此,在下一轮迭代中,被误分类的训练数据就会比上一轮少影响分类模型一些。
    • 于是,在若干轮迭代后,辅助训练数据中符合源训练数据的那些数据就会拥有更高的权重,而那些不符合源训练数据的权重会降低。
    • 那些拥有更高权重的数据将会帮助源训练数据训练一个更好的分类模型。


    TrAdaBoost预测算法描述:


    1. 举例

    比如,新品预测任务是,新品为iphone13,在iphone13开卖2周的时候,想要预测,未来4周的销量。

    那么,训练集,分成,source样本集,和target样本集,

    Source样本集,就用历史上的iphone11,iphone12的销售记录;

    Target样本集,就用iphone13自身的开卖的2周的销售记录。

    比如销量预测使用的特征是:

    weekofyear, 当周促销力度,当周天气,手机的规格特征(价格段,屏幕,新品,内存等)。

    那么,

    训练集中的X_source就是iphone11,iphone12的特征数据,weekofyear, 当周促销力度,当周天气(因为会影响门店客流量),手机的规格特征(价格段,屏幕,新品,内存等)。

    Y_source就是iphone11,iphone12这些SKU在各周的真实销量。

    训练集中的X_target就是iphone13在开卖2周中的特征数据, Y_target就是iphone13在开卖2周的真实销量。

    测试集的X_test就是iphone13开卖第3,4,5,6周的特征数据,weekofyear, 当周促销力度,当周天气,手机的规格特征(价格段,屏幕,新品,内存等)。

    Y_test就是使用迁移学习模型,所预测的iphone13开卖第3,4,5,6周的销量。

    model.fit(x_trains[j],y_trains[j], sample_weight=weights[j])

    predict_tk =model.predict(x_trains[j])

    # 源领域预测值、目标领域预测值

    predict_source, predict_target =predict_tk[:-row_target], predict_tk[-row_target:]



    • 1.第一轮的样本权重的初始化:

    代码:

    第一轮初始化时候每个样本权重相等

    # 多源域初始化权重

    row_sources = [x_source.shape[0] for x_source in x_sources]

    weight_sources = [np.ones([length])/100 for length in row_sources]

    # 目标域初始化权重

    row_target = x_target.shape[0]

    weight_target = np.ones([row_target])/100

    2.每一轮迭代中,从多个源中学习得来的多个模型的加权,得到这一轮迭代的模型:

    见下图中红框处,即模型偏差越大,该模型的权重越小。



    对于训练集中的每个样本

    model =TrAdaboostRegression(base_regression=LGBMRegressor(boosting_type='dart'

    , random_state=666

    , n_estimators=400

    , max_depth=1

    , learning_rate=0.11

    ), N= 10) ##设置迭代次数等于10

    model =copy.deepcopy(self.base_regression) ## 避免每次迭代的模型被覆盖,因为需要每个模型留存,然后多个源的模型加权

    # (6) 计算模型目标领域误差

    epsilon_tk =self._calculate_error_rate(y_target, predict_target[-row_target:],weights[j][-row_target:])

    ### 目标的错误率计算公式,幂的底,

    # (7) 根据目标领域误差更新预测模型权重

    deltas.append(np.exp(1-epsilon_tk)/np.exp(epsilon_tk))

    ##print('tag58, 第{0}次迭代,的第{1}个源,模型权重是{2}'.format((i+1),(j+1),np.exp(1-epsilon_tk)/np.exp(epsilon_tk)))

    if j==0:

    predict_total =predict_target.reshape(predict_target.shape[0], 1) ######## 转成,6行1列的矩阵

    else:

    predict_total = np.concatenate([predict_total,predict_target.reshape(predict_target.shape[0], 1)], axis=1)

    # 加入模型,每一次迭代的,每一个新老组合产生的模型,都放入了列表

    self.regressions.append(model)

    deltas = np.asarray(deltas, order='C')

    # 模型权重

    self.model_weights = deltas/np.sum(deltas)

    final_predict =predict_total.dot(self.model_weights).reshape(row_target)

    # (8) 计算在第 t次迭代得到的候选预测模型的误差

    epsilon_t = self._calculate_error_rate(y_target, final_predict,weight_target)

    train_epsilon_t_list.append(epsilon_t)



    3.训练集中Source集合的样本权重的调整:

    更新第t+1次的权重向量 ————源领域样本

    对于源领域中的样本,如果样本预测值小于γ,则此样本的权重不变;

    相反,如果相差大于γ,则减小此样本的权重,即表示预测错误的样本对目标数据的学习没有帮助,应该降低这些样本的影响。

    这是因为,TrAdaboost的原理就是,

    “如果一个辅助训练数据被误分类,那么这个数据可能和源训练数据是矛盾的,那么我们降低这个数据的权重,具体来说,就是给这个数据的权重乘上

    因此,在下一轮迭代中,被误分类的训练数据就会比上一轮少影响分类模型一些。

    于是,在若干轮迭代后,辅助训练数据中符合源训练数据的那些数据就会拥有更高的权重,而那些不符合源训练数据的权重会降低。

    那些拥有更高权重的数据将会帮助源训练数据训练一个更好的分类模型。”




    从公式可以看到,第t+1次中的权重w,相比第t次的权重,是乘以了一个指数计算的幂值。

    幂的底部分是

    幂的指数部分是红框部分,即这一轮迭代中的模型预测的错误率。

    代码:

    weights = [self._calculate_weight(weight) for weight in weights] ### 获取上一轮迭代调整后的样本权重

    本轮模型预测之和,计算error,然后更新source样本的权重。

    # 权重更新(源领域)

    error = np.abs(y_sources[j] -predict_source)/ np.max(np.abs(y_sources[j] - predict_source))

    error = np.where(error <=self.gama, 0, error)

    weight_sources[j] =weights[j][:-row_target]* np.power(phi_s, error)

    3.1 Source权重调整中的“容忍系数”

    在TrAdaBoost 的权重更新机制中,由于源领域样本的权值只会减少而不会增加,而目标领域样本的权值只会增加却不会减少,因此两个领域的权重之差会越来越大,在迭代次数较多的情况下,会严重影响模型的效果。

    该问题在回归问题中显得尤为严重,因为几乎不可能为0,即使很小的误差,也会导致权重的缩减,所以在多次迭代之后,源领域的样本权重很有可能缩减为0。

    为了解决该问题,引入了误差容忍系数γ,如果某个样本的误差小于容忍系数,那么其权重不发生变化,如果该样本的误差超过了容忍系数,其权重才会发生变化。

    误差容忍系数将一定程度解决源领域权重缩减的问题,提高迁移的效果,并控制模型对误差的容忍程度。

    4. 训练集中Target集合的样本权重的调整:

    更新第t+1次的权重向量 ———— 目标领域的样本

    根据上面得到的误差εt 更新各个源领域和目标领域样本的权重。

    对于目标领域中的样本,需要根据预测的误差大小增加样本的权重,即表示对于预测错误的样本,应增加此样本的重要性,达到强调此样本的目的。

    因为Target领域的是基于AdaBoost的基本思想,“当一个训练样本被误分类后,它认为这是一个比较难的训练样本。于是,AdaBoost增加这个训练样本的权重,用来强调这个样本。下一次分类训练的时候,这个样本被分错的概率就会减小。”





    从公式可以看到,第t+1次中的权重w,相比第t次的权重,是乘以了一个指数计算的幂值。

    幂的底部分是



    幂的指数部分是红框部分,即这一轮迭代中的模型预测的错误率。

    因此,偏差越大,权重越大。

    Target领域的权重调整策略,和source 领域的权重调整策略,是相反的。

    因为,我们希望模型每次迭代都更看重target样本中“还没有学习到的样本”,而source样本,则希望每次迭代都“更多的学习和iphone13的销售特点近似的样本”(对之加大权重),“更少的取学习那些不近似的样本”(对之减少权重)。



    代码:

    # (9) 权重更新(目标域)

    if epsilon_t > 0.5:

    epsilon_t = 0.5

    #raise Exception('epsilon_t> 0.5')

    if epsilon_t == 0:

    break

    phi_t = epsilon_t/(1-epsilon_t)

    error = np.abs(y_target - final_predict)/np.max(np.abs(y_target -final_predict))

    weight_target = weight_target*np.power(phi_t, -error)

    train_mape_list.append(np.sum(np.abs(y_target -final_predict))*100/np.sum(y_target) )

    相关推荐

    Vue 技术栈(全家桶)(vue technology)

    Vue技术栈(全家桶)尚硅谷前端研究院第1章:Vue核心Vue简介官网英文官网:https://vuejs.org/中文官网:https://cn.vuejs.org/...

    vue 基础- nextTick 的使用场景(vue的nexttick这个方法有什么用)

    前言《vue基础》系列是再次回炉vue记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有部分和官网相同的文案,有经验的同学择感兴趣的阅读)在开发时,是不是遇到过这样的场景,响应...

    vue3 组件初始化流程(vue组件初始化顺序)

    学习完成响应式系统后,咋们来看看vue3组件的初始化流程既然是看vue组件的初始化流程,咋们先来创建基本的代码,跑跑流程(在app.vue中写入以下内容,来跑流程)...

    vue3优雅的设置element-plus的table自动滚动到底部

    场景我是需要在table最后添加一行数据,然后把滚动条滚动到最后。查网上的解决方案都是读取html结构,暴力的去获取,虽能解决问题,但是不喜欢这种打补丁的解决方案,我想着官方应该有相关的定义,于是就去...

    Vue3为什么推荐使用ref而不是reactive

    为什么推荐使用ref而不是reactivereactive本身具有很大局限性导致使用过程需要额外注意,如果忽视这些问题将对开发造成不小的麻烦;ref更像是vue2时代optionapi的data的替...

    9、echarts 在 vue 中怎么引用?(必会)

    首先我们初始化一个vue项目,执行vueinitwebpackechart,接着我们进入初始化的项目下。安装echarts,npminstallecharts-S//或...

    无所不能,将 Vue 渲染到嵌入式液晶屏

    该文章转载自公众号@前端时刻,https://mp.weixin.qq.com/s/WDHW36zhfNFVFVv4jO2vrA前言...

    vue-element-admin 增删改查(五)(vue-element-admin怎么用)

    此篇幅比较长,涉及到的小知识点也比较多,一定要耐心看完,记住学东西没有耐心可不行!!!一、添加和修改注:添加和编辑用到了同一个组件,也就是此篇文章你能学会如何封装组件及引用组件;第二能学会async和...

    最全的 Vue 面试题+详解答案(vue面试题知识点大全)

    前言本文整理了...

    基于 vue3.0 桌面端朋友圈/登录验证+60s倒计时

    今天给大家分享的是Vue3聊天实例中的朋友圈的实现及登录验证和倒计时操作。先上效果图这个是最新开发的vue3.x网页端聊天项目中的朋友圈模块。用到了ElementPlus...

    不来看看这些 VUE 的生命周期钩子函数?| 原力计划

    作者|huangfuyk责编|王晓曼出品|CSDN博客VUE的生命周期钩子函数:就是指在一个组件从创建到销毁的过程自动执行的函数,包含组件的变化。可以分为:创建、挂载、更新、销毁四个模块...

    Vue3.5正式上线,父传子props用法更丝滑简洁

    前言Vue3.5在2024-09-03正式上线,目前在Vue官网显最新版本已经是Vue3.5,其中主要包含了几个小改动,我留意到日常最常用的改动就是props了,肯定是用Vue3的人必用的,所以针对性...

    Vue 3 生命周期完整指南(vue生命周期及使用)

    Vue2和Vue3中的生命周期钩子的工作方式非常相似,我们仍然可以访问相同的钩子,也希望将它们能用于相同的场景。...

    救命!这 10 个 Vue3 技巧藏太深了!性能翻倍 + 摸鱼神器全揭秘

    前端打工人集合!是不是经常遇到这些崩溃瞬间:Vue3项目越写越卡,组件通信像走迷宫,复杂逻辑写得脑壳疼?别慌!作为在一线摸爬滚打多年的老前端,今天直接甩出10个超实用的Vue3实战技巧,手把...

    怎么在 vue 中使用 form 清除校验状态?

    在Vue中使用表单验证时,经常需要清除表单的校验状态。下面我将介绍一些方法来清除表单的校验状态。1.使用this.$refs...

    取消回复欢迎 发表评论: