레벨슈타인 거리 알고리즘
레벤슈타인 거리는 두 단어 또는 문장의 차이를 통해 거리를 수치로 나타내는 것이다.
철자 오류 수정, 비슷한 어구 검색 등에 사용되고, 의학 분야에서는 DNA 배열의 유사성을 판단할 때도 사용하고 있다.
예를 들어
‘가나다라’를 ‘가마바라’로 수정할 때 몇 번의 수정이 필요한 지를 거리로 나타낼 수 있다.
0 가나다라
1 가’마’다라
2 가마’바’라
‘가나다라’-> ‘가마바라’는 거리가 2임을 알 수 있다.
코드로 알아보자.
def calc_distance(a, b):
if a == b:
return 0
a_len = len(a)
b_len = len(b)
if a == "":
return b_len
if b == "":
return a_len
# 2차원 표 (a_len+1, b_len+2) 준비하기
matrix = [[] for i in range(a_len+1)]
for i in range(a_len+1):
matrix[i] = [0 for j in range(b_len+1)]
# 0일 때 초기값을 설정
for i in range(a_len+1):
matrix[i][0] = i
for j in range(b_len+1):
matrix[0][j] = j
# 표 채우기
for i in range(1, a_len+1):
ac = a[i-1]
for j in range(1, b_len+1):
bc = b[j-1]
cost = 0 if (ac == bc) else 1
matrix[i][j] = min([
matrix[i-1][j] + 1, # 문자 삽입
matrix[i][j-1] + 1, # 문자 제거
matrix[i-1][j-1] + cost # 문자 변경
])
return matrix[a_len][b_len]
print(calc_distance('가나다라', '가마바라'))
# result : 2
samples = ['신촌역', '신쵼', '신천군', '신천역', '신발', '마곡역',
'하이']
base = samples[0]
r = sorted(samples, key = lambda n: calc_distance(base, n))
for n in r:
print(calc_distance(base, n), n)
N-gram 알고리즘
def ngram(s, num):
res = []
slen = len(s) - num + 1
for i in range(slen):
ss = s[i:i+num]
res.append(ss)
return res
def diff_ngram(sa, sb, num):
a = ngram(sa, num)
b = ngram(sb, num)
r = []
cnt = 0
for i in a:
for j in b:
if i == j:
cnt += 1
r.append(i)
return cnt / len(a), r
a = "오늘 강남에서 맛있는 스파게티를 먹었다."
b = "강남에서 먹었던 오늘의 스파게티는 맛있었다."
# 2-gram
r2, word2 = diff_ngram(a, b, 2)
print("2-gram:", r2, word2)
# 3-gram
r3, word3 = diff_ngram(a, b, 3)
print("3-gram:", r3, word3)
N-gram은 이웃한 N개의 문자를 의미한다.
서로 다른 2개의 문장을 N-gram으로 비교해보면 출현하는 단어의 종류와 빈도수, 유사도를 확인할 수 있다.
N-gram은 논문 도용, 소스코드간 유사도 등에도 사용할 수 있다.
2문장씩 끊었을때의 유사도는 0.76, 3문장씩 끊었을때의 유사도는 0.45로 2문장씩 끊었을 때의 유사도가 더 높았다.
N개의 문장을 끊을지는 hyper parameter가 될 것 같다. 유사도를 구할 문장에따라 적절한 값을 입력하면 좋은 결과가 있을 것 같다.
'Machine Learning > 챗봇 만들기' 카테고리의 다른 글
간단한 챗봇 만들기 (0) | 2020.07.14 |
---|---|
RNN 그리고 LSTM 그리고 문장만들 (0) | 2020.07.09 |
마르코프 체인으로 문장 생성하기 (0) | 2020.07.08 |