高级教程¶
在本教程中,我们使用”diabetes”(糖尿病)数据集: 训练集 and 测试集 。目标是预测一个病人是否有可能患有糖尿病。
进入Silas所在目录,假设该目录为*bin*。在*bin*创建一个名为*tutorial2*的新目录。
把数据集移入*bin/tutorial2/data/*。
机器学习¶
在*bin*目录, 运行如下命令,将自动生成配置文件:
silas gen-all -o tutorial2 tutorial2/data/diabetes_train.csv tutorial2/data/diabetes_test.csv
这个命令将输出所有的设置文件,保存在文件夹*tutorial2*。我们可以运行机器学习算法并得到结果:
silas learn tutorial2/settings.json
使用默认设置,应该得到大约0.80的准确性和0.88的AUC。
打开*tutorial2/metadata-settings.json*,可以检查每个属性的默认参数。规则如下:
如果该属性有数字,并且有许多可以排序的唯一值,那么它的类型就是numerical。例如:年龄、年份、身高、体重、价格等。
如果该属性只有少量的唯一值,而且不能被排序,或者是含有文本数据,那么它的类型就是nominal。例如:性别、方向、颜色等。
在这个例子中,自动选择的特征类型是正确的,所以可以直接使用。如果需要修改metadata-settings.json,就需要使用下面的命令生成新的元数据和设置:
silas gen-metadata -o tutorial2/metadata.json tutorial2/metadata-settings.json tutorial2/data/diabetes_train.csv tutorial2/data/diabetes_test.csv
silas gen-settings -o tutorial2/settings.json -v cv tutorial2/metadata.json tutorial2/data/diabetes_train.csv tutorial2/data/diabetes_test.csv
举例来说,在*tutorial2/settings.json*中,最重要的参数通常有下列几个:
number-of-trees: 树的数量,对于小数据集来说,100通常是足够的。如果数据集包含一百万或更多的实例,那么200~500可能会有更好。如果数据集包含1000万或更多的实例,可以考虑建立1000棵或更多的树。
max-depth: 树的最大深度,对于boosting相关的算法,可以把深度设置为一个小数字,比如2~4。 对于基于随机森林的算法,可以设置为64,这基本上是一棵树所能达到的最大深度。
desired-leaf-size: 需要的叶节点大小,这个参数在很大程度上取决于数据集,可能会使性能发生很大的变化。建议尝试1~128之间的任何数字。
feature-proportion: 特征比例,可以是0到1之间的任何十进制数字。如果在选择决策节点时使用更多的特征,可能会得到更好的结果,但可能会影响模型的泛化。。
森林类型:ClassicForest是最快的,它针对二分类进行了优化。其它可选择的森林类型包括SimpleForest和CascadeForest。
树的类型:GreedyNarrow1D是最快的,它针对二分类进行了优化。另一个可选的树的类型是RdGreedy1D。
关于森林类型和树的类型,详情请参考: 《参数设置文档》
例如,通过以下设置,应该得到大约0.87的准确率和0.95的AUC。
{
"metadata-file": "metadata.json",
"output-feature": "class",
"ignored-features": [],
"learner-settings": {
"mode": "classification",
"reduction-strategy": "none",
"grower-settings": {
"forest-settings": {
"type": "SimpleForest",
"number-of-trees": 100,
"sampling-proportion": 1.0,
"oob-proportion": 0.05
},
"tree-settings": {
"type": "RdGreedy1D",
"feature-proportion": "sqrt",
"max-depth": 64,
"desired-leaf-size": 8
}
}
},
"training-dataset": {
"type": "CSV",
"path": "data/diabetes_train.csv"
},
"validation-settings": {
"type": "TT",
"testing-dataset": {
"type": "CSV",
"path": "data/diabetes_test.csv"
}
}
}
建议尝试不同的设置,以达到更好的结果。确定了设置后,就可以使用-o选项生成模型。
silas learn -o tutorial2/model tutorial2/settings.json
训练后的模型存储在 tutorial/model.
XAI: 模型解释¶
下载以下Python代码 OptExplain 并将代码放置在bin文件夹。
这个python程序需要一个包含Silas预测的文件。在这个例子中,由于只有一个测试集,我们用测试集生成一个预测文件。
silas predict -o tutorial2/pred.csv tutorial2/model tutorial2/data/diabetes_test.csv
然后,可以进入OptExplain文件夹。在使用OptExplain算法之前,需要安装所需的依赖项。:
pip install -r requirements.txt
使用以下命令运行OptExplain算法:
python3 OptExplain.py -m ../tutorial2/model -t ../tutorial2/data/diabetes_test.csv -p ../tutorial2/pred.csv
它可能需要一段计算时间,最终应该看到类似以下的输出:
---------------- Explanation -----------------
max_rule 1.000000 max_node 0.918296
max_rule 0.000000 max_node 0.001355
EX Running time: 0.09924626350402832 seconds
Original #rules: 15488
Original scale: 183526
#rules after rule-filter: 26
No MAX-SAT
SAT running time: 7.772445678710938e-05 seconds
Classes: ['tested_negative', 'tested_positive']
Group 0: | 17 samples | 2 rules | (3.0, 0.0)
9 samples (feature_1 <= 152.17149353027344)
8 samples (feature_6 <= 0.6463924646377563)
Group 1: | 16 samples | 2 rules | (0.0, 3.0)
9 samples (feature_1 > 116.90687561035156)
7 samples (feature_5 > 27.237857818603516)
conjuncts num: 4
---------------- Performance -----------------
ET Running time: 0.009005069732666016 seconds
Sample size: 231
RF accuracy: 0.8787878787878788
RF AUC: 0.9571354794284732
EX accuracy: 0.7532467532467533
EX AUC: 0.7406180065415734
Coverage: 1.0
Overlap: 0.7705627705627706
*Performance: 0.8658008658008658
可以看到,初始森林有超过15K条决策规则,这当然是无法解释的。OptExplain算法简化了森林,只得出4条决策规则,保留了0.75的准确性。解释的方式如下:给定一个样本,用4条规则中的每一条来测试它。例如,一个样本可能满足 “feature_1 <= 152.17149353027344”、”feature_6 <= 0.6463924646377563”和 “feature_5 > 27.237857818603516”。那么结果应该是(3.0, 0.0) * 9 + (3.0, 0.0) * 8 + (0.0, 3.0) * 7 = (51,21)。因此,预测的结果是tested_negative。通过这种方式,我们确定了在进行预测时最重要的决策和它们的权重。
XAI: 特征重要性¶
Silas可以使用predict命令的-e选项,为每个预测实例计算特征重要性。例如,可以用下面的例子来运行预测:
silas predict -o tutorial2/pred2.csv -e tutorial2/model tutorial2/data/diabetes_test.csv
打开pred2.csv,可以看到,除了预测结果外,每个实例还有一些额外的列。特别需要注意如下两列:w_feature给出了该特征的权重(特征重要性得分),r_feature给出了该特征在预测中的重要性范围。
XAI: 对抗样本¶
运行main.py,可以使用MUC计算对抗样本:
python3 main.py -m ../tutorial2/model -t ../tutorial2/data/diabetes_test.csv -A
计算可能需要一段时间,最终应该得到类似于以下的输出。:
========== Adversarial Sample ==========
WARNING: nominal features should be one-hot encoded.
Generating for x: [3, 199.0, 76.0, 43.0, 0.0, 42.9, 1.394, 22.0]
Original class: 1
Good tau found: [0.000 47.754 6.780 7.754 6.794 12.553 0.095 0.000]. (12276.207s)
Best theta found: [0.000 -42.348 -4.849 -4.504 -1.358 -12.423 0.081 0.000]. (4.498s)
Before opt: [3.000 156.652 71.151 38.496 -1.358 30.477 1.475 22.000]
Distance: 8.195414922619799
Optimized sample found. (2.253s)
Opt sample: [3.000 156.756 71.163 38.507 -1.355 30.508 1.475 22.000]
Distance: 8.17525936318561
Adv sample class: 0
程序会自动选择测试数据集中的第一个样本([3, 199.0, 76.0, 43.0, 0.0, 42.9, 1.394, 22.0]) 并生成一个对抗样本。可以修改测试数据集或Python程序,以生成基于其他样本。原始样本的类别是1,最佳的对抗样本([3.000 156.756 71.163 38.507 -1.355 30.508 1.475 22.000])的类别是0。原始样本和对抗样本的距离是8.17。