Поиск процента совпадения между 2 операторами

#go

#Вперед

Вопрос:

У меня есть следующие 2 строки, которые на самом деле означают то же самое:

 GLOVES: LENGTH: 32 CM MATERIAL: NEOPRENE RUBBER FREE FLOW TEXT: RESISTANT TO WIDE RANGE OF GLOVES, TYPE: CHEMICAL RESISTANT, SIZE: 7, MATERIAL: NEOPRENE RUBBER, STANDARD: BS EN 388/BS EN 374, FFT: RESISTANT TO WIDE RANGE OF CHEMICALS SUCH AS ETHYLENE OXIDE IDEAL FOR LONG TERM HEAVY WORK IN CHEMICAL ENVIRONMENT MANUFACTURER REFERENCES: ORIGINAL_MNFR: POLYCO
  

И

 Neoprene Rubber Chemical Resistant Gloves, Size: 7; Length: 32 cm; Standard: BS EN 388; Resistant to wide range of Chemicals such as Ethylene Oxide. Make: Polyco, Model: Duraprene III or Equivalent
  

У меня более 1000 подобных наборов, что является паникой, чтобы делать их вручную, я пытался сделать их как:

 package main

import (
    "fmt"
    "strings"
)

func main() {
    var str1 = "Neoprene Rubber Chemical Resistant Gloves, Size: 7; Length: 32 cm; Standard: BS EN 388; Resistant to wide range of Chemicals such as Ethylene Oxide. Make: Polyco, Model: Duraprene III or Equivalent"
    var str2 = "GLOVES: LENGTH: 32 CM MATERIAL: NEOPRENE RUBBER FREE FLOW TEXT: RESISTANT TO WIDE RANGE OF GLOVES, TYPE: CHEMICAL RESISTANT, SIZE: 7, MATERIAL: NEOPRENE RUBBER, STANDARD: BS EN 388/BS EN 374, FFT: RESISTANT TO WIDE RANGE OF CHEMICALS SUCH AS ETHYLENE OXIDE IDEAL FOR LONG TERM HEAVY WORK IN CHEMICAL ENVIRONMENT MANUFACTURER REFERENCES: ORIGINAL_MNFR: POLYCO"

    cnt := 0
    for _, i := range strings.Fields(str1) {
        for _, j := range strings.Fields(str2) {
            if strings.ToLower(i) == strings.ToLower(j) {
                cnt  = 1
            }
        }
    }
    fmt.Printf("str1 is: %d length, and str2 is: %d length, they have; %d common words.", len(str1), len(str2), cnt)
}
  

Но совпадение очень низкое, я получил:

 str1 is: 197 length, and str2 is: 358 length, they have; 29 common words.
  

Я также пытался использовать Levenshtein_distance как:

 
// Levenshtein Distance in Golang
package main
import "fmt"
 
func levenshtein(str1, str2 []rune) int {
    s1len := len(str1)
    s2len := len(str2)
    column := make([]int, len(str1) 1)
 
    for y := 1; y <= s1len; y   {
        column[y] = y
    }
    for x := 1; x <= s2len; x   {
        column[0] = x
        lastkey := x - 1
        for y := 1; y <= s1len; y   {
            oldkey := column[y]
            var incr int
            if str1[y-1] != str2[x-1] {
                incr = 1
            }
 
            column[y] = minimum(column[y] 1, column[y-1] 1, lastkey incr)
            lastkey = oldkey
        }
    }
    return column[s1len]
}
 
func minimum(a, b, c int) int {
    if a < b {
        if a < c {
            return a
        }
    } else {
        if b < c {
            return b
        }
    }
    return c
}
 
func main(){
    var str1 = []rune("Neoprene Rubber Chemical Resistant Gloves, Size: 7; Length: 32 cm; Standard: BS EN 388; Resistant to wide range of Chemicals such as Ethylene Oxide. Make: Polyco, Model: Duraprene III or Equivalent")
    var str2 = []rune("GLOVES: LENGTH: 32 CM MATERIAL: NEOPRENE RUBBER FREE FLOW TEXT: RESISTANT TO WIDE RANGE OF GLOVES, TYPE: CHEMICAL RESISTANT, SIZE: 7, MATERIAL: NEOPRENE RUBBER, STANDARD: BS EN 388/BS EN 374, FFT: RESISTANT TO WIDE RANGE OF CHEMICALS SUCH AS ETHYLENE OXIDE IDEAL FOR LONG TERM HEAVY WORK IN CHEMICAL ENVIRONMENT MANUFACTURER REFERENCES: ORIGINAL_MNFR: POLYCO")
    fmt.Println("Distance between str1 and str2:",levenshtein(str1,str2))
}
  

Но расстояние между ними выглядит очень большим, я получил:

 Distance between str1 and str2: 304
  

Есть идеи, как я могу это улучшить?

Комментарии:

1. Ну, эти две строки действительно не похожи друг на друга.

2. @SergioTulentsev на самом деле это одно и то же описание одного и того же продукта.

Ответ №1:

Они могут описывать одно и то же, но вы сравниваете их, используя алгоритмы, не понимая этого.

Например, расстояние Левенштейна — это просто мера количества вставок, удалений и замен, которые потребовались бы для того, чтобы одна строка была равна другой. Это будет работать так же хорошо на «Быстрая бурая лиса перепрыгнула через ленивую серую собаку», как и на «Dlkj adlkjll o824hs aldkj ladhfj adlbcvhiuywe». Он не понимает лексики или грамматики.

Напротив, никакая обработка строк не распознает, что «ярко-красный дом стоял передо мной» описывает то же самое, что и «передо мной было сияющее розовое жилище».

Вам нужно искать алгоритмы обработки естественного языка или NLP. Они не просты в использовании и требуют некоторой утонченности. Я не эксперт по НЛП, я бы посоветовал начать с некоторых поисков golang nlp и перейти оттуда.