数学アルゴリズムのテスト

この記事は、ビジネス向けの数学アルゴリズムの産業開発に直接または間接的に関与する人々、および批判を聞きたいプロのテスター向けに書かれています。



画像





私たちは誰ですか



当社は、データ分析、予測、分類、その他のデータ化分野で10年以上にわたって独自のソフトウェアソリューションを開発しているロシアの会社で働いています。 すべてのソリューションは抽象的なツールではなく、顧客の特定の問題を解決するための統合システムです。 主な機能は、高品質の結果を得るために研ぎ澄まされた独自の開発アルゴリズムです。



当社には、数学者とプログラマーの間で明確な責任分担があります。 明確に強調するために、数学者のチームはプログラマーのチームとほぼ同じ大きさであると付け加えます。



どの問題が議論されます



簡略化すると、新しいソリューションを作成するプロセスは次のようになります。



画像

アイデアをテストした後、数学者は完全な分析システムを開発し、そこにすべての顧客のプロセスを実装します。 このシステムでは、原則として、戦闘に近い条件でのアルゴリズムの動作のデモが行われます。 私たちの数学者はMatlabでの作業を好むため、彼らのシステムは迅速な仮説検定に非常に便利ですが、多くの理由で産業目的には使用できません。 適切な開発環境、たとえば.NET(この場合)で同じことを再実装する必要があります。 この瞬間は、プロセスの弱いリンクです。

産業用ソフトウェアの開発者には、Matlabのドキュメントとソースコードがありますが、数学者の教育と経験はありません。 しかし、まったく同じアルゴリズムが彼のペンの下から出てくるはずです。 ここで問題が発生します。プロトタイプの数学者に準拠するために、アルゴリズムの工業用バージョンを適切にテストする方法は?



このタスクの難しさは何ですか?



数学的アルゴリズムでエラーをキャッチすること、たとえば2つのDBMSを同期するプロセスでエラーをキャッチすることは、2つの根本的に異なるタスクであることに注意してください。 データベースを使用すると、同期後のレコード数が同じになり、チェックサムが同じになるため、テストに合格します。 わかりやすく、自動化も比較的簡単です。



予測アルゴリズムは、入力を受け入れ、数十または数百の値(浮動小数点数)を出力します。 1つのアルゴリズムはMatlabの画面にこれらの数値を表示し、もう1つのアルゴリズムはC#コードの変数に書き込みます。 それらを比較する方法は? 浮動小数点計算の精度は限られているため、最後の文字まで一致しません。 比較の精度を制限する方法は? 私たちの状況では、予測の品質が2〜3%低下することが重要です。 場合によっては、ビジネスに与える効果に匹敵します。



問題の解決方法



テスト手順は次のようになりました。



  1. 入力データセットの生成-いわゆる標準。 この作業は、おなじみの環境である数学者-Matlabによって事前に行われます。
  2. 標準を吸収し、それらをテストに変えるテストシステムを起動します。 標準に従って、Matlabでこのシステムを開発しました。どのアルゴリズムを実行する必要があるか、どの順序でデータを転送するか、出力に何を期待するかを理解しています。
  3. 入力としてベンチマークを使用して、Matlabでプロトタイプを実行します。 この手順は、次のように簡単に実行できます。 標準とプロトタイプの両方が、1つのシステム-Matlabのフレームワーク内で作成されます。
  4. MatlabからC#へ、またはその逆への入力および出力データの変換を伴う、産業用.NETバージョンの起動。 このようなブリッジを構築するためのいくつかのアプローチを試みた後、Matlabの最新バージョンですぐに実装できるC#インターフェイスに落ち着きました。 MatlabからほぼすべてのタイプのC#データをインスタンス化し、アセンブリをロードし、関数を実行できます。
  5. システムは両方のアルゴリズムの結果を受け取り、比較手順を開始します。
  6. 比較手順により、0(一致しない)または1(一致)の判定が得られます。 比較手順は、アルゴリズムごとに手動で開発する必要があります。 特定の数量を丸める機能は、値にさまざまな許容差を与えます。 さらに、いくつかのアルゴリズムにはランダム変数の生成が含まれます。
  7. ステップ2〜7は、Matlabコンソールの起動によって自動化され、スケジュールに従って実行されます。


C#-Matlabインターフェイス、比較機能、および2つのシステムのデバッグを開発する必要があるため、平均アルゴリズムを削減するには5〜10日かかります。これは開発に費やした時間に匹敵します。 この時間は、「 基本的には正常に機能し、何かを生成する 」アルゴリズムと、数学者が意図したものを完全に繰り返すアルゴリズムとの違いを反映しています。



繰り返しになりますが、リストを見ると、私たちが直面する困難は次のとおりです。



  1. 入力データをMatlabに送信する必要があり、C#=>で変換を開発する必要があります。
  2. 比較および関連する丸めの問題およびその他の機能により、コードを記述することが難しくなり、デバッグ時に誤解を招く可能性があります。
  3. 同期デバッグ:何が問題なのかを理解するには、2つのシステムで2つのデバッガーを同時に実行する必要がありますが、これは機能しますが、シャーマニズムが必要です。
  4. 包括的な標準セットの生成(数学の問題)。 すべての種類の入力をソートすることはできません。また、アルゴリズムには、すべての組み合わせでの共同検証のための分岐が多すぎる可能性があります。
  5. 各アルゴリズムには、結果を比較するための手動で開発された独自の関数が必要です。


エンコード機能



C#で産業用コードを開発するとき、すぐにMatlabと「ミックス」する必要があると思います。 私たちの生活を楽にするために、いくつかの簡単なトリックを使用します。



比較操作に注意を払うことが重要です。 浮動小数点数が等しいかどうかを比較することは不可能です(再シャーパーがこれについて説明します)。 代わりに

a == b
      
      



使用されています

 Math.Abs(a – b) < eps
      
      





それほど明白ではないが、数学的アルゴリズムで明確に示されているのは、その比較
 <= >= < >
      
      



同じ理由で違法:
 if(a <= b) => if(a < b + eps) if(a < b) => if(a < b - eps)
      
      





NaN(数ではない)やInfinityなどの疑似量を使用して処理の詳細を掘り下げることも重要です。 たとえば、Matlabの場合:
 max(0, NaN) = 0
      
      



C#で
 Math.Max(0, double.NaN) = NaN
      
      





他の方法



人生を楽にするための可能な方法は、私たちが行っていないか、行っていないが、その道はまだ旅していないことです:



  1. 1人によるプロトタイプバージョンと製品バージョンの両方の開発。 この組み合わせにより、次のように人生が大幅に簡素化されます。 これらの人々をお互いから理解するタスクを削除します。 結果がすぐに必要な場合、他の方法はありません。 しかし、実際にそのような多様な仕事ができる人はいません。 それをやりたい人はもっと少ない。

    通常の数学は産業開発の限界と原則に立ち返り、通常のプログラマーはエンジニアであり、数学者ではありません(そう、Yandexではありません)。
  2. ユニットテストの製品版(数学者または産業開発者による)。 MatlabとC#の共同テストの費用のかかる手順の代わりに、Matlabからダウンロードした番号でC#のみをテストします。 この場合、すべてのテストは、完全にC#の便利なフレームワークを使用して実行できます。

    これにより多くの労力を節約できるように見えますが、主なものは失われます。2つのアルゴリズムの同時比較です。 Matlabのバージョンに変更が加えられた場合、タイムリーにそれについて知ることができないか、これらの変更がどれほど重要であるか(それらがどのテストを台無しにしたか)を認識しないかもしれません。
  3. Matlabから直接.NETアセンブリをビルドします。 残念ながら、このための通常の(パフォーマンスと信頼性の観点から)フレームワークはありません。 Matlabは強力なツールですが、他の目的のために作成されました。
  4. C#で、マトリックス、インデックス、条件などの通常の処理を使用して、Matlabスタイルでコードを記述できるフレームワークを開発します。そのような開発が存在します: numerics.mathdotnet.comilnumerics.netですが、不完全です。


最後に



このパスを入力して、私たちのアルゴリズムの検証が非自明なマルチパスプロセスになることを期待していませんでした。 一般に、結果の品質と再現性に満足しており、同様のタスクに直面している人々の意見を聞くことに興味があります。



All Articles