FastPrepBootstrap Decision Tree Classifier

Bootstrap Decision Tree Classifier

Pinterest logoPinterest● HardFULLTIMEOA

Problem statement

Train an ensemble of decision trees using bootstrap samples. For each tree, draw training rows with replacement, train that tree on its own sampled rows, and use it to predict every query. Return the class with the most votes for each query. If several classes tie for the most votes, choose the smallest class label.

trainingData[i] is a training row and labels[i] is its class. The rows in queries have the same number of features. Return one class label per query, in the original query order.

Practice training rules

For this exercise, use the following deterministic sampler and full CART rules. These rules complete details that the report does not specify.

Let n = trainingData.length. Start the random state at seed. For each tree, draw exactly n row indexes. Before each draw, update state = (state * 48271) % 2147483647, then draw row state % n. Keep the state from one tree to the next. Drawing rows is the only operation that advances it. Repeated indexes remain repeated training examples.

Train each tree as follows:

  1. At a node, count the classes in its sampled rows. If all rows have one class, make a leaf with that class.
  2. Consider every feature. Sort its distinct values at this node. Each midpoint between two consecutive distinct values is a candidate split. A row goes left when its feature value is at most the midpoint; otherwise it goes right. Every candidate has two nonempty children.
  3. For a nonempty set S, define G(S) = 1 - sum_c (count_c / |S|)^2. Choose the split minimizing (|L| * G(L) + |R| * G(R)) / |S|. Break a tie by the smallest feature index, then the smallest midpoint.
  4. If no candidate split exists, make a leaf with the most frequent class at this node, choosing the smallest label in a tie.
  5. Otherwise split and apply these rules recursively to both children. Grow the tree even when the best split does not reduce impurity. Do not prune the tree, limit its depth, or select a random subset of features.

A query follows the same at-most-midpoint rule at each internal node until it reaches a leaf. Each tree casts one vote for that leaf class. All feature indexes are zero-based. Since the feature values are integers, a midpoint between a and b can be compared exactly with 2 * value <= a + b.

Function

baggedTreePredictions(trainingData: int[][], labels: int[], queries: int[][], treeCount: int, seed: int) → int[]

Examples

Example 1

trainingData = [[0],[10]]labels = [1,4]queries = [[0],[5],[10]]treeCount = 3seed = 1return = [1,1,4]

With seed 1, the three bootstrap row-index lists are [1,0], [0,1] and [1,1]. The first two trees split at feature value 5: values at most 5 predict class 1, and larger values predict class 4. The third tree contains only class 4. Queries 0 and 5 receive votes [1,1,4], while query 10 receives [4,4,4]. The result is [1,1,4].

Example 2

trainingData = [[1],[1]]labels = [2,5]queries = [[-1000],[1],[1000]]treeCount = 2seed = 2return = [2,2,2]

With seed 2, the two bootstrap row-index lists are [0,0] and [1,1]. The first tree is a leaf predicting class 2; the second is a leaf predicting class 5. Every query therefore receives one vote for each class. The tie rule selects 2, giving [2,2,2].

Constraints

  • 1 <= trainingData.length <= 60
  • labels.length == trainingData.length
  • 1 <= queries.length <= 60
  • 1 <= trainingData[i].length <= 4
  • 1 <= queries[i].length <= 4
  • Every training row and every query row has exactly trainingData[0].length entries.
  • -1000 <= trainingData[i][j] <= 1000
  • -1000 <= queries[i][j] <= 1000
  • 0 <= labels[i] <= 5
  • 1 <= treeCount <= 9
  • 1 <= seed <= 2147483646

More Pinterest problems

See Pinterest hiring insights
Saved
public int[] baggedTreePredictions(int[][] trainingData, int[] labels, int[][] queries, int treeCount, int seed) {
    // Train the specified bootstrap ensemble and return query predictions.
}
Checking account…