Was ist ein guter Weg, um zyklische Ordnungsattribute zu transformieren?

21

Ich habe ein Stundenfeld als Attribut, aber es nimmt zyklische Werte an. Wie könnte ich die Funktion umwandeln, um die Informationen wie '23' und '0' Stunde zu erhalten, sind nicht weit entfernt.

Eine Möglichkeit, die ich mir vorstellen könnte, ist die Transformation: min(h, 23-h)

Input: [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

Output: [0 1 2 3 4 5 6 7 8 9 10 11 11 10 9 8 7 6 5 4 3 2 1]

Gibt es einen Standard für den Umgang mit solchen Attributen?

Update: Ich werde beaufsichtigtes Lernen verwenden, um zufällige Waldklassifikatoren zu trainieren!

Mangat Rai Modi
quelle
1
Ausgezeichnete erste Frage! Können Sie weitere Informationen darüber hinzufügen, was Ihr Ziel ist, um diese spezielle Feature-Transformation durchzuführen? Beabsichtigen Sie, diese transformierte Funktion als Eingabe für ein überwachtes Lernproblem zu verwenden? In diesem Fall sollten Sie diese Informationen hinzufügen, da sie anderen helfen können, diese Frage besser zu beantworten.
Nitesh
1
@ Nitesh, siehe Update
Mangat Rai Modi
Antworten finden Sie hier: datascience.stackexchange.com/questions/4967/…
MrMeritology
Entschuldigung, aber ich kann keinen Kommentar abgeben. @ AN6U5 Könnten Sie bitte erläutern, wie Sie den Wochentag und die Stunde gleichzeitig betrachten können, wenn Sie sich Ihrer erstaunlichen Vorgehensweise anschließen? Ich habe seit einer Woche damit zu kämpfen und ich habe auch ein Q gepostet, aber Sie haben es nicht gelesen.
Seymour

Antworten:

33

Die logischste Art, die Stunde umzuwandeln, besteht in zwei Variablen, die aus der Senke heraus und zurück schwingen. Stellen Sie sich die Position des Stundenendzeigers einer 24-Stunden-Uhr vor. Die xPosition schwingt mit der yPosition aus der Senke . Für eine 24-Stunden - Uhr können Sie erreichen dies mit x=sin(2pi*hour/24), y=cos(2pi*hour/24).

Sie brauchen beide Variablen oder die richtige Bewegung durch die Zeit geht verloren. Dies ist auf die Tatsache zurückzuführen, dass sich die Ableitung von sin oder cos zeitlich ändert, wenn sich die (x,y)Position gleichmäßig ändert, während sie sich um den Einheitskreis bewegt.

Überlegen Sie abschließend, ob es sich lohnt, ein drittes Feature zur Verfolgung der linearen Zeit hinzuzufügen, das aus Stunden (oder Minuten oder Sekunden) ab dem Beginn des ersten Datensatzes oder einem Unix-Zeitstempel oder ähnlichem erstellt werden kann. Diese drei Funktionen liefern dann Proxys für den zyklischen und linearen Verlauf der Zeit. Sie können zyklische Phänomene wie Schlafzyklen in der Bewegung von Menschen und auch lineares Wachstum wie Bevölkerungszahl im Verhältnis zur Zeit herausfiltern.

Hoffe das hilft!

Hinzufügen eines relevanten Beispielcodes, den ich für eine andere Antwort generiert habe:

Beispiel für das Erreichen von:

# Enable inline plotting
%matplotlib inline

#Import everything I need...

import numpy as np
import matplotlib as mp

import matplotlib.pyplot as plt
import pandas as pd

# Grab some random times from here: https://www.random.org/clock-times/
# put them into a csv.
from pandas import DataFrame, read_csv
df = read_csv('/Users/angus/Machine_Learning/ipython_notebooks/times.csv',delimiter=':')
df['hourfloat']=df.hour+df.minute/60.0
df['x']=np.sin(2.*np.pi*df.hourfloat/24.)
df['y']=np.cos(2.*np.pi*df.hourfloat/24.)

df

Bildbeschreibung hier eingeben

def kmeansshow(k,X):

    from sklearn import cluster
    from matplotlib import pyplot
    import numpy as np

    kmeans = cluster.KMeans(n_clusters=k)
    kmeans.fit(X)

    labels = kmeans.labels_
    centroids = kmeans.cluster_centers_
    #print centroids

    for i in range(k):
        # select only data observations with cluster label == i
        ds = X[np.where(labels==i)]
        # plot the data observations
        pyplot.plot(ds[:,0],ds[:,1],'o')
        # plot the centroids
        lines = pyplot.plot(centroids[i,0],centroids[i,1],'kx')
        # make the centroid x's bigger
        pyplot.setp(lines,ms=15.0)
        pyplot.setp(lines,mew=2.0)
    pyplot.show()
    return centroids

Jetzt probieren wir es aus:

kmeansshow(6,df[['x', 'y']].values)

Bildbeschreibung hier eingeben

Sie können kaum erkennen, dass der grüne Cluster vor Mitternacht einige Zeiten nach Mitternacht enthält. Reduzieren Sie jetzt die Anzahl der Cluster und zeigen Sie, dass vor und nach Mitternacht in einem einzelnen Cluster eine detailliertere Verbindung hergestellt werden kann:

kmeansshow(3,df[['x', 'y']].values)

Bildbeschreibung hier eingeben

Sehen Sie, wie der blaue Cluster Zeiten vor und nach Mitternacht enthält, die im selben Cluster zusammengefasst sind ...

QED!

AN6U5
quelle
Geniale Art damit umzugehen. Es würde 0 und 23 Stunden ähnliche Ergebnisse geben, aber wird es nicht auch die Zeit von vormittags bis nachmittags ähnlich machen? Welches ist in der Tat durch 12-Stunden-Fenster getrennt.
Mangat Rai Modi
12-Stunden-Zeit (AM / PM) funktioniert nicht, konvertieren Sie sie einfach in 24-Stunden-Zeit.
AN6U5,
Mir ist gerade aufgefallen, dass Sie durch 24 teilen. Als Sie Analogie zur Uhr gaben, dachte ich, dass es eine Standard-12-Stunden-Uhr ist. Sie nehmen jedoch 24-Stunden-Uhr. Es scheint der beste Weg für mich zu sein, mich zu verwandeln. Danke dir!
Mangat Rai Modi
Erstaunliche Antwort Genau das, wonach ich gesucht habe Danke ..
Aditya
Die akzeptierte Antwort, bei der sin () & cost () kombiniert werden, ist großartig. Hier als Ergänzung eine weitere sehr ausführliche und nette Erklärung von Ian London.
FlorianH
3

Die Frage ist sehr interessant und ich kann mich nicht erinnern, interessante Antworten gelesen zu haben. Aus diesem Grund wage ich es, Ihnen eine mögliche Lösung zu geben, auch wenn sie verrückt genug aussieht.

Normalerweise vermeidet man, die gleichen Informationen in mehreren Funktionen zu haben, da viele Algorithmen damit nicht umgehen können. Dies ist jedoch nicht der Fall bei zufälligen Gesamtstrukturen. Im Gegensatz zur linearen Regression (und allen Modellen, die auf ähnlichen Ideen basieren) testen zufällige Gesamtstrukturen alle Features, indem sie jedes Feature einzeln berücksichtigen. Auf diese Weise ist es möglich, die gleichen Informationen auf verschiedene Arten zu codieren, ohne die Lernleistung, nur den Platz und die Laufzeit zu beeinträchtigen.

(h+Offset)

Es verschwendet etwas Platz und Zeit, aber ich würde versuchen zu sehen, wie das funktioniert.

rapaio
quelle
0

Im Idealfall brauchen Sie keine Transformation. Die relative Zeitdifferenz zwischen zwei Punkten kann als Distanzfunktion verwendet werden. Wo kann die Klassifizierung darauf basieren.

in Java:

public class TimeDistanceMeasurer implements DistanceMeasure {

    @Override
    public double compute(double[] a, double[] b) throws DimensionMismatchException {
        String time1 = String.format("%02d", (int)a[0]) + String.format("%02d", (int)a[0]);
        String time2 = String.format("%02d", (int)b[0]) + String.format("%02d", (int)b[0]);

        SimpleDateFormat format = new SimpleDateFormat("HHmm");
        try {
            Date date1 = format.parse(time1);
            Date date2 = format.parse(time2);
            return Math.abs(date2.getTime() - date1.getTime());
        } catch (Exception e) {
            throw new IllegalStateException("Something went wrong.", e);
        }
    }
}
shiva.n404
quelle
1
Das ist in Ordnung, aber die Frage braucht etwas anderes ..
Aditya