2

PHP を使用して、異なる構造の XML ファイルを結合する必要があります。私がやっていることは次のとおりです。

  1. を使用して最初の XML ファイルを読み取りますsimplexml_load_file()
  2. SimpleXMLElement()クラスを使用して新しい構造を使用して要素を再フォーマットします
  3. SimpleXMLElement()他のファイルについても同じことを行い、最初のインスタンスをインクリメントします
  4. 新しく結合された XML ファイルを保存します。

ここまでは順調ですね。トリッキーな部分は、最初のファイルには約があります。3000 のエントリと 2 番目のファイルには 5000 のエントリがあります。これらのエントリのほぼ 2000 は実際には同じです。数文字違うだけかもしれません。たとえば、「Lenovo G50-70 CoreI5」と「Lenovo G5070 I5」かもしれません。

問題は、最初のファイルのエントリを 2 番目のファイルのエントリと一致させるにはどうすればよいかということです。実際には、新しい結合ファイルでは合計で 1 つのエントリだけになるのでしょうか?

similar_text()PHP と SmithWatermanGotoh の両方の関数を使用して類似度を計算していますが、スコアは 86% です。これで十分です。しかし、1 つのエントリだけに一致するように他のファイルのすべてのエントリを反復することは、非常に賢明ではなく、リソースを消費します。なぜなら、それは約を意味するからです。新しい更新されたファイルを保存するたびに、7 MB のファイルがメモリにロードされ、最低 15,000 回の反復が行われます。

すべてのエントリをデータベース テーブルに挿入することを検討し、Sphinx Search を使用してエントリを照合します。しかし、それが本当に十分に役立つかどうかはわかりません。

4

1 に答える 1

1

私が見ることができる最良のアプローチは、array_uintersect()関数でカスタム コールバックを使用することです。この方法は次のような手順で機能します。

1- 類似度を計算する比較関数を書きます。array_uintersect()このコールバック関数をどのように記述する必要があるかについては、php.net のマニュアルを参照してください。その名前はfind_similar_entries()

2- 異なる XML ファイルから両方のエントリをそれぞれ 2 つの配列に収集します。(簡単な方法として、json_encode()最初に行ってからjson_decode()戻る。)

3-交差関数に類似したエントリを見つけてもらいます。$similar_products = array_uintersect($xml_array1, $xml_array2, 'find_similar_entries');

4- これで、類似したエントリが 1 つのアレイに収集されました。

5-array_diff()元の配列から同様のエントリを削除するために呼び出します。

SimpleXMLElement()6- 最後に、クラスを使用して、希望に応じて 3 つの配列すべてを新しい XML 構造に結合します。

注 1:similar_text()類似度を計算するために SmithWatermanGotoh と SmithWatermanGotoh を使用しました。しかし、互いに数文字しか違わない非常に近い製品名になると、それらは「同一」になってしまいます。文字列から特徴的な単語を抽出する以外にできることはありません。私の場合は「モデル名」のように。

注 2: この方法は期待どおりに機能しますが、PHP の交差関数にはバグがあり、これらの関数が非常に遅くなると思います。そのためのバグレポートを作成しました。Intersection は、2 つの配列の要素を交差方向のみで比較するわけではありません。ただし、配列自体の要素も比較します。交点は少なくとも 2 つの当事者を比較することによってのみ計算できるため、これは実際には非論理的です。したがって、1 つの配列を内側から比較することは、実際には「交差」ではありません。これが、大きなファイルがある場合、これを単純に実行するとスクリプトが停止する理由です。たぶん、チャンクごとに行うことができます。

于 2016-11-01T17:04:09.183 に答える