noHup - lightgbm
type: channel
link: http://chris.nohup.cc/tag/lightgbm/
items: 增量学习的主流实现
items: PySpark笔记之五：lightGBM调参之PySpark + mmlspark + Hyperopt
items: PySpark笔记之四：lightGBM调参之PySpark + mmlspark + Grid Search
items: PySpark笔记之三：lightGBM调参之PySpark + Grid Search
items: PySpark笔记之二：PySpark环境LightGBM训练
items: 互联网金融模型经验总结（一）

增量学习的主流实现
type: item
date: 2020-05-18T07:27:00+00:00
description: Overview1. XGBoost2. LightGBM3. TensorFlow2.0 Overview 之前的文章介绍了一些推荐系统的理论知识，理论虽然很容易理解，但是实际项目当中会有一些细节问题是需要我们去解决的。比如在很多流量很大的电商以及资讯网站的推荐系统中，每天的数据其实是增长很快的，所以模型迭代的频率也是非常高的，甚至于需要每天更新。那么我们就要面临一个很现实的问题，我们每天更新模型，那么每次都要用全量数据去训练模型吗？显然这是不可能的。一来耗费资源，二来时间也不允许。那么，增量学习Incremental Learning就派上用场了。增量学习是这几年才出来的概念，其目的在于训练新数据的同时也能保留以前模型的效果，即在之前的模型基础上对新增的数据进行训练。 主流的几种机器学习框架，已经实现了增量学习的功能，接下来看一下他们是怎么做到的。 1. XGBoost 我们一般情况下用XGBoost训练一个全新的模型，其相关方法是这样的： watchlist = [(xgb_train, 'train'), (xgb_val, 'val'), (xgb_test, 'test')] # training model_path = 'init.model' model = xgb.train(params, xgb_train, num_boost, watchlist) model.save_model(model_path) 如果我们线上已经有一个效果很好的模型，需要在此基础上对新增的数据进行增量训练，那么XGBoost是这样实现的： # 指定基础模型参数，xgb_model # 传入新的增量训练数据，xgb_train_new model_new = xgb.train(params, xgb_train_new, num_boost, xgb_model=model_path) 我们来看这个参数的作用： xgb_model : file name of stored xgb model or 'Booster' instance Xgb model to be loaded before training (allows training continuation). 即在指定的模型上继续训练。 更多相关知识请参考： How can I implement incremental training for xgboost? dmlc/xgboost 2. LightGBM model = lgb.train(params, lgb_train, num_boost_round=1000, valid_sets=lgb_eval, feature_name=x_cols, early_stopping_rounds=10, verbose_eval=False, init_model=model, # 如果init_model不为None，那么就是在init_model基础上接着训练 keep_training_booster=True) # 增量训练 LightGBM实现增量训练也很简单，只需要设置init_model为当前线上的模型，且keep_training_booster设置为True即可。 更多相关知识请参考： Incremental learning using Dataset.subset LightGBM 2.1.1 python API Standard outputs infos even when disabled lightgbm.train 3. TensorFlow2.0 我们知道，TensorFlow2.0已经集成好了Keras高级API，所以，我们看看增量学习在Keras当中是如何实现的。 # 加载线上的模型 model_path = 'init.model' loaded_model = tf.keras.models.load_model(model_path) # 新数据上接着训练 history = loaded_model.fit( train_data_gen, steps_per_epoch=total_train // batch_size, epochs=epochs, validation_data=val_data_gen, validation_steps=total_val // batch_size ) 可以看到，TensorFlow2.0对于增量训练支持也是很完备的。

PySpark笔记之五：lightGBM调参之PySpark + mmlspark + Hyperopt
type: item
date: 2020-04-28T09:33:00+00:00
description: Overview1. 加载相关包2. 加载数据3. 定义参数空间和代价函数4. 随机搜索调参和贝叶斯优化调参 Overview 之前的文章中记录了大数据平台上lightGBM分类器的Grid Search调参方法的应用。这次我们继续用lightGBM分类器，看看另外两种常用的调参方法随机搜索Random Search和贝叶斯优化Bayesian Optimization怎么在Spark平台上使用。 1. 加载相关包 import numpy as np import pyspark spark = pyspark.sql.SparkSession.builder.appName("spark lightgbm") \ .master("spark://***.***.***.***:7077") \ .config("spark.jars.packages", "com.microsoft.ml.spark:mmlspark_2.11:0.18.1") \ .config("spark.cores.max", "20") \ .config("spark.driver.memory", "6G") \ .config("spark.executor.memory", "6G") \ .config("spark.executor.cores", "6") \ .getOrCreate() import mmlspark from mmlspark.lightgbm import LightGBMClassifier from pyspark.ml.feature import VectorAssembler from hyperopt import fmin, rand, tpe, hp, space_eval, Trials 其中hyperopt是一款强大的调参工具，实现了随机搜索和贝叶斯优化。 如果没有安装hyperopt,那么先在master节点安装hyperopt： pip3 install hyperopt 2. 加载数据 df_train = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/yangbingjiao/训练集特征.csv") df_val = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/yangbingjiao/验证集特征.csv") df_test = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/yangbingjiao/测试集特征.csv") 处理特征： feature_cols = list(df_train.columns) feature_cols.remove("label") assembler = VectorAssembler(inputCols=feature_cols, outputCol="features") df_train = assembler.transform(df_train) df_val = assembler.transform(df_val) df_test = assembler.transform(df_test) 3. 定义参数空间和代价函数 定义参数搜索空间，以lambdaL1和lambdaL2为例： space = { 'objective':"binary", 'boostingType':'gbdt', 'isUnbalance':True, 'featuresCol':'features', 'labelCol':'label', 'maxBin':60, 'baggingFreq':1, 'baggingSeed':696, 'earlyStoppingRound':20, 'learningRate':0.1, 'maxDepth':3, 'numLeaves':128, 'baggingFraction':0…

PySpark笔记之四：lightGBM调参之PySpark + mmlspark + Grid Search
type: item
date: 2020-04-23T12:48:00+00:00
description: Overview1. 加载PySpark和mmlspark相关包2.加载数据3.建模4.预测测试集 Overview 上一篇文章PySpark笔记之三：lightGBM调参之PySpark + Grid Search，我们记录了分别用PySpark中自带的CrossValidator和更通用的生成多个分类器同时执行训练预测的方式选取最好的模型。其中CrossValidator并不能得到验证集上最佳的分类器，而是得到训练集上最佳的效果。而mmlspark当中却有更为简单的方式，既可以得到验证集上最佳的效果，也可以方便地记录我们每一组参数对应的结果，是一种很好的方式。 1. 加载PySpark和mmlspark相关包 import numpy as np import pyspark spark = pyspark.sql.SparkSession.builder.appName("spark lightgbm") \ .master("spark://***.***.***.***:7077") \ .config("spark.jars.packages", "com.microsoft.ml.spark:mmlspark_2.11:0.18.1") \ .config("spark.cores.max", "20") \ .config("spark.driver.memory", "6G") \ .config("spark.executor.memory", "6G") \ .config("spark.executor.cores", "6") \ .getOrCreate() from pyspark.ml.feature import VectorAssembler from pyspark.ml.evaluation import BinaryClassificationEvaluator import mmlspark from mmlspark.lightgbm import LightGBMClassifier from mmlspark.automl import * from mmlspark.train import TrainClassifier, ComputeModelStatistics 2.加载数据 df_train = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/训练集特征.csv") df_val = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/验证集特征.csv") df_test = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/测试集特征.csv") 处理训练集、验证集和测试集数据： feature_cols = list(df_train.columns) feature_cols.remove("label") assembler = VectorAssembler(inputCols=feature_cols, outputCol="features") df_train = assembler.transform(df_train) df_val = assembler.transform(df_val) df_test = assembler.transform(df_test) 3.建模 lgb = LightGBMClassifier( objective="binary", boostingType='gbdt', isUnbalance=True, featuresCol='features', labelCol='label', maxBin=60, baggingFreq=1, baggingSeed=696, earlyStoppingRound=20, learningRate=0.1, #l…

PySpark笔记之三：lightGBM调参之PySpark + Grid Search
type: item
date: 2020-04-18T12:33:00+00:00
description: Overview1. 引入依赖包2. 加载数据3. 模型构建4. 交叉验证选择模型5. 官方调参探讨 Overview 在实际机器学习工作当中，调参是我们一个重要的内容。PySpark当中就实现了一个最常用的调参方法Grid Search，我们结合lightGBM使用一下PySpark的调参。这个程序需要安装的依赖的安装方式，可以参考上一篇博客。 1. 引入依赖包 import numpy as np import pyspark spark = pyspark.sql.SparkSession.builder.appName("spark lightgbm") \ .master("spark://***.***.***.***:7077") \ .config("spark.jars.packages", "com.microsoft.ml.spark:mmlspark_2.11:0.18.1") \ .config("spark.cores.max", "20") \ .config("spark.driver.memory", "6G") \ .config("spark.executor.memory", "6G") \ .config("spark.executor.cores", "6") \ .getOrCreate() import mmlspark from mmlspark.lightgbm import LightGBMClassifier from pyspark.ml.feature import VectorAssembler from pyspark.ml.tuning import CrossValidator, ParamGridBuilder from pyspark.ml.evaluation import BinaryClassificationEvaluator from pyspark.ml import Pipeline 其中，pyspark.ml.tuning.ParamGridBuilder就是用以实现Grid Search的包。 2. 加载数据 df_train = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/训练集特征.csv") df_val = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/验证集特征.csv") df_test = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/测试集特征.csv") 处理训练集特征： feature_cols = list(df_train.columns) feature_cols.remove("label") # 从列名当中删除label才是真正的特征列表 assembler = VectorAssembler(inputCols=feature_cols, outputCol="features") df_train = assembler.transform(df_train) 3. 模型构建 lgb = LightGBMClassifier( objective="binary", boostingType='gbdt', isUnbalance=True, featuresCol='features', labelCol='label', maxBin=60, baggingFreq=1, baggingSeed=696, earlyStoppingRound=30, learningRate=0.1, # lambdaL1=1.0, # lambdaL2=45.0, maxDepth=3, numLeaves=128, baggingFraction=0.7, featureFraction=0.7, minSumHessianInLeaf=0.001, …

PySpark笔记之二：PySpark环境LightGBM训练
type: item
date: 2020-04-04T10:00:00+00:00
description: Overview1. 安装mmlspark2. 引入依赖包3. 加载数据4. 模型构建 Overview 就目前的PySpark版本2.4.5来说，虽有pyspark.ml这个模块可以进行机器学习，但是都是一些工业界不太常用的算法，而XGBoost和LightGBM这样的常用算法还没有集成。幸好微软前几年发布了mmlspark这个包，其中包含了深度学习和LightGBM等算法，可以和PySpark无缝对接。下面我们看看怎么用PySpark和mmlspark来运行LightGBM。 1. 安装mmlspark 首先，我们默认已经安装好了PySpark，如果没有安装，那么安装命令如下： pip3 install pyspark 然后，安装mmlspark的方式如下，命令行输入： pyspark --packages com.microsoft.ml.spark:mmlspark_2.11:0.18.1 或者直接在jupyter notebook中，使用PySpark时，这样启动： import pyspark spark = pyspark.sql.SparkSession.builder.appName("MyApp") \ .config("spark.jars.packages", "com.microsoft.ml.spark:mmlspark_2.11:1.0.0-rc1") \ .config("spark.jars.repositories", "https://mmlspark.azureedge.net/maven") \ .getOrCreate() import mmlspark 这个包比较大，第一次安装需要较长时间。我们服务器上maven仓库当中，mmlspark版本是0.18.1，而这个版本训练时会导致一个bug，下面会提到。 详细安装方式可参考官方文档：Azure / mmlspark，最新的mmlspark版本是1.0.0-rc1。 2. 引入依赖包 import numpy as np import pyspark spark = pyspark.sql.SparkSession.builder.appName("spark lightgbm") \ .master("spark://***.***.***.***:7077") \ .config("spark.jars.packages", "com.microsoft.ml.spark:mmlspark_2.11:0.18.1") \ .config("spark.cores.max", "20") \ .config("spark.driver.memory", "6G") \ .config("spark.executor.memory", "6G") \ .config("spark.executor.cores", "6") \ .getOrCreate() import mmlspark from mmlspark.lightgbm import LightGBMClassifier from pyspark.ml.feature import VectorAssembler # from pyspark.ml.tuning import CrossValidator, ParamGridBuilder from pyspark.ml.evaluation import BinaryClassificationEvaluator from pyspark.ml import Pipeline 其中，VectorAssembler这个类，可以将特征转换成一个向量，作为分类器的输入。BinaryClassificationEvaluator可以评价预测效果。Pipeline相当于Spark的流水线，将各个步骤连接在一起后，一起由Spark运行。 3. 加载数据 df_train = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/训练集特征.csv") df_val = spark.read.format("csv") \ .option("inferSchema", "true") \ .option("header", "true") \ .option("sep", ",") \ .load("hdfs://***.***.***.***:39000/young/验证集特征.csv…

互联网金融模型经验总结（一）
type: item
date: 2020-03-18T09:22:00+00:00
description: Overview1. 特征挖掘2. 特征处理2.1 样本不均衡问题2.2 空值问题2.3 类别特征处理2.4 归一化和标准化2.5 特征选择和降维2.6 特征评估3. 模型构建3.1 数据集准备3.2 机器学习算法选择3.3 过拟合与欠拟合3.3.1 过拟合3.3.2 欠拟合3.4 XGBoost调参训练demo3.5 模型预测3.6 多模型融合3.6.1 不同类型的样本产生的多个模型进行融合3.6.2 不同类型的机器学习算法产生的多个模型进行融合 Overview 互联网金融行业主要涉及以下方面：保险、理财、基金、信贷、虚拟信用卡、催收等，主要用到以下类型的模型： 营销模型、召回模型、排序模型（支付宝蚂蚁财富基金推荐红包发放等） 新用户反欺诈模型 新老用户信用额度模型（蚂蚁借呗，腾讯微粒贷，京东金条，微博钱包，美团借钱，各类小贷等） 虚拟信用卡贷中风控模型（蚂蚁花呗，京东白条等） 贷后催收模型 我在互联网金融行业已经工作两年了，也积累了不少信贷数据特征挖掘和信贷模型开发经验。现在将这些经验记录一下，算是对两年时间的一个总结。总体上，这个领域和其他领域在机器学习模型构建的流程上区别不大，主要精力都是在特征挖掘和模型构建上。 1. 特征挖掘 显而易见，这个领域，用户的资产和负债数据是最有效的数据，但是除了银行或者蚂蚁金服和京东金融等大金融平台之外，我们一般情况下很难拿到用户的资产数据，我们最多能拿到用户的第三方征信数据，即用户负债数据（国内常见为同盾，百融，百行征信等），结合用户授权我们爬取的用户的通讯录，APP安装列表，淘宝京东APP订单数据等，以及用户在本公司的借贷历史行为记录和用户登录APP的埋点数据，我们可以做出很多特征，三方多头征信特征是最有效的，其次对于老用户，用户的借贷历史行为也很有效。其中，时间序列数据是特征工程的重头戏，对于和时间相关的订单类，行为类等数据，我们可以用类似的方法开发出一大批时间序列特征，其形式均为“某时间段内 + 某种行为发生的次数/金额/比例/时长间隔/持续时间 + 最值/q1/q2/q3/均值/众数/中位数”，例如"三个月内用户在本平台贷款金额序列的均值"。这部分特征由三部分组成： 时间长度 行为类型 统计量 另外，用户授权我们拿到他们的通讯录之后，我们可以通过他的一二度人脉在本公司的表现，来做关系图特征。我们取得用户的APP安装列表之后，可以将APP按照风险等级给分为3或者4类：714高炮类，小贷类，普通消费金融与正常金融类，学习以及其他正向类。另外，如果是贷后催收模型，还需要加入用户的催收表现特征。 2. 特征处理 2.1 样本不均衡问题 我们在业务上遇到的很多数据，几乎都是正负样本不平衡的，一般情况下是好样本数量远大于坏样本，用户客群质量越高，样本差异越大。小贷平台好坏样本比例一般在3:1到20:1之间，大平台差异更大，这样设计一个课题：样本不均衡问题。 样本不均衡时，我们有以下这些处理方式（通用方式，不只信贷领域），但基本思想就是"再缩放（rescaling）"： 较多类欠采样 较少类过采样 预测时阈值移动 合成数据或无label样本学习 权重缩放或惩罚权重 异常检测的方式（如果好坏样本数量悬殊，例如欺诈检测） 组合/集成学习 个人以为，我们在信贷工作当中，业务样本真实性还是很重要的，因此，不建议用SMOTE等方法进行插值产生坏样本。当然像图像，语音，文本等具象的数据，人可以轻松判断正负样本的领域除外。 2.2 空值问题 我们的特征中是有不少空值的，我们可以进行零值填充、均值填充或者众数填充，不过我们一般不会对这些空值进行填充，因为填充大概率会引入误差。另外，某些机器学习算法，其思想是计算距离来划分类别，例如SVM和KNN，对于这些算法，有空值的情况是不适合的，填充空值也是不适合的，因为填充不同的数据会对结果产生较大影响。而且，我们业务上特征维度是非常高的，即便进行了特征选择和降维，因此有很多算法效率是很低的，不推荐使用，这是后话。 因此，我们原则上，保留空值不处理。 2.3 类别特征处理 类别特征大家一般都是做one-hot处理，因为大部分算法是只支持数字型特征的。但是有少部分算法是支持类别型特征，而不用做独热编码的，例如LightGBM。 2.4 归一化和标准化 归一化和标准化都属于无量纲化，其主要目的就是为了避免数值问题和加快模型收敛速度。有些模型最好要进行无量纲化，例如线性回归，SVM，kNN，逻辑回归，k-Means，神经网络等；而XGBoost，lightGBM，朴素贝叶斯，决策树和随机森林等算法通常是不需要无量纲化的。 归一化和标准化之前的文章数据挖掘之数据标准化(Normalization)写过，这里就不赘述了。 2.5 特征选择和降维 特征选择的主要作用是去掉冗余的…