【发布时间】:2019-10-26 07:59:19
【问题描述】:
为了我的理解,我正在尝试在 python 中从头开始实现决策树/决策规则。特别是我正在尝试实现 takelast 算法(与 takefirst 相反,它规定每个分支都按照它们在训练集中出现的顺序获取属性)。我正在使用lens24 数据集,它有24 个实例,属性分别是age、spect、astig、tear 和label,其中label 包含类标签。为了确定决策规则,我首先根据撕裂对实例进行分组,然后是 astig,然后是 spect,最后是 age。然后将返回的结果保存在列表列表中,其中每个单独的列表代表每个属性的值,用于形成特定的树分支。
newfile="lenses.data"
df = pd.read_table(newfile, delimiter=r"\s+", header=None)
df.columns =["id", "age", "spect", "astig", "tear", "label" ]
gf = df.groupby([ "tear", "astig", 'spect', 'age'], as_index=False)
for name,group in gf:
print(group)
rule = group.values.tolist()[0]
ruleset.append(rule)
print("ruleset")
print(ruleset)
这是规则集的输出
[[1, 1, 1, 1, 3], [2, 1, 1, 1, 3], [3, 1, 1, 1, 3], [1, 2, 1, 1, 3], [2, 2, 1, 1, 3], [3, 2, 1, 1, 3], [1, 1, 2, 1, 3], [2, 1, 2, 1, 3], [3, 1, 2, 1, 3], [1, 2, 2, 1, 3], [2, 2, 2, 1, 3], [3, 2, 2, 1, 3], [1, 1, 1, 2, 2], [2, 1, 1, 2, 2], [3, 1, 1, 2, 3], [1, 2, 1, 2, 2], [2, 2, 1, 2, 2], [3, 2, 1, 2, 2], [1, 1, 2, 2, 1], [2, 1, 2, 2, 1], [3, 1, 2, 2, 1], [1, 2, 2, 2, 1], [2, 2, 2, 2, 3], [3, 2, 2, 2, 3]]
现在下一步是修剪规则集,以便合并一些冗余分支。例如,[1,1,1,1,3] 和 [2,1,1,1,3] 只是年龄的值不同(其中列表表示 [age, spect, astig, tear, label])所以这两个规则可以合并,结果规则将是 (x, 1,1,1,3),其中 x 表示没有属性。我想递归地修剪规则集,以便在第一步中组合所有仅对年龄值不同的规则。在下一步中,那些仅在 spect 上不同的部分被组合起来,依此类推。第一步,我使用了以下代码:
for i in range(len(ruleset)-1):
if ruleset[i][1] == ruleset[i+1][1] and ruleset[i][2] == ruleset[i+1][2] and ruleset[i][3] == ruleset[i+1][3] and ruleset[i][4] == ruleset[i+1][4]:
print("combining: ", ruleset[i], " and ", ruleset[i+1])
ruleset[i][0] = ruleset[i+1][0]= -1
print("after pruning ruleset")
print(ruleset)
minruleset = []
for elem in ruleset:
if elem not in minruleset:
minruleset.append(elem)
print("ruleset: ", len(ruleset))
print("minruleset: ", len(minruleset))
print(minruleset)
print("------------------------")
ruleset = minruleset
包含 24 条规则的原始规则集现在最小化为 10 条规则,如下所示,其中 -1 表示年龄无关紧要,因此我们不再考虑。
[[-1, 1, 1, 1, 3], [-1, 2, 1, 1, 3], [-1, 1, 2, 1, 3], [-1, 2, 2, 1, 3], [-1, 1, 1, 2, 2], [3, 1, 1, 2, 3], [-1, 2, 1, 2, 2], [-1, 1, 2, 2, 1], [1, 2, 2, 2, 1], [-1, 2, 2, 2, 3]]
现在我想以递归方式执行此修剪步骤,即在第一次迭代中,我在比较中排除了年龄(索引 0),下一步我想排除年龄和 spect(索引 0、1),然后排除年龄、spect、astig(索引 0、1、2)等。在每次修剪迭代结束时,修剪的停止标准将是在修剪结束时形成的缩减规则集与在特定修剪迭代开始时形成的规则集的长度。 我无法做的是在 if 语句中指定索引范围(0-4),在该语句中,将每个实例与下一个实例的 age、spect、astig、tear 和 label 的值进行比较,然后重复此操作递归处理。任何帮助将不胜感激。
【问题讨论】: