{ Analytica Model Python_decision_tree_example, encoding="UTF-8" } SoftwareVersion 7.1.8 { System Variables with non-default values: } SampleSize := 1000 TypeChecking := 1 Checking := 1 SaveOptions := 2 SaveValues := 0 PythonModelEnvironment := Analytica_Iris_Tree WindState PythonModelEnvironment: 2,98,82,720,350 PythonStartupCode := import numpy~ import numpy as np~ from sklearn.datasets import load_iris WindState PythonStartupCode: 2,98,82,720,350 {!-50299|DiagramColor Model: 0x00ffffff} {!-50299|DiagramColor Module: 0x00ffffff} {!-50299|DiagramColor LinkModule: 0x00ffffff} {!-50299|DiagramColor Library: 0x00ffffff} {!-50299|DiagramColor LinkLibrary: 0x00ffffff} {!-50299|DiagramColor Form: 0x00ffffff} NodeInfo FormNode: 1,0,0,,0,0,,,,0,,,0 {!-50299|NodeColor Text: 0x00f3f3f3} Model Python_decision_tree_example Title: Python Decision Tree Example Description: Documentation example showing how to load scikit-learn's Iris data, train a CART decision tree in Python, and use its predictions in Analytica. Its setup button creates the required Analytica_Iris_Tree Conda environment without saving any machine-specific paths. Author: Assista~ Lumina Decision Systems Date: Thu, Jul 16, 2026 3:18 PM DiagState: 2,0,1,1560,656,17,10 WindState: 2,98,82,720,350 FontStyle: Arial,15 FileInfo: 0,Model Python_decision_tree_example,2,2,0,0,W:\Testmodels\Python Decision Tree Example.ana {!70104|Att_GUID: d71e036b-3fa7-460a-877f-067b3aa36e90} Module Iris_Decision_Tree Title: Iris decision tree Description: Setup, data viewing, and decision-tree training for a Python-integration documentation example. The setup button creates the model-specific Conda environment Analytica_Iris_Tree locally when Anaconda or Miniconda is available. Author: Assista~ Lumina Decision Systems Date: Thu, Jul 16, 2026 4:13 PM NodeLocation: 160,512,1 NodeSize: 80,24 NodeInfo: 1,,,,,,,0,,,,,,0 DiagState: 2,1055,99,1560,768,17,10 WindState: 2,756,209,720,350 Module Iris_data Title: Iris data Description: The Iris measurements, species labels, and their Observation and Measurement dimensions. NodeLocation: 208,544,2 NodeSize: 96,32 NodeInfo: 1,,,,,,,0,,,,,,0 DiagState: 2,0,1,1560,656,17,10 WindState: 2,98,82,720,350 Index Observation Title: Observation Description: The 150 Iris flower observations supplied with scikit-learn. Definition: 1..150 NodeLocation: 96,64,2 NodeSize: 80,24 NodeInfo: 1,,,,,,,0,,,,,,0 Index Feature Title: Measurement Description: The four flower measurements used as predictor features. Definition: ['Sepal length (cm)','Sepal width (cm)','Petal length (cm)','Petal width (cm)'] NodeLocation: 288,64,2 NodeSize: 80,24 NodeInfo: 1,,,,,,,0,,,,,,0 Variable Iris_measurements Title: Iris measurements Units: cm Description: The 150 by 4 numerical measurements loaded from scikit-learn's built-in Iris data set. Definition: PyExplode(~ PyEval('load_iris().data'),~ Observation,~ Feature~ ) NodeLocation: 512,136,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 WindState: 2,98,82,720,350 ValueState: 2,662,56,752,303,,MIDM Aliases: FormNode Iris_measurements1148013867 Variable Iris_species_code Title: Actual species code Description: Integer target class for each Iris observation: 0=setosa, 1=versicolor, 2=virginica. Definition: PyExplode(~ PyEval('load_iris().target'),~ Observation~ ) NodeLocation: 512,208,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 Variable Iris_species Title: Actual species Description: Species name for each Iris observation, loaded from scikit-learn's built-in Iris data set. Definition: PyExplode(~ PyEval('load_iris().target_names[load_iris().target]'),~ Observation~ ) NodeLocation: 512,280,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 ValueState: 2,100,106,416,303,,MIDM Aliases: FormNode Iris_species611142955 Close Iris_data Module Tree_training Title: Train decision tree Description: Training controls and Python components used to fit the Iris CART decision tree. NodeLocation: 448,544,2 NodeSize: 96,32 NodeInfo: 1,,,,,,,0,,,,,,0 DiagState: 2,0,1,1560,656,17,10 WindState: 2,98,82,720,350 Decision Tree_max_depth Title: Maximum tree depth Description: Maximum depth of the fitted CART decision tree. Increase it to allow a more complex tree. Definition: 3 NodeLocation: 96,176,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 Aliases: FormNode Tree_max_depth1148013867 Decision Random_seed Title: Random seed Description: Seed supplied to scikit-learn's tree estimator, for reproducible fitting. Definition: 7 NodeLocation: 96,248,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 Aliases: FormNode Random_seed1148013867 {!70000|Callable Fit_tree} {!70000|Title: Fit CART tree (Python)} {!70000|Description: Python Callable that fits and returns a scikit-learn CART DecisionTreeClassifier.} {!70000|Definition: PyExec('import numpy as np~ from sklearn.tree import DecisionTreeClassifier~ ~ def fit_tree(X, y, max_depth, seed, test_positions):~ test_pos = np.asarray(test_positions, dtype=int) - 1~ train_mask = np.ones(len(y), dtype=bool)~ train_mask[test_pos] = False~ tree = DecisionTreeClassifier(~ criterion="gini",~ max_depth=int(max_depth),~ random_state=int(seed)~ )~ return tree.fit(X[train_mask], y[train_mask])', flags:0)} {!70000|NodeLocation: 560,280,2} {!70000|NodeSize: 96,24} {!70000|NodeInfo: 1,,,,,,,0,,,,,,0} Variable Fitted_tree Title: Fitted Python decision tree Description: Opaque Python scikit-learn DecisionTreeClassifier obtained from Tree_as_struct's python_model member. Retained as an optional technical view; model calculations use the native Decision_tree instance. Definition: Tree_as_struct -> python_model NodeLocation: 1064,176,2 NodeSize: 104,24 NodeInfo: 1,,,,,,,0,,,,,,0 ValueState: 2,678,121,647,436,,MIDM Aliases: FormNode Fitted_tree611142955 {!70000|Callable Export_tree_JSON} {!70000|Title: Export tree as JSON} {!70000|Description: Python Callable that converts a fitted scikit-learn decision tree into nested JSON suitable for ParseJSON and inspection as native Analytica Structs.} {!70000|Definition: PyExec('import json~ import numpy as np~ ~ def export_tree_json(model, feature_names):~ tree = model.tree_~ ~ def visit(node_id):~ counts = [int(x) for x in tree.value[node_id][0]]~ result = {~ "node": int(node_id),~ "samples": int(tree.n_node_samples[node_id]),~ "class_counts": counts,~ "prediction": int(np.argmax(counts))~ }~ if tree.children_left[node_id] == tree.children_right[node_id]:~ result["kind"] = "leaf"~ else:~ feature_id = int(tree.feature[node_id])~ result.update({~ "kind": "split",~ "feature": str(feature_names[feature_id]),~ "threshold": float(tree.threshold[node_id]),~ "left": visit(int(tree.children_left[node_id])),~ "right": visit(int(tree.children_right[node_id]))~ })~ return result~ ~ return json.dumps({~ "classes": [int(x) for x in model.classes_],~ "root": visit(0)~ })', flags:0)} {!70000|NodeLocation: 96,80,2} {!70000|NodeSize: 80,24} {!70000|NodeInfo: 1,,,,,,,0,,,,,,0} Objective Tree_as_struct Title: Fitted decision tree Description: Native fitted Decision_tree. It is trained only on the 120-observation training set; its Fit and Predict member functions own the model operations, and python_model holds the opaque scikit-learn estimator. Definition: Tree_template -> Fit(~ PyArray(Iris_measurements, Observation, Feature),~ PyArray(Iris_species_code, Observation, dtype:'int64'),~ Tree_max_depth,~ Random_seed,~ PyList(Test_observation),~ 'Iris CART tree'~ ) NodeLocation: 824,176,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 WindState: 2,753,287,720,350 ValueState: 2,1042,111,400,600,0,MIDM Aliases: FormNode Tree_as_struct2037599531 {!70000|Struct Decision_tree( python_model : atom ; feature_names : atom ; display_name : text atom )} {!70000|Title: Decision tree} {!70000|Description: Native Analytica decision-tree datatype. Its instances hold the opaque fitted Python estimator plus native top-level tree metadata: classes, root, and a configurable display name.} {!70000|Definition: If IsNull(python_model) Then Self Else (~ Local tree_data := ParseJSON(~ Export_tree_JSON(python_model, feature_names)~ );~ Self -> classes := tree_data -> classes;~ Self -> root := tree_data -> root;~ Self~ )} {!70000|NodeLocation: 320,80,2} {!70000|NodeSize: 96,24} {!70000|NodeInfo: 1,,,,,,,0,,,,,,0} {!70000|DiagState: 2,0,1,1560,656,17,10} {!70000|WindState: 2,98,82,720,350} Function DisplayName( Self : Decision_tree atom ) Title: Display name Description: Returns the display name used when a Decision_tree instance appears in a result table. Definition: Self->display_name NodeLocation: 160,64,1 NodeSize: 64,24 NodeInfo: 1,,,,,,,0,,,,,,0 WindState: 2,98,82,720,350 Function Fit( Self : Decision_tree atom ; X : atom ; y : atom ; max_depth : atom ; seed : atom ; test_positions : atom ; display_name : text atom ) Title: Fit tree Description: Fits a CART classifier and returns a new Decision_tree instance. The fitted Python estimator is stored in its python_model member. Definition: Decision_tree(~ Fit_tree(X, y, max_depth, seed, test_positions),~ Self -> feature_names,~ display_name~ ) NodeLocation: 352,64,1 NodeSize: 64,24 NodeInfo: 1,,,,,,,0,,,,,,0 Function Predict( Self : Decision_tree atom ; X : atom ) Title: Predict species code Description: Uses this fitted tree's python_model member to predict species codes for a NumPy measurement matrix. Definition: Self -> python_model -> predict(X) NodeLocation: 544,64,1 NodeSize: 64,24 NodeInfo: 1,,,,,,,0,,,,,,0 Function Predict_holdout( Self : Decision_tree atom ; X : atom ; test_positions : atom ) Title: Predict holdout Description: Predicts the selected 1-based observation positions from a full NumPy measurement matrix, using this instance's python_model member. Definition: Predict_tree(~ Self -> python_model,~ X,~ test_positions~ ) NodeLocation: 744,64,1 NodeSize: 72,24 NodeInfo: 1,,,,,,,0,,,,,,0 Function Score_holdout( Self : Decision_tree atom ; X : atom ; y : atom ; test_positions : atom ) Title: Score holdout accuracy Description: Computes classification accuracy for selected 1-based observation positions from full NumPy measurement and target arrays, using this instance's python_model member. Definition: Score_tree(~ Self -> python_model,~ X,~ y,~ test_positions~ ) NodeLocation: 928,64,1 NodeSize: 64,24 NodeInfo: 1,,,,,,,0,,,,,,0 Close Decision_tree Variable Tree_template Title: Unfitted decision tree template Description: Internal untrained Decision_tree instance used to invoke its Fit member function. Definition: Decision_tree(~ Null,~ PyList(Feature, Feature),~ 'Unfitted Iris CART tree'~ ) NodeLocation: 560,80,2 NodeSize: 112,24 NodeInfo: 1,,,,,,,0,,,,,,0 Close Tree_training Module New_flower_classification Title: Classify new flower Description: Classify a new Iris measurement using the fitted decision tree. NodeLocation: 448,672,2 NodeSize: 104,32 NodeInfo: 1,,,,,,,0,,,,,,0 DiagState: 2,0,1,1560,656,17,10 Decision New_measurements Title: New measurements Units: cm Description: Enter the four flower measurements to classify, in the order shown by the Measurement index. Definition: Table(Feature)(5.1,3.5,1.4,0.2) NodeLocation: 96,160,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 DefnState: 2,612,618,416,303,0,DFNM Aliases: FormNode New_measurements2084261163 Variable New_species_code Title: Predicted species code Description: Species code predicted from New_measurements by Tree_as_struct's Predict member function. Definition: Local x := PyArray(New_measurements, Feature);~ Local prediction := Tree_as_struct -> Predict(~ PyEval('np.asarray(x).reshape(1, -1)')~ );~ PyEval('int(prediction[0])') NodeLocation: 352,160,2 NodeSize: 96,24 NodeInfo: 1,,,,,,,0,,,,,,0 Objective New_species Title: Predicted species Description: Species name corresponding to the prediction for New_measurements. Definition: Local code := New_species_code;~ PyEval('load_iris().target_names[int(code)]') NodeLocation: 608,160,2 NodeSize: 80,24 NodeInfo: 1,,,,,,,0,,,,,,0 Aliases: FormNode New_species2084261163 Close New_flower_classification Module Holdout_validation Title: Holdout validation Description: Stratified holdout observations, predictions, and classification-accuracy assessment. NodeLocation: 208,672,2 NodeSize: 96,32 NodeInfo: 1,,,,,,,0,,,,,,0 DiagState: 2,0,1,1560,656,17,10 Variable Test_observation Title: Test observations Description: A reproducible, stratified 20% holdout: 10 observations from each Iris species. It changes with Random_seed. Definition: Local seed := Random_seed;~ PyExplode(~ PyEval(~ 'np.sort(np.concatenate([np.random.default_rng(int(seed) + k).choice(np.arange(1 + 50*k, 51 + 50*k), size=10, replace=False) for k in range(3)]))'~ )~ ) NodeLocation: 104,120,2 NodeSize: 88,24 NodeInfo: 1,,,,,,,0,,,,,,0 Variable Test_actual_species_code Title: Actual test species code Description: Actual species codes for the 30-observation holdout, in the same row order as Test observations. Definition: Local test_positions := PyList(Test_observation);~ PyExplode(~ PyEval(~ 'load_iris().target[np.asarray(test_positions, dtype=int) - 1]'~ )~ ) NodeLocation: 368,80,2 NodeSize: 112,24 NodeInfo: 1,,,,,,,0,,,,,,0 ValueState: 2,580,586,416,303,,MIDM Aliases: FormNode Test_actual_species_code2084261163 Variable Test_predicted_species_code Title: Predicted test species code Description: Species codes predicted for the holdout observations by Tree_as_struct's Predict_holdout member function. Definition: PyExplode(~ Tree_as_struct -> Predict_holdout(~ PyArray(Iris_measurements, Observation, Feature),~ PyList(Test_observation)~ )~ ) NodeLocation: 368,160,2 NodeSize: 120,24 NodeInfo: 1,,,,,,,0,,,,,,0 ValueState: 2,596,602,416,303,,MIDM Aliases: FormNode Test_predicted_species_code2084261163 Objective Test_accuracy Title: Test classification accuracy Units: % Description: Percentage of the 30 stratified holdout observations classified correctly. It is evaluated by Tree_as_struct's Score_holdout member function. Definition: 100 * Tree_as_struct -> Score_holdout(~ PyArray(Iris_measurements, Observation, Feature),~ PyArray(Iris_species_code, Observation, dtype:'int64'),~ PyList(Test_observation)~ ) NodeLocation: 656,120,2 NodeSize: 104,24 NodeInfo: 1,,,,,,,0,,,,,,0 ValueState: 2,628,634,416,303,,MIDM Aliases: FormNode Test_accuracy2084261163 {!70000|Callable Predict_tree} {!70000|Title: Predict tree holdout (Python)} {!70000|Description: Internal Python helper used by the Decision_tree Predict_holdout member function.} {!70000|Definition: PyExec('import numpy as np~ ~ def predict_tree(model, X, positions):~ return model.predict(X[np.asarray(positions, dtype=int) - 1])', flags:0)} {!70000|NodeLocation: 104,264,2} {!70000|NodeSize: 96,24} {!70000|NodeInfo: 1,,,,,,,0,,,,,,0} {!70000|ValueState: 2,644,650,416,303,,MIDM} {!70000|Callable Score_tree} {!70000|Title: Score tree holdout (Python)} {!70000|Description: Internal Python helper used by the Decision_tree Score_holdout member function.} {!70000|Definition: PyExec('import numpy as np~ ~ def score_tree(model, X, y, positions):~ pos = np.asarray(positions, dtype=int) - 1~ return float(np.mean(model.predict(X[pos]) == y[pos]))', flags:0)} {!70000|NodeLocation: 368,264,2} {!70000|NodeSize: 96,24} {!70000|NodeInfo: 1,,,,,,,0,,,,,,0} Close Holdout_validation Close Iris_Decision_Tree FormNode Tree_max_depth1148013867 Definition: 0 NodeLocation: 620,104,2 NodeSize: 140,24 NodeInfo: 1,,,,,,,96,,,,,,0 Original: Tree_max_depth FormNode Random_seed1148013867 Definition: 0 NodeLocation: 620,168,2 NodeSize: 140,24 NodeInfo: 1,,,,,,,96,,,,,,0 Original: Random_seed FormNode Iris_measurements1148013867 Definition: 1 NodeLocation: 248,284,2 NodeSize: 144,20 NodeInfo: 1,,,,,,,96,,,,,,0 Original: Iris_measurements FormNode Iris_species611142955 Definition: 1 NodeLocation: 248,348,2 NodeSize: 144,20 NodeInfo: 1,,,,,,,96,,,,,,0 Original: Iris_species FormNode Fitted_tree611142955 Definition: 1 NodeLocation: 620,292,2 NodeSize: 160,24 NodeInfo: 1,,,,,,,72,,,,,,0 Original: Fitted_tree Text Setup_panel Title: 1. Python setup: Analytica_Iris_Tree Description: One-time setup: Click the button below to create the Analytica_Iris_Tree environment. It requires Anaconda or Miniconda; if neither is found, it displays installation instructions. NodeLocation: 236,136,1 NodeSize: 172,88 NodeInfo: 1,,,,1,1,,0,,,,,,0,,,,8 NodeColor: 0xfff4f7fa Text Controls_panel Title: 2. Training controls NodeLocation: 620,136,1 NodeSize: 180,88 NodeInfo: 1,,,,1,1,,0,,,,,,0,,,,8 NodeColor: 0xfff4f7fa Text Data_panel Title: 3. View Iris data NodeLocation: 236,348,1 NodeSize: 172,108 NodeInfo: 1,,,,1,1,,0,,,,,,0,,,,8 NodeColor: 0xfff4f7fa Text Model_panel Title: 4. Train NodeLocation: 620,348,1 NodeSize: 180,108 NodeInfo: 1,,,,1,1,,0,,,,,,0,,,,8 NodeColor: 0xfff4f7fa Button Create_Iris_Python_environment Title: Create Python environment Description: Creates the Analytica_Iris_Tree Conda environment with Python, NumPy, and scikit-learn when needed. NodeLocation: 236,186,2 NodeSize: 116,18 NodeInfo: 1,,,,,,1,0,,,,,,0 WindState: 2,98,82,992,602 NodeFont: ,10 OnClick: Local envName := 'Analytica_Iris_Tree';~ Local pythonEnvs := GetProcessInfo('Python Environments');~ Local envExists := Sum(~ FindInText(envName, pythonEnvs, caseInsensitive: true) > 0~ ) > 0;~ Local installations := GetProcessInfo('Python Installations');~ Local isConda := FindInText(~ 'conda',~ installations,~ caseInsensitive: true~ ) > 0;~ If envExists Then~ MsgBox(~ 'The ' & envName & ' environment is already available.',~ buttons: 0,~ title: 'Python environment'~ )~ Else If Sum(isConda) = 0 Then~ MsgBox(~ 'Anaconda or Miniconda was not found. Install one of them, then click this button again.',~ buttons: 0,~ title: 'Python environment unavailable'~ )~ Else~ RunConsoleProcess(~ If isConda Then~ installations & '\Scripts\conda.exe'~ Else~ Null,~ 'conda.exe create -n Analytica_Iris_Tree -y python=3.12 numpy scikit-learn',~ '',~ true,~ '',~ 0,~ 2~ ) FormNode Tree_as_struct2037599531 Definition: 1 NodeLocation: 620,348,2 NodeSize: 160,24 NodeInfo: 1,,,,,,,108,,,,,,0 Original: Tree_as_struct FormNode New_measurements2084261163 Definition: 0 NodeLocation: 1040,108,2 NodeSize: 184,28 NodeInfo: 1,,,,,,,128,,,,,,0 Original: New_measurements FormNode New_species2084261163 Definition: 1 NodeLocation: 1040,164,2 NodeSize: 184,28 NodeInfo: 1,,,,,,,128,,,,,,0 Original: New_species FormNode Test_accuracy2084261163 Definition: 1 NodeLocation: 1040,300,2 NodeSize: 184,28 NodeInfo: 1,,,,,,,128,,,,,,0 Original: Test_accuracy FormNode Test_predicted_species_code2084261163 Definition: 1 NodeLocation: 1040,412,2 NodeSize: 184,28 NodeInfo: 1,,,,,,,128,,,,,,0 Original: Test_predicted_species_code FormNode Test_actual_species_code2084261163 Definition: 1 NodeLocation: 1040,356,2 NodeSize: 184,28 NodeInfo: 1,,,,,,,128,,,,,,0 Original: Test_actual_species_code Text Classify_panel Title: 5. Classify a new Iris flower NodeLocation: 1040,132,1 NodeSize: 208,84 NodeInfo: 1,,,,1,1,,0,,,,,,0,,,,8 NodeColor: 0xffeaf2fa {!50400|NodeBorderColor: 0xff6b8cae} Text Test_panel Title: 6. Holdout test performance NodeLocation: 1040,348,1 NodeSize: 208,108 NodeInfo: 1,,,,1,0,,0,,,,,,0,,,,8 NodeColor: 0xfff3f7ec {!50400|NodeBorderColor: 0xff7d9b5d} Close Python_decision_tree_example