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

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

ztj100 2024-11-10 13:14 18 浏览 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) )

    相关推荐

    这个 JavaScript Api 已被废弃!请慎用!

    在开发过程中,我们可能会不自觉地使用一些已经被标记为废弃的JavaScriptAPI。这些...

    JavaScript中10个“过时”的API,你的代码里还在用吗?

    JavaScript作为一门不断发展的语言,其API也在持续进化。新的、更安全、更高效的API不断涌现,而一些旧的API则因为各种原因(如安全问题、性能瓶颈、设计缺陷或有了更好的替代品)被标记为“废...

    几大开源免费的 JavaScript 富文本编辑器测评

    MarkDown编辑器用的时间长了,发现发现富文本编辑器用起来是真的舒服。...

    比较好的网页里面的 html 编辑器 推荐

    如果您正在寻找嵌入到网页中的HTML编辑器,以便用户可以直接在网页上编辑HTML内容,以下是几个备受推荐的:CKEditor:CKEditor是一个功能强大的、开源的富文本编辑器,可以嵌入到...

    Luckysheet 实现excel多人在线协同编辑

    前言前些天看到Luckysheet支持协同编辑Excel,正符合我们协同项目的一部分,故而想进一步完善协同文章,但是遇到了一下困难,特此做声明哈,若侵权,请联系我删除文章!若侵犯版权、个人隐私,请联系...

    从 Element UI 源码的构建流程来看前端 UI 库设计

    作者:前端森林转发链接:https://mp.weixin.qq.com/s/ziDMLDJcvx07aM6xoEyWHQ引言...

    手把手教你如何用 Decorator 装饰你的 Typescript?「实践」

    作者:Nealyang转发连接:https://mp.weixin.qq.com/s/PFgc8xD7gT40-9qXNTpk7A...

    推荐五个优秀的富文本编辑器

    富文本编辑器是一种可嵌入浏览器网页中,所见即所得的文本编辑器。对于许多从事前端开发的小伙伴来说并不算陌生,它的应用场景非常广泛,平时发个评论、写篇博客文章等都能见到它的身影。...

    基于vue + element的后台管理系统解决方案

    作者:林鑫转发链接:https://github.com/lin-xin前言该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(WebManagementSystem)开发。基于v...

    开源富文本编辑器Quill 2.0重磅发布

    开源富文本编辑器Quill正式发布2.0版本。官方TypeScript声明...

    Python之Web开发框架学习 Django-表单处理

    在Django中创建表单实际上类似于创建模型。同样,我们只需要从Django类继承,则类属性将是表单字段。让我们在myapp文件夹中添加一个forms.py文件以包含我们的应用程序表单。我们将创建一个...

    Django测试入门:打造坚实代码基础的钥匙

    这一篇说一下django框架的自动化测试,...

    Django ORM vs SQLAlchemy:到底谁更香?从入门到上头的选择指南

    阅读文章前辛苦您点下“关注”,方便讨论和分享,为了回馈您的支持,我将每日更新优质内容。...

    超详细的Django 框架介绍,它来了!

    时光荏苒,一晃小编的Tornado框架系列也结束了。这个框架虽然没有之前的FastAPI高流量,但是,它也是小编的心血呀。总共16篇博文,从入门到进阶,包含了框架的方方面面。虽然小编有些方面介绍得不是...

    20《Nginx 入门教程》使用 Nginx 部署 Python 项目

    今天的目标是完成一个PythonWeb项目的线上部署,我们使用最新的Django项目搭建一个简易的Web工程,然后基于Nginx服务部署该PythonWeb项目。1.前期准备...

    取消回复欢迎 发表评论: