Array viel zu groß...andere Lösungen?

FabianLurz

Bekanntes Mitglied
Hallo Leute,
vllcht. hat der ein oder andere meinen Post schon gelesen; ich bin dabei, eine Recommendation Engine zu entwickeln. Dabei werden große Datenmengen verwendet; es müssen die Korrelationen von 817k zu 817k Filmen berechnet werden.
Um die MovieFeature Matrix zu erstellen verwende ich folgende Funktion:
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main.java.math;

import java.util.ArrayList;
import main.java.ressources.PropertyReader;

/**
 *
 * @author Fabian
 */
public class ItemMatrixCreator {

    //Variables
    //All entinitys
    private ArrayList<String> values = new ArrayList<>();
    private int counter = 0;
    //Values for the single item
    private ArrayList<String> itemValue = new ArrayList<>();
    private int itemCounter = 0;
    PropertyReader mainconf = new PropertyReader();   
    
    /**
     * Assigns on the one hand all itemValues. On the other hand, it builds a
     * vector excluding all known values, so that no value exists twice.
     *
     * @param value String: get all values for creating the right matrix
     */
    public void assign(String value) {
        mainconf.getProb("conf/MainConfig.properties");
        itemValue.add(itemCounter, value);
        itemCounter++;
        boolean known = false;
        String[] valueSplit = value.split(mainconf.read("split"));
        for (int x = 0; x <= valueSplit.length-1; x++) {
            for (int i = 0; i <= values.size()-1; i++) {
                if (values.get(i) == null ? valueSplit[x] == null : values.get(i).equals(valueSplit[x])) {
                    known = true;
                    break;
                } else {
                    known = false;
                }

            }
            if (known == false) {
                if (!"".equals(valueSplit[x])) {
                    values.add(counter, valueSplit[x]);
                    counter++;
                }
            }
        }
    }

    /**
     * Creates a two-dimensional matrix for the item entinitys. For example a
     * genrearray for films like this: 101001 100000 011111 .......
     *
     * @param value Sets the importance of the item entinity. The entinity can
     * be a genre.
     * @return an two-dimensional String
     */
    public byte[][] fillMatrix(byte value) {
        System.out.print(itemValue.size()+" "+ values.size()+"\n");
        byte[][] array = new byte[itemValue.size()][values.size()];
        for (int i = 0; i <= itemValue.size()-1; i++) {
            String[] itemVal = itemValue.get(i).split(mainconf.read("split"));
            for (int x = 0; x <= values.size()-1; x++) {
                for (int y = 0; y <= (itemVal.length - 1); y++) {
                    if (itemVal[y] == null ? values.get(x) == null : itemVal[y].equals(values.get(x))) {
                        array[i][x] = value;
                        break;
                    } else {
                        array[i][x] = 0;
                    }

                }

            }
        }        
        return array;
    }

    /**
     * Returns all the entinity-values from all items excluding known once.
     *
     * @return ArrayList<String>
     */
    public ArrayList<String> returnMatrix() {
        return values;
    }

    /**
     * Deletes the created matrix so that a new matrix with new values and
     * entinitys can be created.
     */
    public void deleteMatrix() {
        counter = 0;
        itemCounter = 0;
        values.clear();
        itemValue.clear();
    }
}

Die Funktion assign wird wie folgt benutzt:
Java:
private byte[][] createArray(String query, ArrayList<Integer> id, Statement que, String getString, byte fillmatrix, boolean integer) throws SQLException {
        for (int j = 0; j < id.size(); j++) {
            String q = query + "" + id.get(j);
            ResultSet arr = que.executeQuery(q);
            String res = "";
            while (arr.next()) {
                if (integer == false) {
                    res += arr.getString(getString) + mainconf.read("split");
                } else if (integer == true) {
                    res += arr.getInt(getString) + mainconf.read("split");
                }
            }
            matrix.assign(res);
            System.out.print(res + "\n");
        }
        System.out.print("Array created\n");
        byte[][] array = matrix.fillMatrix(fillmatrix);
        matrix.deleteMatrix();
        return array;

    }

Die Funktion private byte[][] create Array() wird wie folgt aufgerufen:
Java:
 byte[][] genreArray = createArray(genreQ, id, query, "info", (byte) prop.readInt("genre"), false);
Soweit dazu. Es ergeben sich nun rießige Arrays...
Mein PC mit 8GB Arbeitsspeicher ist dafür nicht ausreichend.....
Seht ihr eine andere Möglichkeit, nicht so viel Speicher zu verbrauchen beim erstellen der Matrix? Ist irgendwo ein grober Fehler?
EDIT: Sehe gerade, dass die Kommentare noch nicht optimal sind :) Bitte habt Nachsehen; die werden noch verbessert.
Gruß Fabian
 
S

SlaterB

Gast
Informationen sparst du dir weitgehend

wo und wie wird die Matrix genutzt? auf welche Weise welche Information daraus gewonnen?

und welche Informationen enthält sie konkret, vor allem wie viele Daten,
sind praktisch alle bei 0 und nur 100.000 Daten verstreut enthalten?
das wäre dann der Fachbegriff
Dünnbesetzte Matrix ? Wikipedia

denkbar wäre als alternative Datenstruktur eine Map, x+","+y als String zu einem Key zusammenbauen,
das kann auch der Auswerter später, die Map enthält genau die 100.000 Daten, liefert sonst null
 

FabianLurz

Bekanntes Mitglied
Also wie läuft das Ganze ab:
1. Daten werden von der Mysql DB eingelesen:
Java:
 //Create the genreArray matrix
            String genreQ = "SELECT movie_id,info,info_type_id FROM movie_info WHERE info_type_id=3 AND movie_id=";
            byte[][] genreArray = createArray(genreQ, id, query, "info", (byte) prop.readInt("genre"), false);
            float[][] dist = new float[4][(genreArray.length-1)*(genreArray.length-1)];
            dist[0] = cosine.createCosineSimilarity(genreArray);
            Arrays.fill(genreArray,null);
Die Funktion createArray() steht ja im ersten Post.
2. Die Funktion createArray() fügt durch assign unbekannte Werte der ArrayList<String> values hinzu. Alle werte von den Filmen werden in der ArrayList<String> itemValue gespeichert.
3. Die Funktion fillMatrix wird aufgerufen. Es wird nun verglichen, welche Filme ein Wert enthält und an welcher Stelle von value eine 1 gesetzt werden muss.

Das Problem liegt aber aktuell hier:
Java:
float[][] dist = new float[4][(genreArray.length-1)*(genreArray.length-1)];
Bei 25k Filmen brauche ich schon ca. 10GB Arbeitsspeicher (etwas weniger). Leider ist aber die Kosinusähnlichkeit ein float....wüsste nicht, wie das anders gehen soll. Hoffe ihr habt noch eine Idee :)
 
S

SlaterB

Gast
für die dist-Berechnung musst du vielleicht weniger suchen, nur durchgehen,
da ginge dann auch bzw. wäre eher nützlich eine Liste von Einträgen (x,y,wert), aber schwer zu sagen ohne Details
 

AlexSpritze

Bekanntes Mitglied
Versuch das ganze doch gleich auf Datenbankebene umzusetzen. Diese sollte locker mit einer (185k)^2 großen Tabelle umgehen können, wenn du über genug Festplattenspeicher verfügst. Könnte dann sicherlich langsam werden. Aber immer noch besser, als alles im Arbeitsspeicher halten zu wollen ;)
 

FabianLurz

Bekanntes Mitglied
Nein nein ich will das ja gar nicht im Arbeitsspeicher halten. Es wird eben alles berechnet und dann werden diese Korrelationen wieder in die DB geschrieben :) Leider muss aber für die Berechnung ziemlich viel im Arbeitsspeicher gehalten werden; eine Zeit lang zumindest.
Bsp.:
item_id1 item_id2 corr
1 2 0.5
2 1 0.5
3 4 0.6
4 3 0.7
Gruß Fabian
 

Marco13

Top Contributor
Weniger Code und mehr Erklärungen (oder alternativ: Mehr Code, nämlich ein KSKB) wären vielleicht hilfreich. Jedenfalls hab ich's nicht im Detail nachvollzogen. Aber reicht es vielleicht, immer nur eine Zeile+Spalte im Speichern zu halten?
 

Marco13

Top Contributor
Ja, je nachdem, wie das ganze verwendet werden soll, gäbe es schon Möglichkeiten. Man soll ja vermutlich einen Film auswählen, und dann z.B. alle "ähnlichen" Filme angezeigt bekommen. Dazu braucht man nur 817k float-Werte, nämlich die Ähnlichkeit des EINEN Films zu ALLEN anderen. Wann braucht man alle paarweisen Ähnlichkeiten? Wo und wie sollen die gespeichert werden? (Ja wohl nicht bei jedem Start neu ausrechnen? ;) ). Wie zeitkritisch sind die einzelnen Schritte, und welche Laufzeitanforderungen gibt es? Es gibt ja grob-abstrakt gesprochen drei mögliche Abstufungen:
float[][] getPairwiseSimilarities(); // 800k * 800k -> Unpraktikabel
float[] getSimilarities(int currentFilm); // 800k -> Vielleicht OK
float getSimilarity(int film0, int film1); // 1 float, aber vermutlich zu langsam in der Praxis?
 

FabianLurz

Bekanntes Mitglied
Alle Korrelationen werden in der DB gespeichert. Von dort aus werden sie von einer weiteren API abgerufen...also keine Neuberechnung.
Spannend ist der Ansatz, erst alles für einen Film, dann für den nächsten Film zu berechnen. Das sollte möglich sein.
Eine Echtzeitberechnung kann nicht statt finden. Das wäre zu langsam ;)
 

Marco13

Top Contributor
Das Überschneidet sich jetzt schon mit http://www.java-forum.org/allgemeine-java-themen/143046-recommendation-engine.html#post952906 ... aber ... ohne genauer zu wissen, welche Rahmenbedinungen vorliegen, wird es schwierig, dazu etwas zu sagen. Vermutlich sind die allermeisten Korellationen 0 oder sehr klein, oder sie fallen in wenige Kategorien. Zumindest denke ich schonmal, dass man die Float-Werte (-1 bis 1) auch einfach auf byte-Werte (-128 bis 127) abbilden könnte. Evtl. zusätzlich dazu könnte man eine Art "Threshold" einfügen: Wenn die Korrelation zwischen -0.1 und 0.1 liegt (also ca. -12 bis 12 als byte), wird sie als 0 angenommen. Dann hättest du vermutlich eine Sparse Matrix, wie SlaterB schon angedeutet hat. Die kann man dann kompakter Speichern. Vielleicht könnte man auch ganz absurde Sachen mit einer Run length encoding machen, oder die Matrix irgendwie umsortieren, damit sie kompakter gespeichert werden kann, aber nochmal: Das ist alles Stochern im Nebel....
 

FabianLurz

Bekanntes Mitglied
Natürlich ist es stochern im Nebel. Ich kann ja auch zu einem derart komplexen Thema nicht alles erklären :) Das "stochern im Nebel" hat mir hier aber schon sehr weiter geholfen. Siehe dazu auch den anderen Post ;)
Also ich komme jedenfalls jetzt wieder weiter :)
Gruß und Danke Fabian
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H wie viel speicher braucht eigentlich ein array? Allgemeine Java-Themen 2
Fynn29 Liste sortieren ohne Array und ohne vorgegebene Sortierung Allgemeine Java-Themen 24
LucasGlockner Effizienter byte-Zugriff auf ein long[]-Array Allgemeine Java-Themen 8
8u3631984 Frage Performance bei Linked List und Array List Allgemeine Java-Themen 5
M Queue mit einem Array implemetieren Allgemeine Java-Themen 16
M Array Rang eines Elements Allgemeine Java-Themen 4
TheSepp Java bestimmtes Array auf den Wert 0 setzen Allgemeine Java-Themen 32
TheSepp Wie kann man Leerzeichen aus einer Array liste entfernen? Allgemeine Java-Themen 10
B HeapSort für Array of Strings funktioniert nur teilweise Allgemeine Java-Themen 3
noah1407 Array Allgemeine Java-Themen 3
D Methoden Teil-Array mit Maximalwert bestimmen Allgemeine Java-Themen 23
N einem Array Objekte hinzufügen die ihr Array position gespeichert haben Allgemeine Java-Themen 34
N zweidimensionalen Array in dreidimensionalen Array speichern Allgemeine Java-Themen 4
N Schnellste Methode, ein Array durchzugehen? Allgemeine Java-Themen 9
T Objekt Array Aufgabe mit Busdatenbank Allgemeine Java-Themen 2
L Array und Index Allgemeine Java-Themen 26
L die 3 größten Zahlen im Array Allgemeine Java-Themen 1
G jToggleButton in Array/ArrayList Allgemeine Java-Themen 12
S Übergabe eines Sortierkriteriums für ein Artikel Array mittels BiPredicate<Artikel, Artikel> Allgemeine Java-Themen 13
Willi.We Array sortieren Allgemeine Java-Themen 5
gotzi242 Array Summe bestimmen tipps? Allgemeine Java-Themen 14
H Matrix ohne Array erstellen Allgemeine Java-Themen 9
Aboya Char Array rekursiv vergleichen Allgemeine Java-Themen 15
V4ll3.Wff Array in Java Allgemeine Java-Themen 4
Noahscript Aus einem byte Array Steuerungszeichen und Code bekommen und ersetzen Allgemeine Java-Themen 3
H Array Sportschütze Allgemeine Java-Themen 6
Sumo_ow "ArrayIndexOutofBoundsException: 2" Array Problem Allgemeine Java-Themen 6
xGh0st2014 Problem mit Java Array Allgemeine Java-Themen 1
M Array verändern Allgemeine Java-Themen 1
A JavaFX 2 dimensionales array Allgemeine Java-Themen 1
LimDul Direktes return eines Array geht nicht Allgemeine Java-Themen 20
S Array dynamisieren oder ArrayList verwenden? Allgemeine Java-Themen 17
M Java 2D Array für ein Grid erstellen ? Allgemeine Java-Themen 2
H Array mit dem Datentype String[] initializieren Allgemeine Java-Themen 7
L ArrayList mit String Arrays in ein Array umwandeln Allgemeine Java-Themen 1
H Elemente aus ArrayList in Array speichern Allgemeine Java-Themen 8
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
N Byte Array in Java "dekomprimieren" Allgemeine Java-Themen 3
parrot Array Aufgabe Allgemeine Java-Themen 3
N String Array Eingabe Allgemeine Java-Themen 6
R Warum wird mir in der Konsole das "Standard Array" ausgegeben? Allgemeine Java-Themen 2
N Variablen Array Länge ändern. Allgemeine Java-Themen 8
D Kgv aller Paare aus einem Array mit n integer berechnen Allgemeine Java-Themen 5
W Enumeration ein Array/List als Eigenschaft mitgeben - warum geht das nicht? Allgemeine Java-Themen 0
kodela Problem mit strukturiertem Array Allgemeine Java-Themen 18
A Array Problem Allgemeine Java-Themen 8
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
F Datei in String-Array einlesen Allgemeine Java-Themen 8
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
I Array Parameter mit 2 Klassen - NullPointerException Allgemeine Java-Themen 3
X Größten Werte in meinem Array löschen? Allgemeine Java-Themen 16
E Angabe wie groß Array sein soll und in for-schleifen diesen Array füllen Allgemeine Java-Themen 3
F 3 Dimensionales Array mit Allgemeine Java-Themen 9
M Steueralgorithmus verwandelt Array in Anfangszustand Allgemeine Java-Themen 9
W Array vs. ArrayList vs. HashMap Allgemeine Java-Themen 20
D Datentypen 2-3 Baum erstellen mit geordnetem int-array Allgemeine Java-Themen 0
T Objekt in Array packen Allgemeine Java-Themen 6
M Zahlen in Array anordnen Allgemeine Java-Themen 8
M Eclipse Unvollständigen Array ansteuern Allgemeine Java-Themen 2
D Erste Schritte Im Array Werte tauschen Allgemeine Java-Themen 5
Xge For/Array Error: IndexOutOfBounds Allgemeine Java-Themen 4
M Wie kann ich ein int[] Array in einer Methode benutzen? Allgemeine Java-Themen 6
FRI3ND Datentypen Date-Array sortieren - Text mitnehmen? Allgemeine Java-Themen 7
D Integer-Array variabler Größe mit Zahlen befüllen (Schleifen) Allgemeine Java-Themen 0
J Variablen Array ertellen bei model.put Allgemeine Java-Themen 13
S Eindimensionales Array in zweidimensionales Array speichern Allgemeine Java-Themen 5
R convert 2d array list to 2d array Allgemeine Java-Themen 1
J json Array würfel Spalten durcheinander Allgemeine Java-Themen 9
MiMa Array umbau oder Alternative? Allgemeine Java-Themen 5
L Datentypen 3D Array Allgemeine Java-Themen 3
M 2D Array mit unterschiedlichen Längen erstellen und befüllen Allgemeine Java-Themen 11
Mario1409 Methoden JSON Array von URL Allgemeine Java-Themen 8
E Swing Array mit Bildern in GUI darstellen Allgemeine Java-Themen 2
P Array einer abstrakten Klasse Allgemeine Java-Themen 4
H Zweidimensionales Array - Zellen der Tabelle verbinden Allgemeine Java-Themen 2
M Zweidimensionales Array mit Binärzahlen füllen Allgemeine Java-Themen 8
M Array aus Thread Objekten erstellen Allgemeine Java-Themen 2
kodela Dynamisches Array in einer Klasse Allgemeine Java-Themen 5
G Array ohne Aufzählungszeichen ausgeben Allgemeine Java-Themen 6
J Wie kann ich ein Java Array als Säulendiagramm ausgeben? Allgemeine Java-Themen 2
Z 2D Array Pixels reparieren Allgemeine Java-Themen 2
S Algorithmus welcher True-Werte in einem Array findet und auswertet. Allgemeine Java-Themen 5
B Polibios Array erweitern Allgemeine Java-Themen 1
R Index in einem Array löschen Allgemeine Java-Themen 10
R Index in einem Array löschen Allgemeine Java-Themen 2
U Methoden Algorithmus MergeSort String [ ] array sortieren programmieren Allgemeine Java-Themen 17
J Array-List Bubble-Sort Allgemeine Java-Themen 12
4 Variablen Int-Array Int Zuweisen Allgemeine Java-Themen 7
J Array Allgemeine Java-Themen 8
Z Array mit unterschiedlichen Werten Allgemeine Java-Themen 1
L sortiertes Array im main aufrufen klappt nicht. Allgemeine Java-Themen 3
O Mein JButton Array funktioniert nicht Allgemeine Java-Themen 3
A Mit dem letzten bis zum ersten Wert aus Array rechnen Allgemeine Java-Themen 15
A Vector Strings in Array splitten Allgemeine Java-Themen 6
I Muster in Array suchen Allgemeine Java-Themen 10
RalleYTN Datentypen Herausfinden ob Object ein Array ist ohne den Typen des Arrays zu kennen? Allgemeine Java-Themen 12
S Variablen String[] Array per schleife in int[] einlesen Allgemeine Java-Themen 8
B Zahlen manuell eingeben und in Array Speichern Allgemeine Java-Themen 2
R Wärmeleitung, 3d-Array Allgemeine Java-Themen 2
T Java Array in Methoden Allgemeine Java-Themen 1

Ähnliche Java Themen

Neue Themen


Oben