我试图用python从头开始实现决策树/决策规则,以供理解。我特别尝试实现takelast算法(与takefirst相反,takefirst表示每个分支按照属性在训练集中出现的顺序获取属性)。我使用的lens24数据集有24个实例,属性分别是age、spect、astig、tear和label,其中label包含类标签。为了确定决策规则,我首先根据撕裂、astig、spect和年龄对实例进行了分组。然后将返回的结果保存在一个列表列表中,其中每个列表表示每个属性的值,以形成树的特定分支。你知道吗
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值,并递归地重复此过程。任何帮助都将不胜感激。你知道吗
我自己找到了答案。张贴在这里,以帮助任何人与类似的问题在未来。if语句需要更新如下
if语句将嵌套在while循环中,当满足停止条件时,while循环将中断。每次迭代后,col变量将递增,而features值是固定的,例如在我的例子中是5。你知道吗
相关问题 更多 >
编程相关推荐