updates Readme, initializes folder
Vorschlag für Vorgehen
This commit is contained in:
608
BlueJ-Origin/LABOR.java
Normal file
608
BlueJ-Origin/LABOR.java
Normal file
@@ -0,0 +1,608 @@
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import javax.swing.event.*;
|
||||
import java.awt.*;
|
||||
import java.text.*;
|
||||
|
||||
public class LABOR
|
||||
{
|
||||
Object Perzeptron;
|
||||
Method methodeLernen;
|
||||
Method methodeBerechne;
|
||||
ArrayList<Datapoint> Trainingset = new ArrayList<Datapoint>();
|
||||
ArrayList<FormVisualization> listener = new ArrayList<FormVisualization>();
|
||||
|
||||
/* Das Labor-Objekt benötigt bei der Objekterzeugung ein Perzeptron, das
|
||||
* vorher schon erzeugt werden musste. Man kann es in BlueJ übergeben,
|
||||
* indem man einfach auf das Objekt klickt.
|
||||
*/
|
||||
public LABOR(Object perzeptron) throws Exception {
|
||||
Perzeptron = perzeptron;
|
||||
Class<?> pClass = Perzeptron.getClass();
|
||||
Method[] methods = pClass.getDeclaredMethods();
|
||||
ArrayList<Method> mlist = new ArrayList<Method>();
|
||||
|
||||
// Auswertemethode finden
|
||||
for(int i=0;i<methods.length;++i){
|
||||
if((methods[i].getReturnType().getName()).equals("double")
|
||||
&& !Modifier.isPrivate( methods[i].getModifiers())
|
||||
&& !Modifier.isProtected( methods[i].getModifiers())
|
||||
&& methods[i].getParameterCount()==2
|
||||
&& methods[i].getParameterTypes()[0].getName().equals("double")
|
||||
&& methods[i].getParameterTypes()[1].getName().equals("double")
|
||||
){
|
||||
mlist.add(methods[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(mlist.size()==0){
|
||||
JOptionPane.showMessageDialog(null,"Es wurde keine passende Methode zum Auswerten eines Datenpunktes gefunden.\n" +
|
||||
"Es wird erwartet, dass es eine Methode gibt, die als Parameter zwei double-Werte bekommt und\n"+
|
||||
"einen double-Wert zurückliefert.\n\n"+
|
||||
"Beispiel:\n"+
|
||||
"public double berechneAusgabe(double x, double y)");
|
||||
throw new Exception("Keine Auswertungsmethode für das Perzeptron gefunden");
|
||||
}
|
||||
else if(mlist.size()==1){
|
||||
methodeBerechne=mlist.get(0);
|
||||
}
|
||||
else{
|
||||
FormMethodSelector formMS = new FormMethodSelector( mlist.toArray(new Method[0] ), FormMethodSelector.BERECHNE );
|
||||
formMS.setVisible(true);
|
||||
if(formMS.selectedMethodName==null){
|
||||
throw new Exception("Keine Auswertungsmethode für das Perzeptron gewählt");
|
||||
}
|
||||
else{
|
||||
for(int i=0;i<mlist.size();++i){
|
||||
if(mlist.get(i).getName().equals(formMS.selectedMethodName)){
|
||||
methodeBerechne=mlist.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mlist.clear();
|
||||
// Trainingsmethode finden
|
||||
for(int i=0;i<methods.length;++i){
|
||||
if((methods[i].getReturnType().getName()).equals("void")
|
||||
&& !Modifier.isPrivate( methods[i].getModifiers())
|
||||
&& !Modifier.isProtected( methods[i].getModifiers())
|
||||
&& methods[i].getParameterCount()==3
|
||||
&& methods[i].getParameterTypes()[0].getName().equals("double")
|
||||
&& methods[i].getParameterTypes()[1].getName().equals("double")
|
||||
&& methods[i].getParameterTypes()[1].getName().equals("double")
|
||||
){
|
||||
mlist.add(methods[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(mlist.size()==0){
|
||||
JOptionPane.showMessageDialog(null,"Es wurde keine passende Methode zum Lernen eines Traingsdatenpunktes gefunden.\n" +
|
||||
"Es wird erwartet, dass es eine Methode gibt, die als Parameter drei double-Werte bekommt und\n"+
|
||||
"keinen Wert zurückliefert.\n\n"+
|
||||
"Beispiel:\n"+
|
||||
"public void lerne(double x, double y, double label)");
|
||||
throw new Exception("Keine Trainingssmethode für das Perzeptron gefunden");
|
||||
}
|
||||
else if(mlist.size()==1){
|
||||
methodeLernen=mlist.get(0);
|
||||
}
|
||||
else{
|
||||
FormMethodSelector formMS = new FormMethodSelector( mlist.toArray(new Method[0] ), FormMethodSelector.TRAINIERE );
|
||||
formMS.setVisible(true);
|
||||
if(formMS.selectedMethodName==null){
|
||||
throw new Exception("Keine Methode zum Training für das Perzeptron gewählt");
|
||||
}
|
||||
else{
|
||||
for(int i=0;i<mlist.size();++i){
|
||||
if(mlist.get(i).getName().equals(formMS.selectedMethodName)){
|
||||
methodeLernen=mlist.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hier kann man eine Datei öffnen, die Trainingsdaten enthält. Sie endet mit .csv und muss
|
||||
* sich im selben Verzeichnis, wie das BlueJ-Projekt befinden. Oftmals heißt so eine Datei
|
||||
* "daten.csv"
|
||||
*/
|
||||
public void ladeTrainingsdaten(String Dateiname){
|
||||
Trainingset.clear();
|
||||
File file= new File(Dateiname);
|
||||
if(!file.exists()){
|
||||
file= new File(Dateiname + ".csv");
|
||||
if(!file.exists()){
|
||||
JOptionPane.showMessageDialog(null,"Die Datei mit dem Bezeichner " + Dateiname + "\n" +
|
||||
"konnte nicht gefunden werden. Prüfen Sie, ob sich wirklich diese Datei\n" +
|
||||
"in dem Verzeichnis befindet und ob auch die Endung stimmt.\n"+
|
||||
"Üblicherweise lautet die Dateiendung .csv");
|
||||
return;
|
||||
}
|
||||
}
|
||||
try (Scanner scanner = new Scanner(file)) {
|
||||
scanner.nextLine();
|
||||
NumberFormat format = NumberFormat.getInstance(Locale.GERMAN);
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
String[] tokens = line.split(";");
|
||||
Datapoint d = new Datapoint();
|
||||
d.label=tokens[1].equals("1")?1:0;
|
||||
|
||||
Number number = format.parse(tokens[2]);
|
||||
double dv = number.doubleValue();
|
||||
d.x1=dv;
|
||||
number = format.parse(tokens[3]);
|
||||
dv = number.doubleValue();
|
||||
d.x2=dv;
|
||||
Trainingset.add(d);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
JOptionPane.showMessageDialog(null,"Die Datei scheint fehlerhaft zu sein.\n" +
|
||||
"Sie konnte leider nicht gelesen werden.");
|
||||
}
|
||||
UpdateListener();
|
||||
JOptionPane.showMessageDialog(null,"Es wurden Trainingsdaten mit " + Trainingset.size() + " Datenpunkten eingelesen");
|
||||
|
||||
}
|
||||
|
||||
/* Die Delta-Lernregel wird einmal für
|
||||
* alle Trainingsdatenpunkte durchgeführt.
|
||||
*/
|
||||
public void trainiereEinmal(){
|
||||
ArrayList<Datapoint> set = (ArrayList<Datapoint>)Trainingset.clone();
|
||||
Collections.shuffle(set);
|
||||
for (Datapoint dp : set) {
|
||||
Object[] par = new Object[3];
|
||||
par[0]=dp.x1;
|
||||
par[1]=dp.x2;
|
||||
par[2]=dp.label;
|
||||
try{
|
||||
methodeLernen.invoke(Perzeptron, par);
|
||||
}
|
||||
catch(Exception exc){
|
||||
|
||||
}
|
||||
}
|
||||
UpdateListener();
|
||||
}
|
||||
|
||||
private double perzBerechne(double x1, double x2){
|
||||
Object[] par = new Object[2];
|
||||
par[0]=x1;
|
||||
par[1]=x2;
|
||||
double ret = -1;
|
||||
try{
|
||||
ret= (double)methodeBerechne.invoke(Perzeptron,par);
|
||||
}
|
||||
catch(Exception e){}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int testeAnhandTrainingsdaten(){
|
||||
int fehler=0;
|
||||
for(Datapoint dp: Trainingset){
|
||||
Object[] par = new Object[2];
|
||||
par[0]=dp.x1;
|
||||
par[1]=dp.x2;
|
||||
try{
|
||||
double l = (double)methodeBerechne.invoke(Perzeptron,par);
|
||||
if(l!=dp.label)
|
||||
fehler++;
|
||||
}catch(Exception exc){
|
||||
|
||||
}
|
||||
}
|
||||
return fehler;
|
||||
}
|
||||
|
||||
/*
|
||||
* Die Methode testet, ob alle Trainingsdaten richtig klassifiziert werden.
|
||||
*/
|
||||
public void überprüfePerzeptron(){
|
||||
int fehler = testeAnhandTrainingsdaten();
|
||||
if(fehler==0){
|
||||
JOptionPane.showMessageDialog(null,"Alle Trainingsdaten wurden richtig klassifiziert.\n" +
|
||||
"Ein weiteres Training ist nicht erforderlich");
|
||||
}
|
||||
else{
|
||||
JOptionPane.showMessageDialog(null,"Es wurden " + fehler + " Datenpunkte der Trainingsdaten\n" +
|
||||
"falsch klassifiziert.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Die Delta-Lernregel wird auf alle Trainingsdaten angewendet,
|
||||
* bis entweder alle Trainingsdaten richtig klassifiziert werden,
|
||||
* oder die Anzahl der Wiederholungen den Wert des Übergabeparameters
|
||||
* überschreiten.
|
||||
*/
|
||||
public void trainiere(int maximaleAnzahlAnDurchläufen){
|
||||
for(int i=0;i<maximaleAnzahlAnDurchläufen;++i){
|
||||
trainiereEinmal();
|
||||
if(testeAnhandTrainingsdaten()==0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ein Fenster öffnet sich, das die Trainingsdaten anzeigt und auch,
|
||||
* wir das Perzeptron die lineare Separierung durchführt.
|
||||
*/
|
||||
public void visualisiere(){
|
||||
FormVisualization f = new FormVisualization(this);
|
||||
listener.add(f);
|
||||
}
|
||||
|
||||
private void UpdateListener(){
|
||||
for(FormVisualization f: listener){
|
||||
f.canvas.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
class MyCanvas extends JComponent
|
||||
{
|
||||
FormVisualization viz;
|
||||
|
||||
public MyCanvas(FormVisualization f){
|
||||
super();
|
||||
viz=f;
|
||||
this.setBackground(Color.WHITE);
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics g){
|
||||
super.paintComponents(g);
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.clearRect(0, 0, 500, 500);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
double minX1=-0.1;
|
||||
double minX2=-0.1;
|
||||
double maxX1=3;
|
||||
double maxX2=3;
|
||||
|
||||
for(Datapoint d : viz.training){
|
||||
if(d.x1>maxX1) maxX1=d.x1;
|
||||
if(d.x2>maxX2) maxX2=d.x2;
|
||||
if(d.x1<minX1) minX1=d.x1;
|
||||
if(d.x2<minX2) minX2=d.x2;
|
||||
}
|
||||
|
||||
Color green = new Color(144,238,144);
|
||||
Color red = new Color(240,128,128);
|
||||
|
||||
for(double y=0;y<500;y++){
|
||||
for(double x=0;x<500;x++){
|
||||
Datapoint p = new Datapoint();
|
||||
p.x1=minX1 + (x)/500.0*(maxX1-minX1);
|
||||
p.x2=minX2 + (500.0-y)/500.0*(maxX2-minX2);
|
||||
double label=viz.labor.perzBerechne(p.x1, p.x2);
|
||||
if(label==1){
|
||||
g2d.setColor(green);
|
||||
}
|
||||
else{
|
||||
g2d.setColor(red);
|
||||
}
|
||||
g2d.fillRect((int)x, (int)y, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Achsen
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.setStroke(new BasicStroke(3));
|
||||
double vaxs = ((0-minX1)/(maxX1-minX1))*500.0;
|
||||
double vays = 500;
|
||||
double vaxe = ((0-minX1)/(maxX1-minX1))*500.0;
|
||||
double vaye = 0;
|
||||
ZeichnePfeil(g2d,(int)vaxs, (int)vays, (int)vaxe, (int)vaye,10,10);
|
||||
|
||||
double haxs = 0;
|
||||
double hays = 500.0-((0-minX2)/(maxX2-minX2))*500.0;
|
||||
double haxe = 500;
|
||||
double haye = 500.0-((0-minX2)/(maxX2-minX2))*500.0;
|
||||
ZeichnePfeil(g2d,(int)haxs, (int)hays, (int)haxe, (int)haye,10,10);
|
||||
|
||||
g2d.setFont(new Font("TimesRoman", Font.PLAIN, 16));
|
||||
g2d.drawString("x", 477, (int)(haye-4));
|
||||
g2d.setFont(new Font("TimesRoman", Font.PLAIN, 10));
|
||||
g2d.drawString("1", 483, (int)(haye-2));
|
||||
|
||||
g2d.setFont(new Font("TimesRoman", Font.PLAIN, 16));
|
||||
g2d.drawString("x", (int)(vaxe+4), 21);
|
||||
g2d.setFont(new Font("TimesRoman", Font.PLAIN, 10));
|
||||
g2d.drawString("2", (int)(vaxe+11), 23);
|
||||
|
||||
// Trainingspunkte
|
||||
g2d.setStroke(new BasicStroke(1));
|
||||
for(Datapoint d : viz.training){
|
||||
if(d.label==0){
|
||||
g2d.setColor(Color.RED);
|
||||
}
|
||||
else{
|
||||
g2d.setColor(Color.GREEN);
|
||||
}
|
||||
double px = ((d.x1-minX1)/(maxX1-minX1))*500.0;
|
||||
double py = 500.0-((d.x2-minX2)/(maxX2-minX2))*500.0;
|
||||
|
||||
g.fillOval((int)px-4, (int)py-4, 9, 9);
|
||||
g2d.setColor(Color.BLACK);
|
||||
g.drawOval((int)px-4, (int)py-4, 9, 9);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ZeichnePfeil(Graphics2D g, int x1, int y1, int x2, int y2, int d, int h) {
|
||||
int dx = x2 - x1, dy = y2 - y1;
|
||||
double D = Math.sqrt(dx*dx + dy*dy);
|
||||
double xm = D - d, xn = xm, ym = h, yn = -h, x;
|
||||
double sin = dy / D, cos = dx / D;
|
||||
|
||||
x = xm*cos - ym*sin + x1;
|
||||
ym = xm*sin + ym*cos + y1;
|
||||
xm = x;
|
||||
|
||||
x = xn*cos - yn*sin + x1;
|
||||
yn = xn*sin + yn*cos + y1;
|
||||
xn = x;
|
||||
|
||||
int[] xpoints = {x2, (int) xm, (int) xn};
|
||||
int[] ypoints = {y2, (int) ym, (int) yn};
|
||||
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
g.fillPolygon(xpoints, ypoints, 3);
|
||||
}
|
||||
|
||||
public Datapoint isClicked(double x, double y){
|
||||
Datapoint ret = null;
|
||||
|
||||
double minX1=-0.1;
|
||||
double minX2=-0.1;
|
||||
double maxX1=3;
|
||||
double maxX2=3;
|
||||
|
||||
for(Datapoint d : viz.training){
|
||||
if(d.x1>maxX1) maxX1=d.x1;
|
||||
if(d.x2>maxX2) maxX2=d.x2;
|
||||
if(d.x1<minX1) minX1=d.x1;
|
||||
if(d.x2<minX2) minX2=d.x2;
|
||||
}
|
||||
|
||||
for(Datapoint d : viz.training){
|
||||
double px = ((d.x1-minX1)/(maxX1-minX1))*500.0;
|
||||
double py = 500.0-((d.x2-minX2)/(maxX2-minX2))*500.0;
|
||||
if(Math.sqrt((px-x)*(px-x)+(py-y)*(py-y))<=5.0)
|
||||
return d;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
class Datapoint {
|
||||
public double x1;
|
||||
public double x2;
|
||||
public double label;
|
||||
}
|
||||
|
||||
public class FormMethodSelector extends javax.swing.JDialog implements ListSelectionListener {
|
||||
Method[] methods;
|
||||
public String selectedMethodName;
|
||||
int type;
|
||||
public static final int BERECHNE=1;
|
||||
public static final int TRAINIERE=2;
|
||||
|
||||
public FormMethodSelector(Method[] methods, int type) {
|
||||
setModal(true);
|
||||
initComponents();
|
||||
this.methods=methods;
|
||||
this.type=type;
|
||||
DefaultListModel listModel = new DefaultListModel();
|
||||
for(int i=0;i<methods.length;++i){
|
||||
listModel.addElement(methods[i].getName());
|
||||
}
|
||||
jListMethods.setModel(listModel);
|
||||
jListMethods.addListSelectionListener(this);
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jListMethods = new javax.swing.JList<>();
|
||||
jButtonOk = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
if(type==BERECHNE)
|
||||
jLabel1.setText("Wählen Sie die Methode aus, die bewirkt, dass das Perzeptron einen Datenpunkt auswertet:");
|
||||
else
|
||||
jLabel1.setText("Wählen Sie die Methode aus, die bewirkt, dass das Perzeptron einen Schritt der Delta-Lernregel durchführt:");
|
||||
|
||||
jListMethods.setModel(new javax.swing.AbstractListModel<String>() {
|
||||
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
|
||||
public int getSize() { return strings.length; }
|
||||
|
||||
public String getElementAt(int i) { return strings[i]; }
|
||||
});
|
||||
jScrollPane1.setViewportView(jListMethods);
|
||||
|
||||
jButtonOk.setText("Weiter");
|
||||
jButtonOk.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
jButtonOkActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
|
||||
.addComponent(jScrollPane1)
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(jButtonOk))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(jButtonOk)
|
||||
.addContainerGap(10, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>
|
||||
|
||||
private void jButtonOkActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
this.setVisible(false);
|
||||
}
|
||||
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
selectedMethodName = jListMethods.getSelectedValue();
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify
|
||||
private javax.swing.JButton jButtonOk;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JList<String> jListMethods;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
// End of variables declaration
|
||||
}
|
||||
public class FormVisualization extends javax.swing.JFrame {
|
||||
ArrayList<Datapoint> training;
|
||||
LABOR labor;
|
||||
|
||||
public FormVisualization(){
|
||||
initComponents();
|
||||
training = new ArrayList<Datapoint>();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public FormVisualization(LABOR l) {
|
||||
initComponents();
|
||||
training = l.Trainingset;
|
||||
labor=l;
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">
|
||||
private void initComponents() {
|
||||
|
||||
canvas = new MyCanvas(this);
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
jButtonClearDatapoints = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
getContentPane().setLayout(null);
|
||||
|
||||
canvas.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mousePressed(java.awt.event.MouseEvent evt) {
|
||||
canvasMouseClicked(evt);
|
||||
}
|
||||
});
|
||||
getContentPane().add(canvas);
|
||||
canvas.setBounds(10,10,500, 500);
|
||||
|
||||
jLabel1.setText("Rechter Mausklick: Datenpunkt mit Label 0 wird hinzugefügt");
|
||||
getContentPane().add(jLabel1);
|
||||
jLabel1.setLocation(20, 540);
|
||||
jLabel1.setSize(500, 20);
|
||||
|
||||
jLabel2.setText("Linker Mausklick: Datenpunkt mit Label 1 wird hinzugefügt");
|
||||
getContentPane().add(jLabel2);
|
||||
jLabel2.setLocation(20,520);
|
||||
jLabel2.setSize(500, 20);
|
||||
|
||||
jLabel3.setText("Klick auf Datenpunkt: Datenpunkt wird entfernt");
|
||||
getContentPane().add(jLabel3);
|
||||
jLabel3.setLocation(20,560);
|
||||
jLabel3.setSize(500, 20);
|
||||
|
||||
jButtonClearDatapoints.setActionCommand("<html><center>Alle Datenpunkte<br>löschen</center></html>");
|
||||
jButtonClearDatapoints.setLabel("<html><div align=\"center\">Alle Datenpunkte<br>löschen</div></html>");
|
||||
jButtonClearDatapoints.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
public void mouseClicked(java.awt.event.MouseEvent evt) {
|
||||
jButtonClearDatapointsMouseClicked(evt);
|
||||
}
|
||||
});
|
||||
getContentPane().add(jButtonClearDatapoints);
|
||||
jButtonClearDatapoints.setBounds(370, 520, 140, 60);
|
||||
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosing(java.awt.event.WindowEvent e) {
|
||||
CloseHandler();
|
||||
}
|
||||
});
|
||||
|
||||
pack();
|
||||
this.setSize(540, 630);
|
||||
}// </editor-fold>
|
||||
|
||||
private void CloseHandler(){
|
||||
labor.listener.remove(this);
|
||||
}
|
||||
|
||||
private void canvasMouseClicked(java.awt.event.MouseEvent evt) {
|
||||
Datapoint clickedPoint=canvas.isClicked(evt.getPoint().getX(), evt.getPoint().getY());
|
||||
if(clickedPoint!=null){
|
||||
training.remove(clickedPoint);
|
||||
}
|
||||
else{
|
||||
double l=0;
|
||||
if(SwingUtilities.isLeftMouseButton(evt)) l=1;
|
||||
Datapoint p = new Datapoint();
|
||||
|
||||
double x = evt.getPoint().getX();
|
||||
double y = 500.0-evt.getPoint().getY();
|
||||
double minX1=-0.1;
|
||||
double minX2=-0.1;
|
||||
double maxX1=3;
|
||||
double maxX2=3;
|
||||
for(Datapoint d : training){
|
||||
if(d.x1>maxX1) maxX1=d.x1;
|
||||
if(d.x2>maxX2) maxX2=d.x2;
|
||||
if(d.x1<minX1) minX1=d.x1;
|
||||
if(d.x2<minX2) minX2=d.x2;
|
||||
}
|
||||
|
||||
p.label=l;
|
||||
p.x1=minX1 + x/500.0*(maxX1-minX1);
|
||||
p.x2=minX2 + y/500.0*(maxX2-minX2);
|
||||
training.add(p);
|
||||
}
|
||||
canvas.repaint();
|
||||
|
||||
labor.UpdateListener();
|
||||
}
|
||||
|
||||
private void jButtonClearDatapointsMouseClicked(java.awt.event.MouseEvent evt) {
|
||||
training.clear();
|
||||
labor.UpdateListener();
|
||||
canvas.repaint();
|
||||
}
|
||||
|
||||
MyCanvas canvas;
|
||||
private javax.swing.JButton jButtonClearDatapoints;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
}
|
||||
|
||||
}
|
||||
25
BlueJ-Origin/daten.csv
Normal file
25
BlueJ-Origin/daten.csv
Normal file
@@ -0,0 +1,25 @@
|
||||
Beschriftung;Klasse;Kalorien;Eiweiß
|
||||
Erbsen;1;37;3
|
||||
Gurken;1;4;0
|
||||
Karotten;1;29;1
|
||||
Spinat;1;12;2
|
||||
Tomaten;1;16;1
|
||||
Apfel;1;49;0
|
||||
Aprikose;1;49;1
|
||||
Banane;1;70;1
|
||||
Wassermelone;1;12;0
|
||||
Aal;0;204;9
|
||||
Forelle;0;50;10
|
||||
Thunfisch;0;239;22
|
||||
Lachs;0;137;13
|
||||
Makrele;0;124;12
|
||||
Ente;0;192;15
|
||||
Pute;0;122;23
|
||||
Schwein;0;167;18
|
||||
Croissant;0;280;0
|
||||
Donut;0;295;3
|
||||
Semmel;0;276;7
|
||||
Toastbrot;0;326;10
|
||||
Weizenbrot;0;235;8
|
||||
Rührkuchen;0;430;6
|
||||
Roggenbrot;0;243;6
|
||||
|
16
README.md
16
README.md
@@ -1,3 +1,19 @@
|
||||
# PerzeptronLabor
|
||||
|
||||
Eine Portierung des Perzeptron Labors von Christoph Gräßl für die Online-IDE, entwickelt unter MIT-Lizenz.
|
||||
|
||||
## Vorschlag fürs Vorgehen:
|
||||
|
||||
1. Einlesen der Datenpunkte in der CSV-Datei (`ladeTrainigsdaten`)
|
||||
2. Einrichten eines grafischen Koordinatensystems
|
||||
3. Visualisieren der eingelesenen Datenpunkte
|
||||
4. Visualisieren der kategorisierten Bereiche (rote/grüne Fläche)
|
||||
5. Hinzufügen neuer Datenpunkte durch Mausklick (rechts/links)
|
||||
6. Methode `trainiereEinmal`, mit Button#
|
||||
7. Methode `überprüfePerzeptron`
|
||||
8. Überlegen: wie umsetzen: trainiere n-Mal?
|
||||
|
||||
Entwicklung jedes Schrittes auf eigenem Branch, mergen in main, wenn zwei von uns einverstanden sind.
|
||||
|
||||
Verbesserungsvorschläge sind herzlich willkommen!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user