4

着信 SMS を取得するアプリを作成しています。次に、キーワードに基づいて、そのキーワードが実行中のキャンペーンに関連付けられているかどうかを確認します。私が現在行っている方法は、キーワードと可能なスペルの組み合わせのリストをロードすることです。次に、SMS が届くと、すべてのキーワードと組み合わせを調べて一致するかどうかを確認します。

この方法を使用せずに、別の単語に一致する可能性のある単語を実際に探すことによって、これを行うにはどうすればよいでしょうか。

正しいつづりが HAMSTER だとしましょう。通常、キャンペーンには HMSTER HIMSTER HAMSTAR HAMSTR HAMSTIR などの代替語を付けます。

これを行うスマートな方法はありますか?

ハムスター

"hamstir".compare_to("ハムスター") ? マッチ

編集:

2語でどうですか?SMS で一致する必要がある 2 つの単語があることがわかっているとします。

最初の単語に正解 = THE FIRST WORD

2 番目の単語の正解 = AND 2 番目の単語

SMS = 最初の単語 2 番目の単語

編集:

理想的には、コンマで区切られた単語を SMS で送信する必要があります。これにより、どこで単語を分割して検索すればよいかがわかります。

しかし、次のように、そうでない場合はどうなりますか。

UNIQUE KEYWORD 2 番目のパラメーター

単語がどこで分割されているかをどのように見分けることができますか? 最初の単語の長さは 3 単語で、2 番目の単語は 3、1、2 などです。

これらの例では、以下の手法をどのように使用して 2 つの単語を見つけますか?

二度見しますか?必要なパラメータまたはキーワードごとに 1 つですか?

4

5 に答える 5

9

最も簡単な解決策は、おおよその文字列マッチング機能を備えたdifflibパッケージを使用することです。get_close_matches

import difflib
difflib.get_close_matches(word, possibilities)
于 2012-07-19T15:10:08.607 に答える
6

あなたが探しているのはレーベンシュタイン距離です。

キャンペーンのリストが大きすぎないと仮定すると、入力された単語と各キャンペーンの単語との距離を計算し、最短のものを選択できます。完全に間違った単語を除外するには、最小許容距離を設定し、最短でも制限を超えている場合は入力を破棄する必要がある場合があります。

2 つの単語間の距離を計算するには、次のモジュールのいずれかを試すことができます。

たとえば、次を使用しlevenshtein.pyます。

from levenshtein import levenshtein
campaigns = (
    "HAMSTER",
    "TWO WORDED",
    "FRIDAY",
)

def get_campaign(word):
  return min(campaigns, key=lambda x: levenshtein(word, x))

使用法:

>>> get_campaign("HAMSTA")
'HAMSTER'
>>> get_campaign("HAM WORDED")
'TWO WORDED'
>>> get_campaign("FROODY")
'FRIDAY'
>>> get_campaign("FRIDAY")
'FRIDAY'

これは非常に単純なアプローチであり、入力が完全に異なっていても常に何かを返すことに注意してください。

于 2012-07-19T15:06:04.427 に答える
2

同様の問題を解決するためにレーベンシュタイン距離を使用しますhttp://en.wikipedia.org/wiki/Levenshtein_distanceを参照してください

def distance(u1, u2):
    try:
        s1 = unicode(u1)    
        s2 = unicode(u2)
    except:
        s1 = u1
        s2 = u2        
    if len(s1) < len(s2):
        return distance(u2, u1)
    if not s1:
        return len(s2)

    previous_row = xrange(len(s2) + 1)
    for i, c1 in enumerate(s1):
        current_row = [i + 1]
        for j, c2 in enumerate(s2):
            insertions = previous_row[j + 1] + 1 # j+1 instead of j since previous_row and current_row are one character longer
            deletions = current_row[j] + 1       # than s2
            substitutions = previous_row[j] + (c1 != c2)
            current_row.append(min(insertions, deletions, substitutions))
        previous_row = current_row

    return previous_row[-1]


distance("hamstir", "hamster") < 3
True
distance("god", "hamster") < 3
False
于 2012-07-19T15:06:10.713 に答える
1

regexあいまい一致とライブラリを使用した名前付きリストを使用して、たとえば、最大で 1 つのエラー (挿入、削除、置換) を含むリストから任意のフレーズを見つけることができます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import regex as re # pip install regex

words = ["first word", "second word", "third"]
sms = u"junk Furst Word second Third"

for m in re.finditer(ur"(?fie)\L<words>{e<=1}", sms, words=words):
    print(m[0]) # the match
    print(m.span()) # return indexes where the match found in the sms
    # to find out which of the words matched:
    print(next(w for w in words
               if re.match(ur"(?fi)(?:%s){e<=1}" % re.escape(w), m[0])))

出力

Furst Word
(5, 14)
first word
Third
(22, 27)
third

または、単語を直接反復することもできます。

for w in words:
    for m in re.finditer(ur"(?fie)(?:%s){e<=1}" % re.escape(w), sms):
        print(m[0])
        print(m.span())
        print(w)

最初の例と同じ出力が生成されます。

于 2012-07-20T13:32:01.650 に答える
1

スペルチェッカーを構築しようとしているようです。最小編集距離マッチングを使用できます。または、 Peter Norvig の python スペル チェッカーを見てください。

それが役立つことを願っています

于 2012-07-19T15:09:22.037 に答える