DTAI Research Group で使用される時系列距離のライブラリ (ダイナミック タイム ワーピングなど)。このライブラリは、純粋な Python 実装と C での高速実装を提供します。C 実装には依存関係として Cython のみがあります。 Numpy および Pandas と互換性があり、不要なデータ コピー操作が回避されるように実装されています。
ドキュメント: http://dtai distance.readthedocs.io
例:
from dtaidistance import dtw
import numpy as np
s1 = np.array([0.0, 0, 1, 2, 1, 0, 1, 0, 0])
s2 = np.array([0.0, 1, 2, 0, 0, 0, 0, 0, 0])
d = dtw.distance_fast(s1, s2)
この作品を引用すると、
ワネス・メールト、キリアン・ヘンドリックス、トゥーン・ヴァン・クラエネドンク、ピーター・ロベレヒト、ヘンドリック・ブロックール、ジェシー・デイヴィス。
DTAIdistance (バージョン v2)。ゼノド。
http://doi.org/10.5281/zenodo.5901139
v2 の新機能:
int
の代わりにssize_t
を一貫して使用することで、64 ビット マシン上でより大きなデータ構造が可能になり、Numpy との互換性が高まります。max_dist
引数は、PrunedDTW に関する Silva と Batista の研究 [7] に似ていることが判明しました。ツールボックスは、より部分的な距離をプルーニングするため、PrunedDTW と同等のバージョンを実装するようになりました。さらに、Silva と Batista が提案したように、計算を高速化するために、 max_dist
ユークリッド距離に自動的に設定するuse_pruning
引数が追加されています (新しいメソッドub_euclidean
が利用可能です)。dtaidistance.dtw_ndim
パッケージの多次元シーケンスのサポート。 $ pip install dtaidistance
または
$ conda install -c conda-forge dtaidistance
pip のインストールには、Numpy 互換の C コードを (Cython を使用して) コンパイルするための依存関係として Numpy が必要です。ただし、この依存関係はオプションであり、削除できます。
ソース コードは github.com/wannesm/dtai distance で入手できます。
コンパイル中に問題が発生した場合 (C ベースの実装や OpenMP が利用できないなど)、その他のオプションについてはドキュメントを参照してください。
from dtaidistance import dtw
from dtaidistance import dtw_visualisation as dtwvis
import numpy as np
s1 = np.array([0., 0, 1, 2, 1, 0, 1, 0, 0, 2, 1, 0, 0])
s2 = np.array([0., 1, 2, 3, 1, 0, 0, 0, 2, 1, 0, 0, 0])
path = dtw.warping_path(s1, s2)
dtwvis.plot_warping(s1, s2, path, filename="warp.png")
距離は 2 つの数値シーケンスに基づいてのみ測定されます。
from dtaidistance import dtw
s1 = [0, 0, 1, 2, 1, 0, 1, 0, 0]
s2 = [0, 1, 2, 0, 0, 0, 0, 0, 0]
distance = dtw.distance(s1, s2)
print(distance)
最速のバージョン (30 ~ 300 回) は c を直接使用しますが、入力として配列 (double 型) を必要とし、(オプションで) max_dist
ユークリッドの上限に設定することで計算をプルーニングします。
from dtaidistance import dtw
import array
s1 = array.array('d',[0, 0, 1, 2, 1, 0, 1, 0, 0])
s2 = array.array('d',[0, 1, 2, 0, 0, 0, 0, 0, 0])
d = dtw.distance_fast(s1, s2, use_pruning=True)
または、numpy 配列 (dtype double または float を使用) を使用することもできます。
from dtaidistance import dtw
import numpy as np
s1 = np.array([0, 0, 1, 2, 1, 0, 1, 0, 0], dtype=np.double)
s2 = np.array([0.0, 1, 2, 0, 0, 0, 0, 0, 0])
d = dtw.distance_fast(s1, s2, use_pruning=True)
使用可能な引数については、 __doc__
を確認してください。
print(dtw.distance.__doc__)
動的プログラミング アルゴリズムが探索している一部のパスを早期に停止したり、距離測定の計算を調整したりするための多くのオプションが予測されています。
window
: 2 つの対角線から離れる方向へのシフトは、この量までのみ許可されます。max_dist
: 返された距離測定値がこの値より大きい場合は停止します。max_step
: この値より大きいステップは許可されません。max_length_diff
: 2 つの系列の長さの差が大きい場合、無限大を返します。penalty
: 圧縮または拡張が適用される場合に追加されるペナルティ (距離に加えて)。psi
: シーケンスの開始および/または終了を無視するための Psi 緩和 (循環シーケンスの場合) [2]。use_pruning
: ユークリッドの上限に基づいて計算をプルーニングします。 距離の次に、行列全体で考えられるすべてのワーピング パスも確認したい場合は、次のようにします。
from dtaidistance import dtw
s1 = [0, 0, 1, 2, 1, 0, 1, 0, 0]
s2 = [0, 1, 2, 0, 0, 0, 0, 0, 0]
distance, paths = dtw.warping_paths(s1, s2)
print(distance)
print(paths)
すべてのワーピング パスを含むマトリックスは次のように視覚化できます。
from dtaidistance import dtw
from dtaidistance import dtw_visualisation as dtwvis
import random
import numpy as np
x = np.arange(0, 20, .5)
s1 = np.sin(x)
s2 = np.sin(x - 1)
random.seed(1)
for idx in range(len(s2)):
if random.random() < 0.05:
s2[idx] += (random.random() - 0.5) / 2
d, paths = dtw.warping_paths(s1, s2, window=25, psi=2)
best_path = dtw.best_path(paths)
dtwvis.plot_warpingpaths(s1, s2, paths, best_path)
先頭と末尾のマッチングを緩和するpsi
パラメーターに注目してください。この例では、正弦波がわずかにずれているにもかかわらず、完全に一致します。
シーケンスのリスト内のすべてのシーケンス間の DTW 距離測定を計算するには、メソッドdtw.distance_matrix
を使用します。変数を設定して、多かれ少なかれ C コード ( use_c
およびuse_nogil
) と並列実行または直列実行 ( parallel
) を使用できます。
distance_matrix
メソッドはリスト/配列のリストを想定しています。
from dtaidistance import dtw
import numpy as np
series = [
np.array([0, 0, 1, 2, 1, 0, 1, 0, 0], dtype=np.double),
np.array([0.0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0]),
np.array([0.0, 0, 1, 2, 1, 0, 0, 0])]
ds = dtw.distance_matrix_fast(series)
または行列 (すべての系列が同じ長さの場合):
from dtaidistance import dtw
import numpy as np
series = np.matrix([
[0.0, 0, 1, 2, 1, 0, 1, 0, 0],
[0.0, 1, 2, 0, 0, 0, 0, 0, 0],
[0.0, 0, 1, 2, 1, 0, 0, 0, 0]])
ds = dtw.distance_matrix_fast(series)
距離測定行列の一部のみを埋めるように計算を指示できます。たとえば、計算を複数のノードに分散する場合や、ソース シリーズとターゲット シリーズのみを比較する場合などです。
from dtaidistance import dtw
import numpy as np
series = np.matrix([
[0., 0, 1, 2, 1, 0, 1, 0, 0],
[0., 1, 2, 0, 0, 0, 0, 0, 0],
[1., 2, 0, 0, 0, 0, 0, 1, 1],
[0., 0, 1, 2, 1, 0, 1, 0, 0],
[0., 1, 2, 0, 0, 0, 0, 0, 0],
[1., 2, 0, 0, 0, 0, 0, 1, 1]])
ds = dtw.distance_matrix_fast(series, block=((1, 4), (3, 5)))
この場合の出力は次のようになります。
# 0 1 2 3 4 5
[[ inf inf inf inf inf inf] # 0
[ inf inf inf 1.4142 0.0000 inf] # 1
[ inf inf inf 2.2360 1.7320 inf] # 2
[ inf inf inf inf 1.4142 inf] # 3
[ inf inf inf inf inf inf] # 4
[ inf inf inf inf inf inf]] # 5
距離行列は時系列クラスタリングに使用できます。 scipy.cluster.hierarchy.linkage
などの既存のメソッド、または含まれている 2 つのクラスタリング メソッドのいずれかを使用できます (後者は SciPy リンケージ メソッドのラッパーです)。
from dtaidistance import clustering
# Custom Hierarchical clustering
model1 = clustering.Hierarchical(dtw.distance_matrix_fast, {})
cluster_idx = model1.fit(series)
# Augment Hierarchical object to keep track of the full tree
model2 = clustering.HierarchicalTree(model1)
cluster_idx = model2.fit(series)
# SciPy linkage clustering
model3 = clustering.LinkageTree(dtw.distance_matrix_fast, {})
cluster_idx = model3.fit(series)
完全なクラスタリング ツリー ( HierarchicalTree
またはLinkageTree
) を追跡するモデルの場合、ツリーを視覚化できます。
model.plot("myplot.png")
オプション:
発達:
DTAI distance code.
Copyright 2016-2022 KU Leuven, DTAI Research Group
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.