文字列がランダムでないか確認する


8

背景
アルファベットのがあるとしますA,B, C, D。次に、いくつかのデータを調べて「単語」を見つけます。これはDDDDDDDDCDDDDDD、このランダムを見つける可能性が低いようですが、BABDCABCDACDBACDランダムではないようです。

質問
遭遇した文字列がランダムでないかどうかを確認するにはどうすればよいですか?

私はRでいくつかのことを試みました。たとえば、文字を数値的にエンコードし、これらを順列と比較しました。しかし、事前のエンコードはかなり面倒であり、これにはより直接的なアプローチがあると思われます。


12
この文脈で「ランダム」とはどういう意味ですか?
gung-モニカの

3
nビットのステートマシンを作成し、それによって予測ミスの数を記録できます。CPUの分岐予測子のようなものです。
alexyorke 2018年

1
特定の既知のプロセスによって文字列が生成された確率を計算できます。それが「ランダム」かどうかはわかりません(そしておそらく意味のある質問ではありません)。
OrangeDog 2018年

2
会計で確認できます。
hlovdal 2018年

2
シーケンスではなく文字の頻度に焦点を当てている場合は、実際の頻度と予想される頻度のカイ二乗検定が一般的です。つまり、最初の例が「奇数」の場合は「D」が多すぎるため、2番目の例は「A」、「B」、「C」、および「D」の数がかなり等しい場合、次のようになります。 dは、A、B、C、およびDのそれぞれの数と、予想したものの数を比較したい。(A、B、C、Dの数とほぼ同じか、Aの数はBの2倍、Bの数はCまたはDの2倍です。)
Wayne

回答:


19

このランダムを見つける可能性は私には低いようですが、BABDCABCDACDBACDを見つけることはランダムではないようです。

なぜでしょうか?文字A ... Dの全体的な比率が各文字の0.25に等しく、各文字が他の文字から独立している場合、両方の単語の確率はまったく同じです。文字の分布が異なる場合、もちろん、両方の単語を生成する確率は異なる可能性があります。

「複雑さが低い」単語、たとえば1文字の割合が特に高い単語(他の応答で提案されているシャノン情報を使用でき、生物学的配列分析では他の多くのアプローチがあります)を見つけることができますが、 「ランダム性」のテストではありません。実際に分析しているものについてのさらなる仮定や知識がないと、「ランダム性」という用語は意味がありません。


10
「どちらの単語もまったく同じようにありそう」は、大胆に強調するのに最適な場所です。
Tashus、

1
「文字A ... Dの全体的な比率が各文字の0.25に等しい場合...」。いいえ、実際にはすべての可能な単語は、他の単語と同じように、単語に含まれる文字の割合に関係なく同じです。
DJClayworth、

6
@DJClayworthその行の意図は、A:.25 B:.25 C:.25 D.25の代わりに、A:.5、B:.25、C:.125、D :.125、ABAAという単語が表示される可能性は最初のシナリオよりも2番目のケースではるかに高い可能性があり、CDBDは最初のシナリオではABAAと同じように可能ですが、2番目のケースではABAAよりも低い可能性があります。したがって、特定の単語が出現する可能性は、他の可能な比率に対する文字の「比率」に依存します。
ale10ander

17

あなたはシャノン情報を試すことができます:

H=i=0nPilog2(Pi)
どこ、 Pi=cinci いくつかの手紙の数です c 一言で言えば n=|word|

あなたが持っている最初の言葉について H=0.35。あなたが持っている第二の言葉でH=2

エントロピーが高い場合は、エントロピーが低い別の単語よりもランダムであると考えることができます。


これは、文字列の予測不可能性を検出するために行くには良い方法である、と私はupvotedが、あなたの基準は、両方に同じ結果を与えるだろうbababbaabbaaaabbbbbb。明らかに非常に緩い、OPが使用する「ランダム性」の概念では、前者は後者よりも「よりランダム」であると考えられます。
ymbirtt 2018年

8

ここでの他の回答は、シーケンス内のさまざまな文字の全体的な出現に焦点を合わせています。これは、予期される「ランダムさ」の1つの側面である可能性があります。ただし、興味深いもう1つの側面は、シーケンス内の文字の順序の見かけ上のランダム性です。少なくとも、「ランダム性」は文字のベクトルの交換可能性を伴うと思います。これは「実行テスト」を使用してテストできます。実行テストは、シーケンス内の「実行」の数をカウントし、同じ文字を持つベクトルについて、交換可能性の帰無仮説の下で実行の総数をそのnull分布と比較します。「実行」を構成するものの正確な定義は、特定のテストによって異なります(たとえば、ここで同様の回答を参照してください))ですが、この場合、名目上のカテゴリーでは、自然な定義は、1つの文字のみで構成される連続したシーケンスを1つの「ラン」としてカウントすることです。

たとえば、あなたのシーケンスBABD-CABC-DACD-BACD一見ランダムではないように見えます(文字自体は表示されません。これは、この長いシーケンスではおそらく珍しいことです)。 これを正式にテストするために、互換性の実行テストを実行できます。このシーケンスでは、n=16 文字(各文字4つ)と r=16それぞれが1つの文字の1つのインスタンスで構成されます。観測された実行数は、交換可能性の仮説のもとで、そのヌル分布と比較できます。これはシミュレーションを介して行うことができます。これにより、シミュレーションのnull分布とテストのp値が得られます。この一連の文字の結果を下のグラフに示します。

ここに画像の説明を入力してください

このシーケンスの場合、(交換可能性の帰無仮説の下で)実行テストのp値は p=0.0537。これは、10%の有意水準では有意ですが、5%の有意水準では有意ではありません。交換不可能なシリーズ(つまり、ランダムでない順序)を示唆する証拠はいくつかありますが、証拠は特に強力ではありません。観測された文字列が長いほど、実行テストは、交換可能な文字列と交換不可能な文字列を区別するためのより大きな力を持ちます。(ご覧のように、この文字列はランダムではないという最初の一応の判断は間違っている可能性があります。p値は実際には予想していたほど低くはありません。)

最後に、このテストは文字列内の文字の順序のランダム性のみを調べることに注意することが重要です。これは、各タイプの文字の数を固定入力として受け取ります。このテストは、文字列内の文字の非交換性という意味で非ランダム性を検出しますが、異なる文字の全体的な確率という意味で「ランダム性」をテストしません。後者も「ランダム性」の指定された意味の一部である場合、この実行テストは、文字の全体的な数を調べ、これを仮説のnull分布と比較する別のテストで補強できます。


Rコード:上記のプロットとp値は、次のRコードを使用して生成されました。

#Define the character string vector (as factors)
x <- factor(c(2,1,2,4, 3,1,2,3, 4,1,3,4, 2,1,3,4), 
            labels = c('A', 'B', 'C', 'D'))

#Define a function to calculate the runs for an input vector
RUNS <- function(x) { n <- length(x);
                      R <- 1;
                      for (i in 2:n) { R <- R + (x[i] != x[i-1]) }
                      R; }

#Simulate the runs statistic for k permutations
k <- 10^5;
set.seed(12345);
RR <- rep(0, k);
for (i in 1:k) { x_perm <- sample(x, length(x), replace = FALSE);
                 RR[i] <- RUNS(x_perm); }

#Generate the frequency table for the simulated runs
FREQS <- as.data.frame(table(RR));

#Calculate the p-value of the runs test
R      <- RUNS(x);
R_FREQ <- FREQS$Freq[match(R, FREQS$RR)];
p      <- sum(FREQS$Freq*(FREQS$Freq <= R_FREQ))/k;

#Plot estimated distribution of runs with test
library(ggplot2);
ggplot(data = FREQS, aes(x = RR, y = Freq/k, fill = (Freq <= R_FREQ))) +
geom_bar(stat = 'identity') +
geom_vline(xintercept = match(R, FREQS$RR)) +
scale_fill_manual(values = c('Grey', 'Red')) +
theme(legend.position = 'none',
      plot.title      = element_text(hjust = 0.5, face = 'bold'),
      plot.subtitle   = element_text(hjust = 0.5),
      axis.title.y    = element_text(margin = margin(t = 0, r = 10, b = 0, l = 0))) +
labs(title    = 'Runs Test - Plot of Distribution of Runs under Exchangeability',
     subtitle = paste0('(Observed runs is black line, p-value = ', p, ')'),
     x = 'Runs', y = 'Estimated Probability'); 

読みやすくするために、シーケンスをダッシュ​​で区切っています。ダッシュは分析にとって重要ではありません。


1
面白い!間違いなくRスクリプトを見てみましょう
KingBoomie

1

文字列が十分に長いと仮定すると、データにランダム性テストを適用できます。

このようなテストの1つのセットは、ダイハードテストと呼ばれます

ダイハードテストは、乱数ジェネレータの品質を測定するための一連の統計テストです。それらはジョージ・マーサリアによって数年にわたって開発され、1995年に乱数のCD-ROMで最初に公開されました。

これらには、おそらく任意の、次のような一連のテストが含まれます。

  • 誕生日の間隔
  • 重複する順列
  • 行列のランク
  • モンキーテスト
  • 1を数える
  • 駐車場テスト
  • 最小距離テスト
  • ランダム球テスト
  • スクイズテスト
  • 重複合計テスト
  • テストを実行
  • クラップステスト

ランダムデータの適切なシーケンスは、これらのテストに合格する必要があります。

ただし、これらのテストに合格しても、数値が実際の信号を実際にエンコードしていないこと証明するには不十分です。それらは、高品質の暗号化ルーチンからの出力である可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.