0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ひよっこエンジニアが生成AIを組み込んだ名寄せツールを開発した話

Posted at

はじめに

不動産データの名寄せは、表記揺れや欠損情報の補完が必要な場面が多く、手作業で行うには非常に手間がかかります。今回は、機械的な名寄せ処理AIおよび翻訳APIを組み合わせた補完処理を組み込んだツールを作成しました。

このツールは以下の課題を解決します:

  1. 表記揺れの正規化とデータの重複排除
  2. 備考欄の英語を翻訳して日本語データに統一
  3. 欠損情報をAIで補完し、データの品質を向上

使用した技術スタック

以下の技術を使用しました:

  • 言語: TypeScript
  • フレームワーク: Next.js
  • 翻訳サービス: DeepL API
  • AIモデル: Google Generative AI (Gemini Pro)
  • データ操作:
    • Node.js の fs モジュールでファイル操作
    • csv-parser ライブラリでCSVデータ解析
    • csv-writer ライブラリでCSV出力

機能要件

主な機能

  1. 表記揺れの正規化

    • 物件名、住所、電話番号の表記揺れを統一し、データの重複を検出しやすくする。
  2. 備考欄の翻訳

    • 備考欄の英語をDeepL APIで高品質な日本語に翻訳。
    • 日本語の備考は翻訳せずそのまま保持。
  3. フェーズ1:機械的な名寄せ

    • 正規化されたフィールドをもとに、同一データを識別。
    • 備考欄の情報を重複なく統合。
  4. フェーズ2:AIによる補完と仕上げ

    • Google Generative AIを使用し、欠損データの補完や備考欄の整理を実施。

苦労した不具合と解決方法

1. 表記揺れの統一

問題: 名寄せキー作成時、住所や電話番号の表記揺れが原因でデータが正しく統合されない。
解決:

  • normalizeField関数を作成し、全角・半角やハイフン、スペースなどを正規化。

2. 英語翻訳の品質問題

問題: 備考欄をAIで翻訳した場合、翻訳品質が低く、誤訳や不自然な表現が多発。
解決:

  • DeepL APIを使用し、英語の備考のみを高品質な日本語に翻訳。
  • 日本語の備考はそのまま保持するようにcontainsJapanese関数を実装。

3. AIによる名寄せの品質不足

問題: AIを単独で名寄せに使用すると、備考欄の情報が欠損したり、順序が乱れるケースが発生。
解決:

  • 機械的な名寄せ処理(フェーズ1)で同一データを事前に統合。
  • AIには欠損補完や備考欄の調整のみを依頼。

工夫したロジック

1. 機械的な名寄せ処理の採用

AI任せにすると品質が低下するため、以下の手順を追加:

  • 正規化されたフィールドを用いて名寄せキーを生成。
  • 機械的にデータを統合し、備考欄を一意にまとめる。

2. DeepLとAIの役割分担

  • 英語の備考翻訳をDeepL APIに任せることで、翻訳品質を確保。
  • AIには欠損補完や最終的な統合処理を依頼。

3. プロンプト設計

Google Generative AIに渡すプロンプトを以下のように改善:

  • 欠損や順序乱れを防ぐため、具体的な指示を記載。
  • 出力フォーマットをJSONで固定し、解析エラーを防止。

以下は、AIによる名寄せの部分を含めたコードのポイントです。

コードのポイント

1. 備考欄をDeepL APIで翻訳するロジック

英語の備考を高品質な日本語に翻訳し、日本語の備考はそのまま保持します。

const translateNotes = async (records: Array<{ [key: string]: string }>) => {
  const translatedRecords = [];
  for (const record of records) {
    if (record.備考) {
      try {
        if (containsJapanese(record.備考)) {
          // 日本語の場合はそのまま
          translatedRecords.push(record);
        } else {
          // DeepLで英語を日本語に翻訳
          const result = await translator.translateText(record.備考, null, 'ja');
          translatedRecords.push({ ...record, 備考: result.text });
        }
      } catch (err) {
        console.error('Failed to translate note:', record.備考, err);
        translatedRecords.push(record); // 翻訳失敗時は元データを保持
      }
    } else {
      translatedRecords.push(record);
    }
  }
  return translatedRecords;
};

2. AIによる名寄せのロジック

Google Generative AIを使用して、欠損データの補完と備考欄の整理を行います。

const finalizeDeduplicationWithAI = async (records: Array<{ [key: string]: string }>) => {
  const prompt = `
    以下の不動産データについて、重複を名寄せして整理してください。一意のレコードのみを保持し、すべての情報を欠損なく統合してください。
    - 備考欄の情報は重要であるため、欠損や省略がないように統合してください。
    - 既存の備考を削除せず、すべての内容を含めてください。
    - 備考欄の情報が重複する場合は、順序を保持して統一してください。

    入力データ:
    ${JSON.stringify(records)}

    出力フォーマット:
    [
      {
        "物件名": "正規化済みの物件名",
        "住所": "正規化済みの住所",
        "電話番号": "正規化済みの電話番号",
        "備考": "統合された備考情報(, 区切り)"
      },
      ...
    ]
  `;

  const model = googleClient.getGenerativeModel({ model: 'gemini-pro' });
  const response = await model.generateContent(prompt);

  const generatedText = typeof response.response?.text === 'function'
    ? response.response.text()
    : response.response?.text;

  if (!generatedText) {
    throw new Error('No response text from Google Generative AI.');
  }

  const cleanedText = generatedText.trim().replace(/```\n/g, '').replace(/```/g, ''); // 不要な囲み文字を削除
  console.log('Generated JSON:', cleanedText);

  return JSON.parse(cleanedText);
};

ポイント

  • AIのプロンプトに具体的な指示(欠損防止や備考欄の統合ルール)を記載し、出力品質を確保。
  • プロンプト設計を工夫することで、データの欠損や乱れを最小化。

このように、DeepL APIとGoogle Generative AIを適材適所で組み合わせることで、データ品質を大幅に向上させることができました。


実行結果

以下のデータを処理した結果:

入力データ(サンプル)

物件名,住所,電話番号,備考
サンプルマンション,東京都新宿区西新宿1-1-1,0120-123-456,新築物件
サンプルマンション,東京都新宿区西新宿1-1-1,0120-123-456,築2年
さんぷるマンション,東京都新宿区西新宿1-1-1,0120123456,リフォーム済み
SAMPLE MANSION,Tokyo Shinjuku-ku Nishi-Shinjuku 1-1-1,0120123456,Free Wi-Fi
SAMPLE MANSION,Tokyo Shinjuku-ku Nishi-Shinjuku 1-1-1,0120123456,駐車場完備

出力データ

物件名,住所,電話番号,備考
サンプルマンション,東京都新宿区西新宿1-1-1,0120-123-456,"新築物件, 築2年, リフォーム済み, Free Wi-Fi , 駐車場完備"


まとめ

今回作成した不動産名寄せツールでは、DeepL APIとGoogle Generative AIを役割分担させることで、データの品質を大幅に向上させることができました。特に、以下の工夫が有効でした:

  • 機械的な処理で表記揺れを正規化
  • DeepL APIで高品質な英語翻訳を実現
  • AIをデータ補完と調整のみに使用することで効率化

このツールは、不動産データ以外の名寄せ処理やデータ統合にも応用可能です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?