Compare commits

8 Commits

Author SHA1 Message Date
Nathan Huey
fda251f051 First try boundary nudging 2025-06-11 16:55:23 -07:00
Arthur Lu
afc882a569 Merge pull request #5 from ltcptgeneral/Parser
Fix range bug in TreeCompress, update parser to autofail non-singular…
2025-06-11 12:11:39 -07:00
6de3807fe2 fix range bug in TreeCompress, update parser to autofail non-singular classifications 2025-06-11 19:10:19 +00:00
Arthur Lu
fc16d3c586 Merge pull request #4 from ltcptgeneral/Parser
Eval compressed tree accuracy
2025-06-11 11:28:38 -07:00
7bee40ecf9 restore TreeCompress and TreeToRMT from main 2025-06-11 18:28:18 +00:00
krishpatel
e811171a73 Implemented working compressed tree parser to get classification accuracy 2025-06-11 11:10:49 -07:00
61a451b82d fix counting issue in ram bits 2025-06-11 04:47:35 +00:00
c73de36c70 replace classes with class string instead of index 2025-06-11 04:41:32 +00:00
6 changed files with 314 additions and 79 deletions

4
.gitignore vendored
View File

@@ -1,3 +1,5 @@
data.*
__pycache__
*.json
*.json
.DS_Store
.ipynb_checkpoints/

128
CompressedTreeParser.ipynb Normal file
View File

@@ -0,0 +1,128 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "938dec51",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import argparse\n",
"from sklearn.tree import DecisionTreeClassifier, plot_tree, _tree\n",
"from sklearn.metrics import accuracy_score\n",
"from sklearn.tree import export_graphviz\n",
"import pydotplus\n",
"from matplotlib import pyplot as plt\n",
"from labels import mac_to_label\n",
"import json\n",
"import math"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "442624c7",
"metadata": {},
"outputs": [],
"source": [
"Set1 = pd.read_csv('data.csv').values.tolist()\n",
"X = [i[0:3] for i in Set1]\n",
"Y =[i[3] for i in Set1]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "12ad454d",
"metadata": {},
"outputs": [],
"source": [
"predict_Yt = []\n",
"with open('compressed_tree.json', 'r') as file:\n",
" data = json.load(file)\n",
" classes = data[\"classes\"]\n",
" for x in X:\n",
" counter = 0\n",
" class_set = []\n",
" for feature in reversed(data['layers']): #Have to reverse this list due to structure of the data.csv file and how it aligns with the compressed tree layers\n",
" for node in data['layers'][feature]:\n",
" if node['min'] is None:\n",
" if x[counter] < node['max']:\n",
" class_set.append(node['classes'])\n",
" break #is this an issue?\n",
" else:\n",
" continue\n",
" elif node['max'] is None:\n",
" if node['min'] < x[counter]:\n",
" class_set.append(node['classes'])\n",
" break #is this an issue?\n",
" else:\n",
" continue\n",
" elif node['min'] < x[counter] and x[counter] < node['max']:\n",
" class_set.append(node['classes'])\n",
" break #is this an issue?\n",
"\n",
" counter += 1\n",
" result = set(class_set[0])\n",
" for s in class_set[1:]:\n",
" result.intersection_update(s)\n",
"\n",
" #predict_Yt.append(list(result))\n",
" #print(result)\n",
" if len(result) == 1:\n",
" prediction = list(result)[0]\n",
" pred_class = classes[prediction]\n",
" predict_Yt.append(pred_class)\n",
" else:\n",
" predict_Yt.append(None)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "8b4c56b6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.8448217242194891\n"
]
}
],
"source": [
"correct = 0\n",
"for i in range(len(Y)):\n",
" prediction = predict_Yt[i]\n",
" if prediction != None and Y[i] == prediction:\n",
" correct += 1\n",
"\n",
"print(correct / len(Y))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because one or more lines are too long

View File

@@ -89,7 +89,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "switch",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@@ -103,7 +103,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
"version": "3.12.9"
}
},
"nbformat": 4,

View File

@@ -38,14 +38,14 @@
"i = 0\n",
"\n",
"path_ids = set()\n",
"path_classes = set()\n",
"path_classes = tree[\"classes\"]\n",
"\n",
"# for each path in the tree\n",
"for path in paths:\n",
"\t# assign a path id \n",
"\tpath[\"id\"] = i\n",
"\tpath_ids.add(i)\n",
"\tpath_classes.add(path[\"classification\"])\n",
"\t#path_classes.add(path[\"classification\"])\n",
"\ti += 1\t\n",
"\t# for each condition\n",
"\tconditions = path[\"conditions\"]\n",
@@ -86,41 +86,7 @@
"execution_count": 5,
"id": "98cde024",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'dst': {'min': None, 'max': 578}, 'src': {'min': None, 'max': 60}, 'protocl': {'min': None, 'max': 0}}\n",
"{'dst': {'min': None, 'max': 3031}, 'src': {'min': None, 'max': 60}, 'protocl': {'min': None, 'max': 0}}\n",
"{'dst': {'min': None, 'max': 3031}, 'src': {'min': None, 'max': 60}, 'protocl': {'min': 0, 'max': None}}\n",
"{'dst': {'min': None, 'max': 3031}, 'src': {'min': None, 'max': 60}, 'protocl': {'min': 1, 'max': None}}\n",
"{'dst': {'min': None, 'max': 3031}, 'src': {'min': None, 'max': 67}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': None, 'max': 101}, 'src': {'min': 67, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': None, 'max': 101}, 'src': {'min': 54978, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': None, 'max': 101}, 'src': {'min': 59817, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': None, 'max': 101}, 'src': {'min': 60043, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': None, 'max': 3031}, 'src': {'min': 67, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': None, 'max': 3031}, 'src': {'min': 130, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': None, 'max': 3031}, 'src': {'min': 1223, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 3031, 'max': None}, 'src': {'min': None, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 3067, 'max': None}, 'src': {'min': None, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 5110, 'max': None}, 'src': {'min': None, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 33925, 'max': None}, 'src': {'min': None, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 46329, 'max': None}, 'src': {'min': None, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 46331, 'max': None}, 'src': {'min': None, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 49152, 'max': None}, 'src': {'min': None, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 49157, 'max': None}, 'src': {'min': None, 'max': 283}, 'protocl': {'min': None, 'max': 11}}\n",
"{'dst': {'min': 49157, 'max': None}, 'src': {'min': None, 'max': 283}, 'protocl': {'min': 11, 'max': None}}\n",
"{'dst': {'min': 49157, 'max': None}, 'src': {'min': None, 'max': 4566}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 56320, 'max': None}, 'src': {'min': None, 'max': 4566}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 49157, 'max': None}, 'src': {'min': 4566, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 51848, 'max': None}, 'src': {'min': 4566, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 49157, 'max': None}, 'src': {'min': 5225, 'max': None}, 'protocl': {'min': None, 'max': None}}\n",
"{'dst': {'min': 53283, 'max': None}, 'src': {'min': 5225, 'max': None}, 'protocl': {'min': None, 'max': None}}\n"
]
}
],
"outputs": [],
"source": [
"# collapse all paths to ranges for each feature\n",
"# because of how decision trees work, all conditions on a path must be true to reach the leaf node\n",
@@ -143,17 +109,16 @@
"\t\tvalue = condition[\"value\"]\n",
"\n",
"\t\t# move the min/max for the corresponding feature in compressed\n",
"\t\tif operation == \"<=\" and compressed[feature][\"min\"] is None:\n",
"\t\tif operation == \"<=\" and compressed[feature][\"max\"] is None:\n",
"\t\t\tcompressed[feature][\"max\"] = value\n",
"\t\telif operation == \">\" and compressed[feature][\"max\"] is None:\n",
"\t\telif operation == \">\" and compressed[feature][\"min\"] is None:\n",
"\t\t\tcompressed[feature][\"min\"] = value\n",
"\t\telif operation == \"<=\" and value < compressed[feature][\"min\"]:\n",
"\t\telif operation == \"<=\" and value < compressed[feature][\"max\"]:\n",
"\t\t\tcompressed[feature][\"max\"] = value\n",
"\t\telif operation == \">\" and value > compressed[feature][\"max\"]:\n",
"\t\telif operation == \">\" and value > compressed[feature][\"min\"]:\n",
"\t\t\tcompressed[feature][\"min\"] = value\n",
"\n",
"\tpath[\"compressed\"] = compressed\n",
"\tprint(compressed)"
"\tpath[\"compressed\"] = compressed"
]
},
{
@@ -276,7 +241,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "switch",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@@ -290,7 +255,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
"version": "3.12.9"
}
},
"nbformat": 4,

View File

@@ -77,7 +77,7 @@
"\t\t}\n",
"\t\ttcam_bits += num_prefixes * prefix_width\n",
"\n",
"\t\t# assume no pointer reuse for metadata storage\n",
"\t\t# assume basic pointer reuse for metadata storage\n",
"\t\tram = {\n",
"\t\t\t\"id\": f\"{layer}_meta\",\n",
"\t\t\t\"step\": step,\n",
@@ -86,7 +86,7 @@
"\t\t\t\"key_size\": math.ceil(math.log2(num_ranges)),\n",
"\t\t\t\"data_size\": len(classes)\n",
"\t\t}\n",
"\t\tram_bits += math.ceil(math.log2(num_ranges)) * len(classes)\n",
"\t\tram_bits += num_ranges * len(classes)\n",
"\n",
"\t\trmt.append(tcam)\n",
"\t\trmt.append(ram)\n",
@@ -117,8 +117,8 @@
"[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"id mapping: \n",
"[['dst_range', 'dst_meta'], ['src_range', 'src_meta'], ['protocl_range', 'protocl_meta'], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]\n",
"TCAM bits: 13312\n",
"RAM bits: 110\n"
"TCAM bits: 13184\n",
"RAM bits: 504\n"
]
}
],
@@ -182,9 +182,7 @@
"\t\t\tmerge(prefix, prefixes)\n",
"\t\telse:\n",
"\t\t\tprefixes.append(prefix)\n",
"\treturn prefixes\n",
"\n",
"#convert_range(81, 1024, 16)"
"\treturn prefixes"
]
},
{
@@ -234,7 +232,7 @@
"\t\t\t\"key_size\": math.ceil(math.log2(num_ranges)),\n",
"\t\t\t\"data_size\": len(classes)\n",
"\t\t}\n",
"\t\tram_bits += math.ceil(math.log2(num_ranges)) * len(classes)\n",
"\t\tram_bits += num_ranges * len(classes)\n",
"\n",
"\t\trmt.append(tcam)\n",
"\t\trmt.append(ram)\n",
@@ -265,8 +263,8 @@
"[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"id mapping: \n",
"[['dst_range', 'dst_meta'], ['src_range', 'src_meta'], ['protocl_range', 'protocl_meta'], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]\n",
"TCAM bits: 3520\n",
"RAM bits: 110\n"
"TCAM bits: 3320\n",
"RAM bits: 504\n"
]
}
],
@@ -339,7 +337,7 @@
"\t\t\t\"key_size\": math.ceil(math.log2(num_ranges)),\n",
"\t\t\t\"data_size\": len(classes)\n",
"\t\t}\n",
"\t\tram_bits += math.ceil(math.log2(num_ranges)) * len(classes)\n",
"\t\tram_bits += num_ranges * len(classes)\n",
"\n",
"\t\trmt.append(tcam)\n",
"\t\trmt.append(ram)\n",
@@ -370,8 +368,8 @@
"[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"id mapping: \n",
"[['dst_range', 'dst_meta'], ['src_range', 'src_meta'], ['protocl_range', 'protocl_meta'], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]\n",
"TCAM bits: 2120\n",
"RAM bits: 110\n"
"TCAM bits: 2152\n",
"RAM bits: 504\n"
]
}
],
@@ -384,7 +382,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "switch",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@@ -398,7 +396,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
"version": "3.12.9"
}
},
"nbformat": 4,