Ankündigung

Einklappen
Keine Ankündigung bisher.

User helfen User - Programmieren

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    läuft bei mir ohne error durch auf folgendem system:

    win7, python 3.6.7, np 1.15.4 im jupyter

    ist allerdings ein system auf dem ich nicht wirklich code, nur womit ich auf rm surfe und einfach ne python environment installiert habe.

    kann ich nachher nochmal auf dem mac testen.
    Zuletzt geändert von zupzup; 04.06.2020, 22:02.

    Kommentar


      Würde sagen, dass e-06 nah genug an der Null ist. ;)
      Ansonsten kann, iirc, das teilen numerisch immer ein Problem werden, weil gerade sehr kleine Zahlen einen größeren Fehler verursachen können. Aber da rufe ich Erinnerungen ab die 6+ Jahre in der Vergangenheit liegen.

      Kommentar


        Zitat von zupzup Beitrag anzeigen
        läuft bei mir ohne error durch auf folgendem system:

        win7, python 3.6.7, np 1.15.4 im jupyter

        ist allerdings ein system auf dem ich nicht wirklich code, nur womit ich auf rm surfe und einfach ne python environment installiert habe.

        kann ich nachher nochmal auf dem mac testen.
        Danke. Mit oder ohne print? Mich verwundert halt, dass ein print einen Unterschied machen kann.

        Zitat von panda yo Beitrag anzeigen
        Würde sagen, dass e-06 nah genug an der Null ist. ;)
        Ansonsten kann, iirc, das teilen numerisch immer ein Problem werden, weil gerade sehr kleine Zahlen einen größeren Fehler verursachen können. Aber da rufe ich Erinnerungen ab die 6+ Jahre in der Vergangenheit liegen.
        Naja effektiv findet bei dem Test der häufiger fehlschlägt nur zwei Division statt: 2/0.667 an stelle 1,1 der matrix A(die 0 division wird durch die Maske "where=(std_mat!=0) verhindert) bzw im return durch das skalar(3/3). Das sollte beides unkritisch sein. Die Stellen die verkehrte Werte haben, sollte niemals anders als 0 sein und ich kann mir nicht erklären, wie die Abweichungen durch die Matrixmultiplikationen entstehen. Auch bei der Subtraktion sollte das eigentlich nicht auftreten, da das alles runde Werte sind.

        Edit: Okay, scheinbar ist die Maske das Problem.
        Genauer gesagt der ungleichheitscheck auf 0. Ich sehe das grundsätzliche Problem, aber verstehe nicht, warum das in diesem Fall das Problem war.
        Das hier scheint es generell zu fixen:
        Code:
        mask =~np.isclose(std_mat, 0)
        A = np.divide(A,std_mat, where=mask)
        Zuletzt geändert von KleinerElefant; 05.06.2020, 09:39.

        Kommentar


          Ich kann das Problem nicht reproduzieren, auch nicht mit Python 3.6.9 und numpy 1.18.2 auf ubuntu. Weder mit noch ohne print.

          Kommentar


            Hmm strange. Ich glaube mittlerweile, dass bei der Berechnung der Standardabweichung ein floating point error entsteht, wodurch dann die Maske bei der division nicht immer korrekt ist. Naja so funktioniert es jetzt bei mir überall zuverlässig. Habe noch mal einen weiteren Test hinzugefügt. (Code im Spoiler) Finde das ganze immernoch merkwürdig. Vorallendingen, dass ein print Aufruf das Resultat veränderte. Das bedeutet ja, dass in __str()__ irgendwelche Rundungen direkt auf den Daten stattgefinden müssen. Finde dazu auf die schnelle, aber auch nichts in der Dokumentation.
            Spoiler: 

            Code:
            import numpy as np
            
            def autocorrelation(data):
            """
            Input is an array of the form number_data * dimensions
            An example is shown when this cell is executed
            """
            # YOUR CODE HERE
            u = np.mean(data, axis=0, keepdims=True, dtype='float64')
            std_dev = np.std(data, axis=0, keepdims=True, dtype='float64')
            # std dev matrix
            std_mat = std_dev.T @ std_dev
            
            ## 1/|D| * sum {x elem D} ((x - u)/std_dev)^T * ((x - u)/std_dev)
            # (x - u)
            diff = (data - u)
            # (x - u)^T * (x -u)
            A = diff.T @ diff
            # pairwise division matrix std dev
            mask = ~np.isclose(std_mat, 0)
            A = np.divide(A,std_mat, where=mask)
            # A/|D|
            return np.divide(A, float(data.shape[0]))
            
            test_data1 = np.stack([[1,2,3], [2,2,2]], axis=1)
            cor1 = autocorrelation(test_data1)
            real_cor1 = [[1.0, 0.0], [0.0, 0.0]]
            
            test_data2 = np.stack([[1,2,3], [4,5,6]], axis=1)
            cor2 = autocorrelation(test_data2)
            real_cor2 = [[1,1], [1,1]]
            
            test_data3 = np.stack([[21.0, 160, 110, 3.90, 2.620, 16.46]
            ,[21.0, 160, 110, 3.90, 2.875, 17.02]
            ,[22.8, 108, 93, 3.85, 2.320, 18.61]
            ,[21.4, 258, 110, 3.08, 3.215, 19.44]
            ,[18.7, 360, 175, 3.15, 3.440, 17.02]
            ,[18.1, 225, 105, 2.76, 3.460, 20.22]], axis=0)
            cor3 = autocorrelation(test_data3)
            real_cor3 = np.corrcoef(test_data3, rowvar=False)
            
            assert np.allclose(cor1, real_cor1), "Wrong output: correlation should be \n {} \n for this data, is \n {}".format(real_cor1, cor1)
            assert np.allclose(cor2, real_cor2), "Wrong output: correlation should be \n {} \n for this data, is \n {}".format(real_cor2, cor2)
            assert np.allclose(cor3, real_cor3), "Wrong output: correlation should be \n {} \n for this data, is \n {}".format(real_cor3, cor3)


            Danke an alle fürs testen.

            Kommentar


              Kann mir höchstens vorstellen, dass der @ Operator eine Art Generator ist, der dann mit dem print statement evaluiert wird anstatt ohne "Zwischenergebnis" die nächste Operation dranzuhängen.

              Kommentar


                Hast du die Standardabweichung mal selbst ausgerechnet?

                Kommentar


                  Billy Mays
                  Glaube ich nicht, da dasselbe Resultat auch mit np.dot() auftrat. Im 2d Fall wie hier vorliegt, sollte die Operationen sich laut Dokumentation identisch sein. Der "@" operator ruft soweit ich weiß einfach mulmat auf.

                  panda yo
                  Nee noch nicht. Zumindest nicht für das komplette Beispiel. Mache ich nachher mal. Wobei mein minimal Test sich schon einmal korrekt verhält.
                  Spoiler: 

                  Code:
                  import numpy as np
                  from math import sqrt,fsum
                  
                  test_data1 = np.stack([[1,2,3], [2,2,2]], axis=1)
                  # expected value
                  u = fsum(test_data1[:,1])
                  u /= len(test_data1[:,1])
                  
                  # std dev
                  sd = fsum((test_data1[:,1] - u)**2)
                  sd /= len(test_data1[:,1])
                  sd=sqrt(sd)
                  
                  # check result
                  if sd == 0:
                  print("Result: ", sd.as_integer_ratio())
                  Code:
                  Result: (0, 1)

                  Selbes Resultat übrigens bei der Verwendung von sum, sowie bei Aufsummierung mittels += innerhalb von 2 Schleifen.
                  Lese gerade schon hier nach https://docs.python.org/3/tutorial/floatingpoint.html, aber finde nichts, was so richtig zutrifft.

                  edit:
                  Gerade mal durchprobiert und die standard abweichung für alles so ausgerechnet und es funktioniert auch ohne np.isclose()
                  Spoiler: 

                  Maske ist jetzt einfach std_mat!=0 und sonst alles identisch bis auf das hier:
                  Code:
                  [COLOR=#000000]std_dev [/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#000000] [][/COLOR]
                  [COLOR=#569CD6]for[/COLOR][COLOR=#000000] i [/COLOR][COLOR=#569CD6]in[/COLOR][COLOR=#000000] range([/COLOR][COLOR=#B5CEA8]0[/COLOR][COLOR=#000000],data.shape[[/COLOR][COLOR=#B5CEA8]1[/COLOR][COLOR=#000000]]):[/COLOR]
                  [COLOR=#6A9955]# expected value[/COLOR]
                  [COLOR=#000000]u_new [/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#000000] fsum(data[:,i])[/COLOR]
                  [COLOR=#000000]u_new [/COLOR][COLOR=#D4D4D4]/=[/COLOR][COLOR=#000000] len(data[:,i])[/COLOR]
                  
                  [COLOR=#6A9955]# std dev[/COLOR]
                  [COLOR=#000000]sd [/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#000000] fsum((data[:,i] [/COLOR][COLOR=#D4D4D4]-[/COLOR][COLOR=#000000] u_new)[/COLOR][COLOR=#D4D4D4]**[/COLOR][COLOR=#B5CEA8]2[/COLOR][COLOR=#000000])[/COLOR]
                  [COLOR=#000000]sd [/COLOR][COLOR=#D4D4D4]/=[/COLOR][COLOR=#000000] len(data[:,i])[/COLOR]
                  [COLOR=#000000]sd[/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#000000]sqrt(sd)[/COLOR]
                  [COLOR=#000000]std_dev.append(sd)[/COLOR]
                  
                  [COLOR=#000000]std_dev [/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#000000] np.asarray(std_dev)[/COLOR]
                  [COLOR=#000000]std_dev.shape [/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#000000] ([/COLOR][COLOR=#B5CEA8]1[/COLOR][COLOR=#000000], data.shape[[/COLOR][COLOR=#B5CEA8]1[/COLOR][COLOR=#000000]])[/COLOR]
                  Sobald ich wieder,
                  Code:
                  [COLOR=#000000]std_dev [/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#000000] np.std(data, axis[/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#B5CEA8]0[/COLOR][COLOR=#000000], keepdims[/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#569CD6]True[/COLOR][COLOR=#000000], dtype[/COLOR][COLOR=#D4D4D4]=[/COLOR][COLOR=#CE9178]'float64'[/COLOR][COLOR=#000000])[/COLOR]
                  benutze, kriege ich den Fehler.


                  edit2: nvm tritt doch noch auf. Mal das ganze auch noch für den erwartungswert machen.
                  Zuletzt geändert von KleinerElefant; 05.06.2020, 17:44.

                  Kommentar


                    Warum teilst du sd nicht durch len()-1, du rechnest doch die Stichprobenvarianz aus?

                    Aber es scheint einfach ein Fließkommafehler zu sein, oder?

                    Hast du mal float96 oder float128 genutzt? Siehe: https://docs.scipy.org/doc/numpy-1.1...nded-precision
                    Zuletzt geändert von panda yo; 05.06.2020, 22:07.

                    Kommentar


                      Habs leider noch nicht auf dem Mac testen können, aber was mir noch bei dem Test auf meinem zuvorgenannten system aufgefallen ist (FWIF):

                      Mit print läuft es immer durch, ohne print failed es aber meistens, weil in den Fällen das assert am Ende failed. Und das assert klappt dann nicht, weil 3 der 4 berechneten Zahlen nicht exakt 0 sind, sondern halt annähernd 0.

                      Ich schätze bei Stackoverflow bist du sehr viel besser aufgehoben.

                      Kommentar


                        Habe es auch nochmal mit deinem initialen Code getestet, W10, Python 3.7.2, numpy 1.16.1
                        Mit print exakte Übereinstimmung, ohne print Fehler in e-260 bis e-310 :D
                        Weird.

                        Okay, es wurde richtig weird. Ich poste mal auf StackOverflow.
                        https://stackoverflow.com/questions/...in-numpy-array

                        E: Ich lösche die Frage auf SO natürlich, wenn du sie selbst stellen willst.
                        Zuletzt geändert von panda yo; 06.06.2020, 00:58.

                        Kommentar


                          Joa mit der Stichprobenvarianz hast du recht. Sollte n-1 sein, so ist es natürlich biased(bessel korrektur).

                          Mir ist halt echt nicht klar, wie dieser Rundungs/Darstellungsfehler entsteht. Irgendwo muss die float Repräsentation "komisch" sein. Was ich daran so merkwürdig finde ist, dass es im Nenner eigentlich immer exakt 0 sein muss. Und das sollte nach meinem Verständnis kein Problem sein exakt darzustellen. Ebenso wie die Berechnungen, die zu den Nullen führen. 2.0 sollte exakt sein, ebenso wie die Berechnung 2.0 - 2.0.

                          Nee lass den Post gerne stehen, finde es einfach sehr interessant. Und es interessiert mich echt, was diesen Fehler hervorruft. :D
                          Es ist ziemlich sicher nicht das Print, was eine veränderung bewirkt, sondern A.__str()__, was ja beim print aufgerufen wird, hat den selben Effekt. Hatte auch mal mit den numpy.print_options rumgespielt, aber ohne wirkliches Ergbenis.

                          Kommentar


                            Mich würde die Antwort auch sehr interessieren. Auch komisch, dass es nicht immer reproduzierbar ist trotz gleicher numpy Version. Vllt liegt es auch an mkl oder ähnliches. Wobei __str__ ja eigentlich nur nen view auf die Daten ist und niemals diese verändern dürfte.

                            edit:
                            diejenigen die das Problem reproduzieren können sollten das auch bei stackoverflow kommentieren, sonst glaubt ihm keiner :)

                            edit2:
                            ein Minimalbeispiel bei dem der Effekt auftritt wär bestimmt auch hilfreich.
                            Zuletzt geändert von Billy Mays; 06.06.2020, 12:55.

                            Kommentar


                              Zitat von Billy Mays Beitrag anzeigen
                              edit2:
                              ein Minimalbeispiel bei dem der Effekt auftritt wär bestimmt auch hilfreich.
                              Das Beispiel habe ich ja gepostet.

                              Kommentar


                                Ja, ich mein mit bisschen rumprobieren kann man das Problem vllt isolieren ohne den ganzen Code drum herum

                                Kommentar

                                Lädt...
                                X