90294


python初心者です。difflibの概要は掴めたのですが、やりたいことのレベルがちょっと飛躍してしまいどのような処理をすればよいかわかりません。  
Pythonなら何でも知っているという方いらっしゃれば教えていただけますと幸いです。

目的：Pythonのdifflibを使用し、数万個ある文字列の比較したい。

リストa、リストbにそれぞれ文字列があり  
リストaを起点にしてリストbにある文字列の類似度を計測したいです。

[code]

    a = [
        "たかぎ歯科",
        "ホワイトニングクリニックtanaka",
        "大田矯正歯科 五反田院"
    ]
    
    
    b = [
        "ホワイトニングクリニック Tanaka",
        "大田矯正歯科五反田分院"
        "たかぎ歯科 品川院",
    ]
    
[/code]

リストが上記のように２つあった場合  
1\. aの "たかぎ歯科"に対してbの"ホワイトニングクリニック Tanaka","大田矯正歯科五反田分院","たかぎ歯科 品川院"の３つをすべて比較。

2.それぞれの類似度を出す  
※リストaの2つ目"ホワイトニングクリニックtanaka"も同様にbの1〜3番めの文字列を比較して類似度をだしてあげる。  
3.類似度が最も高いb内にある文字列をCSVで抽出したときに横に"たかぎ歯科"の横に並べたい

CSVイメージ

a | b | 類似度  
---|---|---  
たかぎ歯科 | たかぎ歯科 品川院 | 0.8  
ホワイトニングクリニックtanaka | ホワイトニングクリニック Tanaka | 0.9  
大田矯正歯科 五反田院 | 大田矯正歯科五反田分院 | 0.75  
  
※類似度の数値は適当にいれました。

以上が行いたい処理です。  
初心者でほとんどわからない状態ですが、ご教示いただけると幸いです。


CC BY-SA 4.0
2022-07-30T11:10:34.297
90287
2022-07-30T17:13:26.573
2022-07-30T11:34:04.277
3060
52109
question
python python3
Python：difflibで2つのリスト内にある文字列を比較し、類似度が最も高い文字列を横並びでCSVで出したい


`difflib`の仕様はこちらに書かれていますが、何か1つだけ呼び出せば出来るというものが見当たらないので困っているというところでしょうか。  
[difflib --- 差分の計算を助ける](https://docs.python.org/ja/3.10/library/difflib.html)

機能としてはよく使う物を解説しているこんな記事が参考になるでしょう。  
[【Python】文字列の類似度を測るdifflib.SequenceMatcherの使い方](https://www.y-shinno.com/python-
difflib/)  
`get_close_matches()`を使えば一番類似しているものを抽出出来て、それをもう一方のパラメータにして`SequenceMatcher()`を使えば類似度の数値が得られます。

それから「数万個ある」というデータ量に恐れをなしているのかもしれませんが、`a`のリストに対応するデータを全て調べたいのなら、その数の分だけはループする必要があります。  
[5.1.3.
リストの内包表記](https://docs.python.org/ja/3/tutorial/datastructures.html#list-
comprehensions)

csvファイルの作成は色々高機能なライブラリ/パッケージがありますが、今回程度なら標準で組み込まれている物でも使えます。  
[csv --- CSV ファイルの読み書き](https://docs.python.org/ja/3/library/csv.html)

こんな形で出来るでしょう。

[code]

    from difflib import get_close_matches, SequenceMatcher
    import csv
    
    a = [
        "たかぎ歯科",
        "ホワイトニングクリニックtanaka",
        "大田矯正歯科 五反田院"
    ]
    b = [
        "ホワイトニングクリニック Tanaka",
        "大田矯正歯科五反田分院",
        "たかぎ歯科 品川院"
    ]
    
    #### リスト b から一番類似している文字列を抽出し、
    #### その類似度を取得し、それらをリストとして返す関数を定義。
    #### 類似度の足切り率はデフォルトを最低にして、変更出来るようにしておく
    def closest(x, rate=0.01):
        result = get_close_matches(x, b, n=1, cutoff=rate)
        if len(result) <= 0:
            return [x, None, 0.0]
        result = result[0]
        s = SequenceMatcher(None, x, result)
        return [x, result, s.ratio()]
    
    #### リスト a のデータ全てを順番に処理するリスト内包表記
    data = [closest(s) for s in a]
    
    #### csvファイルとして出力(encoding等は必要に応じて変更)
    with open('closest.csv', 'w', newline='', encoding='cp932') as f:
        csvwriter = csv.writer(f)
        csvwriter.writerow(['a','b','類似度'])
        csvwriter.writerows(data)
    
[/code]


CC BY-SA 4.0
2022-07-30T17:13:26.573
90294
2022-07-30T17:13:26.573
26370
90287
answer