001/* 002 * Copyright (c) 2015-2020, Oracle and/or its affiliates. All rights reserved. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.tribuo.classification.dtree; 018 019import com.oracle.labs.mlrg.olcut.config.Config; 020import org.tribuo.Dataset; 021import org.tribuo.Trainer; 022import org.tribuo.classification.Label; 023import org.tribuo.classification.dtree.impl.ClassifierTrainingNode; 024import org.tribuo.classification.dtree.impurity.GiniIndex; 025import org.tribuo.classification.dtree.impurity.LabelImpurity; 026import org.tribuo.common.tree.AbstractCARTTrainer; 027import org.tribuo.common.tree.AbstractTrainingNode; 028import org.tribuo.provenance.TrainerProvenance; 029import org.tribuo.provenance.impl.TrainerProvenanceImpl; 030 031/** 032 * A {@link org.tribuo.Trainer} that uses an approximation of the CART algorithm to build a decision tree. 033 * <p> 034 * See: 035 * <pre> 036 * J. Friedman, T. Hastie, & R. Tibshirani. 037 * "The Elements of Statistical Learning" 038 * Springer 2001. <a href="http://web.stanford.edu/~hastie/ElemStatLearn/">PDF</a> 039 * </pre> 040 */ 041public class CARTClassificationTrainer extends AbstractCARTTrainer<Label> { 042 043 /** 044 * Impurity measure used to determine split quality. 045 */ 046 @Config(description = "The impurity measure used to determine split quality.") 047 private LabelImpurity impurity = new GiniIndex(); 048 049 /** 050 * Creates a CART Trainer. 051 * 052 * @param maxDepth The maximum depth of the tree. 053 * @param minChildWeight The minimum node weight to consider it for a split. 054 * @param minImpurityDecrease The minimum decrease in impurity necessary to split a node. 055 * @param fractionFeaturesInSplit The fraction of features available in each split. 056 * @param useRandomSplitPoints Whether to choose split points for features at random. 057 * @param impurity Impurity measure to determine split quality. See {@link LabelImpurity}. 058 * @param seed The RNG seed. 059 */ 060 public CARTClassificationTrainer( 061 int maxDepth, 062 float minChildWeight, 063 float minImpurityDecrease, 064 float fractionFeaturesInSplit, 065 boolean useRandomSplitPoints, 066 LabelImpurity impurity, 067 long seed 068 ) { 069 super(maxDepth, minChildWeight, minImpurityDecrease, fractionFeaturesInSplit, useRandomSplitPoints, seed); 070 this.impurity = impurity; 071 postConfig(); 072 } 073 074 /** 075 * Creates a CART Trainer. 076 * <p> 077 * Sets the impurity to the {@link GiniIndex}, uses all the features, 078 * builds an arbitrary depth tree, computes the exact split point 079 * and sets the minimum number of examples in a leaf to {@link #MIN_EXAMPLES}. 080 */ 081 public CARTClassificationTrainer() { 082 this(Integer.MAX_VALUE); 083 } 084 085 /** 086 * Creates a CART trainer. 087 * <p> 088 * Sets the impurity to the {@link GiniIndex}, uses all the features, 089 * computes the exact split point and sets the minimum number of 090 * examples in a leaf to {@link #MIN_EXAMPLES}. 091 * @param maxDepth The maximum depth of the tree. 092 */ 093 public CARTClassificationTrainer(int maxDepth) { 094 this(maxDepth, MIN_EXAMPLES, 0.0f, 1.0f, false, new GiniIndex(), Trainer.DEFAULT_SEED); 095 } 096 097 /** 098 * Creates a CART Trainer. 099 * <p> 100 * Sets the impurity to the {@link GiniIndex}. 101 * @param maxDepth The maximum depth of the tree. 102 * @param fractionFeaturesInSplit The fraction of features available in each split. 103 * @param seed The seed for the RNG. 104 */ 105 public CARTClassificationTrainer(int maxDepth, float fractionFeaturesInSplit, long seed) { 106 this(maxDepth, MIN_EXAMPLES, 0.0f, fractionFeaturesInSplit, false, new GiniIndex(), seed); 107 } 108 109 /** 110 * Creates a CART Trainer. 111 * <p> 112 * Sets the impurity to the {@link GiniIndex}. Computes the exact split point. 113 * @param maxDepth The maximum depth of the tree. 114 * @param fractionFeaturesInSplit The fraction of features available in each split. 115 * @param useRandomSplitPoints Whether to choose split points for features at random. 116 * @param seed The seed for the RNG. 117 */ 118 public CARTClassificationTrainer(int maxDepth, float fractionFeaturesInSplit, 119 boolean useRandomSplitPoints, long seed) { 120 this(maxDepth, MIN_EXAMPLES, 0.0f, fractionFeaturesInSplit, useRandomSplitPoints, new GiniIndex(), seed); 121 } 122 123 /** 124 * Creates a CART Trainer. 125 * <p> 126 * Computes the exact split point. 127 * @param maxDepth The maximum depth of the tree. 128 * @param minChildWeight The minimum node weight to consider it for a split. 129 * @param minImpurityDecrease The minimum decrease in impurity necessary to split a node. 130 * @param fractionFeaturesInSplit The fraction of features available in each split. 131 * @param impurity Impurity measure to determine split quality. See {@link LabelImpurity}. 132 * @param seed The RNG seed. 133 */ 134 public CARTClassificationTrainer( 135 int maxDepth, 136 float minChildWeight, 137 float minImpurityDecrease, 138 float fractionFeaturesInSplit, 139 LabelImpurity impurity, 140 long seed 141 ) { 142 this(maxDepth, minChildWeight, minImpurityDecrease, fractionFeaturesInSplit, false, impurity, seed); 143 } 144 145 @Override 146 protected AbstractTrainingNode<Label> mkTrainingNode(Dataset<Label> examples, 147 AbstractTrainingNode.LeafDeterminer leafDeterminer) { 148 return new ClassifierTrainingNode(impurity, examples, leafDeterminer); 149 } 150 151 @Override 152 public String toString() { 153 StringBuilder buffer = new StringBuilder(); 154 155 buffer.append("CARTClassificationTrainer(maxDepth="); 156 buffer.append(maxDepth); 157 buffer.append(",minChildWeight="); 158 buffer.append(minChildWeight); 159 buffer.append(",minImpurityDecrease="); 160 buffer.append(minImpurityDecrease); 161 buffer.append(",fractionFeaturesInSplit="); 162 buffer.append(fractionFeaturesInSplit); 163 buffer.append(",useRandomSplitPoints="); 164 buffer.append(useRandomSplitPoints); 165 buffer.append(",impurity="); 166 buffer.append(impurity.toString()); 167 buffer.append(",seed="); 168 buffer.append(seed); 169 buffer.append(")"); 170 171 return buffer.toString(); 172 } 173 174 @Override 175 public TrainerProvenance getProvenance() { 176 return new TrainerProvenanceImpl(this); 177 } 178}