高级教程

在本教程中,我们使用”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。