2016-11-04 5 views
0

私は任意の長さのストリングアイテムのリストを持っていますが、各アイテムが正規分布の一部であるようにこのリストを正規化してストリングに重みを追加する必要があります。フラットリストを正規分布に重み付けする

私は以下のもの以外に、これについてもっと効果的かつ数学的/統計的にどのような方法がありますか?

func normalizeAppend(in []string, shuffle bool) []string { 
    var ret []string 

    if shuffle { 
     shuffleStrings(in) 
    } 

    l := len(in) 
    switch { 
    case remain(l, 3) == 0: 
     l3 := (l/3) 
     var low, mid, high []string 
     for i, v := range in { 
      o := i + 1 
      switch { 
      case o <= l3: 
       low = append(low, v) 
      case o > l3 && o <= l3*2: 
       mid = append(mid, v) 
      case o >= l3*2: 
       high = append(high, v) 
      } 
     } 

     q1 := 1600/len(low) 
     q2 := 6800/len(mid) 
     q3 := 1600/len(high) 

     for _, v := range low { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q1)) 
     } 

     for _, v := range mid { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q2)) 
     } 

     for _, v := range high { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q3)) 
     } 
    case remain(l, 2) == 0 && l >= 4: 
     l4 := (l/4) 
     var first, second, third, fourth []string 
     for i, v := range in { 
      o := i + 1 
      switch { 
      case o <= l4: 
       first = append(first, v) 
      case o > l4 && o <= l4*2: 
       second = append(second, v) 
      case o > l4*2 && o <= l4*3: 
       third = append(third, v) 
      case o > l4*3: 
       fourth = append(fourth, v) 
      } 
     } 
     q1 := 1600/len(first) 
     q2 := 3400/len(second) 
     q3 := 3400/len(third) 
     q4 := 1600/len(fourth) 

     for _, v := range first { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q1)) 
     } 

     for _, v := range second { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q2)) 
     } 

     for _, v := range third { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q3)) 
     } 

     for _, v := range fourth { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q4)) 
     } 
    default: 
     var first, second, third []string 
     q1 := (1 + math.Floor(float64(l)*.16)) 
     q3 := (float64(l) - math.Floor(float64(l)*.16)) 
     var o float64 
     for i, v := range in { 
      o = float64(i + 1) 
      switch { 
      case o <= q1: 
       first = append(first, v) 
      case o > q1 && o < q3: 
       second = append(second, v) 
      case o >= q3: 
       third = append(third, v) 
      } 
     } 
     lq1 := 1600/len(first) 
     lq2 := 3400/len(second) 
     lq3 := 1600/len(third) 
     for _, v := range first { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq1)) 
     } 

     for _, v := range second { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq2)) 
     } 

     for _, v := range third { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq3)) 
     } 

    } 

    return ret 
} 

いくつかは明確化を要請:

私はの(暗黙の)重みを持つリストを持って開始するには、加重選択することにより、一度にリストから何回も1を選択します項目のリストを持っています1:

[A_1、B_1、C_1、D_1、E_1、F_1、G_1、H_1、I_1、J_1、K_1]

私はより多くを生産するものにそのリストを作るためのより良い方法を探しています選択のための重み付けの「通常の」分布:

[A_1、B_2、C_3、d_5、e_14、f_30、g_14、h_5、I_3、J_2、K_1]

または多分私がより統計学的に接地されたものに私の方法を変更する必要がありそうです。一番下の行は、項目のリストから多くの方法で選択範囲をコントロールしたいのですが、ここでは項目が正規曲線に近づくように戻されることを保証しています。

+0

要件がわかりません。明確にできますか?要素が正規分布の一部であるとはどういう意味ですか?重みを付けることで、単純な文字列の連結を意味しますか?たぶんあなたは例を投稿することができます。 –

+0

コードは質問&コンセプトほど重要ではありません。私が取り組んでいるコンセプトの最初の一歩です。 – blueblank

+0

はちょうど(その後、適切な平均と分散を持つ正規分布の式を使用)、または、この分布からのサンプリングについて(その後、正規分布のための乱数生成器を使用する)重みを計算については、それはありますか? –

答えて

0

あなただけ与えられたリストの重みを計算したい場合は、次のものが必要です。

  • 正規分布
  • 正規分布
  • 離散化の分散の平均値を値の場合

最初は非常に単純です。平均がリストの中央になるようにします。したがって、(ゼロベースのインデックスを想定):

mean = (list.size - 1)/2 

第二は、任意の一種であり、あなたがあなたの重みが落下する方法急に依存します。正規分布の重みは、meanから3 * standard_deviationの距離を超えて実質的にゼロです。だから、ほとんどのケースでは良いの標準偏差は、おそらく第四及び第六リスト長との間に何かある:

standard_deviation = (1/4 .. 1/6) * list.size 
variance = standard_deviation^2 

を使用すると、整数の重みをしたいと仮定すると、あなたは正規分布から重みを離散化する必要があります。これを行う最も簡単な方法は、(平均位置にある要素の)最大の重みを指定することです。

これだけです。 iの要素の重みは、次になります。

weight[i] = round(max_weight * exp(-(i - mean)^2/(2 * variance))) 
関連する問題