Hallo, das ist Sumiyama Wasser.
Ich werde die Fortsetzung der vorherigen [Einführung in die Informatik Nr. 0: Versuch maschinelles Lernen] schreiben. Lassen Sie uns die k-Durchschnittsmethode in Java implementieren.
Im letzten Artikel habe ich vorgestellt, was Sie endlich mit Clustering machen können.
Heute werde ich in Teil 1 das Konzept der "Koordinaten" erklären und implementieren, um die Position dieses Punktes als numerische Daten auszudrücken [^ 1].
Ich habe in diesem Artikel über die Vorbereitung dieser Umgebung geschrieben. Hinweise zum Starten der Neuentwicklung mit IntelliJ + Gradle + SpringBoot + JUnit5 (Jupiter)
Wie ich in 0th erwähnt habe, ist das Ziel des Clusters "Zugriffszeit und Verweilzeit der Website" oder "Nutzungsdatum und Nutzungsbetrag der Kreditkarte". Es sind numerische Daten, die im wirklichen Leben existieren, wie z.
Wenn Sie jedoch die Technik des Clustering erlernen, ist es einfacher, das Konzept zu verstehen, wenn es einmal abstrahiert und als Position auf einer Ebene oder einem Festkörper entschieden wurde. Daher werde ich mit der Diskussion mit "so etwas" fortfahren.
Abgesehen von der schwierigen Geschichte sehen Sie bitte die Abbildung. Wie in der Abbildung gezeigt, wird ein Punkt, der 0,8 in horizontaler Richtung und 0,9 in vertikaler Richtung platziert ist, als [0,8, 0,9] ausgedrückt. Dies wird als Position ** bezeichnet.
Dieser richtig platzierte Punkt kann nun als Daten mit dem numerischen Wert [0,8,0,9] behandelt werden.
Sollen wir es etwas weiter ausbauen?
Wie in der Abbildung gezeigt, wird angenommen, dass die Position 0,8 horizontal, 0,9 vertikal und 1,2 hoch ist, wenn Sie Punkte in einem dreidimensionalen Volumenkörper entsprechend platzieren. Dann kann dieser Punkt ausgedrückt werden als [0,8, 0,9, 1,2].
Wenn Sie Lust dazu haben, können Sie es numerisch wie [0,8, 0,9, 1,2, 1,7, 0,1] ausdrücken, unabhängig davon, ob es sich um 4 oder 10 Dimensionen handelt. Bisher kann es jedoch mit einer Figur gezeichnet werden, die vom menschlichen Auge verstanden werden kann. Da die 3. Dimension bestenfalls ist, machen Sie bitte keine Figur ...
Ich habe Java erst in letzter Zeit berührt, daher werde ich es in Java implementieren.
Derzeit erhöht sich die Achse jedes Mal auf 2D, 3D, 4D
Da der Datentyp "numerischer Wert" ist und "mehrere Zahlen gehalten werden", ist Double Type List meiner Meinung nach gut für die Position eines Punktes.
Wie ich in 0th geschrieben habe, werden schließlich mehrere Punkte verarbeitet, sodass es mehrere Doppellisten gibt. damit,
private final List<List<Double>> points;
Wenn Sie eine Klasse mit einem solchen Feld erstellen, können Sie "zu analysierende Daten" in der Klasse ausdrücken.
Danach können Sie Daten im Konstruktor speichern.
Ich frage mich, ob die Anforderungen für das Speichern von Daten so sein werden
Also, wenn Sie dies implementieren
package net.tan3sugarless.clusteringsample.lib.data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.Value;
import net.tan3sugarless.clusteringsample.exception.DimensionNotUnifiedException;
import net.tan3sugarless.clusteringsample.exception.NullCoordinateException;
import java.util.List;
/**
*Koordinatensatz auf dem euklidischen Distanzraum
*/
@Getter
@ToString
@EqualsAndHashCode
@Value
public class EuclideanSpace {
private final List<List<Double>> points;
/**
*Legen Sie eine Liste mit n-dimensionalen Koordinaten fest
*
* DimensionNotUnifiedException
*Ich habe eine Liste erstellt, in der die Abmessungen der Koordinaten nicht einheitlich sind
*
* NullCoordinateException
*Der numerische Wert der Koordinate enthielt null
*
* NullPointerException
*Übergebene Nulldaten oder Daten, die Nullelemente enthalten
*
* @param points :Liste der n-dimensionalen Koordinaten
*/
public EuclideanSpace(List<List<Double>> points){
if(points.stream().mapToInt(List::size).distinct().count()>1){
throw new DimensionNotUnifiedException();
}
if(points.stream().anyMatch(point -> point.stream().anyMatch(x -> x == null))){
throw new NullCoordinateException();
}
this.points = points;
}
}
Ich habe die Ausnahme selbst definiert.
Plötzlich taucht der Begriff "euklidisch" auf, aber wenn Sie anfangen, etwas wie Raum zu sagen, wird die Geschichte entgleisen, also gehen Sie bitte durch.
Also schreibe ich auch einen Test für den Konstruktor.
package net.tan3sugarless.clusteringsample.lib.data;
import net.tan3sugarless.clusteringsample.exception.DimensionNotUnifiedException;
import net.tan3sugarless.clusteringsample.exception.NullCoordinateException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
public class EuclideanSpaceTest {
//Ganz null,Himmel,1 Element,Mehrere Elemente
//Jedes Element enthält null,Einschließlich Himmel,Alles leer(0 Dimension),1 Dimension,n Abmessungen
//Enthält Nullkoordinaten in jedem Element,Einschließlich 0,Enthält keine Null
//Dimensionsprüfung Alle gleichen Dimensionen,Unterschiedliche Abmessungen
static Stream<Arguments> testConstructorProvider(){
return Stream.of(
Arguments.of(null,new NullPointerException()),
Arguments.of(Collections.emptyList(),null),
Arguments.of(Arrays.asList(Arrays.asList(1.5,-2.1)),null),
Arguments.of(Arrays.asList(Arrays.asList(1.2,0.1),Arrays.asList(0.0,1.5)),null),
Arguments.of(Arrays.asList(null,Arrays.asList(0,1.5),Arrays.asList(-0.9,0.1)),new NullPointerException()),
Arguments.of(Arrays.asList(Arrays.asList(-0.9,0.1),Arrays.asList(0.0,1.5),Collections.emptyList()),new DimensionNotUnifiedException()),
Arguments.of(Arrays.asList(Collections.emptyList(),Collections.emptyList(),Collections.emptyList()),null),
Arguments.of(Arrays.asList(Arrays.asList(1.5),Arrays.asList(0.0),Arrays.asList(-2.2)),null),
Arguments.of(Arrays.asList(Arrays.asList(1.5,2.2,-1.9),Arrays.asList(0.0,0.0,0.0),Arrays.asList(0.9,5.0,2.2)),null),
Arguments.of(Arrays.asList(Arrays.asList(1.5,null,-1.9),Arrays.asList(0.0,0.0,0.0),Arrays.asList(0.9,5.0,2.2)),new NullCoordinateException()),
Arguments.of(Arrays.asList(Arrays.asList(1.5,2.1,-1.9),Arrays.asList(0.0,0.0),Arrays.asList(0.9,5.0,2.2)),new DimensionNotUnifiedException()),
Arguments.of(Arrays.asList(Arrays.asList(2.1,-1.9),Arrays.asList(0,0,0),Arrays.asList(0.9,5.0,2.2)),new DimensionNotUnifiedException())
);
}
@ParameterizedTest
@MethodSource("testConstructorProvider")
@DisplayName("Testen des Konstruktors")
void testConstructor(List<List<Double>> points, RuntimeException e){
if(e==null){
Assertions.assertDoesNotThrow(()->new EuclideanSpace(points));
}else{
Assertions.assertThrows(e.getClass(),()->new EuclideanSpace(points));
}
}
}
Jetzt können Sie in einer Java-Klasse "eine Reihe von Punkten in einer beliebigen Dimension" darstellen.
Der Code, den ich hier geschrieben habe, ist auf GitHub zu finden.
https://github.com/tan3nonsugar/clusteringsample/tree/v0.0.1
Das nächste Mal werde ich erklären, wie man "wie weit die Punkte sind" in Java ausdrückt.
Nächstes Mal! Vielen Dank, dass Sie so weit gelesen haben.
[^ 1]: Tatsächlich ist die Reihenfolge umgekehrt (nur die numerischen Daten werden in einem zweidimensionalen Raum auf leicht verständliche Weise ausgedrückt), aber bitte verzeihen Sie, dass es aufgrund der Betonung der Verständlichkeit an Strenge mangelt.
Recommended Posts