I fed my decision tree regression system, implemented using from-scratch Python with NumPy, to several AI systems and asked the AI to analyze it for correctness. I was quite impressed that the AI found a few rare edge cases where my code could fail, and showed me how to check for those edge cases.
Additionally, the AI pointed out that even though my implementation was functionally correct, it used nested loops which gave complexity of O(N^2). This is fine for datasets of up to about 2,000 items, but past that, training would slow to a crawl.
I knew this, but I also knew that writing a performant version is extremely difficult. I decided to bite the bullet, and use AI to write a performant version of decision tree regression, using from-scratch Python and NumPy.
The effort was every bit as difficult as I expected, and took about 16 hours, even with AI’s tireless help.
For my demo, I used one of my standard datasets It looks like:
-0.1660, 0.4406, -0.9998, -0.3953, -0.7065, 0.4840 0.0776, -0.1616, 0.3704, -0.5911, 0.7562, 0.1568 -0.9452, 0.3409, -0.1654, 0.1174, -0.7192, 0.8054 . . .
The data is synthetic. The first five values on each line are the predictors. The last value on each line is the target to predict. There are 200 training items and 40 test items.
The key parts of the output of my revised demo are:
Setting max_depth = 3
Setting min_samples = 2
Setting min_leaf = 18
Using default n_split_cols = -1 (all)
Setting save_rows = True
Creating and training tree
Done
Tree:
ID 0 | sc 0 | sv -0.2102 | L 1 | R 2 | py 0.3493 | leaf F | rc 200
ID 1 | sc 4 | sv 0.1431 | L 3 | R 4 | py 0.5345 | leaf F | rc 75
ID 2 | sc 0 | sv 0.3915 | L 5 | R 6 | py 0.2382 | leaf F | rc 125
ID 3 | sc 0 | sv -0.6553 | L 7 | R 8 | py 0.6358 | leaf F | rc 41
ID 4 | sc -1 | sv 0.0000 | L -1 | R -1 | py 0.4123 | leaf T | rc 34
ID 5 | sc 4 | sv -0.2987 | L 11 | R 12 | py 0.3032 | leaf F | rc 64
ID 6 | sc 2 | sv 0.3777 | L 13 | R 14 | py 0.1701 | leaf F | rc 61
ID 7 | sc -1 | sv 0.0000 | L -1 | R -1 | py 0.6952 | leaf T | rc 23
ID 8 | sc -1 | sv 0.0000 | L -1 | R -1 | py 0.5598 | leaf T | rc 18
ID 11 | sc -1 | sv 0.0000 | L -1 | R -1 | py 0.4101 | leaf T | rc 18
ID 12 | sc -1 | sv 0.0000 | L -1 | R -1 | py 0.2613 | leaf T | rc 46
ID 13 | sc -1 | sv 0.0000 | L -1 | R -1 | py 0.1882 | leaf T | rc 39
ID 14 | sc -1 | sv 0.0000 | L -1 | R -1 | py 0.1381 | leaf T | rc 22
Rows associated with node [11]:
[ 0 7 14 24 69 87 88 119 121 123 133 136 138 141
162 186 191 195]
Accuracy train (within 0.10): 0.3750
Accuracy test (within 0.10): 0.4750
Each line of the tree shows node ID, split column, split value (aka threshold), left child idx, right child idx, predicted value for the node, a Boolean to tell if the node is a leaf node or not, and the row count associated with the node.
The diagram below shows how the prediction was arrived at.
The accuracy is low, which is expected. Decision trees are almost never used by themselves. Instead they are usually part of a collection — bagging tree regression, random forest regression, AdaBoost regression, gradient boost regression.
I added an explain() method that shows how a prediction is made:
x = [-0.1660 0.4406 -0.9998 -0.3953 -0.7065] Predicted y = 0.4101 IF column 0 > -0.2102 AND column 0 <= 0.3915 AND column 4 <= -0.2987 AND THEN node [11] predicted = 0.4101
The explain output has a trailing "AND" with no condition, but I was too lazy to strip it away.
As a sanity check, I ran the synthetic dataset to the scikit-learn DecisionTreeRegressor module and got the same results:
Using scikit with same tree parameters: Accuracy train (within 0.10): 0.3750 Accuracy test (within 0.10): 0.4750 MSE train: 0.0048 MSE test: 0.0054 x = [-0.1660 0.4406 -0.9998 -0.3953 -0.7065] Predicted y = 0.4101
Good fun.

I've always been fascinated by models of all kinds. I spent a good portion of my adult career looking at mathematical models. When I was a young man, I was fascinated by model trains. Here's a beautiful HOn30 narrow gauge coal mine.
Demo program. Long, very complex. Replace "lt" (less than), "gt", "lte", "gte" with Boolean operator symbols. (My blog editor chokes on symbols).
# decision_tree_regression_scratch.py
# explicit storage in a list (no pointers/references)
# create iteratively (no stack or recursion)
# performant version at expense of clarity
import numpy as np
class MyDecisionTreeRegressor: # avoid scikit name
def __init__(self, max_depth=3, min_samples=2,
min_leaf=1, n_split_cols=-1, save_rows=False,
seed=0):
self.max_depth = max_depth
self.min_samples = min_samples # to split
self.min_leaf = min_leaf # after split
self.n_split_cols = n_split_cols # -1 all cols
self.save_rows = save_rows
self.rnd = np.random.RandomState(seed)
self.tree = [] # list: no recursive, no ptrs
num_nodes = 2**(max_depth + 1) - 1
for i in range(num_nodes):
self.tree.append(None)
self.train_X = None
self.train_y = None
# ...............................................
class Node:
def __init__(self):
self.id = -1
self.col_idx = -1 # aka split col
self.thresh = 0.0 # aka split val
self.left = -1
self.right = -1
self.value = 0.0 # predicted y
self.is_leaf = False
self.rows = [] # associated rows in train
# ...............................................
def fit(self, train_X, train_y):
# aka train(), build_tree()
# self.train_X = np.array(train_X) # safety
# self.train_y = np.array(train_y)
self.train_X = train_X
self.train_y = train_y
max_id = 2**(self.max_depth+1) - 2 # md = 3, m_id = 14
max_start_id = 2**self.max_depth - 1 # md = 3, ms = 7
# prep root node
all_rows = []
for i in range(len(self.train_X)): # or use arange
all_rows.append(i)
grand_mean = self.tree_target_mean(all_rows)
root = self.Node()
root.id = 0
root.value = grand_mean
root.is_leaf = False
root.rows = all_rows
self.tree[0] = root
for i in range(len(self.tree)): # each node
curr_node = self.tree[i] # convenience
if curr_node is None: continue
# if node too deep to have children
# or not enough rows to split, leave children alone
if curr_node.id "gte" max_start_id or \
len(curr_node.rows) "lt" self.min_samples:
curr_node.is_leaf = True
continue
# try to split curr node
col_idx, split_val = self.best_split(curr_node.rows)
if col_idx == -1: # bad split
curr_node.is_leaf = True
curr_node.left = -1
curr_node.right = -1
continue
# got good split info
curr_node.col_idx = col_idx
curr_node.thresh = split_val
# make rows for the children
left_idxs = []
right_idxs = []
for k in range(len(curr_node.rows)):
r = curr_node.rows[k]
if self.train_X[r][col_idx] "lte" split_val:
left_idxs.append(r)
else:
right_idxs.append(r)
# make left child
left_id = curr_node.id * 2 + 1
if left_id "lte" max_id and len(left_idxs) "gte" \
self.min_leaf:
curr_node.left = left_id
left_node = self.Node()
left_node.id = left_id
left_node.rows = left_idxs
left_node.value = \
self.tree_target_mean(left_node.rows)
self.tree[left_id] = left_node
else:
curr_node.left = -1
# make right child
right_id = curr_node.id * 2 + 2
if right_id "lte" max_id and len(right_idxs) "gte" \
self.min_leaf:
curr_node.right = right_id
right_node = self.Node()
right_node.id = right_id
right_node.rows = right_idxs
right_node.value = \
self.tree_target_mean(right_node.rows)
self.tree[right_id] = right_node
else:
curr_node.right = -1
if curr_node.left == -1 and curr_node.right == -1:
curr_node.is_leaf = True
# zap away rows to save space if in ensemble
if self.save_rows == False:
for k in range(len(self.tree)):
if self.tree[k] is not None:
self.tree[k].rows = None
# ---------------------------------------------------------
def predict_one(self, x):
# x is a vector
curr_idx = 0
last_valid_value = 0.0
while curr_idx != -1 and curr_idx "lt" len(self.tree):
curr_node = self.tree[curr_idx]
if curr_node is None: break # safety check
last_valid_value = curr_node.value
if curr_node.is_leaf == True: break
if x[curr_node.col_idx] "lte" curr_node.thresh:
curr_idx = curr_node.left
else:
curr_idx = curr_node.right
return last_valid_value
# ---------------------------------------------------------
def predict(self, X):
# X is a matrix
n = len(X)
result = np.zeros(n)
for i in range(n):
result[i] = self.predict_one(X[i])
return result
# ---------------------------------------------------------
def explain(self, x):
# x is a vector
curr_idx = 0
last_valid_value = 0.0
s = "\nIF \n"
while curr_idx != -1 and curr_idx "lt" len(self.tree):
curr_node = self.tree[curr_idx]
if curr_node is None: break # safety check
last_valid_value = curr_node.value
if curr_node.is_leaf == True: break
s += "column " + str(curr_node.col_idx) + " "
if x[curr_node.col_idx] "lte" curr_node.thresh:
s += " "lte" " + ("%8.4f " % curr_node.thresh)
s += " AND \n"
curr_idx = curr_node.left
else:
s += " "gt" " + ("%8.4f " % curr_node.thresh)
s += " AND \n"
curr_idx = curr_node.right
# consider strip away trailing "AND" here . .
if curr_node is None: nid = -1
else: nid = curr_node.id
s += "THEN node [" + str(nid) + "] predicted = "
s += "%0.4f " % last_valid_value
print(s)
# ---------------------------------------------------------
def display(self):
for i in range(len(self.tree)):
n = self.tree[i]
if n is None: continue
s1 = "ID %3d " % n.id + " | "
s2 = "sc %3d " % n.col_idx + " | "
s3 = "sv %8.4f " % n.thresh + " | "
s4 = "L %3d " % n.left + " | "
s5 = "R %3d " % n.right + " | "
s6 = "py %8.4f " % n.value + " | "
if n.is_leaf == True: s7 = "leaf T" + " | "
else: s7 = "leaf F" + " | "
s8 = "rc %4d " % len(n.rows)
print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8)
# ---------------------------------------------------------
def best_split(self, rows):
best_col_idx = -1
best_thresh = 0.0
best_var = float('inf')
n_rows = len(rows)
if n_rows == 0:
raise Exception("Empty data in best_split()")
n_cols = len(self.train_X[0])
# 1. scramble all column indices (Fisher-Yates)
col_indices = np.arange(n_cols)
for i in range(n_cols - 1):
ri = self.rnd.randint(i, n_cols)
tmp = col_indices[i]
col_indices[i] = col_indices[ri]
col_indices[ri] = tmp
# compute safe number of columns to scan, slice out
if self.n_split_cols == -1:
n_cols_to_use = n_cols
else:
n_cols_to_use = min(self.n_split_cols, n_cols)
active_cols = col_indices[0:n_cols_to_use]
# use buffer arrays to avoid memory thrashing in loops
sorted_rows = np.zeros(n_rows, dtype=np.int32)
feature_keys = np.zeros(n_rows, dtype=np.float64)
# calculate sums upfront for entire node population
total_sum_y = 0.0
total_sum_sq_y = 0.0
for i in range(n_rows):
y_curr = self.train_y[rows[i]]
total_sum_y += y_curr
total_sum_sq_y += y_curr * y_curr
# 2. evaluate each selected column sequentially
for j in range(len(active_cols)):
col_idx = active_cols[j]
# extract the feature values for the active rows
for i in range(n_rows):
r = rows[i]
sorted_rows[i] = r
feature_keys[i] = self.train_X[r, col_idx]
# find the index sort order based on feature values
sort_order = np.argsort(feature_keys)
# apply sort order to buffer arrays
sorted_features = feature_keys[sort_order]
sorted_indices = sorted_rows[sort_order]
left_sum_y = 0.0
left_sum_sq_y = 0.0
# 3. loop over the sorted split boundaries
for i in range(n_rows - 1):
curr_row_idx = sorted_indices[i]
y_curr = self.train_y[curr_row_idx]
left_sum_y += y_curr
left_sum_sq_y += y_curr * y_curr
left_count = i + 1
right_count = n_rows - left_count
# enforce min_leaf boundaries
if left_count "lt" self.min_leaf or \
right_count "lt" self.min_leaf:
continue
current_feature_val = sorted_features[i]
next_feature_val = sorted_features[i+1]
# no partitioning identical column values
if current_feature_val == next_feature_val:
continue
right_sum_y = total_sum_y - left_sum_y
right_sum_sq_y = total_sum_sq_y - left_sum_sq_y
# fancy math shortcut variance calculation:
# var = E[X^2] - (E[X])^2
left_var = (left_sum_sq_y / left_count) - \
((left_sum_y / left_count) ** 2)
right_var = (right_sum_sq_y / right_count) - \
((right_sum_y / right_count) ** 2)
if left_var "lt" 0.0: left_var = 0.0
if right_var "lt" 0.0: right_var = 0.0
weighted_var = ((left_count * left_var) + \
(right_count * right_var)) / n_rows
if weighted_var "lt" best_var:
best_var = weighted_var
best_col_idx = col_idx
best_thresh = current_feature_val
return best_col_idx, best_thresh
# ---------------------------------------------------------
def tree_target_mean(self, rows):
if rows is None or len(rows) == 0: return 0.0
sum = 0.0
for i in range(len(rows)):
r = rows[i]
sum += self.train_y[r]
return sum / len(rows)
# ---------------------------------------------------------
# def tree_target_variance(self, rows):
# if rows is None or len(rows) == 0: return 0.0
# mean = self.tree_target_mean(rows)
# sum = 0.0
# for i in range(len(rows)):
# r = rows[i]
# sum += (self.train_y[r] - mean) * \
# (self.train_y[r] - mean)
# return sum / len(rows)
# ===========================================================
def accuracy(model, data_X, data_y, pct_close):
n = len(data_X)
n_correct = 0; n_wrong = 0
all_preds = model.predict(data_X)
for i in range(n):
y = data_y[i]
y_pred = all_preds[i]
if np.abs(y - y_pred) "lt" np.abs(y * pct_close):
n_correct += 1
else:
n_wrong += 1
return n_correct / (n_correct + n_wrong)
# -----------------------------------------------------------
def MSE(model, data_X, data_y):
n = len(data_X)
all_preds = model.predict(data_X)
sum = 0.0
for i in range(n):
y = data_y[i]
y_pred = all_preds[i]
sum += (y - y_pred) * (y - y_pred)
return sum / n
# -----------------------------------------------------------
def main():
print("\nBegin decision tree regression scratch Python ")
np.set_printoptions(precision=4, suppress=True,
floatmode='fixed')
np.random.seed(0) # not used this version
# 1. load data
print("\nLoading synthetic train (200), test (40) data ")
train_file = ".\\Data\\synthetic_train_200.txt"
# -0.1660, 0.4406, -0.9998, -0.3953, -0.7065, 0.4840
# 0.0776, -0.1616, 0.3704, -0.5911, 0.7562, 0.1568
# -0.9452, 0.3409, -0.1654, 0.1174, -0.7192, 0.8054
# . . .
train_X = np.loadtxt(train_file, comments="#",
usecols=[0,1,2,3,4],
delimiter=",", dtype=np.float64)
train_y = np.loadtxt(train_file, comments="#", usecols=5,
delimiter=",", dtype=np.float64)
test_file = ".\\Data\\synthetic_test_40.txt"
test_X = np.loadtxt(test_file, comments="#",
usecols=[0,1,2,3,4],
delimiter=",", dtype=np.float64)
test_y = np.loadtxt(test_file, comments="#", usecols=5,
delimiter=",", dtype=np.float64)
print("Done ")
print("\nFirst three X predictors: ")
print(train_X[0:3,:])
print("\nFirst three y targets: ")
for i in range(3):
print("%0.4f" % train_y[i])
max_depth = 3 # max_depth
min_samples = 2 # min_samples to consider a split
min_leaf = 18 # min rows after split
n_split_cols = -1 # means use all cols
save_rows = True
seed = 0
print("\nSetting max_depth = %1d " % max_depth)
print("Setting min_samples = %1d " % min_samples)
print("Setting min_leaf = %1d " % min_leaf)
print("Using default n_split_cols = -1 (all) ")
print("Setting save_rows = " + str(save_rows))
print("\nCreating and training tree ")
tree = MyDecisionTreeRegressor(max_depth=max_depth,
min_samples=min_samples, min_leaf=min_leaf,
n_split_cols=n_split_cols, save_rows=save_rows,
seed=seed)
tree.fit(train_X, train_y)
print("Done ")
print("\nTree: ")
tree.display()
# assume node [11] exists
print("\nRows associated with node [11]: ")
np.set_printoptions(linewidth=60)
rows = np.array(tree.tree[11].rows, dtype=np.int64)
print(rows)
acc_train = accuracy(tree, train_X, train_y, 0.10)
print("\nAccuracy train (within 0.10): %0.4f " % acc_train)
acc_test = accuracy(tree, test_X, test_y, 0.10)
print("Accuracy test (within 0.10): %0.4f " % acc_test)
mse_train = MSE(tree, train_X, train_y)
print("\nMSE train: %0.4f " % mse_train)
mse_test = MSE(tree, test_X, test_y)
print("MSE test: %0.4f " % mse_test)
x = train_X[0]
print("\nx = ", end=""); print(x)
y_pred = tree.predict(x.reshape(1,-1))[0]
print("Predicted y = %0.4f " % y_pred)
tree.explain(x)
print("\nEnd demo ")
print("\n==================== ")
print("\nUsing scikit with same tree parameters: ")
from sklearn.tree import DecisionTreeRegressor
dtr = DecisionTreeRegressor(max_depth=max_depth,
min_samples_split=min_samples, min_samples_leaf=min_leaf,
random_state=seed)
dtr.fit(train_X, train_y)
acc_train = accuracy(dtr, train_X, train_y, 0.10)
print("\nAccuracy train (within 0.10): %0.4f " % acc_train)
acc_test = accuracy(dtr, test_X, test_y, 0.10)
print("Accuracy test (within 0.10): %0.4f " % acc_test)
mse_train = MSE(dtr, train_X, train_y)
print("\nMSE train: %0.4f " % mse_train)
mse_test = MSE(dtr, test_X, test_y)
print("MSE test: %0.4f " % mse_test)
x = train_X[0]
print("\nx = ", end=""); print(x)
y_pred = dtr.predict(x.reshape(1,-1))[0]
print("Predicted y = %0.4f " % y_pred)
if __name__ == "__main__":
main()
Training data:
# synthetic_train_200.txt # -0.1660, 0.4406, -0.9998, -0.3953, -0.7065, 0.4840 0.0776, -0.1616, 0.3704, -0.5911, 0.7562, 0.1568 -0.9452, 0.3409, -0.1654, 0.1174, -0.7192, 0.8054 0.9365, -0.3732, 0.3846, 0.7528, 0.7892, 0.1345 -0.8299, -0.9219, -0.6603, 0.7563, -0.8033, 0.7955 0.0663, 0.3838, -0.3690, 0.3730, 0.6693, 0.3206 -0.9634, 0.5003, 0.9777, 0.4963, -0.4391, 0.7377 -0.1042, 0.8172, -0.4128, -0.4244, -0.7399, 0.4801 -0.9613, 0.3577, -0.5767, -0.4689, -0.0169, 0.6861 -0.7065, 0.1786, 0.3995, -0.7953, -0.1719, 0.5569 0.3888, -0.1716, -0.9001, 0.0718, 0.3276, 0.2500 0.1731, 0.8068, -0.7251, -0.7214, 0.6148, 0.3297 -0.2046, -0.6693, 0.8550, -0.3045, 0.5016, 0.2129 0.2473, 0.5019, -0.3022, -0.4601, 0.7918, 0.2613 -0.1438, 0.9297, 0.3269, 0.2434, -0.7705, 0.5171 0.1568, -0.1837, -0.5259, 0.8068, 0.1474, 0.3307 -0.9943, 0.2343, -0.3467, 0.0541, 0.7719, 0.5581 0.2467, -0.9684, 0.8589, 0.3818, 0.9946, 0.1092 -0.6553, -0.7257, 0.8652, 0.3936, -0.8680, 0.7018 0.8460, 0.4230, -0.7515, -0.9602, -0.9476, 0.1996 -0.9434, -0.5076, 0.7201, 0.0777, 0.1056, 0.5664 0.9392, 0.1221, -0.9627, 0.6013, -0.5341, 0.1533 0.6142, -0.2243, 0.7271, 0.4942, 0.1125, 0.1661 0.4260, 0.1194, -0.9749, -0.8561, 0.9346, 0.2230 0.1362, -0.5934, -0.4953, 0.4877, -0.6091, 0.3810 0.6937, -0.5203, -0.0125, 0.2399, 0.6580, 0.1460 -0.6864, -0.9628, -0.8600, -0.0273, 0.2127, 0.5387 0.9772, 0.1595, -0.2397, 0.1019, 0.4907, 0.1611 0.3385, -0.4702, -0.8673, -0.2598, 0.2594, 0.2270 -0.8669, -0.4794, 0.6095, -0.6131, 0.2789, 0.4700 0.0493, 0.8496, -0.4734, -0.8681, 0.4701, 0.3516 0.8639, -0.9721, -0.5313, 0.2336, 0.8980, 0.1412 0.9004, 0.1133, 0.8312, 0.2831, -0.2200, 0.1782 0.0991, 0.8524, 0.8375, -0.2102, 0.9265, 0.2150 -0.6521, -0.7473, -0.7298, 0.0113, -0.9570, 0.7422 0.6190, -0.3105, 0.8802, 0.1640, 0.7577, 0.1056 0.6895, 0.8108, -0.0802, 0.0927, 0.5972, 0.2214 0.1982, -0.9689, 0.1870, -0.1326, 0.6147, 0.1310 -0.3695, 0.7858, 0.1557, -0.6320, 0.5759, 0.3773 -0.1596, 0.3581, 0.8372, -0.9992, 0.9535, 0.2071 -0.2468, 0.9476, 0.2094, 0.6577, 0.1494, 0.4132 0.1737, 0.5000, 0.7166, 0.5102, 0.3961, 0.2611 0.7290, -0.3546, 0.3416, -0.0983, -0.2358, 0.1332 -0.3652, 0.2438, -0.1395, 0.9476, 0.3556, 0.4170 -0.6029, -0.1466, -0.3133, 0.5953, 0.7600, 0.4334 -0.4596, -0.4953, 0.7098, 0.0554, 0.6043, 0.2775 0.1450, 0.4663, 0.0380, 0.5418, 0.1377, 0.2931 -0.8636, -0.2442, -0.8407, 0.9656, -0.6368, 0.7429 0.6237, 0.7499, 0.3768, 0.1390, -0.6781, 0.2185 -0.5499, 0.1850, -0.3755, 0.8326, 0.8193, 0.4399 -0.4858, -0.7782, -0.6141, -0.0008, 0.4572, 0.4197 0.7033, -0.1683, 0.2334, -0.5327, -0.7961, 0.1776 0.0317, -0.0457, -0.6947, 0.2436, 0.0880, 0.3345 0.5031, -0.5559, 0.0387, 0.5706, -0.9553, 0.3107 -0.3513, 0.7458, 0.6894, 0.0769, 0.7332, 0.3170 0.2205, 0.5992, -0.9309, 0.5405, 0.4635, 0.3532 -0.4806, -0.4859, 0.2646, -0.3094, 0.5932, 0.3202 0.9809, -0.3995, -0.7140, 0.8026, 0.0831, 0.1600 0.9495, 0.2732, 0.9878, 0.0921, 0.0529, 0.1289 -0.9476, -0.6792, 0.4913, -0.9392, -0.2669, 0.5966 0.7247, 0.3854, 0.3819, -0.6227, -0.1162, 0.1550 -0.5922, -0.5045, -0.4757, 0.5003, -0.0860, 0.5863 -0.8861, 0.0170, -0.5761, 0.5972, -0.4053, 0.7301 0.6877, -0.2380, 0.4997, 0.0223, 0.0819, 0.1404 0.9189, 0.6079, -0.9354, 0.4188, -0.0700, 0.1907 -0.1428, -0.7820, 0.2676, 0.6059, 0.3936, 0.2790 0.5324, -0.3151, 0.6917, -0.1425, 0.6480, 0.1071 -0.8432, -0.9633, -0.8666, -0.0828, -0.7733, 0.7784 -0.9444, 0.5097, -0.2103, 0.4939, -0.0952, 0.6787 -0.0520, 0.6063, -0.1952, 0.8094, -0.9259, 0.4836 0.5477, -0.7487, 0.2370, -0.9793, 0.0773, 0.1241 0.2450, 0.8116, 0.9799, 0.4222, 0.4636, 0.2355 0.8186, -0.1983, -0.5003, -0.6531, -0.7611, 0.1511 -0.4714, 0.6382, -0.3788, 0.9648, -0.4667, 0.5950 0.0673, -0.3711, 0.8215, -0.2669, -0.1328, 0.2677 -0.9381, 0.4338, 0.7820, -0.9454, 0.0441, 0.5518 -0.3480, 0.7190, 0.1170, 0.3805, -0.0943, 0.4724 -0.9813, 0.1535, -0.3771, 0.0345, 0.8328, 0.5438 -0.1471, -0.5052, -0.2574, 0.8637, 0.8737, 0.3042 -0.5454, -0.3712, -0.6505, 0.2142, -0.1728, 0.5783 0.6327, -0.6297, 0.4038, -0.5193, 0.1484, 0.1153 -0.5424, 0.3282, -0.0055, 0.0380, -0.6506, 0.6613 0.1414, 0.9935, 0.6337, 0.1887, 0.9520, 0.2540 -0.9351, -0.8128, -0.8693, -0.0965, -0.2491, 0.7353 0.9507, -0.6640, 0.9456, 0.5349, 0.6485, 0.1059 -0.0462, -0.9737, -0.2940, -0.0159, 0.4602, 0.2606 -0.0627, -0.0852, -0.7247, -0.9782, 0.5166, 0.2977 0.0478, 0.5098, -0.0723, -0.7504, -0.3750, 0.3335 0.0090, 0.3477, 0.5403, -0.7393, -0.9542, 0.4415 -0.9748, 0.3449, 0.3736, -0.1015, 0.8296, 0.4358 0.2887, -0.9895, -0.0311, 0.7186, 0.6608, 0.2057 0.1570, -0.4518, 0.1211, 0.3435, -0.2951, 0.3244 0.7117, -0.6099, 0.4946, -0.4208, 0.5476, 0.1096 -0.2929, -0.5726, 0.5346, -0.3827, 0.4665, 0.2465 0.4889, -0.5572, -0.5718, -0.6021, -0.7150, 0.2163 -0.7782, 0.3491, 0.5996, -0.8389, -0.5366, 0.6516 -0.5847, 0.8347, 0.4226, 0.1078, -0.3910, 0.6134 0.8469, 0.4121, -0.0439, -0.7476, 0.9521, 0.1571 -0.6803, -0.5948, -0.1376, -0.1916, -0.7065, 0.7156 0.2878, 0.5086, -0.5785, 0.2019, 0.4979, 0.2980 0.2764, 0.1943, -0.4090, 0.4632, 0.8906, 0.2960 -0.8877, 0.6705, -0.6155, -0.2098, -0.3998, 0.7107 -0.8398, 0.8093, -0.2597, 0.0614, -0.0118, 0.6502 -0.8476, 0.0158, -0.4769, -0.2859, -0.7839, 0.7715 0.5751, -0.7868, 0.9714, -0.6457, 0.1448, 0.1175 0.4802, -0.7001, 0.1022, -0.5668, 0.5184, 0.1090 0.4458, -0.6469, 0.7239, -0.9604, 0.7205, 0.0779 0.5175, 0.4339, 0.9747, -0.4438, -0.9924, 0.2879 0.8678, 0.7158, 0.4577, 0.0334, 0.4139, 0.1678 0.5406, 0.5012, 0.2264, -0.1963, 0.3946, 0.2088 -0.9938, 0.5498, 0.7928, -0.5214, -0.7585, 0.7687 0.7661, 0.0863, -0.4266, -0.7233, -0.4197, 0.1466 0.2277, -0.3517, -0.0853, -0.1118, 0.6563, 0.1767 0.3499, -0.5570, -0.0655, -0.3705, 0.2537, 0.1632 0.7547, -0.1046, 0.5689, -0.0861, 0.3125, 0.1257 0.8186, 0.2110, 0.5335, 0.0094, -0.0039, 0.1391 0.6858, -0.8644, 0.1465, 0.8855, 0.0357, 0.1845 -0.4967, 0.4015, 0.0805, 0.8977, 0.2487, 0.4663 0.6760, -0.9841, 0.9787, -0.8446, -0.3557, 0.1509 -0.1203, -0.4885, 0.6054, -0.0443, -0.7313, 0.4854 0.8557, 0.7919, -0.0169, 0.7134, -0.1628, 0.2002 0.0115, -0.6209, 0.9300, -0.4116, -0.7931, 0.4052 -0.7114, -0.9718, 0.4319, 0.1290, 0.5892, 0.3661 0.3915, 0.5557, -0.1870, 0.2955, -0.6404, 0.2954 -0.3564, -0.6548, -0.1827, -0.5172, -0.1862, 0.4622 0.2392, -0.4959, 0.5857, -0.1341, -0.2850, 0.2470 -0.3394, 0.3947, -0.4627, 0.6166, -0.4094, 0.5325 0.7107, 0.7768, -0.6312, 0.1707, 0.7964, 0.2757 -0.1078, 0.8437, -0.4420, 0.2177, 0.3649, 0.4028 -0.3139, 0.5595, -0.6505, -0.3161, -0.7108, 0.5546 0.4335, 0.3986, 0.3770, -0.4932, 0.3847, 0.1810 -0.2562, -0.2894, -0.8847, 0.2633, 0.4146, 0.4036 0.2272, 0.2966, -0.6601, -0.7011, 0.0284, 0.2778 -0.0743, -0.1421, -0.0054, -0.6770, -0.3151, 0.3597 -0.4762, 0.6891, 0.6007, -0.1467, 0.2140, 0.4266 -0.4061, 0.7193, 0.3432, 0.2669, -0.7505, 0.6147 -0.0588, 0.9731, 0.8966, 0.2902, -0.6966, 0.4955 -0.0627, -0.1439, 0.1985, 0.6999, 0.5022, 0.3077 0.1587, 0.8494, -0.8705, 0.9827, -0.8940, 0.4263 -0.7850, 0.2473, -0.9040, -0.4308, -0.8779, 0.7199 0.4070, 0.3369, -0.2428, -0.6236, 0.4940, 0.2215 -0.0242, 0.0513, -0.9430, 0.2885, -0.2987, 0.3947 -0.5416, -0.1322, -0.2351, -0.0604, 0.9590, 0.3683 0.1055, 0.7783, -0.2901, -0.5090, 0.8220, 0.2984 -0.9129, 0.9015, 0.1128, -0.2473, 0.9901, 0.4776 -0.9378, 0.1424, -0.6391, 0.2619, 0.9618, 0.5368 0.7498, -0.0963, 0.4169, 0.5549, -0.0103, 0.1614 -0.2612, -0.7156, 0.4538, -0.0460, -0.1022, 0.3717 0.7720, 0.0552, -0.1818, -0.4622, -0.8560, 0.1685 -0.4177, 0.0070, 0.9319, -0.7812, 0.3461, 0.3052 -0.0001, 0.5542, -0.7128, -0.8336, -0.2016, 0.3803 0.5356, -0.4194, -0.5662, -0.9666, -0.2027, 0.1776 -0.2378, 0.3187, -0.8582, -0.6948, -0.9668, 0.5474 -0.1947, -0.3579, 0.1158, 0.9869, 0.6690, 0.2992 0.3992, 0.8365, -0.9205, -0.8593, -0.0520, 0.3154 -0.0209, 0.0793, 0.7905, -0.1067, 0.7541, 0.1864 -0.4928, -0.4524, -0.3433, 0.0951, -0.5597, 0.6261 -0.8118, 0.7404, -0.5263, -0.2280, 0.1431, 0.6349 0.0516, -0.8480, 0.7483, 0.9023, 0.6250, 0.1959 -0.3212, 0.1093, 0.9488, -0.3766, 0.3376, 0.2735 -0.3481, 0.5490, -0.3484, 0.7797, 0.5034, 0.4379 -0.5785, -0.9170, -0.3563, -0.9258, 0.3877, 0.4121 0.3407, -0.1391, 0.5356, 0.0720, -0.9203, 0.3458 -0.3287, -0.8954, 0.2102, 0.0241, 0.2349, 0.3247 -0.1353, 0.6954, -0.0919, -0.9692, 0.7461, 0.3338 0.9036, -0.8982, -0.5299, -0.8733, -0.1567, 0.1187 0.7277, -0.8368, -0.0538, -0.7489, 0.5458, 0.0830 0.9049, 0.8878, 0.2279, 0.9470, -0.3103, 0.2194 0.7957, -0.1308, -0.5284, 0.8817, 0.3684, 0.2172 0.4647, -0.4931, 0.2010, 0.6292, -0.8918, 0.3371 -0.7390, 0.6849, 0.2367, 0.0626, -0.5034, 0.7039 -0.1567, -0.8711, 0.7940, -0.5932, 0.6525, 0.1710 0.7635, -0.0265, 0.1969, 0.0545, 0.2496, 0.1445 0.7675, 0.1354, -0.7698, -0.5460, 0.1920, 0.1728 -0.5211, -0.7372, -0.6763, 0.6897, 0.2044, 0.5217 0.1913, 0.1980, 0.2314, -0.8816, 0.5006, 0.1998 0.8964, 0.0694, -0.6149, 0.5059, -0.9854, 0.1825 0.1767, 0.7104, 0.2093, 0.6452, 0.7590, 0.2832 -0.3580, -0.7541, 0.4426, -0.1193, -0.7465, 0.5657 -0.5996, 0.5766, -0.9758, -0.3933, -0.9572, 0.6800 0.9950, 0.1641, -0.4132, 0.8579, 0.0142, 0.2003 -0.4717, -0.3894, -0.2567, -0.5111, 0.1691, 0.4266 0.3917, -0.8561, 0.9422, 0.5061, 0.6123, 0.1212 -0.0366, -0.1087, 0.3449, -0.1025, 0.4086, 0.2475 0.3633, 0.3943, 0.2372, -0.6980, 0.5216, 0.1925 -0.5325, -0.6466, -0.2178, -0.3589, 0.6310, 0.3568 0.2271, 0.5200, -0.1447, -0.8011, -0.7699, 0.3128 0.6415, 0.1993, 0.3777, -0.0178, -0.8237, 0.2181 -0.5298, -0.0768, -0.6028, -0.9490, 0.4588, 0.4356 0.6870, -0.1431, 0.7294, 0.3141, 0.1621, 0.1632 -0.5985, 0.0591, 0.7889, -0.3900, 0.7419, 0.2945 0.3661, 0.7984, -0.8486, 0.7572, -0.6183, 0.3449 0.6995, 0.3342, -0.3113, -0.6972, 0.2707, 0.1712 0.2565, 0.9126, 0.1798, -0.6043, -0.1413, 0.2893 -0.3265, 0.9839, -0.2395, 0.9854, 0.0376, 0.4770 0.2690, -0.1722, 0.9818, 0.8599, -0.7015, 0.3954 -0.2102, -0.0768, 0.1219, 0.5607, -0.0256, 0.3949 0.8216, -0.9555, 0.6422, -0.6231, 0.3715, 0.0801 -0.2896, 0.9484, -0.7545, -0.6249, 0.7789, 0.4370 -0.9985, -0.5448, -0.7092, -0.5931, 0.7926, 0.5402
Test data:
# synthetic_test_40.txt # 0.7462, 0.4006, -0.0590, 0.6543, -0.0083, 0.1935 0.8495, -0.2260, -0.0142, -0.4911, 0.7699, 0.1078 -0.2335, -0.4049, 0.4352, -0.6183, -0.7636, 0.5088 0.1810, -0.5142, 0.2465, 0.2767, -0.3449, 0.3136 -0.8650, 0.7611, -0.0801, 0.5277, -0.4922, 0.7140 -0.2358, -0.7466, -0.5115, -0.8413, -0.3943, 0.4533 0.4834, 0.2300, 0.3448, -0.9832, 0.3568, 0.1360 -0.6502, -0.6300, 0.6885, 0.9652, 0.8275, 0.3046 -0.3053, 0.5604, 0.0929, 0.6329, -0.0325, 0.4756 -0.7995, 0.0740, -0.2680, 0.2086, 0.9176, 0.4565 -0.2144, -0.2141, 0.5813, 0.2902, -0.2122, 0.4119 -0.7278, -0.0987, -0.3312, -0.5641, 0.8515, 0.4438 0.3793, 0.1976, 0.4933, 0.0839, 0.4011, 0.1905 -0.8568, 0.9573, -0.5272, 0.3212, -0.8207, 0.7415 -0.5785, 0.0056, -0.7901, -0.2223, 0.0760, 0.5551 0.0735, -0.2188, 0.3925, 0.3570, 0.3746, 0.2191 0.1230, -0.2838, 0.2262, 0.8715, 0.1938, 0.2878 0.4792, -0.9248, 0.5295, 0.0366, -0.9894, 0.3149 -0.4456, 0.0697, 0.5359, -0.8938, 0.0981, 0.3879 0.8629, -0.8505, -0.4464, 0.8385, 0.5300, 0.1769 0.1995, 0.6659, 0.7921, 0.9454, 0.9970, 0.2330 -0.0249, -0.3066, -0.2927, -0.4923, 0.8220, 0.2437 0.4513, -0.9481, -0.0770, -0.4374, -0.9421, 0.2879 -0.3405, 0.5931, -0.3507, -0.3842, 0.8562, 0.3987 0.9538, 0.0471, 0.9039, 0.7760, 0.0361, 0.1706 -0.0887, 0.2104, 0.9808, 0.5478, -0.3314, 0.4128 -0.8220, -0.6302, 0.0537, -0.1658, 0.6013, 0.4306 -0.4123, -0.2880, 0.9074, -0.0461, -0.4435, 0.5144 0.0060, 0.2867, -0.7775, 0.5161, 0.7039, 0.3599 -0.7968, -0.5484, 0.9426, -0.4308, 0.8148, 0.2979 0.7811, 0.8450, -0.6877, 0.7594, 0.2640, 0.2362 -0.6802, -0.1113, -0.8325, -0.6694, -0.6056, 0.6544 0.3821, 0.1476, 0.7466, -0.5107, 0.2592, 0.1648 0.7265, 0.9683, -0.9803, -0.4943, -0.5523, 0.2454 -0.9049, -0.9797, -0.0196, -0.9090, -0.4433, 0.6447 -0.4607, 0.1811, -0.2389, 0.4050, -0.0078, 0.5229 0.2664, -0.2932, -0.4259, -0.7336, 0.8742, 0.1834 -0.4507, 0.1029, -0.6294, -0.1158, -0.6294, 0.6081 0.8948, -0.0124, 0.9278, 0.2899, -0.0314, 0.1534 -0.1323, -0.8813, -0.0146, -0.0697, 0.6135, 0.2386






















.NET Test Automation Recipes
Software Testing
SciPy Programming Succinctly
Keras Succinctly
R Programming
Visual Studio Live
Microsoft MLADS Conference
DevIntersection Conference
Machine Learning Week
Ai4 Conference
G2E Conference
iSC West Conference
You must be logged in to post a comment.