《机器学习实战》决策树“IndexError: list index out of range”问题的解决

《机器学习实战》决策树这一章第三节“使用决策树预测隐形眼镜类型”在调用之前创建好的决策树生成函数时,会出现下面的错误:

IndexError: list index out of range

生成决策树的代码如下:

def createTree(dataSet, labels, featLabels):
    # 取分类标签
    classList = [example[-1] for example in dataSet]
    # 如果类别完全相同则停止继续划分
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    # 遍历完所有特征时返回出现次数最多的类标签
    if len(dataSet[0]) == 1:
        return majorityCnt(classList)
    # 选择最优特征
    bestFeat = chooseBestFeatureToSplit(dataSet)
    # 最优特征的标签
    bestFeatLabel = labels[bestFeat]
    featLabels.append(bestFeatLabel)
    # 根据最优特征的标签生成树
    myTree = {bestFeatLabel: {}}
    # 删除已经使用的特征标签
    del (labels[bestFeat])
    # 得到训练集中所有最优解特征的属性值
    featValues = [example[bestFeat] for example in dataSet]
    # 去掉重复的属性值
    uniqueVals = set(featValues)
    # 遍历特征,创建决策树
    for value in uniqueVals:
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), labels, featLabels)
    return myTree

调用代码如下:

fr = open('lenses.txt')
lenses = [inst.strip().split('\t') for inst in fr.readlines()]
lensesLabels = ['age', 'prescript', 'astigmatic', 'tearRate']
featLabels = []
lensesTree = trees.createTree(lenses, lensesLabels, featLabels)
print(lensesTree)

之所以会出现“IndexError”问题,是因为:
在for循环中,每调用一次createTree()函数本身,都会执行

del (labels[bestFeat])

假设for循环中的value有两个,则在对第二个value调用createTree()时,labels可能已经被删去很多了,此时再执行

bestFeatLabel = labels[bestFeat]

就会出现:

IndexError: list index out of range

解决方法是循环时每调用一次createTree()后都要把删去的label给插入。
修改后的代码如下:

def createTree(dataSet, labels, featLabels):
    # 取分类标签(是否放贷:yes or no)
    classList = [example[-1] for example in dataSet]
    # 如果类别完全相同则停止继续划分
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    # 遍历完所有特征时返回出现次数最多的类标签
    if len(dataSet[0]) == 1:
        return majorityCnt(classList)
    # 选择最优特征
    bestFeat = chooseBestFeatureToSplit(dataSet)
    # 最优特征的标签
    bestFeatLabel = labels[bestFeat]
    featLabels.append(bestFeatLabel)
    # 根据最优特征的标签生成树
    myTree = {bestFeatLabel: {}}
    # 删除已经使用的特征标签
    # 得到训练集中所有最优解特征的属性值
    featValues = [example[bestFeat] for example in dataSet]
    # 去掉重复的属性值
    uniqueVals = set(featValues)
    # 遍历特征,创建决策树
    for value in uniqueVals:
        del_bestFeat = bestFeat
        del_labels = labels[bestFeat]
        del (labels[bestFeat])
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), labels, featLabels)
        labels.insert(del_bestFeat, del_labels)
    return myTree

你可能感兴趣的:(错误处理)