主动学习之Alipy包使用

引入

0.1 主动学习简介

  在诸多实际问题中,未标记数据大量而已标记数据稀缺。由于人类专家的参与,标签的获取通常昂贵。因此,通过少量的标签实例来训练准确的预测模型至关重要。
  主动学习的目的即是:
  通过只查询最有价值的实例来减少人类专家在机器学习系统中注释实例的比例,并已成功地应用到各种实际任务中。
  原文链接~~
  
  声明:此文为笔者学习Alipy包使用的历程,绝无半点侵权之意。

0.2 主动学习示例

  常规的主动学习过程中,示例查询和模型更新迭代进行。以下是一个具体的例子:
在这里插入图片描述

图0-1 主动学习过程示例


  上述过程伪代码如下:
  输入:有标签的训练集(仅有少量实例)LL
  while:
    查询算法选择一批被认为有价值的无标签数据
    oracle根据其已有知识提供一些有监督的信息
    新的有标签实例添加到标记集LL
    更新模型
  直到满足特定的停止标准(如,有限的查询数量或有限的成本预算)。

0.3 查询策略及评价

  主动学习的研究方向之一是查询策略。学习者将根据特定的查询策略选择一些未标记的数据,并从oracle中查询其标签。在主动学习文献中,各种策略从不同方面进行评估,以此判断实例对模型改进的有用性。
  那如何评估不同算法的性能呢?
  通过构造学习曲线的方式直观有效,如将查询次数与准确率的关系进行绘制。对于不同的查询策略,由于会选择不同的数据进行查询,将会产生不同的学习曲线。

0.4 Alipy概述

  Alipy提供了一个基于模块的主动学习框架,其目标是用各种工具功能支持实验实现。这些工具是以低耦合的方式设计的,以便用户可以根据自己的习惯来编程实验项目。支持的模块如下:

序列 模块名 功用
1 alipy.data_manipulate 数据划分
2 alipy.query_strategy 数据查询策略
3 alipy.index.IndexCollection 索引管理
4 alipy.metric 模型性能计算
5 alipy.experiment.state/alipy.experiment.state_io 保存每次查询后的中间结果并从断点恢复程序
6 alipy.experiment.stopping_criteria 获取停止标准
7 alipy.experiment.experiment_analyser 可视化实验结果
8 alipy.oracle 提供清洁、噪音或者代价敏感的oracle
9 alipy.utils.multi_thread 多次实验

  支持以下算法:

序列 算法类型 具体算法
1 实例选择 Uncertainty (SIGIR 1994) , Graph Density (CVPR 2012) , QUIRE (TPAMI 2014)、
SPAL (AAAI 2019) , Query By Committee (ICML 1998) , Random
BMDR (KDD 2013) , LAL (NIPS 2017) , Expected Error Reduction (ICML 2001)…
2 多标签数据 AUDI (ICDM 2013) , QUIRE (TPAMI 2014) , Random
MMC (KDD 2009) , Adaptive (IJCAI 2013) …
3 特征查询 AFASMC (KDD 2018) , Stability (ICDM 2013) , Random
4 不同代价 AL with Different Costs : HALC (IJCAI 2018) , Random
Cost performance…
5 噪声oracle AL with Noisy Oracles : CEAL (IJCAI 2017) , IEthresh (KDD 2009)
All , Random…
6 特殊查询类型 AURO (IJCAI 2015) …
7 大规模任务 Subsampling…

1 高级封装

1.1 ToolBox

  ToolBox是一个提供所有可用工具类的类,以下说明大致功用。

1.1.1 初始化ToolBox对象:

程序清单1-1: 初始化工具箱

from sklearn.datasets import *
from alipy import ToolBox
import warnings
warnings.filterwarnings("ignore")    #忽略警告

def test():
    data_set, label_set = load_iris(return_X_y=True)    #示例:导入iris数据集;返回实例集合与相应标签
    print("The data set:", data_set)
    print("The label set", label_set)
    alibox = ToolBox(X=data_set, y=label_set, query_type='AllLabels', saving_path='.')

if __name__ == '__main__':
    test()

  运行结果(注:载入boston数据时会出现未知错误):

...
 [5.9 3.  5.1 1.8]]
The label set [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

  引入的sklearn.datasets自带以下数据集(当然可以自行导入数据集):

数据集名称 导入命令 用途
鸢尾花数据集 load_iris() 用于分类或聚类任务的数据集
手写数字数据集 load_digits() 用于分类任务或者降维任务的数据集
乳腺癌数据集 load_barest_cancer() 用于二分类任务的数据集
糖尿病数据集 load_diabetes() 用于回归任务的数据集
波士顿房价数据集 load_boston() 用于回归任务的数据集
体能训练数据集 load-linnerud() 用于多变量回归任务的数据集

  查询类型有下:

AllLabels PartLabels Features

1.1.2 获取默认模型

  Alipy默认模型为logistic回归模型,相应的获取、训练、测试方法如下:

程序清单1-2: 获取默认模型及预测

from sklearn.datasets import *
from alipy import ToolBox
import warnings
warnings.filterwarnings("ignore")    #忽略警告

def test():
    data_set, label_set = load_iris(return_X_y=True)    #示例:导入iris数据集;返回实例集合与相应标签
    # print("The data set:", data_set)
    # print("The label set", label_set)
    alibox = ToolBox(X=data_set, y=label_set, query_type='AllLabels', saving_path='.')    #一般使用‘AllLabels’

    de_model = alibox.get_default_model()    #获取默认模型
    de_model.fit(data_set, label_set)    #传入数据及标签
    pred = de_model.predict(data_set)    #标签预测
    print(pred)
    pred = de_model.predict_proba(data_set)    #获取概率输出
    # print(pred)

if __name__ == '__main__':
    test()

  运行结果:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1
 1 1 1 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

1.1.3 划分数据

  ToolBox中有两种获取划分数据的方式:
  1)使用alibox.split_AL()并指定参数来划分,即:

train_ind, test_ind, label_ind, unlabel_ind = alibox.split_AL(test_ratio=0.3, initial_label_rate=0.1, split_count=1)

  参数说明:

参数名称 意义
test_ratio 测试集比例
initial_label_rate 测试集中带标签实例的比例
split_count 划分次数
train_ind 训练集
test_ind 测试集
label_ind 训练集中带标签实例
unlabel_ind 训练集中不带标签实例

2)方式2与方式1是类似的,需要注意的是返回值均为索引:

alibox.split_AL(test_ratio=0.3, initial_label_rate=0.1, split_count=10)

train_0, test_0, label_0, unlabel_0 = alibox.get_split(round=0)
train_1, test_1, label_1, unlabel_1 = alibox.get_split(round=1)

1.1.4 创建IndexCollection对象

  alipy.index.IndexCollection是一个管理索引的工具类,可通过以下方式创建和使用该类:

程序清单1-3: IndexCollection类使用示例

from sklearn.datasets import *
from alipy import ToolBox
import warnings
warnings.filterwarnings("ignore")    #忽略警告

def test1():
    data_set, label_set = load_iris(return_X_y=True)
    alibox = ToolBox(X=data_set, y=label_set, query_type='AllLabels', saving_path='.')
    a = [1, 2, 3]
    a_ind = alibox.IndexCollection(a)    #这里的a可以是训练集索引或者其他
    print("index:", a_ind.index)    #索引输出
    a_ind.add(10)    #添加单个索引;注:索引不会重复
    print("add:", a_ind)
    a_ind.discard(1)     #删除已有索引
    print("discard", a_ind)
    a_ind.update([4, 5, 10])    #添加多个元素
    print("update", a_ind)
    a_ind.difference_update([4, 10])    #删除多个元素
    print("difference_update", a_ind)

  运行结果:

index: [1, 2, 3]
add: [1, 2, 3, 10]
discard [2, 3, 10]
update [2, 3, 10, 4, 5]
difference_update [2, 3, 5]

1.1.5 获得Oracle或Repository 对象

  1)获取clean oracle

clean_oracle = alibox.get_clean_oracle(query_by_example=False, cost_mat=None)

  如按特征查询:query_by_example=True。

  提供一个索引或一个索引列表,以便查询标签和相应代价(标签为初始化数据集所对应的标签):

label, cost = clean_oracle.query_by_index([1])

  如果在初始化时没有指定代价,则默认为1,否则可以设置代价矩阵;代价矩阵的形状应与标签矩阵的形状相同,以便进行代价敏感查询。
  2)获取 repository

alibox.get_repository(round=0, instance_flag=False)

  round即与之前split_count相对应。当然,若要保存当前所选实例的特征向量则设置:instance_flag=True。

程序清单1-4: clean oracle类使用示例

from sklearn.datasets import *
from alipy import ToolBox
import warnings
warnings.filterwarnings("ignore")    #忽略警告

def test2():
    data_set, label_set = load_iris(return_X_y=True)    #示例:导入iris数据集;返回实例集合与相应标签
    alibox = ToolBox(X=data_set, y=label_set, query_type='AllLabels', saving_path='.')    #一般使用‘AllLabels’
    clean_oracle = alibox.get_clean_oracle(query_by_example=False, cost_mat=None)
    label, cost = clean_oracle.query_by_index([1])
    print("label:", label)
    print("cost:", cost)

if __name__ == '__main__':
    test2()

  运行结果:

label: [0]
cost: [1]

1.1.6 获取State 或 StateIO 对象

  alipy.experiment.StateIO用于保存或者载入中间结果,几个重要功能如下:
  1)以文件形式保存中间结果;
  2)在任意次迭代中恢复工作台(标签集和非标签集);
  3)程序意外退出时从断点恢复程序;
  4)输出主动学习过程:当前迭代次数、当前平均性能、当前代价等。
  
  对于每一次round,可如下保存:

saver = alibox.get_stateio(round=1)    #1作为示例

  可设置相应参数如下:

st = alibox.State(select_index=select_ind, performance=accuracy, cost=cost, queried_label=queried_label)	#此处并为给出select_ind等的定义
saver.add_state(st)    #添加参数
saver.save()    #保存至文件,默认保存于当前文件夹

1.1.7 获取预设查询策略对象

  Alipy支持的查询策略如下:

序号 策略名称
1 QueryInstanceQBC
2 QueryInstanceUncertainty
3 QueryRandom
4 QureyExpectedErrorReduction
5 QueryInstanceGraphDensity
6 QueryInstanceQUIRE

  具体使用如下:

QBCStrategy = alibox.get_query_strategy(strategy_name='QueryInstanceQBC')

  注意:QueryInstanceGraphDensity及QueryInstanceQUIRE需要额外指定参数!

1.1.8 计算性能

  支持性能计算方法如下:

序号 性能计算方法名
1 accuracy_score
2 roc_auc_score
3 get_fps_tps_thresholds
4 hamming_loss
5 one_error
6 coverage_error
7 label_ranking_loss
8 label_ranking_average_precision_score

一个具体的例子如下:

程序清单1-5: 性能计算示例

from sklearn.datasets import *
from alipy import ToolBox
import warnings
warnings.filterwarnings("ignore")    #忽略警告

def test3():
    data_set, label_set = load_iris(return_X_y=True)    #示例:导入iris数据集;返回实例集合与相应标签
    alibox = ToolBox(X=data_set, y=label_set, query_type='AllLabels', saving_path='.')    #一般使用‘AllLabels’
    alibox.split_AL(test_ratio=0.3, initial_label_rate=0.1, split_count=10)
    de_model = alibox.get_default_model()
    de_model.fit(data_set, label_set)
    pred = de_model.predict(data_set)
    
    """新增"""
    acc = alibox.calc_performance_metric(y_true=label_set, y_pred=pred, performance_metric='accuracy_score')
    print("accuracy score:", acc)

if __name__ == '__main__':
    test3()

  运行结果:

accuracy score: 0.96

1.1.9 获取停止标准

  常用停止标准如下:

序号 命令名 代表意义
1 None 默认:没有未标记实例
2 num_of_queries 查询数量
3 cost_limit 代价限制
4 percent_of_unlabel 未标记实例比例
5 time_limit 时间限制

  一个示例如下:

stopping_criterion = alibox.get_stopping_criterion(stopping_criteria='time_limit', value=1)

    for i in range(10):
        print(i)
        while not stopping_criterion.is_stop():
            pass

1.1.10 可视化实验结果

  一个示例如下:

analyser = alibox.get_experiment_analyser(x_axis='time_limit')    #设置x轴名称
analyser.add_method(method_name='QBC', method_result=QBC_result)
analyser.plot_learning_curves()    #绘制

1.1.11 最终结果保存

  一个示例如下:

alibox.save()
alibox = ToolBox.load('./al_settings.pkl')

1.2 智能实验

  alipy.experiment.AlExperiment是一个封装了各种工具并实现了主循环的类。以下为一个具体示例:

程序清单1-6: 一次简单的实验

from sklearn.datasets import load_iris
from alipy.experiment.al_experiment import AlExperiment
import warnings
warnings.filterwarnings("ignore")    #忽略警告

def test5():
    data_set, label_set = load_iris(return_X_y=True)
    al = AlExperiment(data_set, label_set, stopping_criteria='num_of_queries', stopping_value=50)
    al.split_AL()
    al.set_query_strategy(strategy="QueryInstanceUncertainty", measure='least_confident')
    al.set_performance_metric('accuracy_score')
    al.start_query(multi_thread=True)    #开启多线程
    al.plot_learning_curve()

if __name__ == '__main__':
    test5()

  运行结果:

|   7   |         50        |   00:00:04  |       0.909 ± 0.12       |
|   8   |         50        |   00:00:04  |       0.957 ± 0.04       |
|   9   |         50        |   00:00:04  |       0.698 ± 0.10       |
+-------+-------------------+-------------+--------------------------+

+--------------------------+-------------------+---------------------------+--------------+------------+
|         Methods          | number_of_queries | number_of_different_split | performance  | batch_size |
+--------------------------+-------------------+---------------------------+--------------+------------+
| QueryInstanceUncertainty |         50        |             10            | 0.843 ± 0.08 |     1      |
+--------------------------+-------------------+---------------------------+--------------+------------+

  绘制结果:
在这里插入图片描述

图1-1 实验示例

2 Alipy工具类

  接下来详细讲解具体工具类的用途。

2.1 数据操作

  alipy.data_manipulate用于管理实验数据。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章