ml-trust-model

git clone git://git.codymlewis.com/ml-trust-model.git
Log | Files | Refs | README

commit 71053249f78f3d2a4f5336cf6f44a15125e40288
parent 4afaa53aba8b86556ab2d600da926a3069f4cb46
Author: Cody Lewis <codymlewis@protonmail.com>
Date:   Sat, 30 Mar 2019 15:23:42 +1100

Split the program into a few separate files and add command line flags

Diffstat:
M.gitignore | 1+
ABadMouther/__init__.py | 9+++++++++
AFunctions.py | 43+++++++++++++++++++++++++++++++++++++++++++
ANode/__init__.py | 36++++++++++++++++++++++++++++++++++++
AReport/__init__.py | 15+++++++++++++++
MTest.py | 34+++++++++++++++++++---------------
ATrustManager/__init__.py | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MTrustModel.py | 196++++++++-----------------------------------------------------------------------
8 files changed, 228 insertions(+), 191 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -391,3 +391,4 @@ TSWLatexianTemp* tags tags.lock Session.vim +reports.csv diff --git a/BadMouther/__init__.py b/BadMouther/__init__.py @@ -0,0 +1,9 @@ +import Node + + +class BadMouther(Node.Node): + ''' + A bad mouthing malicious node. + ''' + def take_note(self, proxy, service_target, capability_target): + return -1 diff --git a/Functions.py b/Functions.py @@ -0,0 +1,43 @@ +import numpy as np + + +def print_progress(current_epoch, total_epochs, progress_len=20): + ''' + Print a progress bar about how far a process has went through it's epochs. + ''' + progress = int(100 * current_epoch / total_epochs) + + if (100 * current_epoch / total_epochs) == progress: + progress_bar_progress = int(progress_len * progress * 0.01) + if progress_bar_progress != 0: + unprogressed = progress_len - progress_bar_progress + else: + unprogressed = progress_len - 1 + progress_bar = "[" + progress_bar += "".join( + ["#" for _ in range(progress_bar_progress - 1)] + ) + progress_bar += "".join(["." for _ in range(unprogressed)]) + progress_bar += "]" + print(f"{progress_bar} {progress}%") + + +def wrong_note(note): + ''' + Get the wrong note randomly + ''' + wrong_notes = {-1, 0, 1} - {note} + return list(wrong_notes)[int(np.round(np.random.rand()))] + + +def get_conditioned_ids(no_of_nodes, condition_factor): + ''' + Give an id list of random nodes that fit a given condition. + ''' + conditioned_list = [] + ids = [i for i in range(no_of_nodes)] + + for _ in range(int(no_of_nodes * condition_factor)): + conditioned_list.append(ids.pop(np.random.randint(len(ids)))) + + return conditioned_list diff --git a/Node/__init__.py b/Node/__init__.py @@ -0,0 +1,36 @@ +import numpy as np + +import Functions +import Report + + +class Node: + ''' + A node in the trust managed network. + ''' + def __init__(self, service=100, capability=100, note_acc=1.0): + self.service = service + self.capability = capability + self.note_taking_acc = note_acc # This is unknown to the trust manager + + def send_report(self, proxy, service_target, capability_target, time): + ''' + Create a report on a given proxy. + ''' + note = self.take_note(proxy, service_target, capability_target) + + return Report.Report(service_target, capability_target, note, time) + + def take_note(self, proxy, service_target, capability_target): + if proxy.service >= service_target and \ + proxy.capability >= capability_target: + note = 1 + elif proxy.service >= service_target or \ + proxy.capability >= capability_target: + note = 0 + else: + note = -1 + + if np.random.rand() < self.note_taking_acc: + return note + return Functions.wrong_note(note) diff --git a/Report/__init__.py b/Report/__init__.py @@ -0,0 +1,15 @@ +class Report: + ''' + Report that states the context and how well the node performed at that. + ''' + def __init__(self, service=0, capability=0, note=0, time=0): + self.service = service + self.capability = capability + self.note = note + self.time = time + + def csv_output(self): + ''' + Output contained data in a format suitable for a csv + ''' + return f"{self.service},{self.capability},{self.note},{self.time}" diff --git a/Test.py b/Test.py @@ -2,7 +2,11 @@ import unittest import numpy as np -import TrustModel +import Functions +import Report +import Node +import BadMouther +import TrustManager ''' Perform unit tests on the program. @@ -27,7 +31,7 @@ class TestTrustModel(unittest.TestCase): ''' Test the creation of reports. ''' - report = TrustModel.Report(service, capability, note, time) + report = Report.Report(service, capability, note, time) self.assertEqual(report.service, service) self.assertEqual(report.capability, capability) self.assertEqual(report.note, note) @@ -41,18 +45,18 @@ class TestTrustModel(unittest.TestCase): Test that the wrong note is assigned for each possible note. ''' for note in [-1, 0, 1]: - self.assertNotEqual(TrustModel.wrong_note(note), note) + self.assertNotEqual(Functions.wrong_note(note), note) def test_note_take(self): ''' Test that note taking returns the expected values. ''' - node = TrustModel.Node() - proxy = TrustModel.Node() + node = Node.Node() + proxy = Node.Node() self.assertEqual(node.take_note(proxy, 50, 50), 1) - proxy = TrustModel.Node(100, 1) + proxy = Node.Node(100, 1) self.assertEqual(node.take_note(proxy, 50, 50), 0) - proxy = TrustModel.Node(1, 1) + proxy = Node.Node(1, 1) self.assertEqual(node.take_note(proxy, 50, 50), -1) def test_network_creation(self): @@ -63,7 +67,7 @@ class TestTrustModel(unittest.TestCase): constrained_nodes = 0.5 poor_witnesses = 0.2 malicious_nodes = 0.1 - trust_manager = TrustModel.TrustManager( + trust_manager = TrustManager.TrustManager( no_of_nodes, constrained_nodes, poor_witnesses, malicious_nodes ) self.assertEqual(len(trust_manager.network), no_of_nodes) @@ -76,7 +80,7 @@ class TestTrustModel(unittest.TestCase): num_constrained += 1 if node.note_taking_acc < 1.0: num_poor_witnesses += 1 - if isinstance(node, TrustModel.BadMouther): + if isinstance(node, BadMouther.BadMouther): num_malicious += 1 self.assertEqual(no_of_nodes * constrained_nodes, num_constrained) @@ -87,14 +91,14 @@ class TestTrustModel(unittest.TestCase): ''' Test the report creation of the bad mouther. ''' - proxy = TrustModel.Node(100, 100) - bad_mouther = TrustModel.BadMouther() + proxy = Node.Node(100, 100) + bad_mouther = BadMouther.BadMouther() self.make_report(bad_mouther, proxy, note=-1) - proxy = TrustModel.Node(1, 100) + proxy = Node.Node(1, 100) self.make_report(bad_mouther, proxy, note=-1) - proxy = TrustModel.Node(100, 1) + proxy = Node.Node(100, 1) self.make_report(bad_mouther, proxy, note=-1) - proxy = TrustModel.Node(1, 1) + proxy = Node.Node(1, 1) self.make_report(bad_mouther, proxy, note=-1) def make_report(self, client, proxy, service=50, @@ -109,7 +113,7 @@ class TestTrustModel(unittest.TestCase): self.assertEqual(report.time, time) def test_bootstrap(self): - trust_manager = TrustModel.TrustManager() + trust_manager = TrustManager.TrustManager() no_of_transactions = 5 trust_manager.bootstrap(no_of_transactions) diff --git a/TrustManager/__init__.py b/TrustManager/__init__.py @@ -0,0 +1,85 @@ +import numpy as np + +import Functions +import Node +import BadMouther + + +class TrustManager: + ''' + Create and control the network. + ''' + def __init__(self, no_of_nodes=200, constrained_nodes=0.5, + poor_witnesses=0.2, malicious_nodes=0.1): + self.network = [] + constrained_list = Functions.get_conditioned_ids( + no_of_nodes, constrained_nodes + ) + poor_witness_list = Functions.get_conditioned_ids( + no_of_nodes, poor_witnesses + ) + malicious_list = Functions.get_conditioned_ids( + no_of_nodes, malicious_nodes + ) + + for i in range(no_of_nodes): + if i in constrained_list: + service = np.round(np.random.rand()) + capability = np.round(np.random.rand()) + else: + service = 100 + capability = 100 + note_acc = np.random.rand() if i in poor_witness_list else 1.0 + if i in malicious_list: + self.network.append( + BadMouther.BadMouther(service, capability, note_acc) + ) + else: + self.network.append(Node.Node(service, capability, note_acc)) + + self.reports = [ + [[] for _ in range(no_of_nodes)] for _ in range(no_of_nodes) + ] + + def bootstrap(self, epochs=100): + ''' + Go through the network and perform artificial transactions to develop + reports. + ''' + print(f"\nBootstrapping network for {epochs} epochs:") + Functions.print_progress(0, epochs) + for i in range(1, epochs + 1): + self._artificial_transactions(i) + Functions.print_progress(i, epochs) + print("Done.") + + def _artificial_transactions(self, current_epoch): + ''' + Perform some transactions through the entire network with random + targets. + ''' + for i_node_i in enumerate(self.network): + for j_node_j in enumerate(self.network): + if i_node_i[0] != j_node_j[0]: + service_target = np.round(np.random.rand() * 100) + capability_target = np.round(np.random.rand() * 100) + self.reports[i_node_i[0]][j_node_j[0]].append( + i_node_i[1].send_report( + j_node_j[1], + service_target, + capability_target, + current_epoch + ) + ) + + def save_reports_csv(self, filename="reports.csv"): + ''' + Save a csv on the report data + ''' + with open(filename, "w") as report_csv: + for reports_from_node_i in enumerate(self.reports): + for reports_on_node_j in enumerate(reports_from_node_i[1]): + for report in reports_on_node_j[1]: + report_csv.write( + f"{reports_from_node_i[0]},{reports_on_node_j[0]},{report.csv_output()}\n" + ) diff --git a/TrustModel.py b/TrustModel.py @@ -1,6 +1,9 @@ #!/usr/bin/env python3 -import numpy as np +import sys +import argparse + +import TrustManager ''' A trust model simulation which uses machine learning techniques to find trust. @@ -10,179 +13,20 @@ Date: 2019-03-12 ''' -class Report: - ''' - Report that states the context and how well the node performed at that. - ''' - def __init__(self, service=0, capability=0, note=0, time=0): - self.service = service - self.capability = capability - self.note = note - self.time = time - - def csv_output(self): - ''' - Output contained data in a format suitable for a csv - ''' - return f"{self.service},{self.capability},{self.note},{self.time}" - - -class Node: - ''' - A node in the trust managed network. - ''' - def __init__(self, service=100, capability=100, note_acc=1.0): - self.service = service - self.capability = capability - self.note_taking_acc = note_acc # This is unknown to the trust manager - - def send_report(self, proxy, service_target, capability_target, time): - ''' - Create a report on a given proxy. - ''' - note = self.take_note(proxy, service_target, capability_target) - - return Report(service_target, capability_target, note, time) - - def take_note(self, proxy, service_target, capability_target): - if proxy.service >= service_target and \ - proxy.capability >= capability_target: - note = 1 - elif proxy.service >= service_target or \ - proxy.capability >= capability_target: - note = 0 - else: - note = -1 - - if np.random.rand() < self.note_taking_acc: - return note - return wrong_note(note) - - -class BadMouther(Node): - ''' - A bad mouthing malicious node. - ''' - def take_note(self, proxy, service_target, capability_target): - return -1 - - -class TrustManager: - ''' - Create and control the network. - ''' - def __init__(self, no_of_nodes=200, constrained_nodes=0.5, - poor_witnesses=0.2, malicious_nodes=0.1): - self.network = [] - constrained_list = get_conditioned_ids(no_of_nodes, constrained_nodes) - poor_witness_list = get_conditioned_ids(no_of_nodes, poor_witnesses) - malicious_list = get_conditioned_ids(no_of_nodes, malicious_nodes) - - for i in range(no_of_nodes): - if i in constrained_list: - service = np.round(np.random.rand()) - capability = np.round(np.random.rand()) - else: - service = 100 - capability = 100 - note_acc = np.random.rand() if i in poor_witness_list else 1.0 - if i in malicious_list: - self.network.append(BadMouther(service, capability, note_acc)) - else: - self.network.append(Node(service, capability, note_acc)) - - self.reports = [ - [[] for _ in range(no_of_nodes)] for _ in range(no_of_nodes) - ] - - def bootstrap(self, epochs=100): - ''' - Go through the network and perform artificial transactions to develop - reports. - ''' - print(f"\nBootstrapping network for {epochs} epochs:") - print_progress(0, epochs) - for i in range(1, epochs + 1): - self._artificial_transactions(i) - print_progress(i, epochs) - print("Done.") - - def _artificial_transactions(self, current_epoch): - ''' - Perform some transactions through the entire network with random - targets. - ''' - for i_node_i in enumerate(self.network): - for j_node_j in enumerate(self.network): - if i_node_i[0] != j_node_j[0]: - service_target = np.round(np.random.rand() * 100) - capability_target = np.round(np.random.rand() * 100) - self.reports[i_node_i[0]][j_node_j[0]].append( - i_node_i[1].send_report( - j_node_j[1], - service_target, - capability_target, - current_epoch - ) - ) - - def save_reports_csv(self): - ''' - Save a csv on the report data - ''' - with open("reports.csv", "w") as report_csv: - for reports_from_node_i in enumerate(self.reports): - for reports_on_node_j in enumerate(reports_from_node_i[1]): - for report in reports_on_node_j[1]: - report_csv.write( - f"{reports_from_node_i[0]},{reports_on_node_j[0]},{report.csv_output()}\n" - ) - - -def get_conditioned_ids(no_of_nodes, condition_factor): - ''' - Give an id list of random nodes that fit a given condition. - ''' - conditioned_list = [] - ids = [i for i in range(no_of_nodes)] - - for _ in range(int(no_of_nodes * condition_factor)): - conditioned_list.append(ids.pop(np.random.randint(len(ids)))) - - return conditioned_list - - -def print_progress(current_epoch, total_epochs, progress_len=20): - ''' - Print a progress bar about how far a process has went through it's epochs. - ''' - progress = int(100 * current_epoch / total_epochs) - - if (100 * current_epoch / total_epochs) == progress: - progress_bar_progress = int(progress_len * progress * 0.01) - if progress_bar_progress != 0: - unprogressed = progress_len - progress_bar_progress - else: - unprogressed = progress_len - 1 - progress_bar = "[" - progress_bar += "".join( - ["#" for _ in range(progress_bar_progress - 1)] - ) - progress_bar += "".join(["." for _ in range(unprogressed)]) - progress_bar += "]" - print(f"{progress_bar} {progress}%") - - -def wrong_note(note): - ''' - Get the wrong note randomly - ''' - wrong_notes = {-1, 0, 1} - {note} - return list(wrong_notes)[int(np.round(np.random.rand()))] - - if __name__ == '__main__': - TRUST_MANAGER = TrustManager() - TRUST_MANAGER.bootstrap(1000) - TRUST_MANAGER.save_reports_csv() - print(f"Shape of the reports: {np.shape(TRUST_MANAGER.reports)}") + PARSER = argparse.ArgumentParser(description="Simulate a trust model") + PARSER.add_argument("--create-data", dest="is_creating", + action="store_const", const=True, default=False, + help="Create data and place it in the csv file.") + PARSER.add_argument("-f", "--file", dest="filename", + action="store", default="reports.csv", + help="Specify the file to read from or write to.") + ARGS = PARSER.parse_args() + + if len(sys.argv) == 1: + PARSER.print_help() + + if ARGS.is_creating: + TRUST_MANAGER = TrustManager.TrustManager() + TRUST_MANAGER.bootstrap(500) + TRUST_MANAGER.save_reports_csv(ARGS.filename)