1

私はこのSOの質問を拡張し、 2つのラテックス方程式を比較しています。2 つの二次方程式の例を次に示します。

eqn1 = "*=\frac{-*\pm\sqrt{*^2-4ac}}{2a}"
eqn2 = "x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}"

x、bの代わりに*を使用しているため、これらを正しいものとして比較する必要があります。私がしているのは、方程式を単語リストに変換することだけです。

eqn1_word = [*,frac,*,pm,sqrt,*,2,4ac,2a]
eqn2_word = [x,frac,b,pm, sqrt, b, 2, 4ac, 2a]

したがって、ベクトルは

eqn1_vec= Counter({'*': 3, 'frac': 1, 'sqrt': 1, '2': 1, '2a': 1, '4ac': 1, 'pm': 1})
eqn2_vec = Counter({'b': 2, 'frac': 1, 'sqrt': 1, '2': 1, '2a': 1, '4ac': 1, 'x': 1, 'pm': 1})

今私の拡張は、私は eqn1_word の * のパーセンテージをチェックしており、その答えで与えられた通常のコサイン類似度でチェックしています。最後に、ほぼ 1 に等しくなければならない 2 つの値を追加します。

これは、ほとんどのシナリオで問題なく機能します (1 つの変数が * に置き換えられた場合)。* eqn1_vec の値は 3 で、eqn2_vec では b = 2、x=1 です。

詳細な説明と理解を深めるために、これを確認してください。その参照から、私のコードは次のようになります。

def get_cosine(self, c_eqn1_eqn, c_eqn2_eqn):
    print 'c_eqn1_eqn = ', c_eqn1_eqn
    print 'c_eqn2_eqn = ', c_eqn2_eqn
    _special_symbol = float(c_eqn1_eqn.count("*"))
    cos_result = 0
    symbol_percentage = 0
    try:
        eqn1_vector = Counter(self.get_word(c_eqn1_eqn))# get word will return word list
        eqn2_vector = Counter(self.get_word(c_eqn2_eqn))
        _words = sum([x for x in eqn1_vector.values()])
        if eqn2_vector.has_key("*"):
            _special_symbol -= eqn2_vector["*"]
        print '_special_symbol = ', _special_symbol
        print '_words @ last = ', _words
        try:
            symbol_percentage = _special_symbol / _words
        except ZeroDivisionError:
            symbol_percentage = 0.0
    except Exception as exp:
        print "Exception at converting equation to vector", exp
        traceback.print_exc()
    else:
        intersection = set(eqn1_vector.keys()) & set(eqn2_vector.keys())
        numerator = sum([eqn1_vector[x] * eqn2_vector[x] for x in intersection])
        _sum1 = sum([eqn1_vector[x]**2 for x in eqn1_vector.keys()])
        _sum2 = sum([eqn2_vector[x]**2 for x in eqn2_vector.keys()])
        denominator = math.sqrt(_sum1) * math.sqrt(_sum2)
        print 'numerator = ', numerator
        print 'denominator = ', denominator
        if not denominator:
            cos_result = 0
        else:
            cos_result = float(numerator) / denominator
        print cos_result
    final_result = float(symbol_percentage) + cos_result
    return final_result if final_result <= 1.0 else 1

問題は、交差値が小さいため、分子が小さくなっているということです。クラスからコピーしました。自分は無視してください。

これを解決する方法。前もって感謝します。質問に間違いや私のコンセプトが間違っている場合は、私と共有してください.

4

1 に答える 1

1

この問題の解決策を得ました。

分子の値を増やすことができる/できないため、代わりに分母を処理することにしました。私の論理は、*の数とeqn2の交差しない値の数が同じ場合、分母の値を減らすことです。そうでない場合は、そのまま放っておきます。これで、「*」のパーセンテージを計算したり、コサイン結果に追加したりする必要がなくなりました。

def get_cosine(c_eqn1, c_eqn2):
    _special_symbol = float(c_eqn1.count("*"))
    cos_result = 0
    try:
        eqn1_vector = Counter(get_word(c_eqn1))
        eqn2_vector = Counter(get_word(c_eqn2))
        _special_symbol = 0
        spe_list = list()
        # Storing number of * & the value contains *
        for _val in eqn1_vector.keys():
            if _val.__contains__("*"):
                _special_symbol += eqn1_vector[_val]
                spe_list.append(_val)
        if eqn2_vector.has_key("*"):
            _special_symbol -= eqn2_vector["*"]
    except Exception as exp:
        print "Exception at converting equation to vector", exp
        traceback.print_exc()
    else:
        intersection = set(eqn1_vector.keys()) & set(eqn2_vector.keys())
        numerator = sum([eqn1_vector[x] * eqn2_vector[x]
                         for x in intersection])
        non_intersection_sum = 0
        non_intersection_value = list()
        # storing no of non_matched value
        for _val in eqn2_vector.keys():
            if _val not in intersection:
                non_intersection_sum += eqn2_vector[_val]
                non_intersection_value.append(_val)
        # Join both non intercet lists
        if non_intersection_value:
            non_intersection_value.extend(spe_list)
        # If both non intersect value are not same
        # Empty the list
        if _special_symbol != non_intersection_sum:
            non_intersection_value = list()
        # Cosine similarity formula
        _sum1 = sum([eqn1_vector[x]**2 for x in eqn1_vector.keys() if x not in non_intersection_value])
        _sum2 = sum([eqn2_vector[x]**2 for x in eqn2_vector.keys() if x not in non_intersection_value])
        denominator = math.sqrt(_sum1) * math.sqrt(_sum2)
        if not denominator:
            cos_result = 0
        else:
            cos_result = float(numerator) / denominator
    return cos_result if cos_result <= 1.0 else 1
于 2014-11-05T10:28:16.683 に答える