From e38de94bc6ae88a21cf245d5c648744d00d826de Mon Sep 17 00:00:00 2001
From: Simon Adick <sa911412@fh-muenster.de>
Date: Sun, 7 May 2023 00:30:52 +0200
Subject: [PATCH] =?UTF-8?q?feat:=20Perzeptron=20hinzugef=C3=BCgt?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 algorithm/__init__.py               |  0
 algorithm/pla/__init__.py           |  0
 algorithm/pla/perceptron.py         | 29 +++++++++++++++++++++++++
 algorithm/pla/test_perceptron.py    | 33 +++++++++++++++++++++++++++++
 algorithm/pla/transfer_functions.py |  9 ++++++++
 5 files changed, 71 insertions(+)
 create mode 100644 algorithm/__init__.py
 create mode 100644 algorithm/pla/__init__.py
 create mode 100644 algorithm/pla/perceptron.py
 create mode 100644 algorithm/pla/test_perceptron.py
 create mode 100644 algorithm/pla/transfer_functions.py

diff --git a/algorithm/__init__.py b/algorithm/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/algorithm/pla/__init__.py b/algorithm/pla/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/algorithm/pla/perceptron.py b/algorithm/pla/perceptron.py
new file mode 100644
index 0000000..93ecac9
--- /dev/null
+++ b/algorithm/pla/perceptron.py
@@ -0,0 +1,29 @@
+import numpy
+
+
+class Perceptron:
+
+    def __init__(self, start_weights: list, threshold: float, transfer_function):
+        # Das erste Gewicht ist -threshold. Hierdurch muss der Threshold nicht bei jeder Summe mitberechnet werden
+        self.weights = [- threshold] + start_weights
+        self.transfer_function = transfer_function
+
+    def classify(self, features: list):
+        """
+        Klassifiziert einen Vektor an Merkmalen.
+        Die Dimension des Merkmalsvektors muss dabei mt der Dimension des Startgewichtvektors übereinstimmen.
+        """
+
+        if len(features) != len(self.weights) - 1:
+            print("Es wurden nicht genug Features übergeben")
+            return
+
+        # Das erste Merkmal m_0 ist konstant 1
+        all_features = [1] + features
+        transposed_weights = numpy.transpose(self.weights)
+
+        # Multipliziere die transponierten mit dem Merkmalsvektor
+        result = numpy.matmul(transposed_weights, all_features)
+
+        # Wende die Aktivierungsfunktion auf das Ergebnis an
+        return self.transfer_function(result)
diff --git a/algorithm/pla/test_perceptron.py b/algorithm/pla/test_perceptron.py
new file mode 100644
index 0000000..bc1ac98
--- /dev/null
+++ b/algorithm/pla/test_perceptron.py
@@ -0,0 +1,33 @@
+from algorithm.pla.perceptron import Perceptron
+from algorithm.pla.transfer_functions import normalized_tanh
+from server.testserver import get_testdata, send_result
+
+
+def test_perceptron():
+    response = get_testdata("perceptron_processing")
+    results = []
+
+    for data in response['data']:
+        # Hole die einzelnen Traningsdaten
+        test_id = data['id']
+        all_weights = data['weights']
+        features = data['input']
+
+        # Der Threshold ist der erste Wert in der Liste.
+        # Der Rest sind die anderen Gewichte
+        threshold = all_weights[0] * -1
+        weights = all_weights[1: len(all_weights)]
+
+        # Klassifizere die Trainingsdaten
+        perceptron = Perceptron(weights, threshold, normalized_tanh)
+        result = perceptron.classify(features)
+
+        # Hänge das Ergebnis in der Liste an
+        results.append({'id': test_id, 'value': result})
+
+    # Sende die Ergebnis-Liste zurück an das IUL
+    send_result('perceptron_processing', {'session': response['session'], 'results': results})
+
+
+if __name__ == '__main__':
+    test_perceptron()
diff --git a/algorithm/pla/transfer_functions.py b/algorithm/pla/transfer_functions.py
new file mode 100644
index 0000000..3a79631
--- /dev/null
+++ b/algorithm/pla/transfer_functions.py
@@ -0,0 +1,9 @@
+import numpy
+
+
+def normalized_tanh(value):
+    """ Der Tangens hyperbolicus hat einen Wertebereich von ]-1, 1[. Diese Funktion normiert den Wertebereich zu ]0, 1["""
+
+    # Verschiebe den Tangenz um 1 nach oben --> Wertebereich ]0, 2[
+    # Teile durch Zwei --> Wertebereich ]0, 1[
+    return (numpy.tanh(value) + 1) / 2
\ No newline at end of file
-- 
GitLab