gcForest 集成学习方法的 Python 实现
前言
看完 gcForest 这篇 paper 有一段时间了,但是一直没有去网上搜集相关的实现代码,去把它调试跑通,并将之应用到实际的项目中。这两天终于抽空做了实现,并和自己项目中常用的集成算法(TreeNet、XGBoost)做了简单对比。下面总结一下整个算法的 Python 实现过程,以及将它应用到自己的数据集上出现的问题和解决办法。
一、运行环境要求
Python 版本:3.6.0 以上;
numpy 版本:1.12.0 以上;
jupyter 版本:1.0.0 以上;
scikit-learn 版本:0.18.1 以上。
解决办法: 可以直接在 Anaconda 官网 去下载对应操作系统的 Python 3.6 version;然后在 pycharm 上去选择对应版本的 project Interpreter;之后可以在 Package 列表中查看上述包对应的版本,不符合要求的可以直接更新。这样,整个 gcForest 算法的 Python 运行环境就 OK 了。
二、gcForest 实现
gcForest 算法在 github 上已经有大神实现了,版本也有好几个,我自己把其中一个版本(地址:https://github.com/pylablanche/gcForest) clone 到本地,并做了调试实现。
1) gcForest 算法实现
gcForest 算法的实现代码相对较多,直接以附件的形式上传,名称:GCForest.py(可以直接将该附件导入工程就可以了)。
2)示例——验证算法能否跑通
为了验证算法的可行性,写一个小的 demo 去测试,至于 model 中的参数(详细说明见具体实现类,12 个参数,一点儿也不多)可以根据自己的要求去调试,代码如下:
# -*- coding:utf-8 -*-
__author__ = 'Administrator'
from python_dailyworking.GCForest import gcForest
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from python_dailyworking.Get_KS import get_ks
import pandas as pd
#loading the iris data
iris = load_iris()
X = iris.data
Y = iris.target
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.33)
gcf = gcForest(shape_1X=4, window = 2, tolerance=0.0)
gcf.fit(X_train, Y_train)
#predict 方法预测的是每一条样本的分类类别,结果 pred_X 是一个 [0,1,2...]的 array
pred_X = gcf.predict(X_test)
accuracy = accuracy_score(y_true=Y_test, y_pred=pred_X) #用 test 数据的真实类别和预测类别算准确率
print ('gcForest accuracy:{}'.format(accuracy))
# predict_proba 方法预测的是每一条样本为 0,1,...类别的概率,结果是这样的:
# [[ 概率 1,概率 2,...],[ 概率 1,概率 2,...],...]的 DataFrame
# [:,1]表示取出序号为 1 的列,也就是预测类别为 1 的概率值,结果是一个数组
Y_predict_prod_test = gcf.predict_proba(X_test)[:, 1]
Y_predict_prod_train = gcf.predict_proba(X_train)[:, 1]
#下面是算 KS 值,不理解的可以置之不理
print ('model Y_test ks: ',get_ks(Y_test, Y_predict_prod_test))
print ('model Y_train ks: ',get_ks(Y_train, Y_predict_prod_train))
上面的代码中要导入我们已经实现了的 GCForest 类(第三行),后面的模型训练和预测分类结果,跟正常的 Python 调用 sklearn 中的方法一样,都是 fit(X,Y),predict(X_test) 等;代码最后两句是计算训练样本和测试样本的 KS 值,读者可以不用管,不影响程序的可运行性(运行的时候可以注释掉)。
3)用自己的数据集去跑模型
自己的数据:csv 文件,5000 个样本(有点少,但是不影响测试算法),77 个特征;
代码实现如下:
# -*- coding:utf-8 -*-
__author__ = 'Administrator'
import pandas as pd
import time
import numpy as np
from sklearn.model_selection import train_test_split
from python_dailyworking.GCForest import gcForest
from python_dailyworking.Get_KS import get_ks
from sklearn.metrics import accuracy_score
def train():
input_path = 'D:\working_temp_file\final_combine_file_phone_xgb_77X.csv'
input_data = pd.read_csv(input_path)
drop_columns_all = 'bad'
targetName = 'bad'
X1 = input_data.drop(drop_columns_all, axis=1, inplace=False)
X1 = X1.fillna(0)
# 先将 X1 和 Y1(DataFrame)转化成 array
X = np.array(X1)
Y1 = input_data[targetName]
Y1 = Y1.fillna(0)
Y = np.array(Y1)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.25)
starttime = time.time()
# gcForest Model
# shape_1X 默认是 None,但是用到 Multi-Grain Scanning 时,需要用到,我理解的是特征的数量(对于序列数据)
# window:滑动窗口的大小
# stride:滑动步长,默认是 1
# tolerance:提升的精度小于 tolerance 时,就停止整个过程。
# n_mgsRFtree=30, cascade_test_size=0.2, n_cascadeRF=2,
# n_cascadeRFtree=101, cascade_layer=np.inf,min_samples_mgs=0.1,
# min_samples_cascade=0.05, tolerance=0.0, n_jobs=1
gcf = gcForest(shape_1X=76, n_mgsRFtree=30, window=20,
stride=1, cascade_test_size=0.2, n_cascadeRF=2,
n_cascadeRFtree=50, cascade_layer=np.inf, min_samples_mgs=0.05,
min_samples_cascade=0.1, tolerance=0.0, n_jobs=1)
gcf.fit(X_train, Y_train)
pred_X = gcf.predict(X_test)
print (pred_X)
accuracy = accuracy_score(y_true=Y_test, y_pred=pred_X)
print ('gcForest accuracy:{}'.format(accuracy))
Y_predict_prod_test = gcf.predict_proba(X_test)[:, 1]
Y_predict_prod_train = gcf.predict_proba(X_train)[:, 1]
print ('model Y_test ks: ',get_ks(Y_test, Y_predict_prod_test))
print ('model Y_train ks: ',get_ks(Y_train, Y_predict_prod_train))
print ('整个模型的训练预测耗时为:',(time.time() - starttime))
if __name__ == '__main__':
train()
用自己的数据集去跑 gcForest 算法的时候,还是会遇到很多问题,特别是数据格式方面,可以根据自己的数据格式去做一系列的调试和格式转换。
4)算法对比
自己通过调参,简单的和线上的算法(XGBoost)以及另外一个集成学习算法 TreeNet 做了对比,由于 gcForest 算法中要做多粒度平滑处理和训练级联森林,所以当参数中的森林数量和对应树的数量较多时,训练模型的时间比 XGBoost 和 TreeNet 都长;效果嘛,gcForest 也稍逊一点。
说明:其实本篇文章的重点是实现测试 gcForest 算法,并对其做一个简单的应用尝试,初衷也不是和其他算法在自己数据集上做性能对比,本身这个算法的优势是做序列数据和图像数据,对于一般的常规数据样本,效果不好也可以理解,加上自己用的样本数量也太少了点,可能或多或少影响了 model 的精度。
写的比较仓促,或许会存在一些问题,希望看到的伙伴能不吝赐教,或者是有兴趣的同事,我们可以一起探讨交流,谢谢!
附件:
- python文件读写出现乱码总结
- 分布式监控系统Zabbix-图形集中展示插件Graphtree
- 分布式监控系统Zabbix-添加windows监控主机
- 盘点世界十大著名黑客攻击事件
- AS3中的单件(Singleton)模式
- puremvc框架之hello world!
- windows平台下编辑的内容传到linux平台出现中文乱码的解决办法
- puremvc框架之Command
- python sorted函数
- Centos 6.9下部署Oracle 11G数据库环境的操作记录
- puremvc框架之proxy
- Oracle数据库冷备份与热备份操作梳理
- Oracle数据库重做日志及归档日志的工作原理说明
- 用vs.net2010做flex/flash/as3开发
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- msf工具之木马程序制作以及伪装
- 一次服务器沦陷为肉鸡后的实战排查过程!
- 使用 centOS 7 部署前端项目
- PHP rand() 函数随机整数。
- PHP使用htmlspecialchars方法实现像ASP的Server.HTMLEncode一样的效果
- jquery.ajax()怎么把获取来的内容转为JSON,并使用。
- Spring:IOC 控制反转
- Spring:AOP 面向切面编程
- JavaScript进阶教程(5)-一文让你搞懂作用域链和闭包
- JavaScript进阶教程(6)—硬核动图让你轻松弄懂递归与深浅拷贝
- Spring:JDBC Template,声明式事务
- Spring:讲解编程题
- SpringMVC:基本应用
- SpringMVC:进阶
- SpringMVC:SSM 整合