非線圢蚈画問題の応甚

こんにちは、Habr か぀お、私は䞭孊生ずしお、最適化理論ず最適な非線圢力孊系の合成の分野で研究を始めたした。 ほが同時期に、この分野を普及させ、圌らの経隓や考えを人々ず共有したいずいう芁望がありたした。 これの確認は、Habréに関する私の子䟛たちの未熟な蚘事のいく぀かです。 しかし、圓時、この考えは私にずっお圧倒的でした。 おそらく、私の仕事、経隓の浅さ、批刀やアドバむスで仕事をするこずができない、たたは䜕か他のもののために。 理由を無限に芋぀けようずするこずはできたすが、状況は倉わりたせん。このアむデアを棚に投げお、ここたで安党に眮いおほこりを払いたした。

専門を終えお論文を守る準備をした埌、論理的な質問をしたした。「次は䜕ですか」ほこりの䞋。 しかし、私はより意識的な圢でこの考えに戻りたした。

私は、8幎前から取り組んでいる業界に関連する゜フトりェアの開発ず、最適化手法や機械孊習などの個人的な孊問的バむアスの開発を開始するこずにしたした。



さお、興味のある方ぞ

卒業蚌曞およびその埌の論文の゜フトりェアの実装に携わっおいたので、この問題に「正面から」取り組みたした。システムの柔軟性、䜜成の容易さを気にしたせんでした。 ここで結果を取埗したいずいう欲求は、経隓䞍足ず盞たっお、コヌドを絶えず曞き盎さなければならないずいう事実に぀ながりたしたが、それはもちろん専門的な開発にプラスの圱響を䞎えたせんでした。 すでに私は、私がどのように望んでも、問題を解決するために真っ向から急ぐこずはできないこずを理解しおいたす。 その本質を掘り䞋げ、既存の知識を評䟡し、䞍足しおいるものを理解し、サブゞェクト領域の抂念をクラス、むンタヌフェヌス、および抜象化ず比范する必芁がありたす。 ぀たり、利甚可胜な埋蔵量を実珟し、゜フトりェアアプリケヌションのアヌキテクチャの蚭蚈に適切にアプロヌチする必芁がありたす。

ご想像のずおり、この蚘事は将来のアプリケヌションの最初の芁玠の開発ず説明に専念したす。

開発アプロヌチの定矩ず䞻なタスクの定匏化


Habréには、゜フトりェア開発方法論に関する蚘事が倚数ありたす。 たずえば、 これは䞻なアプロヌチを非垞に明確に説明しおいたす。 それぞれに぀いお説明したしょう。

  1. 「りォヌタヌフォヌルモデル」 -少なくずも芁件が明確に定矩されおいないため、適切ではありたせん。その埌、盞互䜜甚を確立する必芁がある䞀連のアむデアがありたす。
  2. 「Vモデル」 -同じ理由で適合しない
  3. 「むンクリメンタルモデル」は以前のモデルよりも適切なモデルですが、ここでも詳现な圢匏化が必芁です。
  4. 「RADモデル」 -経隓豊富な専門家のチヌムにより適したモデル、
  5. 「アゞャむルモデル」 -芁件を指定する必芁がないずいう基準、および開発プロセスの柔軟性に完党に適合しおおり、
  6. 「反埩モデル」 -仕事は目暙の明確な定矩の必芁性を瀺しおいるずいう事実にもかかわらず、むデオロギヌ的に、そのようなモデルは近いようです「䞻なタスクを定矩する必芁がありたすが、実装の詳现は時間ずずもに進化する可胜性がありたす」、
  7. 「スパむラルモデル」 -提案された゜フトりェアに起因するこずはほずんどない倧芏暡プロゞェクトの実装を目的ずしおいたす。

私はアゞャむルモデルの抂念を厳守しようずしたす。 開発の反埩ごずに、特定の目暙ず目的のセットが提案されたす。これに぀いおは、蚘事でさらに詳しく説明したす。

そのため、珟時点では䞀般的な問題の次の定匏化がありたす開発䞭の゜フトりェアは、さたざたな最適化アルゎリズム叀兞的な分析ず珟代のヒュヌリスティックの䞡方および機械孊習分類、クラスタリング、空間次元削枛、回垰アルゎリズムを実装する必芁がありたす。 最埌の最終目暙は、これらのアルゎリズムを最適制埡合成の分野に適甚し、金融垂堎で取匕戊略を䜜成する方法を開発するこずです。 Scalaが䞻芁な開発蚀語ずしお遞ばれたした。

したがっお、この䜜業では次のように䌝えたす。

  1. 最適化の問題ず、それを研究の基本的な察象ずしお遞択する理由に぀いおは、
  2. 䞻な抜象化ずその実装では、最適化の問題を枛らすこずにより、適甚された問題を解決するこずに基づいたアプロヌチを䜿甚できたす。
  3. K-Meansアルゎリズム、最も単玔なランダム怜玢アルゎリズム、およびそれらを友達にしお単䞀の目暙のために機胜させる方法に぀いお。

最適化


私はほずんどの研究業務を最適化問題の解決に費やしたずいう事実により、この芳点から操䜜する方がより䟿利になりたす。

通垞、最適化問題を解くこずにより、どんなに些现で鈍い蚀語に聞こえおも、䜕らかの「最適な」問題条件の芳点からオブゞェクトの怜玢を意​​味したす。 「最適性」の抂念は、䞻題分野ごずに異なりたす。 たずえば、関数の最小倀を芋぀ける問題では、目的関数の最小倀に察応する点を芋぀ける必芁がありたす。メタ最適化問題では、最適な制埡の合成の問題で、最も正確な結果/最も迅速に満たす/最も安定した結果を䞎えるアルゎリズムのパラメヌタヌを決定する必芁がありたす最短時間でオブゞェクトを最終状態に倉換できるコントロヌラを合成する必芁がありたす。 すべおの専門家は、圌の専門分野に関連するこのタスクのリストを継続できるず確信しおいたす。

数孊では、 非線圢プログラミング問題に特別な泚意が払われたす。 非線圢問題には、他の倚くの応甚問題を枛らすこずができたす。 䞀般的な堎合、非線圢蚈画問題の定匏化には、以䞋を指定する必芁がありたす。


したがっお、この問題の本質は次のように説明できたす。目的関数の最小/最倧倀を提䟛するベクトルを怜玢領域で芋぀ける必芁がありたす。

この問題を解決するための膚倧な数のアルゎリズムがありたす。 埓来、これらは2぀のグルヌプに分けるこずができたす。


原則ずしお、ヒュヌリスティックアルゎリズムは、方向性列挙の方法ずしお認識できたす。 このグルヌプには、かなり有名な遺䌝的アルゎリズム 、 アニヌリングシミュレヌションアルゎリズム 、さたざたなポピュ レヌションアルゎリズムがありたす。 倚数のアルゎリズムが非垞に簡単に説明されおいたす。すべおのタむプのタスクに同時に適した普遍的なアルゎリズムはありたせん。 凞関数をうたく凊理できる人もいれば、レベル線の枓谷構造を持぀関数を扱うこずを目的ずする人もいたす。 人生のように-すべおには独自の専門性がありたす。

䜿甚される抜象化


䞊蚘の掚論に基づいお、 倉換ずアルゎリズムずいう 2぀の抂念を扱う最も簡単な方法は私には思えたす 。 それらに぀いおさらに詳しく説明したす。

倉換


ほずんどすべおのプロシヌゞャ/関数/アルゎリズムは、ある皮の倉換ず芋なすこずができるため、このオブゞェクトを基本的なものの1぀ずしお操䜜したす。

さたざたなタむプの倉換の間に、次の階局が提案されおいたす。



芁玠に぀いおさらに詳しく芋おいきたしょう。


䞍均䞀な倉換クラスコヌド
class InhomogeneousTransformation[A, B](transform: A => B) extends Serializable { def apply(a: A): B = transform(a) def *[C](f: InhomogeneousTransformation[B, C]) = new InhomogeneousTransformation[A, C](x => f(transform(x))) } 

2぀のメ゜ッドのみが含たれおおり、そのうちの1぀がいく぀かの倉換の構成を䜜成する手順を実装しおいるこずがわかりたす通垞ずは異なる方法でのみ。 これは、単玔な倉換からより耇雑な倉換を䜜成するために将来必芁になりたす。

均䞀倉換クラスコヌド
 class HomogeneousTransformation[A](transform: A => A) extends InhomogeneousTransformation[A, A](transform) { } 

ここでは、2぀の型パラメヌタヌが1぀にたずめられたした。

ベクトル関数クラスコヌド
 class VectorFunction[A <: Algebra[A]] (transform: Vector[A] => Vector[A])(implicit converter: Double => A) extends HomogeneousTransformation[Vector[A]](transform) { } 

䞀般化クラスの修正されたパラメヌタヌ化がありたす。 珟圚、このパラメヌタヌは、倉換されたベクトルがどのオブゞェクトのクラスで構成されるかを決定したす。 このコヌド「[A <Algebra [A]]」によっお決定されるクラスに課せられる制限に泚意する必芁がありたす。 制限は次のように衚されたす。ベクトルを構成するオブゞェクトは基本的な算術挔算をサポヌトする必芁があり、おなじみの基本関数指数関数、䞉角関数などの匕数ずしお䜿甚できたす。 詳现なコヌドは、github'eに投皿されおいる゜ヌスで芋るこずができたすリンクは䜜業の最埌にありたす。

Functionクラスのコヌドず、暗黙的に異皮倉換に倉換する方法
 class Function[A <: Algebra[A]] (transform: Vector[A] => A)(implicit converter: Double => A) extends VectorFunction[A](x => Vector("result" -> transform(x))) { def calculate(v: Vector[A]): A = transform(v) } object Function { implicit def createFromInhomogeneousTransformation[A <: Algebra[A]] (transformation: InhomogeneousTransformation[Vector[A], A])(implicit converter: Double => A) = new Function[A](x => transformation(x)) } 

メトリッククラスコヌドず関連する倉換
 class Metric[A](transform: A => Real) extends InhomogeneousTransformation[A, Real](transform) { } object Metric { implicit def createFromInhomogeneousTransformation[A](transformation: InhomogeneousTransformation[A, Real]) = new Metric[A](x => transformation(x)) implicit def toFunction (metric: Metric[Vector[Real]])(implicit converter: Double => Real): Function[Real] = new Function[Real](x => metric(x)) } 

䞊蚘の抜象化は、䞀芋したずころ、問題のさらなる定匏化に必芁ずなる可胜性のある基本的なタむプの倉換をカバヌしおいたす。

アルゎリズム


アルゎリズムを3぀の操䜜のセットずしお定矩するのは自然だず思いたす初期化、反埩郚分、終了。 アルゎリズムの入力で、いく぀かのタスクTaskが提䟛されたす。 初期化䞭に、アルゎリズムの状態が生成され、反埩郚分を繰り返すこずで修正されたす。 最埌に、終了手順を䜿甚しお、アルゎリズムの出力パラメヌタヌのタむプRに察応するオブゞェクトが、アルゎリズムの最埌の状態から䜜成されたす。

クラスコヌドアルゎリズム
 trait GeneralAlgorithm[T <: GeneralTask, S <: GeneralState, R] { def initializeRandomly(task: T): S def initializeFromSeed(task: T, seed: S): S final def initialize(task: T, state: Option[S]): S = { state match { case None => initializeRandomly(task) case Some(seed) => initializeFromSeed(task, seed) } } def iterate(task: T, state: S): S def terminate(task: T, state: S): R def prepareFolder(log: Option[String]): Unit = { if (log.isDefined) { val temp = new File(log.get) if (!temp.exists() || !temp.isDirectory()) temp.mkdir() else { if (temp.exists() && temp.isDirectory()) { def prepare(file: File): Unit = if (file.isDirectory()) { file.listFiles.foreach(prepare) file.delete() } else file.delete() prepare(temp) } } } } def logState(log: Option[String], state: S, fileId: Int): Unit = { log match { case Some(fileName) => { val writer = new ObjectOutputStream(new FileOutputStream(s"${fileName}/${fileId}.st")) writer.writeObject(state) writer.close() } case None => () } } final def work(task: T, terminationRule: S => Boolean, seed: Option[S] = None, log: Option[String] = None): R = { prepareFolder(log) var currentState = initialize(task, seed) var id = 0 logState(log, currentState, id) val startTime = System.nanoTime() while (!terminationRule(currentState)) { currentState = iterate(task, currentState) id = id + 1 currentState.id = id currentState.timestamp = 1e-9 * (System.nanoTime() - startTime) logState(log, currentState, id) } terminate(task, currentState) } } 

したがっお、特定のアルゎリズムを䜜成するには、前述の3぀の手順を再定矩する必芁がありたす。

最適化アルゎリズムずは䜕ですか
非線圢蚈画問題の前述の説明から、最適化アルゎリズムのタスクが関数ず怜玢領域で構成されおいるこずは明らかです珟時点では、怜玢領域が倚次元平行六面䜓で指定されおいる単玔なケヌスに限定しおいたす。
 case class OptimizationTask[A <: Algebra[A]](f: Function[A], searchArea: Map[String, (Double, Double)]) extends GeneralTask { def apply(v: Vector[A]): A = f.calculate(v) } 
通垞、最適化アルゎリズムの状態は 、シングルポむント䜜業䞭に1぀のベクトルが分析および倉曎される堎合たたはポピュレヌション/マルチポむント䜜業䞭に耇数のベクトルが分析および倉曎される堎合のいずれかの圢匏をずりたす。
 abstract class OptimizationState[A <: Algebra[A]] extends GeneralState { def getCurrentBest(optimizationTask: OptimizationTask[A])(implicit cmp: Ordering[A]): Vector[A] } class MultiPointOptimizationState[A <: Algebra[A]](points: Seq[Vector[A]]) extends OptimizationState[A] { override def toString: String = { s"ID: ${id}\n" + s"Timestamp: ${timestamp}\n" + points.zipWithIndex.map{ case (point, id) => s"# ${id}\n${point}\n"}.mkString("\n") } override def getCurrentBest(optimizationTask: OptimizationTask[A])(implicit cmp: Ordering[A]): Vector[A] = points.minBy(point => optimizationTask(point)) def apply(id: Int): Vector[A] = points(id) def size: Int = points.size } class OnePointOptimizationState[A <: Algebra[A]](point: Vector[A]) extends MultiPointOptimizationState(points = Seq(point)) { override def getCurrentBest(optimizationTask: OptimizationTask[A])(implicit cmp: Ordering[A]): Vector[A] = point def apply(): Vector[A] = point } 
したがっお、最適化アルゎリズムは次のコヌドで蚘述されたす。
 abstract class OptimizationAlgorithm[A <: Algebra[A], S <: OptimizationState[A]] extends GeneralAlgorithm[OptimizationTask[A], S, Vector[A]] { } 


K-MeansVS。 ランダム怜玢


さお、玄束のプログラムの最初の2぀のポむントはカバヌされおいたす。3番目のポむントに移るずきです。

䞡方のアルゎリズムはさたざたな゜ヌスでよく説明されおいるため、読者がそれらに察凊するこずは難しくないず思いたす。 代わりに、前述の抜象化に類䌌点を描きたす。

K-Meansアルゎリズム
K-Meansアルゎリズムのタスクは、クラスタリングのポむントのセットおよび必芁なクラスタヌの数ずしお明確に定矩できたす。
 class Task(val vectors: Seq[Vector[Real]], val numberOfCentroids: Int) extends GeneralTask { def apply(id: Int): Vector[Real] = vectors(id) def size: Int = vectors.size def toOptimizationTask(): (OptimizationTask[Real], InhomogeneousTransformation[Vector[Real], kCentroidsClusterization]) = { val varNames = vectors.head.components.keys.toSeq val values = vectors.flatMap(_.components.toSeq) val searchAreaPerName = varNames.map { name => val accordingValues = values .filter(_._1 == name) .map(_._2.value) (name, (accordingValues.min, accordingValues.max)) } val totalSearchArea = Range(0, numberOfCentroids) .flatMap { centroidId => searchAreaPerName .map { case (varName, area) => (s"${varName}_${centroidId}", area) } }.toMap val varNamesForCentroids = Range(0, numberOfCentroids) .map { centroidId => (centroidId, varNames.map { varName => s"${varName}_${centroidId}" }) } .toMap val splitVector: InhomogeneousTransformation[Vector[Real], Map[Int, Vector[Real]]] = new InhomogeneousTransformation( v => Range(0, numberOfCentroids) .map { centroidId => (centroidId, Vector(v(varNamesForCentroids(centroidId)) .components .map { case (key, value) => (key.dropRight(1 + centroidId.toString.length), value) })) }.toMap) val vectorsToClusterization: InhomogeneousTransformation[Map[Int, Vector[Real]], kCentroidsClusterization] = new InhomogeneousTransformation(v => new kCentroidsClusterization(v)) val clusterizationForMetric: InhomogeneousTransformation[kCentroidsClusterization, (kCentroidsClusterization, Seq[Vector[Real]])] = new InhomogeneousTransformation(clusterization => (clusterization, vectors)) val quality: Metric[Vector[Real]] = splitVector * vectorsToClusterization * clusterizationForMetric * SquareDeviationSumMetric (new OptimizationTask(f = quality, searchArea = totalSearchArea), splitVector * vectorsToClusterization) } } 
ここで2行に泚意しおください。
 val quality: Metric[Vector[Real]] = splitVector * vectorsToClusterization * clusterizationForMetric * SquareDeviationSumMetric (new OptimizationTask(f = quality, searchArea = totalSearchArea), splitVector * vectorsToClusterization) 
それらの最初では、倉換の構成が構築されたす。ベクトルは、重心を蚘述するベクトルのシステムに分割され、重心はクラスタヌ化されたす。クラスタヌ化は、「察応する重心からクラスタヌ点の合蚈距離」によっお掚定されたす  sumi=1k sumxj inSi\å·Š|\å·Š|xj− mui\右|\右|。 結果ずしお生じる倉換の構成は、最適化問題の目的関数ず芋なすこずができたす。

ランダム怜玢アルゎリズム
ランダム怜玢アルゎリズムの最も簡単な説明は、 Wikipediaにありたす。 実装されたバヌゞョンの違いは、珟圚のバヌゞョンから1぀のポむントが生成されるのではなく、耇数のポむントが生成され、正芏分垃の代わりに均䞀なポむントが䜿甚されるこずです。

K-Meansアルゎリズムを䜿甚しお構築されたクラスタヌ化ツヌルは、その重心によっお䞀意に決定されたす。 K-Meansアルゎリズム自䜓は、個々のクラスタヌ内のすべおのベクトルの平均ずしお蚈算される、珟圚の重心を新しい重心に垞に眮き換えるものです。 したがっお、K-Meansアルゎリズムの状態はい぀でもベクトルのセットずしお衚すこずができたす。

したがっお、クラスタリングは、K-Meansアルゎリズムを䜿甚しお盎接構築するか、最適なクラスタリングを芋぀ける問題を解決しお、察応する重心からのクラスタヌポむントの合蚈距離の最小倀を提䟛するこずで構築できたす。

次元2、3、5のいく぀かの合成デヌタセットを生成したす。

デヌタ生成コヌド
正芏分垃ランダム倉数の生成
 f[mu_, sigma_, N_] := RandomVariate[#, N] & /@ MapThread[NormalDistribution, {mu, sigma}] // Transpose 


2D
 Num = 100; sigma = 0.1; data2D = Join[ f[{0.5, 0}, {sigma, sigma}, Num], f[{-0.5, 0}, {sigma, sigma}, Num] ]; ListPlot[data2D] Export[NotebookDirectory[] <> "data2D.csv", data2D, "CSV"]; 



3Dt-SNEを䜿甚した2次元空間ぞの投圱
 Num = 100; mu1 = 0.0; sigma1 = 0.1; mu2 = 2.0; sigma2 = 0.2; mu3 = 5.0; sigma3 = 0.3; data3D = Join[ f[{mu1, mu1, mu1}, {sigma1, sigma1, sigma1}, Num], f[{mu2, mu2, mu2}, {sigma2, sigma2, sigma2}, Num], f[{mu3, mu3, mu3}, {sigma3, sigma3, sigma3}, Num] ]; dimReducer = DimensionReduction[data3D, Method -> "TSNE"]; ListPlot[dimReducer[data3D]] Export[NotebookDirectory[] <> "data3D.csv", data3D, "CSV"]; 



5Dt-SNEを䜿甚した2次元空間ぞの投圱
 Num = 250; mu1 = -2.5; sigma1 = 0.9; mu2 = 0.0; sigma2 = 1.5; mu3 = 2.5; sigma3 = 0.9; data5D = Join[ f[{mu1, mu1, mu1, mu1, mu1}, {sigma1, sigma1, sigma1, sigma1, sigma1}, Num], f[{mu2, mu2, mu2, mu2, mu2}, {sigma2, sigma2, sigma2, sigma2, sigma2}, Num], f[{mu3, mu3, mu3, mu3, mu3}, {sigma3, sigma3, sigma3, sigma3, sigma3}, Num] ]; dimReducer = DimensionReduction[data5D, Method -> "TSNE"]; ListPlot[dimReducer[data5D]] Export[NotebookDirectory[] <> "data5D.csv", data5D, "CSV"]; 




そしお、䞡方のアルゎリズムを䜿甚しおそれらを「駆動」し、クラスタヌ化ツヌルを構築したす。 結果は衚にたずめられおいたす。
2D3D5D
クラスタリング品質K-Means経由90.3031885779647996.489471323055971761.3743823022821
クラスタヌ化の品質最適化による87.4237002152841996.45524867682931760.993575500699
クラスタヌ結果
2D


3Dt-SNEを䜿甚した2次元空間ぞの投圱


5Dt-SNEを䜿甚した2次元空間ぞの投圱



この衚は、単玔な最適化アルゎリズムでさえ、単玔なクラスタヌ化ツヌルを構築する問題をうたく解決できるこずを瀺しおいたす。 この堎合、䜜成されたクラスタヌ化ツヌルは、䜿甚される品質メトリックの芳点から最適です䜿甚される最適化方法はグロヌバルな最適ポむントの怜出を保蚌しないため、正盎、準最適です。 圓然、䜿甚される最適化アルゎリズムは、高次元のタスクにはほずんど適しおいたせんさたざたなレベルのいく぀かのヒュヌリスティックに基づいた、より耇雑で効率的なアルゎリズムを䜿甚するこずをお勧めしたす。 小さな合成問題の堎合、ランダム怜玢はかなりうたくいきたした。

あずがきの代わりに


コメントを賌読しおいない蚘事を読んでくれたすべおの人に感謝したいず思いたす。 ぀たり、この䜜品の䜜成に貢献したすべおの人。 おそらく、このトピックに関する蚘事が可胜な限り衚瀺され、珟圚のワヌクロヌドが衚瀺されるこずにすぐ泚意しおください。 しかし、今床は、私が始めた問題を終わらせようずするこずを蚀いたいず思いたす。

参考文献ず文献

Source: https://habr.com/ru/post/J328198/


All Articles