0

このスクリプトは、play.golang.org でエラーなしでコンパイルされています: http://play.golang.org/p/Hlr-IAc_1f

しかし、自分のマシンで実行すると、ターミナルで何も起こらずに、予想よりもはるかに長い時間がかかります。

私が構築しようとしているのは、PartOfSpeech Tagger です。

最も長い部分は、lexicon.txt をマップにロードし、各単語をそこにあるすべての単語と比較して、辞書で既にタグ付けされているかどうかを確認することだと思います。レキシコンには動詞のみが含まれています。しかし、動詞かどうかを確認するために、すべての単語をチェックする必要はありません。

より大きな問題は、単語が副詞や形容詞などの簡単なヒューリスティックを使用して動詞であるかどうかを判断する方法がわからないことです。

4

2 に答える 2

7

(引用):

単語が副詞、形容詞などの簡単なヒューリスティックを使用して動詞であるかどうかを判断する方法がわかりません。

あなたの Go 実装の問題について話すことはできませんが、一般的な POS タグ付けのより大きな問題に対処します。ルールベースのユニグラムタガーを構築しようとしているようです。これらの用語について少し詳しく説明します。

  • 「ユニグラム」とは、文中の各単語を個別に検討していることを意味します。ユニグラム タガーは、複数の POS タグを使用できる単語のあいまいさを解消できないという点で、本質的に制限があることに注意してください。たとえば、'fish' は名詞または動詞としてタグ付けする必要がありますか? 「最後」は動詞か副詞か.
  • 「ルールベース」とは、まさにその名の通り、各単語のタグを決定する一連のルールを意味します。ルールベースのタグ付けは、別の方法で制限されます。共通言語のあいまいさの合理的な部分を処理するルールセットを組み立てるには、かなりの開発努力が必要です。この取り組みは、適切なトレーニング リソースがない言語で作業している場合に適しているかもしれませんが、ほとんどの一般的な言語では、高精度のタグ付けモデルをトレーニングするのに十分なタグ付きテキストが用意されています。

最先端の POS タグ付けは、整形式のニュースワイヤー テキストで 97% を超える精度です (形式的ではないジャンルの精度は当然低くなります)。ルールベースのタガーは、パフォーマンスが大幅に低下する可能性があります (要件を満たすために必要な精度レベルを決定する必要があります)。ルールベースの道を進みたい場合は、このチュートリアルを読むことをお勧めします。コードは Haskell に基づいていますが、ルールベースのタグ付けの概念と問題を学ぶのに役立ちます。

とはいえ、他のタグ付け方法を検討することを強くお勧めします。ユニグラムのタグ付けの弱点について述べました。関連するアプローチは「bigram」です。これは、単語 n にタグを付けるときに前の単語を考慮することを意味します。「trigram」(通常、前の 2 つの単語、または前の単語、現在の単語、次の単語)。より一般的には、「n-gram」は n 個の単語のシーケンスを考慮することを指します (多くの場合、現在タグ付けしている単語の周りのスライド ウィンドウ)。そのコンテキストは、「魚」、「最後」、「ハエ」などを明確にするのに役立ちます。

たとえば、

私たちは釣りをします

おそらく魚を動詞としてタグ付けしたいでしょうが、

魚を食べた

確かに名詞です。

ここでは、NLTK チュートリアルが参考になるかもしれません。堅実な n-gram タガーを使用すると、90% を超える精度が得られるはずです。95% を超える可能性が高い (これもニュースワイヤーのテキストで)。

より洗練された方法 (「構造化推論」として知られている) では、タグ シーケンス全体が全体として考慮されます。つまり、各単語の最も可能性の高いタグを個別に予測しようとする代わりに、入力シーケンス全体の最も可能性の高いタグのシーケンスを予測しようとします。もちろん、構造化された推論は実装とトレーニングがより困難ですが、通常は n-gram アプローチよりも精度が向上します。この分野について詳しく知りたい場合は、Sutton と McCallum の優れた紹介をお勧めします。

于 2014-04-29T19:14:25.693 に答える
0

この関数には大きな配列引数があります:

func stringInArray(a string, list [214]string) bool{
    for _, b := range list{
        if b == a{
            return true;
        }
    }
    return false
}

この関数を呼び出すたびに、ストップワードの配列がコピーされます。

ほとんどの場合、Go では、ほとんどの場合、配列ではなくスライスを使用する必要があります。this の定義を に変更し、配列ではなくスライスとしてlist []string定義します。stopWords

stopWords := []string{
    "and", "or", ...
}

おそらくさらに良いアプローチは、ストップワードのマップを作成することです:

isStopWord := map[string]bool{}
for _, sw := range stopWords {
    isStopWord[sw] = true
}

次に、単語がストップワードかどうかをすばやく確認できます。

if isStopWord[word] { ... }
于 2014-04-27T07:24:48.647 に答える