Jaki jest dobry sposób na przekształcenie atrybutów porządkowych cyklicznych?

21

Jako atrybut mam pole „godzina”, ale przyjmuje ono wartości cykliczne. Jak mogłem przekształcić tę funkcję, aby zachować informacje, takie jak „23” i „0” godzina są blisko.

Jednym ze sposobów, w jaki mogłem myśleć, jest transformacja: 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]

Czy istnieje jakiś standard obsługi takich atrybutów?

Aktualizacja: Będę korzystał z nadzorowanej nauki, aby trenować losowy klasyfikator lasu!

Mangat Rai Modi
źródło
1
Doskonałe pierwsze pytanie! Czy możesz dodać więcej informacji o tym, jaki jest Twój cel przeprowadzenia tej konkretnej transformacji funkcji? Czy zamierzasz wykorzystać tę przekształconą funkcję jako wkład w nadzorowany problem uczenia się? Jeśli tak, rozważ dodanie tych informacji, ponieważ mogą one pomóc innym lepiej odpowiedzieć na to pytanie.
Nitesh
1
@Nitesh, Proszę zobaczyć aktualizację
Mangat Rai Modi
Odpowiedzi można znaleźć tutaj: datascience.stackexchange.com/questions/4967/…
MrMeritology
Przepraszam, ale nie mogę komentować. @ AN6U5, czy mógłbyś proszę rozszerzyć sposób jednoczesnego rozważania dnia tygodnia i godziny po twoim niesamowitym podejściu? Walczę o to od tygodnia, a także opublikowałem pytanie, ale nie przeczytałeś go.
Seymour

Odpowiedzi:

33

Najbardziej logicznym sposobem na przekształcenie godziny są dwie zmienne, które wychylają się do przodu i do tyłu z ujścia. Wyobraź sobie pozycję końca wskazówki godzinowej 24-godzinnego zegara. Te xwahania pozycji iz powrotem z umywalką z ypozycji. Na zegarze 24-godzinnym można to osiągnąć z x=sin(2pi*hour/24), y=cos(2pi*hour/24).

Potrzebujesz obu zmiennych lub utracisz właściwy ruch w czasie. Wynika to z faktu, że pochodna grzechu lub cos zmienia się w czasie, gdy (x,y)pozycja zmienia się płynnie, gdy przemieszcza się po okręgu jednostki.

Na koniec zastanów się, czy warto dodać trzecią cechę do śledzenia czasu liniowego, którą można skonstruować w ciągu moich godzin (lub minut lub sekund) od początku pierwszego rekordu, uniksowego znacznika czasu lub czegoś podobnego. Te trzy cechy zapewniają następnie przybliżenie zarówno cyklicznego, jak i liniowego postępu czasu, np. Można wyciągnąć zjawisko cykliczne, takie jak cykle snu w ruchu ludzi, a także liniowy wzrost, jak populacja w funkcji czasu.

Mam nadzieję że to pomoże!

Dodając odpowiedni przykładowy kod wygenerowany dla innej odpowiedzi:

Przykład realizacji:

# 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

wprowadź opis zdjęcia tutaj

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

Teraz wypróbujmy to:

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

wprowadź opis zdjęcia tutaj

Ledwo widać, że niektóre są po północy dołączone do zielonego gromady przed północą. Teraz pozwala zmniejszyć liczbę klastrów i pokazać, że przed i po północy można połączyć bardziej szczegółowo w jednym klastrze:

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

wprowadź opis zdjęcia tutaj

Zobacz, jak niebieski klaster zawiera czasy sprzed i po północy, które są skupione w tym samym klastrze ...

CO BYŁO DO OKAZANIA!

AN6U5
źródło
Świetny sposób na poradzenie sobie z tym. Dałoby to 0 i 23 godziny podobnych wyników, ale czy nie sprawi, że czas rano / godziny będzie podobny? Co tak naprawdę jest oddzielone 12-godzinnym oknem.
Mangat Rai Modi
Czas 12 godzin (AM / PM) nie działa, wystarczy przekonwertować go na 24 godziny.
AN6U5
Właśnie zauważyłem, że dzielisz przez 24. Kiedy podałeś analogię do zegara, myślałem, że to standardowy 12-godzinny zegar. Jednak bierzesz 24-godzinny zegar. To wydaje mi się najlepszym sposobem na transformację. Dziękuję Ci!
Mangat Rai Modi
Niesamowita odpowiedź Dokładnie to, czego szukałem Dzięki.
Aditya,
Przyjęta odpowiedź łącząca sin () i cost () jest świetna; tutaj jako uzupełnienie kolejne bardzo szczegółowe i miłe wyjaśnienie Iana London'a.
FlorianH
3

Pytanie jest bardzo interesujące i nie pamiętam o ciekawych odpowiedziach. Z tego powodu odważę się podać jedno możliwe rozwiązanie, nawet jeśli wygląda na wystarczająco szalone.

Zwykle unika się posiadania tych samych informacji w wielu funkcjach, ponieważ wiele algorytmów nie może sobie z tym poradzić. Ale to nie jest przypadkowy las. Kontrastowe regresje liniowe (i wszystkie modele oparte na podobnych pomysłach), losowe lasy testują wszystkie cechy, biorąc pod uwagę każdą cechę pojedynczo. W ten sposób można kodować te same informacje na wiele sposobów bez wpływu na wydajność uczenia się, tylko przestrzeń i czas pracy.

Tak więc moją propozycją byłoby utworzenie 24 operacji, każda z form . To tak, jakbyś kodował czas w lokalnych strefach czasowych. W ten sposób dajesz rf okazję do wykrycia za pomocą tych samych jednostek interesujących aglomeracji w ciągu kilku godzin, ponieważ każda możliwa godzina ma szansę zostać poprawnie zakodowana w co najmniej 1 z 24 funkcji.(h+offset)

Marnuje trochę miejsca i czasu, ale spróbuję zobaczyć, jak to działa.

rapaio
źródło
0

Idealnie nie potrzebujesz żadnej transformacji. Względną różnicę czasu między dwoma punktami można wykorzystać jako funkcję odległości. Gdzie klasyfikacja może być oparta na tym.

w 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
źródło
1
Zgadza się, ale pytanie wymaga czegoś innego ...
Aditya,