Python | NLP를 사용하여 문서 유사성 비교

어이, 인터넷 개발!
유튜브 채널에서 영상 강좌 제공 -
본고에서 우리는 웹 응용 프로그램을 구축하여 두 문서 간의 유사성을 비교할 것이다.우리는 자연언어처리(NLP)의 기초 지식을 배울 것이다. NLP는 인공지능의 한 가지로 컴퓨터와 자연언어를 사용하는 사람 간의 상호작용을 처리한다.
이 글은 최초로 나의 실험실Reverse Python에 발표되었다.
프로그램의 기본 구조부터 시작해서 그래픽 인터페이스를 추가하여 프로그램을 더욱 쉽게 사용할 수 있도록 하겠습니다.제 GitHub에서 이 프로젝트에 마음대로 공헌해 주십시오.

NLTK 및 Gensim


네이처 언어 키트(Natural language toolkit, NLTK)는 가장 유행하는 네이처 언어 처리 라이브러리(Natural language processing, NLP)로 파이톤으로 작성된 것으로 뒤에 커다란 커뮤니티가 있다.NLTK도 쉽게 배울 수 있는데, 실제로는 우리가 사용할 가장 간단한 자연 언어 처리 (NLP) 라이브러리이다.이것은 표기화, 해석, 분류, 어간 분석, 표기, 의미 추리에 사용되는 텍스트 처리 라이브러리를 포함한다.
Gensim은'인간 테마 모델링'에 사용되는 자연 언어 처리 소프트웨어 패키지라고 불린다.하지만 사실은 이뿐만이 아니다.이것은 선도적이고 가장 선진적인 텍스트 처리 소프트웨어 패키지로 텍스트 벡터 모델(예를 들어Word2Vec,FastText 등)과 협조하여 사용할 수 있다.
테마 모델과 단어 삽입은 scikit, R 등 다른 소프트웨어 패키지에서 사용할 수 있습니다. 그러나 테마 모델을 구축하고 평가하는 도구의 폭과 범위는gensim에서 비길 데 없이 넓고 편리한 텍스트 처리 도구가 많습니다.gensim의 또 다른 중요한 장점은 큰 텍스트 파일을 관리할 수 있고 전체 파일을 메모리에 불러올 필요가 없다는 것이다.
먼저 다음 명령을 사용하여 nltk와gensim을 설치합니다.
pip install nltk
pip install gensim

단어 태그 지정(NLTK)


우리는 word tokenize () 방법을 사용하여 문장을 단어로 나누었다.아래의 예를 보아라
from nltk.tokenize import word_tokenize

data = "Mars is approximately half the diameter of Earth."
print(word_tokenize(data))
출력:
['Mars', 'is', 'approximately', 'half', 'the', 'diameter', 'of', 'Earth']

문장 표시(NLTK)


네 머릿속에 뚜렷한 문제는 우리가 단어 표기화를 선택할 수 있을 때 왜 문장 표기화가 필요한가 하는 것이다.우리는 문장마다 평균 단어 수를 계산해야 하기 때문에 이런 임무를 완수하기 위해 문장 표기화와 단어를 사용하여 비율을 계산한다.
from nltk.tokenize import sent_tokenize

data = "Mars is a cold desert world. It is half the size of Earth. "
print(sent_tokenize(data))
출력:
['Mars is a cold desert world', 'It is half the size of Earth ']
현재, 당신은 이러한 방법들이 텍스트를 처리할 때 얼마나 유용한지 알고 있습니다
분류하다.유사성 알고리즘에서 그것을 실현합시다.

파일을 열고 문장 표시


를 생성합니다.txt 파일을 작성하고 4 ~ 5개의 문장을 씁니다.Python 프로그램 디렉토리와 같은 파일을 포함합니다.이제 이 파일을 파이톤과 구절로 열 것입니다.
import nltk
from nltk.tokenize import word_tokenize, sent_tokenize

file_docs = []

with open ('demofile.txt') as f:
    tokens = sent_tokenize(f.read())
    for line in tokens:
        file_docs.append(line)

print("Number of documents:",len(file_docs))
프로그램이 파일을 열고 내용을 읽습니다.그리고 단어 표기화를 위해 표기화 문장을 그룹에 추가합니다.

단어 표시 및 사전 만들기


일단 우리가 수조에 표기화 문장을 추가하면 모든 문장에 단어를 표기할 수 있다.
gen_docs = [[w.lower() for w in word_tokenize(text)] 
            for text in file_docs]
출력:
[['mars', 'is', 'a', 'cold', 'desert', 'world', '.'],
 ['it', 'is', 'half', 'the', 'size', 'of', 'earth', '.']]
Gensim은 텍스트 문서를 처리하기 위해 단어(또는 토큰)를 고유한 ID로 변환해야 합니다.따라서 Gensim은 모든 단어를 유일한 id에 비추는 사전 대상을 만들 수 있습니다. 문장을 [단어 목록] 으로 변환해서 자료 라이브러리에 전달합니다.Dictionary () 객체
dictionary = gensim.corpora.Dictionary(gen_docs)
print(dictionary.token2id)
출력:
{'.': 0, 'a': 1, 'cold': 2, 'desert': 3, 'is': 4, 'mars': 5,
 'world': 6, 'earth': 7, 'half': 8, 'it': 9, 'of': 10, 'size': 11, 'the': 12}
사전은 모든 단어를 하나의 숫자로 비추었다.Gensim은 전체 텍스트 파일을 시스템 메모리에 불러올 필요가 없이 텍스트를 읽고 사전을 업데이트할 수 있습니다.

단어 패키지 만들기


gensim에서 일하기 위해서는 다음 중요한 대상이 어료 라이브러리 (단어 한 봉지) 입니다.이것은 기본적으로 하나의 대상으로 단어 id와 문서마다 나타나는 빈도를 포함한다. (단어마다 문장에 나타나는 횟수만 열거한다.)
"태그"는 일반적으로 "단어"를 의미합니다.'문서'는 일반적으로'문장'또는'단락'을 가리키고,'어료 라이브러리'는 통상적으로'한 봉지의 단어의 문서 집합'을 가리킨다.
현재, 단어 자료 라이브러리를 만들고, 표시된 단어 목록을 사전에 전달합니다.doc2bow()
파일이 다음과 같다고 가정합니다.
Mars is a cold desert world. It is half the size of the Earth.
corpus = [dictionary.doc2bow(gen_doc) for gen_doc in gen_docs]
출력:
{'.': 0, 'a': 1, 'cold': 2, 'desert': 3, 'is': 4, 
'mars': 5, 'world': 6, 'earth': 7, 'half': 8, 'it': 9, 
'of': 10, 'size': 11,'the': 12}
[[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1)],
 [(0, 1), (4, 1), (7, 1), (8, 1), (9, 1), (10, 1), (11, 1), (12, 2)]]
보시다시피 우리는 두 번째 문장에서'the'를 두 번 사용했습니다. id=12(the)의 단어를 보면 빈도가 2(문장에 두 번 나타났음)입니다.

TFIDF


용어 주파수인 역방향 문서 주파수(TF-IDF)도 하나의 단어 패키지 모델이지만 일반적인 자료 라이브러리와 달리 TFIDF는 문서에 자주 나타나는 태그(단어)의 무게를 낮춘다.
Tf Idf는 로컬 컴포넌트(Tf)를 글로벌 컴포넌트(Idf)에 곱하고 결과를 단위 길이로 선택적으로 표준화함으로써 계산됩니다.용어의 주파수는 단어가 문서에 나타나는 주파수이고 역문서의 주파수는 단어가 자료 라이브러리에서 보기 드문 정도에 따라 값을 평가한다.간단하게 말하면 문서에 나타나는 빈도가 높은 단어의 중요성은 비교적 작다.
This is the space. This is our planet. This is the Mars.        
tf_idf = gensim.models.TfidfModel(corpus)
for doc in tfidf[corpus]:
    print([[dictionary[id], np.around(freq, decimals=2)] for id, freq in doc])
출력:
[['space', 0.94], ['the', 0.35]]
[['our', 0.71], ['planet', 0.71]]
[['the', 0.35], ['mars', 0.94]]
'The'라는 단어는 두 문서에 나타나기 때문에 그 중요도가 비교적 낮다.'this'와'is'라는 두 단어가 세 파일에 나타나 삭제되었다.

유사성 메트릭 객체 작성


이제 우리는 비슷한 대상을 만들어야 한다.주요 클래스는 유사성입니다. 이것은 한 그룹이 지정한 문서에 색인을 만듭니다.유사성 클래스는 인덱스를 디스크를 기반으로 하는 몇 개의 작은 하위 인덱스로 분리합니다.비슷한 대상을 만들면 우리가 그것을 어떻게 사용해서 비교하는지 알게 될 것이다.
 # building the index
 sims = gensim.similarities.Similarity('workdir/',tf_idf[corpus],
                                        num_features=len(dictionary))

색인 행렬을 "workdir"디렉터리에 저장하지만, 프로그램의 같은 디렉터리로 만들어야 합니다.

질의 문서 작성


일단 색인을 만들면, 우리는 이 검색 문서와 색인에 있는 모든 문서의 유사도를 계산할 것이다.그래서 두 번째를 만듭니다.txt 파일, 검색 문서나 문장을 포함하고, 우리가 이전에 했던 것처럼 표시합니다.
file2_docs = []

with open ('demofile2.txt') as f:
    tokens = sent_tokenize(f.read())
    for line in tokens:
        file2_docs.append(line)

print("Number of documents:",len(file2_docs))  
for line in file2_docs:
    query_doc = [w.lower() for w in word_tokenize(line)]
    query_doc_bow = dictionary.doc2bow(query_doc) #update an existing dictionary and
create bag of words
우리는 새로운 문서 (문서나 문장 조회) 를 얻었기 때문에 기존 사전을 업데이트해서 새로운 단어를 포함할 수 있습니다.

문서와 조회의 유사성


이 단계에서, 검색과 모든 색인 문서 사이의 유사점을 볼 수 있습니다.질의 문서와 색인 문서의 유사성을 가져오려면 다음과 같이 하십시오.
# perform a similarity query against the corpus
query_doc_tf_idf = tf_idf[query_doc_bow]
# print(document_number, document_similarity)
print('Comparing Result:', sims[query_doc_tf_idf]) 
여현 도량은 범위 내의 유사성을 되돌려줍니다.
파일이 다음과 같다고 가정합니다.
Mars is the fourth planet in our solar system.
It is second-smallest planet in the Solar System after Mercury. 
Saturn is yellow planet.
질의 문서는 다음과 같습니다.
Saturn is the sixth planet from the Sun.
출력:
[0.11641413 0.10281226 0.56890744]
따라서 세 번째 파일이 가장 비슷하다는 것을 알 수 있다

평균 유사성


다음은요?나는 조회 문서의 평균 유사도를 계산하는 것이 가장 좋다고 생각한다.이 때, 우리는 유사성 출력의 총계를 계산하기 위해numpy를 가져올 것이다.

import numpy as np

sum_of_sims =(np.sum(sims[query_doc_tf_idf], dtype=np.float32))
print(sum_of_sims)

Numpy는 다음과 같은 부동의 합계를 계산하는 데 도움을 줍니다.
# [0.11641413 0.10281226 0.56890744]
0.78813386
평균 싱크로율을 계산하기 위해서, 우리는 이 값을 문서 수로 나누어야 한다
percentage_of_similarity = round(float((sum_of_sims / len(file_docs)) * 100))
print(f'Average similarity float: {float(sum_of_sims / len(file_docs))}')
print(f'Average similarity percentage: {float(sum_of_sims / len(file_docs)) * 100}')
print(f'Average similarity rounded percentage: {percentage_of_similarity}')
출력:
Average similarity float: 0.2627112865447998
Average similarity percentage: 26.27112865447998
Average similarity rounded percentage: 26
현재, 우리는 조회 문서 (demofile2.txt) 가 주 문서 (demofile.txt) 와 26퍼센트 비슷하다고 말할 수 있다
만약 우리가 조회 문서가 여러 개 있다면?
해결 방안으로서, 우리는 모든 조회 문서의 평균 값의 합을 계산할 수 있으며, 이것은 우리에게 전체적인 유사성 비율을 제공할 것이다.

기본 파일은 다음과 같습니다.
Malls are great places to shop, I can find everything I need under one roof.
I love eating toasted cheese and tuna sandwiches.
Should we start class now, or should we wait for everyone to get here?

참고로, 나는 랜덤 단어 생성기 도구를 사용하여 이 문서들을 만들고 있다.한 마디로 하면, 우리의 조회 문서는 다음과 같다.
Malls are goog for shopping. What kind of bread is used for sandwiches? Do we have to start class now, or should we wait for
everyone to come here? 
코드를 살펴보겠습니다.
avg_sims = [] # array of averages

# for line in query documents
for line in file2_docs:
        # tokenize words
        query_doc = [w.lower() for w in word_tokenize(line)]
        # create bag of words
        query_doc_bow = dictionary.doc2bow(query_doc)
        # find similarity for each document
        query_doc_tf_idf = tf_idf[query_doc_bow]
        # print (document_number, document_similarity)
        print('Comparing Result:', sims[query_doc_tf_idf]) 
        # calculate sum of similarities for each query doc
        sum_of_sims =(np.sum(sims[query_doc_tf_idf], dtype=np.float32))
        # calculate average of similarity for each query doc
        avg = sum_of_sims / len(file_docs)
        # print average of similarity for each query doc
        print(f'avg: {sum_of_sims / len(file_docs)}')
        # add average values into array
        avg_sims.append(avg)  
   # calculate total average
    total_avg = np.sum(avg_sims, dtype=np.float)
    # round the value and multiply by 100 to format it as percentage
    percentage_of_similarity = round(float(total_avg) * 100)
    # if percentage is greater than 100
    # that means documents are almost same
    if percentage_of_similarity >= 100:
        percentage_of_similarity = 100
출력:
Comparing Result: [0.33515707 0.02852172 0.13209888]
avg: 0.16525922218958536
Comparing Result: [0.         0.21409164 0.27012902]
avg: 0.16140689452489218
Comparing Result: [0.02963242 0.         0.9407785 ]
avg: 0.3234703143437703
우리는 세 개의 조회 문서를 가지고 있는데, 프로그램은 각 문서의 평균 유사도를 계산했다.이러한 값을 계산하면 결과는 다음과 같습니다.
0.6501364310582478
우리는 이 값을 백분율로 포맷해서 100을 곱하고 반올림을 해서 값을 더욱 간단하게 할 것이다.Django의 최종 결과는 다음과 같습니다.

임무 완수!


위대하다나는 네가 이 프로젝트에서 NLP의 기초 지식을 좀 배웠으면 한다.또한 저는 Django에서 이 알고리즘을 실현하여 도형 인터페이스를 만드는 데 사용했습니다.제 GitHub에서 이 프로젝트에 마음대로 공헌해 주십시오.

피로하다 / 닮다


[잘못된 항목은 더 이상 지원되지 않습니다.]


닮다


두 txt 파일 사이의 유사성 측정하기(Python)

개시하다


유사성은 Python 3+와 Django 2+에 적용됩니다.
종속성 설치:
python3 -m pip3 install -r requirements.txt
그런 다음 다음 다음 명령을 실행합니다.
python3 manage.py makemigrations sim
python3 manage.py migrate
python3 manage.py runserver
View on GitHub
나는 네가 이 실험실에서 약간의 것을 배웠으면 한다😃 만약 당신이 그것이 유용하다고 생각한다면 공유하고 나의 소셜 미디어에 가입하세요!예전과 같이 연락을 유지하세요!🚀
별도Reverse Python
참조 자료:
machinelearningplus
gensim

좋은 웹페이지 즐겨찾기