12

文字列内のキーワードまたはキーフレーズを検索するアルゴリズムの作成方法に関するアドバイスや指示が必要です。

文字列には次のものが含まれます。

  • 英語で書かれた技術情報(GB)
  • 単語は主にスペースで区切られます
  • キーワードにスペースは含まれていませんが、ハイフン、アポストロフィ、コロンなどが含まれている場合があります。
  • キーフレーズには、スペース、コンマ、またはその他の句読点を含めることができます
  • 2つ以上のキーワードが一緒に表示される場合は、「インバータドライブ」などのキーフレーズである可能性があります。
  • テキストにもHTMLが含まれていますが、必要に応じて事前に削除できます。
  • 非キーワードは、「and」、「the」、「we」、「see」、「look」などの単語になります。
  • キーワードでは大文字と小文字が区別されません。たとえば、「インバータ」と「インバータ」は同じキーワードです。

アルゴリズムには次の要件があります。

  1. バッチ処理シナリオで操作します。たとえば、1日1回または2回実行します。
  2. 長さが約200〜7000文字の文字列を処理します
  3. 1時間以内に1000本の文字列を処理する
  4. 適度に優れた電力のサーバーで実行されます
  5. 次のいずれかで記述されています:C#、VB.NET、またはT-SQLは、F#、Python、Luaなどです。
  6. 事前定義されたキーワードまたはキーフレーズのリストに依存しません
  7. ただし、「and」、「the」、「go」などのキーワード除外のリストに依存することができます。
  8. 理想的には他の言語に転送可能(例:メタプログラミングなどの言語固有の機能に依存しない)
  9. キーフレーズのリスト(頻度の降順)とそれに続くキーワードのリスト(頻度の降順)を出力します。

数秒で最大8000文字を処理でき、リアルタイムで実行できるとしたら、さらにすばらしいでしょうが、私はすでに十分に質問しています。

アドバイスと方向性を探しているだけです:

  • これは2つの別個のアルゴリズムと見なされるべきですか?
  • 私が従うことができる確立されたアルゴリズムはありますか?
  • 私の要件は実行可能ですか?

どうもありがとう。

PS文字列はSQLServer2008 R2データベースから取得されるため、理想的には言語がこれをサポートします。そうでない場合は、STDOUT、パイプ、ストリーム、ファイルなどに対して読み取り/書き込みができる必要があります。

4

1 に答える 1

11

関連するロジックにより、T-SQLでのプログラミングが複雑になります。C#のような言語を選択してください。まず、簡単なデスクトップアプリケーションを作成してみてください。後で、このアプリケーションへのすべてのレコードの読み込みが遅すぎることがわかった場合は、SQL-Serverで実行されるC#ストアドプロシージャを作成できます。SQL-Serverのセキュリティポリシーによっては、強力なキーが必要になります。


今アルゴリズムに。除外された単語のリストは、一般にストップワードリストと呼ばれます。この検索用語をグーグルで検索すると、最初からストップワードリストが見つかる場合があります。これらのストップワードをに追加しHashSet<T>ます(ここではC#を使用します)

// Assuming that each line contains one stop word.
HashSet<string> stopWords =
    new HashSet<string>(File.ReadLines("C:\stopwords.txt"), StringComparer.OrdinalIgnoreCase);

後で、キーワード候補がストップワードリストにあるかどうかを確認できます。

If (!stopWords.Contains(candidate)) {
    // We have a keyword
}

HashSetは高速です。アクセス時間はO(1)です。つまり、ルックアップを実行するために必要な時間は、含まれるアイテムの数に依存しません。

キーワードの検索は、正規表現を使用して簡単に行うことができます。

string text = ...; // Load text from DB
MatchCollection matches = Regex.Matches(text, "[a-z]([:']?[a-z])*",
                                        RegexOptions.IgnoreCase);
foreach (Match match in matches) {
    if (!stopWords.Contains(match.Value)) {
        ProcessKeyword(match.Value); // Do whatever you need to do here
    }
}

azが文字に対して制限が厳しく、アクセント付きの文字が必要な場合は、正規表現をに変更できます@"\p{L}([:']?\p{L})*"。文字クラス\p{L}には、すべての文字と文字修飾子が含まれます。

フレーズはもっと複雑です。テキスト全体を検索する代わりに、最初にテキストをフレーズに分割してから、これらのフレーズにキーワード検索を適用することができます。これにより、フレーズ内のキーワードの数が同時に得られます。

テキストをフレーズに分割するには、「。」で終わる文を検索する必要があります。また "?" また "!" また ":"。単語内に表示されるドットとコロンは除外する必要があります。

string[] phrases = Regex.Split(text, @"[\.\?!:](\s|$)");

これは、句読点の後に空白または行末が続くものを検索します。しかし、これは完璧ではないことに同意する必要があります。文末として略語を誤って検出する場合があります。分割メカニズムを改良するには、実験を行う必要があります。

于 2012-06-12T23:31:11.853 に答える