순환 서수 속성을 변환하는 좋은 방법은 무엇입니까?


21

내 속성으로 '시간'필드가 있지만 주기적 값이 필요합니다. '23'과 '0'시간과 같은 정보를 유지하기 위해 기능을 어떻게 변환 할 수 있습니까?

내가 생각할 수있는 한 가지 방법은 변환을 수행하는 것입니다. 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]

그러한 속성을 처리하는 표준이 있습니까?

업데이트 : 임의의 숲 분류기를 훈련시키기 위해 감독 학습을 사용할 것입니다!


1
훌륭한 첫 질문! 이 특정 기능 변환을 수행하려는 목표에 대한 정보를 추가 할 수 있습니까? 이 변형 된 기능을지도 학습 문제에 대한 입력으로 사용 하시겠습니까? 그렇다면 다른 사람들이이 질문에 더 잘 대답 할 수 있도록 해당 정보를 추가하십시오.
Nitesh

1
@Nitesh, 업데이트를 참조하십시오
Rai Modi

여기에서 답변을 찾을 수 있습니다 : datascience.stackexchange.com/questions/4967/…
MrMeritology

죄송하지만 댓글을 달 수 없습니다. @ AN6U5 당신은 놀라운 접근 방식에 따라 요일과 시간을 simultaneously 고려하는 방법을 확장 할 수 있습니까? 일주일 이래로 어려움을 겪고 있으며 Q도 게시했지만 읽지 않았습니다.
Seymour

답변:


33

시간을 변환하는 가장 논리적 인 방법은 싱크대에서 앞뒤로 움직이는 두 가지 변수입니다. 24시 시계의 시침 끝 위치를 상상해보십시오. x위치 스윙은 함께 갔다 싱크에서 백업 y위치. 24 시간 시계를 들어 당신이 이것을 달성 할 수있다 x=sin(2pi*hour/24), y=cos(2pi*hour/24).

두 변수가 모두 필요하거나 시간을 통한 적절한 이동이 손실됩니다. 이는 (x,y)원 또는 원 주위를 이동함에 따라 위치가 매끄럽게 변할 때 sin 또는 cos의 파생어가 시간에 따라 변하기 때문입니다.

마지막으로, 선형 레코드를 추적하는 세 번째 기능을 추가 할 가치가 있는지 고려하십시오. 첫 번째 레코드의 시작 또는 유닉스 타임 스탬프 또는 이와 유사한 것으로 시작하여 몇 시간 또는 몇 분 또는 몇 초를 구성 할 수 있습니다. 이 세 가지 기능은 주기적 및 선형 시간 진행 모두에 대한 프록시를 제공합니다. 예를 들어 사람들의 운동에서 수면주기와 같은 순환 현상을 제거하고 인구 대 시간과 같은 선형 성장을 이끌어 낼 수 있습니다.

이것이 도움이되기를 바랍니다!

다른 답변을 위해 생성 한 관련 예제 코드 추가 :

달성중인 경우의 예 :

# 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

여기에 이미지 설명을 입력하십시오

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

이제 시도해보십시오.

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

여기에 이미지 설명을 입력하십시오

자정 이전 녹색 클러스터에 자정 이후 시간이 포함되어 있음을 간신히 알 수 있습니다. 이제 클러스터 수를 줄이고 자정 전후에 단일 클러스터에서 더 자세히 연결할 수 있음을 보여줍니다.

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

여기에 이미지 설명을 입력하십시오

파란색 클러스터에 자정 전후의 시간이 동일한 클러스터에 함께 클러스터 된 시간을 포함하는 방법을 확인하십시오.

QED!


그것을 처리하는 훌륭한 방법. 0과 23 시간의 비슷한 점수를 주지만 오전 / 오후 시간도 비슷하지 않습니까? 실제로 12 시간 창으로 구분됩니다.
Mangat Rai Modi

12 시간 (AM / PM) 시간이 작동하지 않습니다. 24 시간으로 변환하면됩니다.
AN6U5

방금 당신이 24로 나누는 것을 알았습니다. 당신이 시계를 비유했을 때, 나는 그것이 표준 12 시간 시계라고 생각했습니다. 그러나 24 시간 시계를 사용하고 있습니다. 내가 변형하는 가장 좋은 방법 인 것 같습니다. 고맙습니다!
Mangat Rai Modi

놀라운 답변 정확히 내가 찾던 것은 감사합니다 ..
Aditya

sin () & cost ()를 결합하여 허용되는 대답은 훌륭합니다. 여기 이안 런던하여 또 다른 매우 상세하고 좋은 설명이 보완.
FlorianH

3

질문은 매우 흥미롭고 흥미로운 답변에 대해 읽은 것을 기억하지 않습니다. 그 때문에 나는 충분히 미친 것처럼 보일지라도 당신에게 하나의 가능한 해결책을 제공하기 위해 감히.

많은 알고리즘이 처리 할 수 ​​없기 때문에 일반적으로 여러 기능에서 동일한 정보를 갖는 것을 피합니다. 그러나 이것은 임의의 숲이 아닙니다. 선형 회귀 (및 유사한 아이디어를 기반으로하는 모든 모델)와 대조적으로 임의 포리스트는 각 기능을 한 번에 하나씩 고려하여 모든 기능을 테스트합니다. 이런 식으로 학습 성과, 공간 및 실행 시간에 영향을주지 않고 여러 가지 방법으로 동일한 정보를 코딩 할 수 있습니다.

(h+offset)

그것은 약간의 공간과 시간을 낭비하지만, 그것이 어떻게 작동하는지 보려고 노력할 것입니다.


0

이상적으로는 변환이 필요하지 않습니다. 두 지점 사이의 상대 시간차는 거리 함수로 사용할 수 있습니다. 분류에 근거 할 수있는 곳.

자바에서 :

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);
        }
    }
}

1
괜찮습니다.하지만 질문에는 다른 것이 필요합니다.
Aditya
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.