3

私は単語ジェネレーターを構築しました。それは長さを選択し、アルファベットの文字をランダムに選択して単語を構成します。

プログラムは動作しますが、出力の 99% は英語の構造を観察していないためゴミです。

一般的な文字をより頻繁に使用するように RNG にバイアスをかけるための私のオプションは何ですか?

私は stl から rand() を使用しています。

4

8 に答える 8

5

乱数ジェネレーターにバイアスをかけるだけでは適切な英語の単語を作成できないため、出力はまだごみになります。ただし、rngにバイアスをかける1つのアプローチは次のとおりです。

  1. 大きな英語のテキスト(コーパス)の文字の出現のヒストグラムを作成します。500'e'、3'x'、1'q'、450'a'、200'b'などのようになります。
  2. 間隔を、各文字がスライスを取得する範囲に分割します。スライスの長さは、間隔内の出現回数です。aは[0-450)、b [450,650)、...、q [3500,3501)を取得します。
  3. 0から間隔の全長までの乱数を生成し、それがどこに着地するかを確認します。450〜650の範囲内の任意の数値は、abを提供しますが、3500のみが「q」を提供します。
于 2011-07-29T09:14:44.573 に答える
2

1つの方法は、文字の頻度を使用することです。文字ごとに範囲を定義します:a = [0、2](文字「a」が使用される可能性が2%の場合)、b = [2、5](3%の可能性)など。 0〜100の乱数を使用して、文字を選択します。

もう1つの方法は、特定の遷移を定義できる非決定性有限オートマトンを使用することです(聖書を解析して確率を構築することができます)。したがって、次のような遷移がたくさんあります。たとえば、「a」から「b」への遷移は5%です。次に、オートマトンをウォークスルーして、いくつかの単語を生成します。

適切な用語がマルコフ連鎖であることがわかりました。これはおそらくNFAよりも優れています。

于 2011-07-29T09:17:19.800 に答える
1

テキストの一部のn-gram分析を実行し、それをバイアスのベースとして使用できます。これは、文字または音節のいずれかで行うことができます。音節による分析の実行は、おそらくもっと複雑です。

文字でやるのは簡単です。ソーステキストの各文字を繰り返し処理し、最後に出会ったn-1文字を追跡します。次に、次の文字ごとに、最後のn-1文字とこの新しい文字(n-gram)を頻度のテーブルに追加します。

この頻度の表はどのように見えますか?n-gramをそれらの頻度にマッピングするマップを使用できます。しかし、このアプローチは、以下で提案するアルゴリズムにはあまり適していません。そのためには、各(n-1)グラムをnグラムの最後の文字の頻度へのマップにマップすることをお勧めします。のようなもの:std::map<std::string, std::map<char,int>>

分析を行い、統計を収集すると、アルゴリズムは次のようになります。

  1. ランダムな開始n-gramを選択します。以前の分析には、文字が通常単語を開始する重み付けデータが含まれている場合があります。
  2. 前のn-1文字で始まるすべてのn-gramから、ランダムな最後の文字を選択します(分析からの重みを考慮)。
  3. 単語の終わりに達するまで繰り返します(事前定義された長さを使用するか、単語の終わりの頻度に関するデータから)。

異なる重みを持つ値のセットからランダムな値を選択するには、累積度数のテーブルを設定することから始めることができます。次に、周波数の合計よりも小さい数の間の乱数を選択し、それがどの間隔で落ちるかを確認します。

例えば:

  • Aは10回発生します。
  • Bは7回発生します。
  • Cは9回発生します。

次のテーブルを作成します:{A:10、B:17、C:26}。1から26までの数字を選択します。10未満の場合はAです。10以上17未満の場合は、Bです。17より大きい場合は、Cです。

于 2011-07-29T09:43:42.127 に答える
0

発音可能な単語を作成したい場合は、文字を結合しようとしないでください。

サウンドに参加します。選択するサウンドのリストを作成します:「abe」、「ape」、「gre」など

于 2011-07-29T11:21:10.143 に答える
0

より現実的な出力を得るために、英語の文字頻度を使用することをお勧めします: http://en.wikipedia.org/wiki/Letter_frequency

しかし、発音可能な単語が必要な場合は、おそらく音節から生成する必要があります。詳細については、オンラインで確認できます。たとえば、次のURLを参照してください。

于 2011-07-29T09:08:47.683 に答える
0

ソーステキストを読んでマルコフモデルを導出し、ソースに「似た」単語を生成できます。

これは、単語から文を生成する場合にも機能します。まあ、一種の作品。

于 2011-07-29T09:32:14.603 に答える
0

単語の文字頻度のみを変更したい場合は、(quペアのように) 語彙分析を行わずに、英語の文字頻度のリストを取得します。

次に、 (1000 分の 1 程度) よりも ( e7 分の 1 の確率)を出力する可能性が高い加重ランダム ジェネレーターを作成します。x

加重乱数発生器 (rand は整数を生成、IIRC) を生成するには:
1. すべての整数になるように文字の頻度を正規化します (ウィキペディアの頻度は基本的に 100000 を掛けます)
2. ある種のルックアップ テーブルを作成します。下の表のように、特定の範囲を割り当てます

letter  | weight  |  start   |    end
a       |   8.17% |      0   |   8167
b       |   1.49% |   8168   |   9659
c       |   2.78% |   9660   |  12441
d       |   4.25% |  12442   |  16694
e       |  12.70% |  16695   |  29396
f       |   2.23% |  29397   |  31624
g       |   2.02% |  31625   |  33639
.....
z       |   0.07% | 99926    |  99999

3. 0 から 99999 までの乱数を生成し、それを使用して対応する文字を見つけます。このようにして、正しい文字頻度が得られます。

于 2011-07-29T09:13:56.423 に答える
0

まず、次のような文字とその重みを含むテーブルが必要です。

struct WeightedLetter
{
    char letter;
    int  weight;
};

static WeightedLetter const letters[] =
{
    { 'a', 82 },
    { 'b', 15 },
    { 'c', 28 },
    //  ...
};

char getLetter()
{
    int totalWeight = 0;
    for ( WeightedLetter const* iter = begin( letters );
            iter != end( letters );
            ++ iter ) {
        totalWeight += iter->weight;
    }
    int choice = rand() % totalWeight;
                // but you probably want a better generator
    WeightedLetter const* result = begin( letters );
    while ( choice > result->weight ) {
        choice -= result->weight;
        ++ result;
    }
    return result->letter;
}

これは私の頭の中で考えただけなので、エラーが含まれている可能性があります。少なくとも、2 番目のループでは検証が必要です。しかし、それはあなたに基本的な考え方を与えるはずです。

もちろん、これでも英語のような単語にはなりません。"uq" のシーケンスは "qu" と同じように可能性が高く、母音のない単語や母音だけの 10 文字の単語を妨げるものは何もありません。英語の音韻論に関するウィキペディアのページには、どの組み合わせがどこで発生する可能性があるかについての良い情報がありますが、それらに関する統計はありません. 一方、Jabberwocky のように可能な単語を作成しようとしている場合、それは問題にならない可能性があります。1 から最大値までのランダムな数の音節を選択し、次にオンセット、核、およびコーダを選択します。(オンセットとコーダが空になる可能性があることを忘れないでください。)

于 2011-07-29T09:47:53.380 に答える