4

私は外国為替市場向けの自動取引ソフトウェアを設計しています。MYSQLデータベースには、5分間隔で何年もの市場データがあります。価格と時間に加えて、このデータには4つの異なる指標があります。

[Time|Price|M1|M2|M3|M4] 
x ~400,0000

Timeは主キーであり、M1スルーM4はさまざまなメトリック(標準偏差や移動平均の傾きなど)です。

これが実際の例です(抜粋:)

+------------+--------+-----------+--------+-----------+-----------+
|  Time      | Price  |     M1    |   M2   |    M3     |     M4    |
+------------+--------+-----------+--------+-----------+-----------+
| 1105410300 | 1.3101 |   12.9132 | 0.4647 |   29.6703 |        50 |
| 1105410600 | 1.3103 |    14.056 | 0.5305 | 29.230801 |        50 |
| 1105410900 | 1.3105 |   15.3613 | 0.5722 |   26.8132 |        25 |
| 1105411200 | 1.3106 | 16.627501 | 0.4433 | 24.395599 |  26.47059 |
| 1105411500 | 1.3112 |   18.7843 | 1.0019 | 24.505501 |    34.375 |
| 1105411800 | 1.3111 |   19.8375 | 0.5626 |        20 |   32.8125 |
| 1105412100 | 1.3105 |   20.0168 | 0.6718 |    9.7802 |   23.4375 |
| 1105412400 | 1.3105 |   20.4538 | 0.8943 |     7.033 |   23.4375 |
| 1105412700 | 1.3109 |   21.6078 | 0.4902 |   11.7582 |   29.6875 |
| 1105413000 | 1.3104 |   21.2045 |  1.565 |    8.6813 |    21.875 |
+------------+--------+-----------+--------+-----------+-----------+...400k more

M1、、、の入力が与えられた場合、M2(迅速かつ正確に)5,000個の最も近い一致を見つけたいM3と思います。M4

サンプル入力:

+------------+--------+-----------+--------+-----------+-----------+
|  Time      | Price  |     M1    |   M2   |    M3     |     M4    |
+------------+--------+-----------+--------+-----------+-----------+
| 1205413000 | 1.4212 |   20.1045 | 1.0012 |    9.1013 |    11.575 |
+------------+--------+-----------+--------+-----------+-----------+

これらの各メトリックは「ディメンション」と見なすことができnearest neighbor search、この多次元空間で最も近いデータポイントを見つけるために実行できると考えました。

これを行う最も簡単な方法は、すべてのデータポイントを反復処理し、入力ポイントまでの多次元距離を測定することです。しかし、スピードが重要です!

K-D Trees私はこの目的のために使用されると呼ばれるものについて読みました。誰かがMYSQLでこれを実装する方法を説明するいくつかの資料を説明または提供してくれますか?

テーブルを前処理することはできますが、入力はリアルタイムで受信されます。

現在、各ディメンションのデータの周りに個別に大まかなクラスターを作成しています。

INSERT INTO Dim1 SELECT * FROM myTable AS myTable USE INDEX(M1) WHERE myTable.M1 < currentM1 ORDER BY M1 DESC LIMIT 2500;
INSERT INTO Dim1 SELECT * FROM myTable AS myTable USE INDEX(M1) WHERE myTable.M1 > currentM1 ORDER BY M1  ASC LIMIT 2500;

INSERT INTO Dim2 SELECT * FROM myTable AS myTable USE INDEX(M2) WHERE myTable.M2 < currentM2 ORDER BY M2 DESC LIMIT 2500;
INSERT INTO Dim2 SELECT * FROM myTable AS myTable USE INDEX(M2) WHERE myTable.M2 > currentM2 ORDER BY M2  ASC LIMIT 2500;

INSERT INTO Dim3 SELECT * FROM myTable AS myTable USE INDEX(M3) WHERE myTable.M3 < currentM3 ORDER BY M3 DESC LIMIT 2500;
INSERT INTO Dim3 SELECT * FROM myTable AS myTable USE INDEX(M3) WHERE myTable.M3 > currentM3 ORDER BY M3  ASC LIMIT 2500;

INSERT INTO Dim4 SELECT * FROM myTable AS myTable USE INDEX(M4) WHERE myTable.M4 < currentM4 ORDER BY M4 DESC LIMIT 2500;
INSERT INTO Dim4 SELECT * FROM myTable AS myTable USE INDEX(M4) WHERE myTable.M4 > currentM4 ORDER BY M4  ASC LIMIT 2500;

私が興味を持っているのは、値ではなくランクによる距離であることを理解することが重要です。

編集:私はそれを行う方法を少し理解することに近づいています(私は思う):各メトリックの各行を前処理percentileし、その範囲内の位置(パーセント単位)を表すaを割り当てる必要があります。

たとえば、次の任意の値に対してM1

percentile = (#  rows with values less than input)/(# total rows) 

入力のパーセンタイルを計算し、それを実際の値の代わりに最近傍検索に使用すると、ディメンションとして使用できるようにさまざまなメトリックを効果的にスケーリングできます。

しかし、実際の検索方法についてはまだ迷っています。これはMySQLで効率的に達成することさえ可能ですか?

4

1 に答える 1

0

次のようなクエリを実行できるはずです。

SELECT * FROM myTable
WHERE M1 BETWEEN searchM1 - radiusM1 AND searchM1 + radiusM1
  AND M2 BETWEEN searchM2 - radiusM2 AND searchM2 + radiusM2
  AND M3 BETWEEN searchM3 - radiusM3 AND searchM3 + radiusM3
  AND M4 BETWEEN searchM4 - radiusM4 AND searchM4 + radiusM4

もちろん、球の場合、すべてのradius値は同じになります。次に、必要なレコード数に近づくまで半径を調整します。二分探索をお勧めします。

分布をいじりたいかどうかはわかりませんが、そうすると仮定すると、各検索値に、テーブル内の2つの値の間にランクを付ける必要があります(たとえば、ランク5が5.5の場合)。 、ランク6は5.9、検索値は5.6の場合、検索ランクは5.5になる可能性があります)

于 2011-08-11T03:46:37.773 に答える