2011-10-30 23 views
1

トークン化されたテキストを表すデータベースにトークンというテーブルがあります。データベースからテーブル全体を反復処理する最も良い方法は何ですか?

各行は、私が知りたいのは何(トークンからであるというテキストを識別するための)のTextBlock、文や位置などの属性やなどのテキスト、カテゴリ、chartype、のような論理フィールド

をぐるぐる以上のすべての反復でありますパターンを見つけていくつかの操作を行うトークン。たとえば、カテゴリとして名前を持つ2つの隣接するトークンを1つにマージします(この後、位置をリセットします)。私は何らかのリストが必要だと思う。

これを行うにはどのような方法が最適ですか? SQLクエリを使用して、パターンを検索したり、テーブル内のすべてのトークンを反復処理したりします。私はクエリが複雑になるだろうと思うし、多分リストがよりシンプルになるように繰り返しますが、どのような方法であるのかわかりません(例として、Javaリストを取得するか、繰り返し実行できる言語を使用しますデータベース上で右に変化する)。

この質問に私が知りたいことは、これを行うための最も推奨される方法です。私はJavaを使用していますが、もし他の言語がうまくいけば問題はありません。私はRを使って統計計算を行う必要があると思います。

編集:テーブルが大きく、何百万行もあり、メモリ全体が読み込めません。

+0

R http://www.joeconway.com/plr/あまりにも多くの新しい質問を開かないでください。あなたの研究分野は面白いですが(私たちの一部に)、人々は混乱したり、迷惑になるかもしれません。 – wildplasser

答えて

2

これは、主に保守したいコーパスのサイズと、それらに対して実行する操作の種類に基づいて行われることになります。

サイズが「エディタに収まるもの」よりも大きくなる場合は、何らかの種類のデータベースが必要になります。これは、SQLデータベースであってもなくてもよい。しかし、コード部分もあります。データに対して軽微な操作を実行するには、のプログラミング言語が必要です(C、Java、Pythonなど)。その場合、データベースとの通信はボトルネックになります。アプリケーションプログラムのメモリに収まる結果を生成するクエリを生成する必要があります。 SQLは、Nグラムを表現して保存するのに十分強力ですが、それについてはいくつかの計算を行いますが、それはあなたが得ようとしている限りです。どのような場合でも、データベースは完全に正規化されている必要があり、非DBAの方が理解しにくくなります。

私自身の玩具プロジェクト、http://sourceforge.net/projects/wakkerbot/ハイブリッドアプローチを使用した:

  • データがデータベース
  • 実際の(修飾MegaHalにあるように、コーパスが格納されたPythonのクローラー
  • によって得られましたマルコフコードは、辞書、Nグラム、および関連する係数を含む(バイナリ)フラットファイルにコーパスの独自のバージョンを格納します。
  • 高度に最適化されたCプログラムによってトレーニングとテキスト生成が行われます。
  • 出力は別のpythonスクリプトによって取得され、ターゲットに送信されました。

[別の人生では、おそらくさらに正規化を行い、Nグラムまたはツリーをデータベースに格納していたでしょう。そうすれば、パフォーマンスは1秒あたり生成される文章が数個に減少する可能性があります。今は約4000 /秒]

あなたが望むのは、ちょうど1つのタスクを効率的に行うプログラム(wakkerbotなど)よりも "言語的な作業台"に似ているということです。いずれにしても、もう少し正規化する必要があります:トークンを{tokennumber、tokentext}として保存し、数字だけで参照してください。基本的には、テキストはトークン番号の束を含むテーブル(または配列)です。 Nグラムは、ちょうどカップルのtokennumbers +対応する係数です。

+0

あなたの最初の段落は、データベースの実際の言語でそれを行うための完璧な議論です。PostgreSQLは文字通り何十もの一般的であいまいな手続き型言語をサポートしています。新しいものを学びたくなければ、perl、python、C、sql、plsql、R(Sと似た統計プログラム)、java、およびもっと多くの。 –

+0

修正、第2段落。 –

+0

私は違います。一般的な用途(OPのような)のためには、データベースが必要です。これにより、データ管理が容易になります。狭い規模のアプリケーションでは、専用の最適化がデータベースを強制的に排除します。 (覚えておいてください:Google 1.0は辞書をコアにロードする必要がありました)明白な理由のために、その後の開発により、GoogleはGFSや他のプレnosqlのものを作り出しました。スクリプト言語に関して:pythonの辞書は、この種のアプリケーションではあまりにも肥満です。私の共同開発者の一人がそれを試してみました。しかし、それはすべて手元のアプリケーション – wildplasser

1

IMOすべてをJavaにロードして操作を簡単にすることができ、DB全体の再クエリが頻繁に繰り返されるのを避けるために、

Javaと統計には非常に強力な数値ライブラリがいくつかあります。あなたが必要としているものが入手できない(または遅すぎる)かどうかを確かめるまで、私はそれを外して解雇しません。

+0

私はメモリ内のテーブル全体を読み込むことができないと言ったことを忘れましたが、私はこれにカーソルを使うことができると思います。 –

+0

@RenatoDinhaniConceiçãoああ、この場合、最良の方法が何であるかはわかりません –

+0

カーソルが最良の方法です。 updateキーワードで宣言して、マスター表の値を変更できるようにしてください。 Daveは、データセット全体をJavaにロードすることはスケーラブルではありません。私は昨年、開発者が私が取り組んだアプリケーションの初期段階で何をしたかで、その問題を追いかけて修正しました。対処する悪夢。 pgsqlで統計情報が必要な場合はplrを使用すると、Javaのパフォーマンスが賢明になります。統計情報は統計情報を作成するために作成されています。本当に印象的です。 –

3

小さいテーブルを使用して作業している場合、またはマージ戦略を証明している場合は、候補の重複する行をすべて検索し、関連する列をテーブルにダンプします。その表をテキストエディタまたはスプレッドシートで表示して、重複に関する仮説が正しいかどうかを確認します。

2つの行を1つにマージしようとすると、データが削除されることに注意してください。最悪の場合は、すべての行を1つにマージすることです。慎重に進んでください!

+0

ええ、テスト時には、トランザクション内のすべてのクエリを実行し、中間状態を表示してバックアップを取る... pgsqlで簡単にプレイデータベースを作成できます。 テンプレートolddbでデータベースnewdbを作成します。 tada再生する使い捨てデータベース。注:データベース全体をコピーする必要があるので、しばらく時間がかかります。ダンプして新しいdbを復元するよりも速いです。 –

2

これは最適化された方法ではありませんが、コードを簡単に書くことができるデザインです。

  1. テーブルの行を表すエンティティクラスを作成します。

  2. 特定の行IDのエンティティオブジェクトを取得できるファクトリメソッドを記述します。つまり、指定された行の値を持つエンティティクラスのオブジェクトを作成するメソッドです。

  3. テーブルに特定の行オブジェクトを削除して挿入するメソッドを書き込みます。

  4. 行カウント方法を書き込みます。

  5. 今、あなたのJavaコードを使用してテーブルを反復しようとすることができます。 2つの行の間をマージすると、次のインデックスを正しく調整する必要があることに注意してください。

この方法では、小さなメモリを使用できますが、多くのクエリを使用して行を作成します。

概念はORM(オブジェクトリレーショナルマッピング)と非常によく似ています。もしあなたがhibernateや他のORMを使う方法を知っていたら、それらのライブラリを試してみてください。

+0

インデックスがインデックスを管理している場合、インデックスを更新または再インデックスする必要はありません。それは自動的です。以前に述べたように、jdbcは何らかの「カーソルを自動的に使用する」モードに入ることができるはずです。それで、一度にすべてをメモリに保持しているわけではありません。 –

+0

"データベースがインデックスを管理している場合" –

+0

私はデータベースのインデックスについて話していませんでした。プログラム内のループのインデックスについて話していました。それらは異なる場合があり、通常、twholeテーブルのインデックスを更新したくない場合があります。 – gigadot

1

これは、テキスト検索エンジンを設計しているようです。まず、pgsqlの全文検索エンジンが適切かどうかを確認する必要があります。

フルテキスト検索を行わないと、plをpgsqlにロードしてドライブすることを学ぶことが、最も高速で効率的な解決策になりそうです。それはあなたがRのいくつかのよく考えられた行にこのすべての作業を置くことを可能にし、データへのアクセスが最も近いdbのすべてでそれを行います。そのような計画を避ける唯一の時間は、データセットをメモリに保持し、その中の単一のCPUコアをクランキングするなど、データベースサーバを非常に難しくする場合です。それから、アプリ側にするのは大丈夫です。

pl/Rを使用するかどうかにかかわらず、カーソル内の大量のデータセットにアクセスすると、1つまたは複数の行のサブセットを取得するのが最も効率的です。あなたが処理したいそれぞれの事柄に対してwhere句を使ってselectを実行すると、メモリ内のすべての行を一度に保持する必要はありません。実行中の平均などのように、結果セットの一部を取得して破棄することができます。

ここでスケールについて考えてみましょう。 5 TBのデータベースがある場合、これを最も速くアクセスするにはどのようにアクセスしますか?データセットの1%にしかアクセスしていない場合でも、スケーリングの貧弱なソリューションが戻ってきます。そして、あなたがすでにかなり大きなデータセットを開始しているのであれば、それは時間とともに悪化するでしょう。

PL/[トピックオフ]

+0

私は彼の分野がコンピュータ言語学のようなものだと思います。あなたの5 TBデータベースの例では、行の1%が有効であることを期待しています。しかし、このクエリーは、(ほぼ)1%異なるオブジェクトの選択があるたびに、複数回実行する必要があります。言語研究はDNA研究に非常に関連しています。どちらもメソッドのようにボリュームがあります。ゲノム研究は現在ハイブリッド/フラットファイル法も使用しています。一般的な使い方は分散型と増分型の方法を可能にするほど狭いため、検索エンジンとBIは少し異なります。 – wildplasser

関連する問題