Einzelnen Beitrag anzeigen

Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#7

Re: Prozentuale Ähnlichkeit (Mustererkennung)

  Alt 9. Okt 2007, 10:07
So ich habe mal ein schmutziges schnelles Programm geschrieben:

Ich habe 1000 Zeilen in der Daten.txt (liegt bei)
Damit es nicht zu kompliziert wird, habe ich mich auf die erste Zeile in der "Datenbank" beschränkt, die auf Ähnlichkeit mit den restlichen 999 Zeilen zu prüfen ist.
Wir sehen ab der Zeile 2 bis 1000 nach, wie ähnlich sich die Zeilen sind.

Ich verwende folgende Formel,
Ergebnis[x,i]:=(daten[x,i]/daten[1,i])/5;

wobei
x von 2 nach 1000 alle Zeilen durchläuft
i von 2 nach 6 alle Spalten, bis auf die erste Spalte, durchlaufen werden. (Mit der ersten Spalte habe ich noch ein Problem, sie verfälscht mein Ergebnis.) Die Ergebnisse speichere ich in das Array Ergebnis[1..1000,1..7], wobei die ich die Spaltenergebnisse in Ergebnis[1..1000,2..6] und die Summe/5 (5=Anzahl der Spalten) in Position 7 (Ergebnis[1..1000,7]) speichere.


Vorgehensweise:
Daten einlesen.
Alle Nullen in 0.01 ändern, weil ich ein Problem mit Division mit 0 bekomme.
Negative Ergebnisse unserer Berechnung werden in positive Zahlen mit *-1 überführt.
Einzelergebnisse von Spalte 2 bis 6 in 7 speichern.
Ausgabe der Ergebnisse beschränken auf Zahlen kleiner als 1 mit: if (ergebnis[x,7] < 1) then ...
Delphi-Quellcode:
program ReadDaten;

{$APPTYPE CONSOLE}
uses math;
var f:textfile;
    Feldnamen:string;
    Daten:Array[1..1000,1..6] of real;
    Ergebnis:Array[1..1000,1..7] of real;
    x,i:integer;
    h:real;
    AnzahlZeilen:integer;

function Runden(x: Extended; Stellen: Byte): Extended;
begin
Result:= Round(x * IntPower(10, Stellen))/IntPower(10, Stellen);
end;

begin

// DATEN in Array Daten einlese
assignfile(f,'C:\Daten.txt');
Reset(f);
readln(f,Feldnamen);
for X:=1 to 1000 do
    begin
    for i:=1 to 6 do
        begin
        read(f,daten[x,i]);
        end;
end;
closefile(f);


//Wir stellen sicher, dass keine 0 vorkommt und ersetzten diese durch 0.01;
for x:=1 to 1000 do
     begin
     for i:=1 to 6 do if daten[x,i]=0 then daten[x,i]:=0.01;
     end;


// Wir gehen alle Zeilen und Spalten in Muster durch und speichern das Ergebnis:
for x:=2 to 1000 do
    begin
    for i:=2 to 6 do
        begin
        // Wir dividieren durch die Anzahl der Daten, hier 5:
        Ergebnis[x,i]:=(daten[x,i]/daten[1,i])/5;
        //<Negative Ergebnisse bringen nicht das resultat, daher *-1
        if Ergebnis[x,i]< 0 then ergebnis[x,i]:=ergebnis[x,i]*-1;
        //Ursprünglich:
        {
        Ergebnis[x,i]:=(daten[x,i]/daten[1,i]);
        }


        end;//i..
    //Ergebnis von Spalte 2 bis 6 in 7 speichern:
    ergebnis[x,7]:=0;
    for I:=2 to 6 do ergebnis[x,7]:=ergebnis[x,7]+ergebnis[x,i];


// Die Ausgabe wird beschränkt:
if (ergebnis[x,7] < 1) then
    begin
    writeln('Datensatz: ',x);
    for i:=2 to 6 do write(daten[1,i]:2:2,' ');writeln;
    for i:=2 to 6 do write(daten[x,i]:2:2,' ');writeln;
    for i:=2 to 6 do write(ergebnis[x,i]:2:2,' ');writeln;
    writeln('Ergebnis: ',ergebnis[x,7]:2:2);writeln;
    writeln('Taste');
    readln;
end;

end;//x..
writeln('Ende - ENTER');
readln;

end.
Ach ja, Datensatz 94 und 905 entspricht fast dem ersten Datensatz.
Wie könnte man es besser lösen?
Nachtrag: Die Datei Daten.txt bitte als C:\daten.txt speichern. Ich habe keine Fehlerabfragen zu besseren Übersichtlichkeit eingebaut.
Angehängte Dateien
Dateityp: txt daten_849.txt (30,3 KB, 7x aufgerufen)
  Mit Zitat antworten Zitat