DataWhale-树模型与集成学习-Task02-Cart分类树代码实现-202110

    助教老师实现了Cart回归树,在老师代码的基础上,实现了Cart分类树,代码如下:

import numpy as np

def Gini(y):
    gn=1.0
    n=y.shape[0]
    for i in np.unique(y):
        gn=gn-(np.sum(y==i)/n)**2
    return gn

def argmax(y):
    l=sorted([(np.sum(y==i),i) for i in np.unique(y)],reverse=True)
    return l[0][1]

class Node:

    def __init__(self, depth, idx):
        self.depth = depth
        self.idx = idx

        self.left = None
        self.right = None
        self.feature = None
        self.pivot = None


class Tree:

    def __init__(self, max_depth):
        self.max_depth = max_depth

        self.X = None
        self.y = None
        self.feature_importances_ = None

    def _able_to_split(self, node):
        return (node.depth < self.max_depth) & (node.idx.sum() >= 2)

    def _get_inner_split_score(self, to_left, to_right):
        total_num = to_left.sum() + to_right.sum()
        left_val = to_left.sum() / total_num * Gini(self.y[to_left])
        right_val = to_right.sum() / total_num * Gini(self.y[to_right])
        return left_val + right_val

    def _inner_split(self, col, idx):
        data = self.X[:, col]
        best_val = np.infty
        for pivot in data[:-1]:
            to_left = (idx==1) & (data<=pivot)
            to_right = (idx==1) & (~to_left)
            if to_left.sum() == 0 or to_left.sum() == idx.sum():
                continue
            Hyx = self._get_inner_split_score(to_left, to_right)
            if best_val > Hyx:
                best_val, best_pivot = Hyx, pivot
                best_to_left, best_to_right = to_left, to_right
        return best_val, best_to_left, best_to_right, best_pivot

    def _get_conditional_entropy(self, idx):
        best_val = np.infty
        for col in range(self.X.shape[1]):
            Hyx, _idx_left, _idx_right, pivot = self._inner_split(col, idx)
            if best_val > Hyx:
                best_val, idx_left, idx_right = Hyx, _idx_left, _idx_right
                best_feature, best_pivot = col, pivot
        return best_val, idx_left, idx_right, best_feature, best_pivot

    def split(self, node):
        # 首先判断本节点是不是符合分裂的条件
        if not self._able_to_split(node):
            return None, None, None, None
        # 计算H(Y)
        entropy = Gini(self.y[node.idx==1])
        # 计算最小的H(Y|X)
        (
            conditional_entropy,
            idx_left,
            idx_right,
            feature,
            pivot
        ) = self._get_conditional_entropy(node.idx)
        # 计算信息增益G(Y, X)
        info_gain = entropy - conditional_entropy
        # 计算相对信息增益
        relative_gain = node.idx.sum() / self.X.shape[0] * info_gain
        # 更新特征重要性
        self.feature_importances_[feature] += relative_gain
        # 新建左右节点并更新深度
        node.left = Node(node.depth+1, idx_left)
        node.right = Node(node.depth+1, idx_right)
        self.depth = max(node.depth+1, self.depth)
        return idx_left, idx_right, feature, pivot

    def build_prepare(self):
        self.depth = 0
        self.feature_importances_ = np.zeros(self.X.shape[1])
        self.root = Node(depth=0, idx=np.ones(self.X.shape[0]) == 1)

    def build_node(self, cur_node):
        if cur_node is None:
            return 
        idx_left, idx_right, feature, pivot = self.split(cur_node)
        cur_node.feature, cur_node.pivot = feature, pivot
        self.build_node(cur_node.left)
        self.build_node(cur_node.right)

    def build(self):
        self.build_prepare()
        self.build_node(self.root)

    def _search_prediction(self, node, x):
        if node.left is None and node.right is None:
            return argmax(self.y[node.idx])
        if x[node.feature] <= node.pivot:
            node = node.left
        else:
            node = node.right
        return self._search_prediction(node, x)

    def predict(self, x):
        return self._search_prediction(self.root, x)


class DecisionTreeClassification:
    """
    max_depth控制最大深度,类功能与sklearn默认参数下的功能实现一致
    """

    def __init__(self, max_depth):
        self.tree = Tree(max_depth=max_depth)

    def fit(self, X, y):
        self.tree.X = X
        self.tree.y = y
        self.tree.build()
        self.feature_importances_ = (
            self.tree.feature_importances_ 
            / self.tree.feature_importances_.sum()
        )
        return self

    def predict(self, X):
        return np.array([self.tree.predict(x) for x in X])

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: # 下面是一段实现MAML-Transformer模型代码: import torch import torch.nn as nnclass MAMLTransformer(nn.Module): def __init__(self, input_size, output_size, hid_size): super(MAMLTransformer, self).__init__() self.input_size = input_size self.output_size = output_size self.hid_size = hid_size self.fc1 = nn.Linear(input_size, hid_size) self.fc2 = nn.Linear(hid_size, output_size) self.relu = nn.ReLU() self.softmax = nn.Softmax(dim=1) self.maml_transformer = nn.TransformerEncoder(nn.TransformerEncoderLayer(hid_size, 8, 8)) def forward(self, x): x = self.fc1(x) x = self.relu(x) x = self.maml_transformer(x) x = self.fc2(x) x = self.softmax(x) return x ### 回答2: MAML-Transformer(Model-Agnostic Meta-Learning with Transformer Model)是一种基于元学习的模型,可以用于训练深度学习模型在小样本任务上进行快速适应。 下面是一段伪代码实现MAML-Transformer模型的示例: ```python import torch import torch.nn as nn import torch.optim as optim # 定义MAML-Transformer模型 class MAMLTransformer(nn.Module): def __init__(self, input_dim, output_dim): super(MAMLTransformer, self).__init__() self.encoder = nn.TransformerEncoder(...) self.decoder = nn.Linear(...) def forward(self, x): encoded = self.encoder(x) decoded = self.decoder(encoded) return decoded # 定义元优化器 class MetaOptimizer: def __init__(self, model, lr=0.001): self.model = model self.lr = lr self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr) def meta_update(self, loss): self.optimizer.zero_grad() loss.backward() self.optimizer.step() def clone_model(self): return self.model.clone() # 定义元学习算法 def maml_train(dataset, num_tasks, num_epochs, num_inner_updates, lr_inner=0.01, lr_outer=0.001): model = MAMLTransformer(...) meta_optimizer = MetaOptimizer(model, lr_outer) for epoch in range(num_epochs): for task in range(num_tasks): task_data = dataset.get_task_data(task) # 进行内循环更新参数 inner_model = meta_optimizer.clone_model() task_optimizer = optim.SGD(inner_model.parameters(), lr=lr_inner) for _ in range(num_inner_updates): x, y = task_data.sample_batch() y_pred = inner_model(x) loss = nn.MSEloss(y_pred, y) task_optimizer.zero_grad() loss.backward() task_optimizer.step() # 计算用更新过的参数在训练集上的损失 train_loss = calculate_loss(inner_model, task_data.train_data) # 使用元优化器进行元更新 meta_optimizer.meta_update(train_loss) # 主程序入口 if __name__ == '__main__': dataset = MyDataset(...) maml_train(dataset, num_tasks=10, num_epochs=100, num_inner_updates=5, lr_inner=0.01, lr_outer=0.001) ``` 以上代码仅为伪代码示例,实际的MAML-Transformer模型需要根据具体的任务和数据进行适应和调整。需要根据具体情况定义模型结构、损失函数和数据集的读取、数据处理等操作。当然,还可以根据需要对代码进行优化和改进,以提高训练效率和性能。 ### 回答3: MAML (Model-Agnostic Meta-Learning) 是一种元学习算法,它可以通过少量的样本来快速适应新的任务。MAML-Transformer 是将 MAML 算法应用于 Transformer 模型的一种实现方式。下面是一段简化版的代码实现 MAML-Transformer 模型的示例: ```python import torch import torch.nn as nn import torch.optim as optim # 定义 MAML-Transformer 模型 class MAMLTransformer(nn.Module): def __init__(self): super(MAMLTransformer, self).__init__() self.transformer = nn.Transformer() def forward(self, x): out = self.transformer(x) return out # 初始化 MAML-Transformer 模型 model = MAMLTransformer() # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.001) # 定义元学习的步骤 def maml_train_step(x_support, y_support, x_query, y_query): # 在支持集上进行梯度更新 with torch.set_grad_enabled(True): support_logits = model(x_support) support_loss = criterion(support_logits, y_support) model.zero_grad() support_loss.backward() optimizer.step() # 在查询集上计算损失 with torch.set_grad_enabled(False): query_logits = model(x_query) query_loss = criterion(query_logits, y_query) return query_loss # 进行元学习的循环 for meta_iteration in range(num_meta_iterations): for task in tasks: # 为每个任务生成一个新的模型实例 task_model = MAMLTransformer() # 在任务上拆分支持集和查询集 x_support, y_support, x_query, y_query = task.split() # 在任务上进行多步梯度更新 for inner_iteration in range(num_inner_iterations): task_loss = maml_train_step(x_support, y_support, x_query, y_query) # 在任务上计算元梯度并进行元梯度更新 task_logits = task_model(x_query) task_loss = criterion(task_logits, y_query) task_model.zero_grad() task_loss.backward() optimizer.step() ``` 在上述示例代码中,我们首先定义了一个 MAML-Transformer 模型,该模型使用了 Transformer 的结构。我们还定义了损失函数和优化器,以及进行元学习的步骤。在每个元学习循环中,我们迭代处理每个任务,为每个任务生成一个新的模型实例,并在任务上拆分支持集和查询集。然后,我们在任务上进行多步梯度更新,并根据元梯度更新更新模型的参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值