実践的な Golang の基本データ構造とアルゴリズム、k-means クラスタリング アルゴリズム

実践的な Golang の基本データ構造とアルゴリズム、k-means クラスタリング アルゴリズム

起源

最近読んだ本『はじめてのアルゴリズム』(石田康樹、宮崎修一)

この一連のノートは、Golangの実践を目的としたものです

k平均法クラスタリングアルゴリズム

クラスタリングとは、入力データが複数ある場合に、「類似した」データを 1 つのグループにまとめる操作です。 k-means アルゴリズムはクラスタリング アルゴリズムです。 まず、クラスターの中心点としてランダムに k 個の点を選択し、「データを対応するクラスターに分割する」と「中心点を重心に移動する」という 2 つの操作を、中心点が変化しなくなるまで繰り返します。 k-means アルゴリズムでは、演算を繰り返すと中心点の位置がどこかに収束することが数学的に証明されています。 石田康樹、宮崎修一著『はじめてのアルゴリズムより抜粋

シナリオ

  • ある場所で突如として新型コロナウイルス感染症が発生しました。感染者の分布状況から、感染源の特定を急ぐことが防疫上急務となっています。
  • まず、ケース分布の座標をシステムに入力します
  • 次に、k-meansアルゴリズムに従って、1から3までのkに応じてクラスタリングが実行されます。
  • クラスターの中心が病気の発生源である可能性がある

プロセス

  1. サンプル数とサンプル距離計算機が与えられた場合、k 個のサンプル中心点を見つける必要があります。
  2. まず、サンプルからk点をランダムに選択して中心点とする。
  3. 各サンプルをループする

    1. サンプル点からk個の中心点までの距離をそれぞれ計算する
    2. サンプルポイントからの距離が最小の中心点を決定する
    3. サンプルを最小の中心点を持つクラスターに分割する
  4. 各クラスターの中心点を新しい中心点として計算する

    1. クラスター内の各サンプルをループする
    2. このサンプルからこのクラスター内の他のサンプルまでの距離の合計を計算します
    3. 他のサンプルとの距離が最も短い点が新しい中心点となる
  5. 中心点が変化しなくなり計算が完了するまで、3~4を繰り返します。

デザイン

  • IPoint: サンプル ポイント インターフェイス (実際には空のインターフェイス)
  • IDistanceCalculator: 距離計算インターフェース
  • IClassifier: 分類器インターフェース。サンプルを k にクラスタ化し、k の中心点を返します。
  • tPerson: ケースサンプルポイント、IPoint インターフェースを実装、x、y 座標を含む
  • tPersonDistanceCalculator: ケース距離計算機。x 座標と y 座標の 2 点間の直線距離を計算します。
  • tKMeansClassifier: k-means クラスタラー。IClassifier インターフェイスを実装します。

ユニットテスト

k_means_test.go

  1. その他をパッケージ化する
  2. 輸入
  3. km 「学習/gooop/その他/k_means」
  4. 「文字列」
  5. 「テスト」
  6. 関数Test_KMeans(t *testing.T) {
  7. // サンプルポイントを作成する
  8. サンプル:= []km.IPoint {
  9. km.NewPerson( 2 , 11 )、
  10. km.NewPerson( 2 , 8 )、
  11. km.NewPerson( 2 , 6 )、
  12. km.NewPerson( 3 , 12 )、
  13. km.NewPerson( 3 , 10 )、
  14. km.NewPerson( 4 , 7 )、
  15. km.NewPerson( 4 , 3 )、
  16. km.NewPerson( 5 , 11 )、
  17. km.NewPerson( 5 , 9 )、
  18. km.NewPerson( 5 , 2 )、
  19. km.NewPerson( 7 , 9 )、
  20. km.NewPerson( 7 , 6 )、
  21. km.NewPerson( 7 , 3 )、
  22. km.NewPerson( 8 , 12 )、
  23. km.NewPerson( 9 , 3 )、
  24. km.NewPerson( 9 , 5 )、
  25. km.NewPerson( 9 , 10 )、
  26. km.NewPerson( 10 , 3 )、
  27. km.NewPerson( 10 , 6 )、
  28. km.NewPerson( 10 , 12 )、
  29. km.NewPerson( 11 , 9 )、
  30. }
  31. fnPoints2String := func(points []km.IPoint) 文字列 {
  32. アイテム:= make([]文字列、len(ポイント))
  33. i ,it := 範囲ポイント {
  34. アイテム[i] = it.String()
  35. }
  36. 文字列を返します。Join (items, " " )
  37. }
  38. k:= 1 ;k<= 3 ;k++の場合
  39. センター:= km.KMeansClassifier.Classify(サンプル、 km.PersonDistanceCalculator、 k)
  40. t.Log(fnPoints2String(中心))
  41. }
  42. }

テスト出力

  1. $ テストを実行 -v k_means_test.go
  2. === Test_KMeans を実行
  3. k_means_test.go: 53 : p( 7 , 6 )
  4. k_means_test.go: 53 : p( 5 , 9 ) p( 7 , 3 )
  5. k_means_test.go: 53 : p( 9 , 10 ) p( 3 , 10 ) p( 7 , 3 )
  6. --- 合格: Test_KMeans ( 0.00 秒)
  7. 合格
  8. ok コマンドライン引数0.002s

アイポイント

サンプルポイントインターフェースは実際には空のインターフェースです

  1. パッケージキロ
  2. 「fmt」をインポートする
  3. IPointインターフェース型{
  4. fmt.ストリンガー
  5. }

IDistanceCalculator.go

距離計算インターフェース

  1. パッケージキロ
  2. IDistanceCalculatorインターフェース型{
  3. Calc(a, b IPoint) int
  4. }

IClassifier.go

分類器インターフェース、サンプルをkにクラスタ化し、kの中心点を返す

  1. パッケージキロ
  2. IClassifierインターフェース型{
  3. //サンプルをk個のクラスターにクラスタ化し、k個の中心点を返す
  4. 分類(サンプル[]IPoint、calc IDistanceCalculator、k int )[]IPoint
  5. }

tPerson.go

ケースサンプルポイント、IPointインターフェースを実装、x、y座標を含む

  1. パッケージキロ
  2. 「fmt」をインポートする
  3. tPerson構造体型{
  4. x整数
  5. y整数
  6. }
  7. NewPerson関数(x, y int ) IPoint {
  8. &tPerson{x, y, }を返す
  9. }
  10. func (me *tPerson) String() 文字列 {
  11. fmt.Sprintf( "p(%v,%v)" , me.x, me.y)を返します
  12. }

tPersonDistanceCalculator.go

ケース距離計算機、x 座標と y 座標の 2 点間の直線距離を計算します

  1. パッケージキロ
  2. tPersonDistanceCalculator構造体型{
  3. }
  4. var gMaxInt = 0x7fffffff_ffffffff
  5. func newPersonDistanceCalculator() IDistanceCalculator {
  6. &tPersonDistanceCalculator{}を返します
  7. }
  8. func (me *tPersonDistanceCalculator) Calc(a, b IPoint) int {
  9. a == bの場合{
  10. 0を返す
  11. }
  12. p1、OK := a.(*tPerson)
  13. !okの場合{
  14. gMaxIntを返す
  15. }
  16. p2、OK := b.(*tPerson)
  17. !okの場合{
  18. gMaxIntを返す
  19. }
  20. dx := p1.x - p2.x
  21. dy := p1.y - p2.y
  22. d := dx*dx + dy*dy
  23. d < 0 の場合{
  24. パニック
  25. }
  26. 戻るd
  27. }
  28. var 人物距離計算機 = 新しい人物距離計算機()

tKMeansClassifier.go

k-means クラスタラー。IClassifier インターフェイスを実装します。

  1. パッケージキロ
  2. 輸入
  3. 「数学/ランド」
  4. "時間"
  5. tKMeansClassifier構造体型{
  6. }
  7. tPointEntry構造体型{
  8. ポイント IPoint
  9. 距離int
  10. インデックスint
  11. }
  12. func newPointEntry(p IPoint, d int , i int ) *tPointEntry {
  13. &tPointEntry{を返す
  14. p、d、i、
  15. }
  16. }
  17. 関数 newKMeansClassifier() IClassifier {
  18. &tKMeansClassifier{}を返す
  19. }
  20. //サンプルをk個のクラスターにクラスタ化し、k個の中心点を返す
  21. func (me *tKMeansClassifier) ​​Classify(samples []IPoint, calc IDistanceCalculator, k int ) []IPoint {
  22. サンプル数:= len(サンプル数)
  23. サンプル数 <= kの場合
  24. サンプルを返却する
  25. }
  26. // 初期化、k 個の中心点をランダムに選択
  27. rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
  28. 中心 := make([]IPoint, k)
  29. 選択された場合、i:= make(map[ int ]bool, 0 ), 0 ;i < k; {
  30. n := rnd.Intn(サンプル数)
  31. _,ok := 選択[n]
  32. !okの場合{
  33. 選択された[n] = true
  34. センター[i] = サンプル[n]
  35. 私は++
  36. }
  37. }
  38. // 中心点までの距離に応じてサンプルを分割します
  39. のために{
  40. グループ := me.split(サンプル、センター、計算)
  41. 新しい中心点:= make([]IPoint, k)
  42. i ,g := 範囲グループ {
  43. 新しい中心[i] = me.centerOf(g, calc)
  44. }
  45. me.groupEquals(centers, newCenters)の場合{
  46. 返品センター
  47. }
  48. センター = newCenters
  49. }
  50. }
  51. // サンプルポイントと中心点の間の距離をクラスター化します
  52. func (me *tKMeansClassifier) ​​split(samples []IPoint, centers []IPoint, calc IDistanceCalculator) [][]IPoint {
  53. k := len(中心)
  54. 結果:= make([][]IPoint, k)
  55. i := 0 ;i<k;i++ {の場合
  56. 結果[i] = make([]IPoint, 0 )
  57. }
  58. エントリ := make([]*tPointEntry, k)
  59. i ,c := 範囲の中心 {
  60. エントリ[i] = newPointEntry(c, 0 , i)
  61. }
  62. _ ,p := 範囲サンプル {
  63. for _,e := 範囲エントリ {
  64. e.距離 = calc.Calc(p, e.ポイント)
  65. }
  66. 中心 := me.min(エントリ)
  67. 結果[センター.インデックス] = append(結果[センター.インデックス], p)
  68. }
  69. 結果を返す
  70. }
  71. // サンプルのクラスターの重心を計算します。重心は、すべてのポイントまでの距離の合計が最小のポイントです。
  72. func (me *tKMeansClassifier) ​​centerOf(samples []IPoint, calc IDistanceCalculator) IPoint {
  73. エントリ:= make([]*tPointEntry, len(サンプル))
  74. i ,src := 範囲サンプル {
  75. 距離:= 0
  76. _ ,it := 範囲サンプル {
  77. 距離 += calc.Calc(src, it)
  78. }
  79. エントリ[i] = newPointEntry(src, 距離, i)
  80. }
  81. me.min(entries).pointを返す
  82. }
  83. // 2つの点の集合が同じかどうかを判定する
  84. func (me *tKMeansClassifier) ​​groupEquals(g1, g2 []IPoint) bool {
  85. len(g1) != len(g2)の場合{
  86. を返す
  87. }
  88. i ,v := 範囲 g1 {
  89. g2[i] != v の場合
  90. を返す
  91. }
  92. }
  93. を返す
  94. }
  95. // 距離が最小の点を見つける
  96. func (me *tKMeansClassifier) ​​min(entries []*tPointEntry) *tPointEntry {
  97. 最小値:= 0
  98. minD := gMaxInt
  99. i ,it := 範囲エントリ {
  100. it.distance < minD {の場合
  101. 最小I = i
  102. minD = it.距離
  103. }
  104. }
  105. エントリを返す[minI]
  106. }
  107. var KMeansClassifier = newKMeansClassifier()

<<:  GGVファミリー|Kuoboo Smartが2億人民元のプレB-4ラウンドの資金調達完了を発表

>>:  2021 年に企業に影響を与える自然言語処理のトレンド

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

ResearchAndMarkets: 世界の AI ソリューション市場は 2027 年に 2,820 億ドルに達する見込み

ResearchAndMarkets が発表した最新のレポートによると、2027 年までに世界の人...

Google は、ロボット犬に曖昧な指示を理解させるため、大型モデルを使用しています。

人間と四足歩行ロボットのシンプルで効果的な相互作用は、有能なインテリジェントアシスタントロボットを生...

LLaMA 2 エンドツーエンド推論が利用可能になりました。中国チームより

Buddy CompilerのエンドツーエンドLLaMA2-7B推論例がbuddy-mlirリポジト...

人工知能技術はゴミリサイクルに革命的な変化をもたらすかもしれない

新たな研究によると、最先端の人工知能が英国の廃棄物リサイクル方法に革命をもたらす可能性があるという。...

強化学習でデータ分析を行うにはどうすればいいでしょうか?シンガポール国立大学等によるTKDE 2022レビュー論文

データの処理と分析は基本的かつ広範囲にわたります。アルゴリズムはデータの処理と分析において重要な役割...

ガートナーは、2025年までにクラウドデータセンターの半数がAI機能を備えたロボットを導入すると予測している。

ガートナーの予測によると、2025年までにクラウドデータセンターの半数が人工知能(AI)と機械学習(...

フロントエンドではアルゴリズムを理解する必要はないと思いますか?実際の例を見てみましょう。

[[431020]]アルゴリズムは、問題を解決するための手順です。同じ問題でも複数の解決策が存在す...

人工知能が地震監視を新たな時代へ導く

[[388691]]被害の程度を軽減することは地震研究者にとって重要な目標です。破壊的な地震が発生し...

顔認識、マルチターゲット追跡…Suningのスマートストアのその他のブラックテクノロジーを公開!

[51CTO.comからのオリジナル記事] インターネット+の急速な発展に伴い、オフライン小売業界...

第四次産業革命:人工知能

人工知能 (AI): 私たちの日常生活、生き方、他者との関わり方に根本的な変化がもたらされるのは、第...

AI、機械学習、ディープラーニングの解放

【51CTO.com クイック翻訳】 [[393512]] AI、機械学習、ディープラーニングの発展...

模倣学習: ロボットはプログラミングなしで自然言語を理解できます!

人間が日常のコミュニケーションで話す自然言語の指示を使用して、ロボットアームにタスクを実行するよう指...