周期的順序属性を変換する良い方法は何ですか?


21

属性として「時間」フィールドがありますが、周期的な値を取ります。「23」や「0」時間などの情報を保持するように機能を変換するにはどうすればよいでしょうか。

私が考えることができる1つの方法は、変換を行うことです: 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
素晴らしい最初の質問!この特定の機能変換を実行する目標について、さらに情報を追加できますか?この変換された機能を教師付き学習問題への入力として使用するつもりですか?もしそうなら、他の人がこの質問によりよく答えるのに役立つかもしれないので、その情報を追加することを検討してください。
ニテシュ

1
@Nitesh、更新を参照してください
マンガライモディ

あなたはここで答えを見つけることができます。datascience.stackexchange.com/questions/4967/...
MrMeritology

申し訳ありませんが、コメントできません。@ AN6U5すばらしいアプローチに続いて曜日と時間を同時に考慮する方法を拡張してください。私は1週間以来これに苦労しており、Qも投稿しましたが、あなたはそれを読みませんでした。
シーモア

回答:


33

時間を変換する最も論理的な方法は、シンクからシンクへと前後にスイングする2つの変数になります。24時間時計の時針の終わりの位置を想像してください。x前後にとシンクのうち位置スイングy位置。24時間制の場合x=sin(2pi*hour/24)、でこれを達成できますy=cos(2pi*hour/24)

両方の変数が必要です。そうでない場合、時間の経過とともに適切な動きが失われます。これは、sinまたはcosのいずれかの微分が時間的に変化するという事実によるものです。この場合、(x,y)位置は単位円の周りを移動するときに滑らかに変化します。

最後に、線形時間をトレースする3番目の機能を追加する価値があるかどうかを検討します。これは、最初のレコードの開始から数時間(または分または秒)、Unixタイムスタンプまたは同様のもので構成できます。これらの3つの機能は、時間の周期的および線形的進行の両方のプロキシを提供します。たとえば、人々の動きの睡眠サイクルなどの周期的現象や、人口対時間などの線形成長を引き出すことができます。

お役に立てれば!

別の回答用に生成したいくつかの関連するサンプルコードを追加します。

達成された場合の例:

# 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)

ここに画像の説明を入力してください

真夜中より前の緑のクラスターには、真夜中より後の時刻が含まれていることがほとんどわかりません。次に、クラスターの数を減らして、深夜の前後に1つのクラスターでより詳細に接続できることを示します。

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

ここに画像の説明を入力してください

青いクラスターに、同じクラスター内で一緒にクラスター化された深夜の前後の時刻がどのように含まれているかを確認してください...

QED!


それを処理する素晴らしい方法。0時間と23時間の同様のスコアが得られますが、午前と午後の時間も同様になりませんか?実際には、12時間のウィンドウで区切られています。
マンガライモディ

12時間(AM / PM)の時間は機能しません。24時間に変換するだけです。
-AN6U5

あなたが24で割っていることに気づきました。あなたが時計にたとえると、標準の12時間時計だと思いました。ただし、24時間クロックを使用しています。それは私にとって変身する最良の方法のようです。ありがとうございました!
マンガライモディ

私は、おかげで探していたまさにアメージング答え...
アーディティヤ

sin()とcost()を組み合わせた受け入れられる答えは素晴らしいです。ここで補足として、イアン・ロンドンによる非常に詳細で素晴らしい説明があります。
FlorianH

3

質問は非常に興味深いものであり、興味深い答えについて読んだことは覚えていません。そのため、たとえそれが十分に狂っているように見えても、1つの可能な解決策を提供することを敢えてします。

通常、多くのアルゴリズムでは処理できないため、複数の機能に同じ情報を含めることは避けます。しかし、これはランダムフォレストの場合ではありません。線形回帰(および同様のアイデアに基づくすべてのモデル)とは対照的に、ランダムフォレストは各機能を1つずつ考慮して、すべての機能をテストします。この方法により、学習パフォーマンス、スペースのみ、実行時間に影響を与えることなく、同じ情報を複数の方法でコーディングできます。

したがって、私の提案は、それぞれのフォーム 24個の特徴を作成することです。h+offset。ローカルタイムゾーンで時間をエンコードするときのようです。したがって、可能性のある各時間は24の機能の少なくとも1つで適切にエンコードされる可能性があるため、rfに同じユニットを使用して数時間で興味深い凝集を検出する機会を与えます。

スペースと時間を無駄にしますが、それがどのように機能するかを試してみます。


0

理想的には、変換は必要ありません。2点間の相対時間差は、距離関数として使用できます。分類はこれに基づいて行うことができます。

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

1
それは大丈夫だけど質問が...何か他のものを必要とする
アーディティヤ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.