wordset1
とwordset2
のタイプについては言及していません。私は彼らが両方ともstrings
であると仮定します。
あなたの距離を単語カウントとして定義し、スコアが悪いです。同じサイズの2つの電子メールは完全に異なるものの話をされながら、異なるサイズを持つ2通の電子メールが、同じことについて話すことができます。これは明らかに、テキストの長さが良い非類似性の尺度ではないのです。上記で示唆したよう
だから、あなたは試みることができるし、代わりに類似した単語をチェック:
import numpy as np
def distance(wordset1, wordset2):
wordset1 = set(wordset1.split())
wordset2 = set(wordset2.split())
common_words = wordset1 & wordset2
if common_words:
return 1/len(common_words)
else:
# They don't share any word. They are infinitely different.
return np.inf
それに伴う問題は、二つの大きな電子メールは、このメトリック二つの小さなものよりも言葉を共有する可能性が高い、とということですそれらを好意して、小さなものと比べてより「互いに似ている」ようにします。これをどうやって解決するのですか?さて、何とかメトリックを正規化します:
これはクールだが、単語の頻度を完全に無視します。これを考慮に入れて、Bag-of-wordsモデルを使用することができます。つまり、すべての可能な単語のリストを作成し、それぞれの文書の外観をヒストグラム化します。
from sklearn.feature_extraction.text import CountVectorizer
def distance(wordset1, wordset2):
model = CountVectorizer()
X = model.fit_transform([wordset1, wordset2]).toarray()
# uses Euclidean distance between bags.
return np.linalg.norm(X[0] - X[1])
しかし、今の電子メールの2組を考慮してください。私たちの仕事はeaiserにするために、学ぶscikitからCountVectorizer実装を使用してみましょう。最初のペアのメールは必要それは文法的に正しいとは、「小」の単語(例えばa
、an
、is
、and
、that
)の完全な、完全に書かれた英語で構成されています。 2番目のペアのメールは異なります。キーワードのみが含まれているため、非常に乾燥しています。あなたは、最初のペアは2番目のペアよりも似ている可能性があります。私たちは、各テキストに意味のある言葉を優先しなければならない一方で、我々は現在、すべての単語のために同じ占めているので、それは起こります。これを行うには、term frequency–inverse document frequencyを使用しましょう。 Luckly、非常によく似た実装がscikit-学ぶにあります:
from sklearn.feature_extraction.text import TfidfVectorizer
def distance(wordset1, wordset2):
model = TfidfVectorizer()
X = model.fit_transform([wordset1, wordset2]).toarray()
similarity_matrix = X.dot(X.T)
# The dissimilarity between samples wordset1 and wordset2.
return 1-similarity_matrix[0, 1]
はこのquestionでこの詳細についてはこちらをご覧ください。また、複製?
あなたは今、かなり良い精度を持つ必要があります。やってみて。まだそれがあなたの望みどおりではないなら、もっと深く進む必要があります(それを得るには?なぜなら、深い学習)。最初に、訓練するデータセットまたは既に訓練されたモデルのいずれかが必要であることです。有用な変換を提供するためにネットワークには多くのパラメータを調整しなければならないので、これが必要です。
これまでに見逃していたことは理解できません。単語をヒストグラム化し、文脈や意味からストライピングしました。代わりに、それらをどこに残してパターンのブロックを認識しようとしましょう。これはどうすればできますか?
- さまざまなサイズの単語を扱う数字に単語を埋め込みます。
- すべての数字(単語埋め込み)シーケンスを単一の長さにパッドします。
- 畳み込みネットワークを使用して、シーケンスから意味のある機能を抽出します。
- 完全に接続されたネットワークを使用して、類似の電子メール間の距離を最小限に抑え、類似しない電子メール間の距離を最大にする空間に抽出された機能を投影します。
Kerasを私たちの生活に使いましょう。
# ... imports and params definitions
model = Sequential([
Embedding(max_features,
embedding_dims,
input_length=maxlen,
dropout=0.2),
Convolution1D(nb_filter=nb_filter,
filter_length=filter_length,
border_mode='valid',
activation='relu',
subsample_length=1),
MaxPooling1D(pool_length=model.output_shape[1]),
Flatten(),
Dense(256, activation='relu'),
])
# ... train or load model weights.
def distance(wordset1, wordset2):
global model
# X = ... # Embed both emails.
X = sequence.pad_sequences(X, maxlen=maxlen)
y = model.predict(X)
# Euclidean distance between emails.
return np.linalg.norm(y[0]-y[1])
あなたがKeras github repoを確認することができ文処理の実用的な例があります:それは次のようになります。また、誰かがこのstackoverflow questionのsiamese recurrentネットワークを使ってこのまったく同じ問題を解決します。
これはあなたにある方向性を与えてくれることを願っています。 :-)
多分、両方の単語セットの交差の長さが、より良い距離機能になる可能性があります。 –
その関数は1行にすることができます。 'math.abs(len1 - len2)' –