fn add_node_from_json()

in gbdt-rs/src/decision_tree.rs [1758:1842]


    fn add_node_from_json(&mut self, index: TreeIndex, node: &serde_json::Value) -> Result<()> {
        {
            let node_ref = self
                .tree
                .get_node_mut(index)
                .expect("node should not be empty!");
            // This is the leaf node
            if let serde_json::Value::Number(pred) = &node["leaf"] {
                let leaf_value = pred.as_f64().ok_or_else(|| "parse 'leaf' error")?;
                node_ref.value.pred = leaf_value as ValueType;
                node_ref.value.is_leaf = true;
                return Ok(());
            } else {
                // feature value
                let feature_value = node["split_condition"]
                    .as_f64()
                    .ok_or_else(|| "parse 'split condition' error")?;
                node_ref.value.feature_value = feature_value as ValueType;

                // feature index
                let feature_index = match node["split"].as_i64() {
                    Some(v) => v,
                    None => {
                        let feature_name = node["split"]
                            .as_str()
                            .ok_or_else(|| "parse 'split' error")?;
                        let feature_str: String = feature_name.chars().skip(3).collect();
                        feature_str.parse::<i64>()?
                    }
                };
                node_ref.value.feature_index = feature_index as usize;

                // handle unknown feature
                let missing = node["missing"]
                    .as_i64()
                    .ok_or_else(|| "parse 'missing' error")?;
                let left_child = node["yes"].as_i64().ok_or_else(|| "parse 'yes' error")?;
                let right_child = node["no"].as_i64().ok_or_else(|| "parse 'no' error")?;
                if missing == left_child {
                    node_ref.value.missing = -1;
                } else if missing == right_child {
                    node_ref.value.missing = 1;
                } else {
                    return Err(GbdtError::NotSupportExtraMissingNode);
                }
            }
        }

        // ids for children
        let left_child = node["yes"].as_i64().ok_or_else(|| "parse 'yes' error")?;
        let right_child = node["no"].as_i64().ok_or_else(|| "parse 'no' error")?;
        let children = node["children"]
            .as_array()
            .ok_or_else(|| "parse 'children' error")?;
        let mut find_left = false;
        let mut find_right = false;
        for child in children.iter() {
            let node_id = child["nodeid"]
                .as_i64()
                .ok_or_else(|| "parse 'nodeid' error")?;

            // build left child
            if node_id == left_child {
                find_left = true;
                let left_index = self
                    .tree
                    .add_left_node(index, BinaryTreeNode::new(DTNode::new()));
                self.add_node_from_json(left_index, child)?;
            }

            // build right child
            if node_id == right_child {
                find_right = true;
                let right_index = self
                    .tree
                    .add_right_node(index, BinaryTreeNode::new(DTNode::new()));
                self.add_node_from_json(right_index, child)?;
            }
        }

        if (!find_left) || (!find_right) {
            return Err(GbdtError::ChildrenNotFound);
        }
        Ok(())
    }