web-dev-qa-db-ja.com

日付のリストから頻度パターンを検出する

特定のイベントが発生した日付のリストがあります。イベントの特定の発生が次のことを可能にすることを考慮に入れて:

  • 一回限りのものになるか
  • Nか月ごとに発生する定期的なシリーズに参加する(Nは整数)

日付は互いに関連しているので、分類してグループ化したいと思います。つまり、定期的なシリーズがいつ発生し、セット内のどの日付がその定期的なシリーズに属し、どの日付が1回限りのイベントであるかを検出できるようにしたいと考えています。

例:

  • 20/01/2016, 20/02/2016, 20/03/2016, 20/04/2016は、月に1回発生するイベントのセットです。
  • 20/01/2016, 25/01/2016, 20/02/2016, 20/03/2016, 20/04/2016は、1回限りのイベントである2番目のイベントを除いて、月に1回発生するイベントのセットです。
  • 20/01/2016, 20/03/2016, 20/04/2016, 20/05/2016, 20/07/2016は、1度だけのイベントである3番目のイベントを除いて、2か月に1回発生するイベントのセットです。

決定的なアルゴリズムを作成することは不可能であることを理解しています(つまり、最後の例では、3つの異なるイベントストリームが表示されていません。 2016年5月5日、そして最後に2016年7月20日の1回限りのイベント?).

アルゴリズムが十分に簡単で、詳細に説明されている場合は、アルゴリズムを自分で実装してください。ライブラリが必要な場合は、プロジェクトがPythonであることを考慮してください。

2
user2891462

要件から除外したのは、それらを分類するために使用される情報です。

あなたが提示したデータを考えると、私はこれを解決可能にするために2つの仮定をしなければなりません

  1. セットで指定された各日付が同じイベントであること、つまり、考慮すべき他の識別データがないこと
  2. イベントが発生した日に分類したい

それらが成立する場合、発生したすべての日をキーとして使用して、各イベントを辞書にダンプする必要があります。これらのイベントをAとしましょう。

イベントのセットが収集されたのと同じ期間に、発生した毎日のイベントを作成します。そのセットを別の辞書に入れます。これで、その月の最初、秒、3番目などが何回起こったかを数える方法があります。これらのイベントをBと呼びましょう。

その月の毎日がバケツです。 31バケットまで可能です。各バケットについて、AをBで割ります。

毎月のイベントが問題の日に必ず発生した場合、スコアは1になります。発生しなかった場合、スコアは0になります。分類のカットオフ値は、これら2つの数値の間のどこにでも設定できます。

2
candied_orange

他の回答と完全に区別されるわけではありませんが、おそらく一連の histograms を使用します。データを取得して、「バケット」または「ビン」の異なるセットに分類します。

  • 曜日
  • 月の日
  • 隔週の日
  • 年の日
  • 半年の日
  • その他の興味深いシナリオ...

これらのビンの一部には、他のほとんどのビンよりも多くのものが含まれます。 1つまたは多くのビンが表示される場合があります。これらのビンのサイズはそれぞれスコアであり、ビン内の日付に関連付けることができます。

日付ごとに、すべてのビニング戦略とそのスコアがわかります。日付ごとに、ビンをスコアでソートできます。スコアの高いビンが頻度の最も可能性の高い候補になります。たとえば、月曜日に一連の20の日付と15の土地がある場合、毎週行われる会議を検討している可能性があります。

これらのビンの一部が一致することを考慮する必要があります。会議が半年ごとの場合。それはまた、毎月のビニングで良いスコアを得るかもしれません。あなたはおそらく、あまり頻繁ではない候補者がより可能性が高いと仮定したいでしょう。

ここでは、これらの会議がシリーズの一部であることをすでにご存じだと思います。複数のシリーズ会議と非シリーズ会議が混在している場合は、会議の名前や参加者など、他の情報を使用してそれらを区別できます。その場合は、上記の調整を行って、同じ日の会議を日付のビンのスコアにカウントしないようにします。

1
JimmyJames

期間自体が月を含むものとして定義されている場合、基本的な頻度分析は、どの月の日が不釣り合いに多数のイベントを蓄積しているかを調べるだけです。

数か月をスキップできる場合、またはパターンがより長い期間にわたって動作する場合は、妊娠中期、妊娠中期、またはその他のより長い範囲のサイクルの1日を見るでしょう。

このプロセスで何らかの人間の入力がある場合、人間の目はこれらの基本的な分析の結果を確認するときに周期的なパターンをすばやく検出します。

重複する可能性のある多数の同時パターンおよびランダムノイズから個々のパターンを検出および分離しようとしていて、人間の入力なしでそれを実行しようとしている場合、どの方法を使用すればよいのか正確にはわかりませんが、私はそれを疑っています。オーディオ処理分野からのいくつかのテクニックでしょう。

0
Steve

概要

概念的には、次の要素が必要です。

  1. 一連の日付の仮説または可能な解釈を列挙する方法。これはおそらくO(n ^ 2)の複雑さになる可能性があるため、日付のリストが大きい場合は、ある程度の整理が必要になる場合があります。
  2. 与えられた仮説がどれだけ「良い」かを決定するフィットネス関数。

次に、単に仮説を列挙し、答えとして最高のフィットネスを持つものを維持します。

これらの日付を使用した簡単な例を次に示します:20/01/201920/02/201920/04/2019

仮説を列挙する

4つの考えられる仮説があります。

  1. 3つのシングルイベント
  2. 0102の毎月のイベント、および04の1つのイベント
  3. 01の1つのイベントと0204の隔月イベント
  4. 0104の四半期イベント、および02の単一イベント

フィットネス機能

フィットネス関数は、仮説の要素(単一のイベントまたはシリーズ)の総数に異なるペナルティを割り当てる場合があり、より大きな間隔で毎月の繰り返しを優先する場合があります。重みに応じて、異なる「最良の」結果が得られる可能性がありますが、この場合、代替案2がおそらく選択されます。

0

提案されたアルゴリズム

  1. 日付のリストを時系列で昇順に並べ替えます。
  2. リストに日付がある場合は、最初の日付をポップします(これを現在の日付と呼びます)。それ以外の場合、アルゴリズムは終了しました。
  3. 元の日付リストに残っている日付と同じ数の要素を使用して、整数の新しいリストを作成します。この新しいリストのi番目の要素は、元のリストのi番目の日付から現在の日付を区切る月数です。 i番目の日付が現在の日付から整数の月数で区切られていない場合は、何らかの方法で(たとえば-1を使用して)通知します。
  4. このリストでは、-1を無視すると、昇順で並べ替えられた数値のリストがあります。 -1ではない最初の要素を見つけます。その数は、分析するパターンの頻度(月単位)を表します。そのような要素がない場合、current_dateは1回限りのイベントを表すため、手順2に戻ります。
  5. リストの各要素をこの最初の数値で除算して、リストを正規化します。数値がこの最初の数値で割り切らない場合は、-1にします。
  6. 連番を探します(-1は省略)1、2、3、4 ...このシーケンスに属する各エントリは、Nか月ごとに繰り返し発生する日付を表します。
  7. このパターンの一部であったすべての日付をリストからポップします(日付を2つの異なるパターンの一部にすることはできないため)。
  8. 2に戻ります。

実際に見る

したがって、元の投稿の最後の例では、[20/01/2016, 20/03/2016, 20/04/2016, 20/05/2016, 20/07/2016]

  • current_date = 20/01/2016; list=[20/03/2016, 20/04/2016, 20/05/2016, 20/07/2016]
  • number_list=[2, 3, 4, 6]
  • リストの最初の要素:2;正規化されたリスト:number_list=[1, -1, 2, 3]
  • リストのエントリ0、2、3は1, 2, 3のシーケンスを形成するため、同じシリーズの一部であり、2か月ごとに繰り返されます(2は正規化した要素であるため)。
  • それらを分類したら、それらをリストからポップして、list=[20/05/2016]
  • 未分類の新しい日付でもう一度開始します。リストの最初の要素をポップするので、current_date=20/05/2016; list=[]
  • リストにはこれ以上要素がないため、current_dateは1回限りのイベントです。

ご覧のとおり、個々のイベントは、Nか月ごとに1回限りのイベントまたは繰り返しパターンの一部として分類されています。Nは識別されたパターンごとに既知です。

0
user2891462