核心思路:按题面规则现建一棵 CART 二叉分类树。每个节点选一个特征和一个取值做二元切分,左子树放该特征等于这个取值的样本,右子树放不等于的样本。只有加权基尼指数比当前节点严格更小的切分才接受,否则停止。叶子预测人数更多的类别,两种人数相同就预测编号较小的 0。
实现方法:特征按编号从 1 到 4 枚举,每个特征里出现过的取值按从小到大枚举,基尼用分数比较,只有分子分母交叉相乘后严格变小才更新。这样平局会自然留下更小的特征编号和更小的取值。样本数小于 2,或者节点里只剩一种标签,也直接变成叶子。预测时从根往下走,测试样本的特征值等于切分值就进左子树,否则进右子树。
特征个数是 4,一个节点里每个特征的不同取值不超过 4 种,都可以看成常数。每个节点只扫描自己的样本,而每个样本出现在从根到叶的一条链上,链长不超过 N,所以建树是 O(N2)。每个测试样本沿树向下,深度不超过 N,M 个样本是 O(NM)。节点数是 O(N),空间 O(N)。本题 N≤20,M≤10,足够。
CART(Classification and Regression Trees)分类树通过二元切分,递归地把样本划入不纯度更低的子集。分裂特征和切分点由基尼指数(Gini Index)算出,得到一棵二叉树;离散取值和连续取值都可以参与分裂。 本题用这棵 CART 分类树预测客户是否购房。根据训练集建出二叉决策树,每个节点按基尼指数选择特征和切分点,再对测试样本给出预测。
划分规则: 对每一个特征,把它所有可能的取值逐一当作切分点,当前节点的样本分成左子集和右子集:
每条记录包含 4 个特征和 1 个标签,输入时全部写成整数枚举。
数据集里若有 K 个类别,pk 表示第 k 类样本所占比例:
Gini(D)=1−k=1∑Kpk2加权基尼指数 特征 A 以取值 v 为切分点时,D 被分成 D1(A=v) 与 D2(A=v):
Gini(D,A,v)=∣D∣∣D1∣×Gini(D1)+∣D∣∣D2∣×Gini(D2)叶子节点输出该节点中人数最多的类别;若两个类别人数相同,输出编号较小的类别。
下面任一条件成立,节点即停止分裂:
第一行给出整数 N,表示训练集的客户人数(4≤N≤20)。 随后 N 行,每行 5 个整数,依次是 4 个特征和 1 个标签,整数之间以空格分隔。 第 N+2 行给出整数 M,表示待预测的样本人数(1≤M≤10)。 随后 M 行,每行 4 个整数,依次是 4 个特征,整数之间以空格分隔。
输出一行,共 M 个整数,依次为 M 个测试样本在所建 CART 树上的预测结果,整数之间以空格分隔。
输入:
8
0 0 0 0 0
1 1 0 1 0
2 2 0 0 0
3 1 0 1 0
0 1 1 0 1
1 2 1 1 1
2 0 1 0 1
3 2 1 1 1
4
2 1 0 1
0 2 1 0
3 0 0 0
1 1 1 1
输出:
0 1 0 1
解释:
根节点共 8 名客户,标签 0(否)与标签 1(是)各 4 人,所以 Gini(D)=1−(4/8)2−(4/8)2=0.5
选取加权基尼指数最小的切分。特征3(是否有房)取切分点 0 时,左子集 4 人标签全为 0,右子集 4 人标签全为 1,加权基尼指数为 0。取切分点 1 只是左右对调,加权基尼指数同样为 0。二者并列,按平局规则保留较小取值 0,左子集为「是否有房 = 0」。 其余切分的加权基尼指数都大于 0。例如特征2(婚姻状况)取切分点 1 时,左子集 3 人里有 2 个 0、1 个 1,右子集 5 人里有 2 个 0、3 个 1,加权基尼指数为 7/15;特征4(是否有工作)取 0 或 1 时,两侧都是 2 个 0 与 2 个 1,加权基尼指数为 1/2。
左右子集的标签都已相同,停止分裂。左叶子预测 0,右叶子预测 1。
四个测试样本的特征3依次为 0、1、0、1。等于切分点的进入左子树,不等于的进入右子树,预测为 0 1 0 1。
© CodeFun2000 · 使用条款
Scan the QR code below with WeChat to sign in
First-time scan will create your account automatically
请使用微信扫描下方二维码完成注册