Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

平均しないでください:統計的平均とパーセンタイル101

パフォーマンスの監視は、アプリケーションを成功させるための重要な部分です。 何かのパフォーマンスを伝える最も基本的な方法の1つ それが発生するたびに期間を測定し、そこから統計を抽出することです。

平均

値のコレクションの平均または平均は、何かがどのように動作するかを確認するための良いスタートです。検討中のすべての値を合計し、発生数で割って計算されます。

Rubyでは、平均応答時間の計算は次のようになります。

def mean(array)
 (array.sum.to_f / array.length).round(2)
end
 
durations = [1,2,3,4,5,6,7,8,9,0]
mean(durations) #=> 4.5

:この例では、除算時の結果をより正確にするために、合計期間の値をFloatにキャストしています。それ以外の場合、Rubyは最も近い整数に切り捨てられ、4を返します。 代わりに。

中央値

もう1つの有用な統計は、中央値です。似ているように聞こえますが、値のコレクションの平均と中央値には違いがあります。

中央値は、セットの上半分とセットの下半分を分ける値です。

値の数が奇数のデータセットの場合、最初に値を並べ替えてから中央値を選択することで中央値を取得します。偶数の値を持つセットの場合、それらを並べ替えると、中央値は2つの中央値の平均になります。

def median(array)
  sorted_array = array.sort
  length = sorted_array.length
 
  if length.odd? # Middle number for odd arrays
    sorted_array[length / 2]
  else # Mean of two middle numbers
    first_value = sorted_array[length / 2]
    second_value = sorted_array[length / 2 - 1]
    (first_value + second_value) / 2.to_f
  end
end
 
# Even array
durations = [1,2,3,4,5,6,7,8,9,0]
median(durations) #=> 4.5
 
# Odd array
durations = [1,1,2,3,4,5,6,7,8,9,0]
median(durations) #=> 4

この統計は、データに大きな偏りがあるか、ロングテールがあるかを確認するための良い方法です。

durations = [1,2,3,4,5,2000]
 
median(durations) #=> 3.5
mean(durations) #=> 335.83

上記の期間の平均は335.83になります 2000msの単一の外れ値のため。中央値は3.5のみです 、スキューがあることを示します。

データセットの平均と中央値の両方を計算することで、大きな外れ値やロングテールがあるかどうかを判断できます。

平均の問題

平均値と中央値はパフォーマンスの優れた指標ですが、全体像を示すものではありません。ウェブページを10回リクエストした場合、平均は非常に低くなる可能性がありますが、1つ以上のリクエストが完了するまでに非常に長い時間がかかる可能性があります。

下の画像は、99番目(青)と90番目(緑)のパーセンタイルと、AppSignalの特定のアクションの平均(赤)を示しています。 99番目と90番目は平均からかなり離れており、いくつかのスパイクがあることがわかります。これは、平均的な顧客は優れたエクスペリエンスを提供しますが、ページがレンダリングされるまでほぼ2倍の時間を待たなければならないユーザーがいることを意味します。理想的には、これらすべての値を可能な限り互いに近づけて、すべてのユーザーにとってより一貫したエクスペリエンスを作成する必要があります。

たとえば、10人の顧客が100ミリ秒から1秒の間の期間のページを要求する次の期間セットがあるとします。

[100,100,100,100,100,100,100,100,100,1_000]

これにより、平均で190msになります。 一方、1人のユーザーは1秒の応答時間という非常に悪い経験をしました。平均値を追跡するだけの場合、Webサイトのパフォーマンスが優れていると考えるのは簡単ですが、実際には、ユーザーはひどい体験をすることがあります。

上記の例は10件のリクエストのみですが、1日に1,000件のリクエストがあるとすると、それらのユーザーの100人がひどい経験をしたことを意味します。

パーセンタイル

値の分布をよりよく理解するために、パーセンタイルを使用します。パーセンタイルは中央値に似ています。データセット内で、セットの半分が数値より下にあり、半分が数値より上にあるポイントを示す数値です。パーセンタイルは、20パーセンタイルが、データセット内の数値の20%がその数値を下回っていることを意味するという意味で類似しています。

次の(ソートされた)セットがあるとします:

[100,100,200,200,300,300,400,400,500,5_000]

20パーセンタイルを知りたい場合は、次の方法で計算できます。セットには10​​個の値があります。必要な値は位置1にあります(20.0 / 100 * 10 - 1 )配列はゼロから始まります。この配列には均等な量のアイテムが含まれているため、インデックス間の平均を計算する必要があります(2 )およびインデックス+ 1(3 )。これにより、値は150になります。 20パーセンタイルの場合。

非常に単純なRubyの実装は次のようになります:

def percentile(array, wanted_percentile)
  sorted_array = array.sort
 
  index = (wanted_percentile.to_f / 100) * sorted_array.length - 1
 
  # Check if index is not a round number
  if index != index.to_i
    sorted_array.at(index.ceil)
  elsif sorted_array.length.even?
    first_value = sorted_array.at(index)
    second_value = sorted_array.at(index + 1)
    (first_value + second_value) / 2
  else
    sorted_array.at(index)
  end
end
 
# An array with an odd amount of numbers
durations = [100,200,200,300,300,400,400,500,5_000]
 
percentile(durations, 20) #=> 100
percentile(durations, 90) #=> 500
percentile(durations, 95) #=> 5000, index is a fraction, 9.5 the rounded index is 10
 
# An array with an even amount of numbers
durations = [100,100,200,200,300,300,400,400,500,5_000]
 
percentile(durations, 20) #=> 150, average of index 1 & 2 `(100 + 200) / 2`
percentile(durations, 90) #=> 2750, average of index 8 & 9 `(500 + 5000) / 2
percentile(durations, 95) #=> 500, index is a fraction, 8.55 the index is 9

このpercentile 関数はmedianと非常によく似ています 計算と実際には、median 50thと同じです パーセンタイル。

durations = [1,2,3]
 
percentile(durations, 50) == median(durations) #=> true

AppSignalは、上記の統計を使用して、アプリケーションのパフォーマンスメトリックを生成します。平均/平均だけでなく、90パーセンタイルと95パーセンタイルを計算して、リクエストの分布をより正確に把握できる外れ値を示します。詳細については、パフォーマンスツアーページをご覧ください。

奇妙な

パーセンタイルと平均の計算方法が原因で、たとえば次のデータセットを使用すると、90パーセンタイルが平均を下回る可能性があります。

durations = [1,1,1,1,1,1,1,1,1,1,2000]
 
percentile(durations, 90) #=> 1
mean(durations) #=> 182.73

これにより、meanが得られます 182.73の 、および1の90パーセンタイル 。

指標収集システムに90パーセンタイルと平均のみが表示されている場合でも、90パーセンタイルが平均を下回った場合、データセットのどこかに大きな外れ値があると推測できます。

👋この記事が気に入った場合は、Ruby(on Rails)のパフォーマンスについてさらに多くのことを書いています。Rubyのパフォーマンス監視チェックリストを確認してください。

あなたはこの投稿のほぼ100%にいます

今のところ以上です!別の投稿では、Quantilesを使用して、すべての顧客の要求に対するパーセンタイルを効率的に保存および計算する方法について説明します。統計やAPM、エラートラッキング、パフォーマンスモニタリングについて質問や意見がある場合は、Twitter@AppSignalまたはメールでお問い合わせください。


  1. PythonでO(n)時間とO(1)空間でBSTの中央値を見つける

    二分探索木(BST)があるとすると、その中央値を見つける必要があります。偶数のノードの場合、中央値=((n / 2番目のノード+(n + 1)/ 2番目のノード)/ 2奇数のノードの場合、中央値=(n + 1)/2番目のノードです。 したがって、入力が次のような場合 その場合、出力は7になります これを解決するには、次の手順に従います- rootがNoneと同じ場合、 0を返す node_count:=ツリー内のノードの数 count_curr:=0 現在:=ルート currentがnullでない場合は、実行してください curren

  2. コンピュータが「泣き言を言う」理由とその意味

    最新のゲームをレンダリングする場合でも、ビデオを処理する場合でも、PCに負担をかける人であれば、ストレスがかかるとコンピューターのサウンドスケープが変化することがわかります。ヒートシンクの音だけで、プロセッサがどれだけの負担を感じているかがわかる場合があります。 ただし、ユーザーがコンピューターに期待しないノイズの1つは、柔らかなうなり音です。すべてのコンピューターに1つあるわけではありませんが、ある場合、ユーザーは間違いなく気付くでしょう。ほとんどのユーザーは、この泣き言は自分のコンピューターが限界に達したときにのみ発生し、どのような種類のアプリが泣き言を引き起こすかを予測できると報告して