创建提升树 创建算法依据“8.1.2 AdaBoost算法” 算法8.1 :param trainDataList:训练数据集 :param trainLabelList: 训练测试集 :param treeNum: 树的层数 :return: 提升树
(trainDataList, trainLabelList, treeNum = 50)
| 135 | return sigleBoostTree |
| 136 | |
| 137 | def createBosstingTree(trainDataList, trainLabelList, treeNum = 50): |
| 138 | ''' |
| 139 | 创建提升树 |
| 140 | 创建算法依据“8.1.2 AdaBoost算法” 算法8.1 |
| 141 | :param trainDataList:训练数据集 |
| 142 | :param trainLabelList: 训练测试集 |
| 143 | :param treeNum: 树的层数 |
| 144 | :return: 提升树 |
| 145 | ''' |
| 146 | #将数据和标签转化为数组形式 |
| 147 | trainDataArr = np.array(trainDataList) |
| 148 | trainLabelArr = np.array(trainLabelList) |
| 149 | #没增加一层数后,当前最终预测结果列表 |
| 150 | finallpredict = [0] * len(trainLabelArr) |
| 151 | #获得训练集数量以及特征个数 |
| 152 | m, n = np.shape(trainDataArr) |
| 153 | |
| 154 | #依据算法8.1步骤(1)初始化D为1/N |
| 155 | D = [1 / m] * m |
| 156 | #初始化提升树列表,每个位置为一层 |
| 157 | tree = [] |
| 158 | #循环创建提升树 |
| 159 | for i in range(treeNum): |
| 160 | #得到当前层的提升树 |
| 161 | curTree = createSigleBoostingTree(trainDataArr, trainLabelArr, D) |
| 162 | #根据式8.2计算当前层的alpha |
| 163 | alpha = 1/2 * np.log((1 - curTree['e']) / curTree['e']) |
| 164 | #获得当前层的预测结果,用于下一步更新D |
| 165 | Gx = curTree['Gx'] |
| 166 | #依据式8.4更新D |
| 167 | #考虑到该式每次只更新D中的一个w,要循环进行更新知道所有w更新结束会很复杂(其实 |
| 168 | #不是时间上的复杂,只是让人感觉每次单独更新一个很累),所以该式以向量相乘的形式, |
| 169 | #一个式子将所有w全部更新完。 |
| 170 | #该式需要线性代数基础,如果不太熟练建议补充相关知识,当然了,单独更新w也一点问题 |
| 171 | #没有 |
| 172 | #np.multiply(trainLabelArr, Gx):exp中的y*Gm(x),结果是一个行向量,内部为yi*Gm(xi) |
| 173 | #np.exp(-1 * alpha * np.multiply(trainLabelArr, Gx)):上面求出来的行向量内部全体 |
| 174 | #成员再乘以-αm,然后取对数,和书上式子一样,只不过书上式子内是一个数,这里是一个向量 |
| 175 | #D是一个行向量,取代了式中的wmi,然后D求和为Zm |
| 176 | #书中的式子最后得出来一个数w,所有数w组合形成新的D |
| 177 | #这里是直接得到一个向量,向量内元素是所有的w |
| 178 | #本质上结果是相同的 |
| 179 | D = np.multiply(D, np.exp(-1 * alpha * np.multiply(trainLabelArr, Gx))) / sum(D) |
| 180 | #在当前层参数中增加alpha参数,预测的时候需要用到 |
| 181 | curTree['alpha'] = alpha |
| 182 | #将当前层添加到提升树索引中。 |
| 183 | tree.append(curTree) |
| 184 | |
| 185 | #-----以下代码用来辅助,可以去掉--------------- |
| 186 | #根据8.6式将结果加上当前层乘以α,得到目前的最终输出预测 |
| 187 | finallpredict += alpha * Gx |
| 188 | #计算当前最终预测输出与实际标签之间的误差 |
| 189 | error = sum([1 for i in range(len(trainDataList)) if np.sign(finallpredict[i]) != trainLabelArr[i]]) |
| 190 | #计算当前最终误差率 |
| 191 | finallError = error / len(trainDataList) |
| 192 | #如果误差为0,提前退出即可,因为没有必要再计算算了 |
| 193 | if finallError == 0: return tree |
| 194 | #打印一些信息 |
no test coverage detected