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

迁移学习和冷启动(迁移和启发区别)

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

? 本文是《智能风控原理、算法和工程实践》第3章学习笔记。算法推导部分较难,就没有列出来,因为我也看不懂。

冷启动

? 冷启动是指在没有或只有很少量数据的情况下,从0到1建立业务模型的过程。在风控业务中,早期缺乏数据积累,迁移学习和异常检测技术都可以用来处理部分冷启动问题。

应用场景

  • 新开了某个业务,只有少量样本,需要用其他场景的数据来建模。此时其他场景为源域,新业务场景为目标域。
  • 业务被迫停止3个月后重启,大部分训练样本比较老旧。大部分旧样本为源域,新的少量训练样本为目标域。
  • 在某个国家开展类似国内的业务。国内业务积累的数据为源域,新国家场景为目标域。

? 概括起来,源域样本和目标域样本分布有区别,目标域样本量又不够。

概念介绍

? 迁移学习是一种通过调用不同场景中的数据来建立模型的方法。通过迁移学习可以将知识从源域迁移到目标域。

? 一个简单的例子,假如现在有大量英短银渐层和少量英短高地的图片,期望训练一个能够识别当前的猫是不是英短高地的学习器。这时可以用英短银渐层图片来训练一个卷积神经网络,并将这个网络的中间结点取出来作为目标模型的前半部分,然后在少量英短高地的样本上再继续训练学习后面的几层网络。

? 卷积神经网络前几层学习的是轮廓和局部形状等猫的共性特征,通过前面网络的学习模型就掌握了猫的共性,再通过后续网络对英短高地学习。

常见迁移学习算法

  1. TrAdaBoost。
    ? 赋予源域中的样本某种权重,使其分布靠近目标域。
  2. 联合分布适配方法(JDA)。
    ? 寻找一个低维子空间,使源域和目标域的数据样本在映射到该子空间后服从相同或相近的分布。
  3. 迁移极限学习机(DTELM)。
    ? 利用低秩矩阵重构数据点,实现域之间的鲁棒自适应。
    ? 第一种算法因为不在特征空间上做任何扭曲变化,可以很好地保留模型的解释性,所以应该更为广泛。第二、第三种算法在解释性上有一定不足,但不需要在目标场景有真实的样本标签,对于初期的业务支持度更好。

TrAdaBoost模型

? 将不同分布的训练集放在一起训练,这种方法也叫作基于实例的迁移学习方法。 ? TraAdaBoost是有AdaBoost演变而来。在一个包含源域训练数据和目标域样本的训练集中,TrAdaBoost会对训练样本进行权重调整。

  • 对目标域样本,如果被误分类,根据目标域样本的分类错误率进行调整,增加其权重,使得下次训练时更关注错分的目标域样本。
  • 对源域样本,如果被误分类,则会认为它们是与目标数据不同分布的,会降低其权重。

跨场景迁移模型

? 在新场景下开展小额现金贷产品,积累了1200条有标签的样本,尝试对原有大额产品的存量客户进行迁移。有4个在旧业务上表现较好的特征,保证原有场景和目标场景都有这个特征且含义一致。

import pandas as pd
from sklearn.metrics import roc_auc_score,roc_curve,auc
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
import numpy as np
import random
import math
from sklearn.calibration import CalibratedClassifierCV

data = pd.read_excel('./data/tra_sample.xlsx')
data.head()

? type的三种标签分别代表着目标域、源域和时间外样本集。根据标签划分样本集。

feature_lst = ['zx_score','msg_cnt','phone_num_cnt','register_days']

train = data[data.type == 'target'].reset_index().copy()
diff = data[data.type == 'origin'].reset_index().copy()
val = data[data.type == 'offtime'].reset_index().copy()

#trans_S, trans_A, label_S, label_A, test
train = train.loc[:1200]

trans_S = train[feature_lst].copy()
label_S = train['bad_ind'].copy()

trans_A = diff[feature_lst].copy()
label_A = diff['bad_ind'].copy()

val_x =  val[feature_lst].copy()
val_y = val['bad_ind'].copy()

test = val_x.copy()

? 对目标域的少量样本进行拟合,结果如下:

? 训练集和时间外样本集KS相差超过10%,远高于行业要求的5%。且ROC曲线不稳定,意味着模型的泛化能力较差。

? 将源域数据和目标域数据整合到一起拟合,注意一下整合时用到的函数,结果如下:

trans_data = np.concatenate((trans_A, trans_S), axis=0)
trans_label = np.concatenate((label_A, label_S), axis=0)

? 下面使用TrAdaBoost算法,将源域数据中与目标域分布差别较大的数据设置一个很小的值,来弱化两个数据集的分布差异。 算法比较复杂,代码无法看懂,等用到的时候再回来研究。

import numpy as np
from sklearn import tree

#逻辑回归的学习率、权重的大小,影响整体收敛的快慢
#初始权重很重要

# H 测试样本分类结果
# TrainS 目标域样本
# TrainA 源域样本
# LabelS 目标域标签
# LabelA 源域标签
# Test  测试样本
# N 迭代次数

#计算weight
def calculate_P(weights, label):
    total = np.sum(weights)
    return np.asarray(weights / total, order='C')

#用逻辑回归作为基分类器,输出概率
def train_classify(trans_data, trans_label, test_data, P):
    clf = LogisticRegression(C=0.3,class_weight = 'balanced',solver='liblinear')
    clf.fit(trans_data, trans_label, sample_weight=P[:, 0])
    return clf.predict_proba(test_data)[:,1],clf

#计算在目标域上面的错误率
def calculate_error_rate(label_R, label_H, weight):
    total = np.sum(weight)
    return np.sum(weight[:, 0] / total * np.abs(label_R - label_H))

#根据逻辑回归输出的score的得到标签,注意这里不能用predict直接输出标签
def put_label(score_H,thred):
    new_label_H = []
    for i in score_H:
        if i <= thred:
            new_label_H.append(0)
        else:
            new_label_H.append(1)
    return new_label_H

#指定迭代次数,相当于集成模型中基模型的数量
N=500

trans_data = np.concatenate((trans_A, trans_S), axis=0)
trans_label = np.concatenate((label_A, label_S), axis=0)

row_A = trans_A.shape[0]
row_S = trans_S.shape[0]
row_T = test.shape[0]

test_data = np.concatenate((trans_data, test), axis=0)

# 初始化权重
weights_A = np.ones([row_A, 1])/row_A
weights_S = np.ones([row_S, 1])/row_S*2
weights = np.concatenate((weights_A, weights_S), axis=0)

bata = 1 / (1 + np.sqrt(2 * np.log(row_A / N)))

# 存储每次迭代的标签和bata值?
bata_T = np.zeros([1, N])  # 存每一次迭代的 error_rate / (1 - error_rate)
result_label = np.ones([row_A + row_S + row_T, N])

predict = np.zeros([row_T])

trans_data = np.asarray(trans_data, order='C')
trans_label = np.asarray(trans_label, order='C')
test_data = np.asarray(test_data, order='C')

best_ks = -1    #最优KS
best_round = -1 #最优基模型数量
best_model = -1 #最优模型

# 初始化结束

for i in range(N):
    P = calculate_P(weights, trans_label)

    result_label[:, i],model = train_classify(trans_data, trans_label,
                                        test_data, P)
    score_H = result_label[row_A:row_A + row_S, i]
    pctg = np.sum(data.bad_ind)/len(data.bad_ind)
    thred = pd.DataFrame(score_H).quantile(1-pctg)[0]
    label_H = put_label(score_H,thred)
    error_rate = calculate_error_rate(label_S, label_H,
                                      weights[row_A:row_A + row_S, :])

    if error_rate > 0.5:
        error_rate = 0.5
    if error_rate == 0:
        N = i
        break  # 防止过拟合
        # error_rate = 0.001

    bata_T[0, i] = error_rate / (1 - error_rate)

    # 调整目标域样本权重
    for j in range(row_S):
        weights[row_A + j] = weights[row_A + j] * np.power(bata_T[0, i],
                                                           (-np.abs(result_label[row_A + j, i] - label_S[j])))

    # 调整源域样本权重
    for j in range(row_A):
        weights[j] = weights[j] * np.power(bata, np.abs(result_label[j, i] - label_A[j]))

        
    y_pred = result_label[(row_A + row_S):,i]
    fpr_lr_train,tpr_lr_train,_ = roc_curve(val_y,y_pred)
    train_ks = abs(fpr_lr_train - tpr_lr_train).max()
    print('test_ks : ',train_ks,'当前第',i+1,'轮')
    
    
    if train_ks > best_ks :
        best_ks = train_ks
        best_round = i
        best_model = model

? 训练结束后,用最优的逻辑回归模型对样本进行测试,结果如下:

? 该方案只使用训练过程中表现最好的学习器进行决策,因此保留了单个逻辑回归模型的解释性,对于模型上线部署没有影响。但是这也增大了过拟合的风险,在实际使用中需要权衡迭代次数。

【作者】:Labryant

【原创公众号】:风控猎人

【简介】:某创业公司策略分析师,积极上进,努力提升。乾坤未定,你我都是黑马。

【转载说明】:转载请说明出处,谢谢合作!~

相关推荐

30天学会Python编程:16. Python常用标准库使用教程

16.1collections模块16.1.1高级数据结构16.1.2示例...

强烈推荐!Python 这个宝藏库 re 正则匹配

Python的re模块(RegularExpression正则表达式)提供各种正则表达式的匹配操作。...

Python爬虫中正则表达式的用法,只讲如何应用,不讲原理

Python爬虫:正则的用法(非原理)。大家好,这节课给大家讲正则的实际用法,不讲原理,通俗易懂的讲如何用正则抓取内容。·导入re库,这里是需要从html这段字符串中提取出中间的那几个文字。实例一个对...

Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)

实现功能:Python数据分析实战-利用正则表达式提取文本中的URL网址和邮箱...

python爬虫教程之爬取当当网 Top 500 本五星好评书籍

我们使用requests和re来写一个爬虫作为一个爱看书的你(说的跟真的似的)怎么能发现好书呢?所以我们爬取当当网的前500本好五星评书籍怎么样?ok接下来就是学习python的正确姿...

深入理解re模块:Python中的正则表达式神器解析

在Python中,"re"是一个强大的模块,用于处理正则表达式(regularexpressions)。正则表达式是一种强大的文本模式匹配工具,用于在字符串中查找、替换或提取特定模式...

如何使用正则表达式和 Python 匹配不以模式开头的字符串

需要在Python中使用正则表达式来匹配不以给定模式开头的字符串吗?如果是这样,你可以使用下面的语法来查找所有的字符串,除了那些不以https开始的字符串。r"^(?!https).*&...

先Mark后用!8分钟读懂 Python 性能优化

从本文总结了Python开发时,遇到的性能优化问题的定位和解决。概述:性能优化的原则——优化需要优化的部分。性能优化的一般步骤:首先,让你的程序跑起来结果一切正常。然后,运行这个结果正常的代码,看看它...

Python“三步”即可爬取,毋庸置疑

声明:本实例仅供学习,切忌遵守robots协议,请不要使用多线程等方式频繁访问网站。#第一步导入模块importreimportrequests#第二步获取你想爬取的网页地址,发送请求,获取网页内...

简单学Python——re库(正则表达式)2(split、findall、和sub)

1、split():分割字符串,返回列表语法:re.split('分隔符','目标字符串')例如:importrere.split(',','...

Lavazza拉瓦萨再度牵手上海大师赛

阅读此文前,麻烦您点击一下“关注”,方便您进行讨论和分享。Lavazza拉瓦萨再度牵手上海大师赛标题:2024上海大师赛:网球与咖啡的浪漫邂逅在2024年的上海劳力士大师赛上,拉瓦萨咖啡再次成为官...

ArkUI-X构建Android平台AAR及使用

本教程主要讲述如何利用ArkUI-XSDK完成AndroidAAR开发,实现基于ArkTS的声明式开发范式在android平台显示。包括:1.跨平台Library工程开发介绍...

Deepseek写歌详细教程(怎样用deepseek写歌功能)

以下为结合DeepSeek及相关工具实现AI写歌的详细教程,涵盖作词、作曲、演唱全流程:一、核心流程三步法1.AI生成歌词-打开DeepSeek(网页/APP/API),使用结构化提示词生成歌词:...

“AI说唱解说影视”走红,“零基础入行”靠谱吗?本报记者实测

“手里翻找冻鱼,精心的布局;老漠却不言语,脸上带笑意……”《狂飙》剧情被写成歌词,再配上“科目三”背景音乐的演唱,这段1分钟30秒的视频受到了无数网友的点赞。最近一段时间随着AI技术的发展,说唱解说影...

AI音乐制作神器揭秘!3款工具让你秒变高手

在音乐创作的领域里,每个人都有一颗想要成为大师的心。但是面对复杂的乐理知识和繁复的制作过程,许多人的热情被一点点消磨。...

取消回复欢迎 发表评论: