close_btn
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print

문서유사도 과제


from konlpy.tag import Kkma

import re

from bs4 import BeautifulSoup

import requests

from konlpy.tag import Twitter

from collections import Counter

import numpy as np

import pandas as pd

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer


def crawling(add):

    result =[]

    for p in range(50) :

        r = requests.get("{}{}" .format(add, p+1))

        soup = BeautifulSoup(r.content, "html.parser", from_encoding= 'ms949')

        title = soup.find_all("td", {"class":"title"})


        sub_result =[]

        for i in range(10) :

            sub_result.append(title[i].text.replace("\r", "").replace("\t", "").replace("\n", "").replace("신고", "").replace("군함도", "").replace("택시운전사", "").replace("청년경찰", "").replace("종의 전쟁", "").replace("혹성탈출", "").replace("노무현입니다", "").replace("500일의 썸머", "").replace("덩케르크", "").replace("애나벨", "").replace("이터널 선샤인", "").replace("스파이더맨", ""))

        result = result + sub_result

    return("".join(result))

# 모든 리뷰들마다 영화제목이 크롤링됨.  이건 네티즌들이 쓴 것이 아니다. 그래새 싹 다 지워주도록 함수를 짰다.

# 그 외에도 신고 버튼에 있는 '신고' 글자나 \로 시작하는 이상한 문자들을 모두 지우도록 했다.

# 또 "".join() 함수를 이용해서 영화 하나에 해당하는 모든 후기들을 하나의 스트링으로 변환했다.



taxi = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=146469&target=after&page=")

gunhamdo = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=146506&target=after&page=")

young_police = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=153652&target=after&page=")

war_of_species = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=143394&target=after&page=")

nomuhyun = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=162173&target=after&page=")

summer_500 = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=53152&target=after&page=")

dung = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=146480&target=after&page=")

sunshine = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=38444&target=after&page=")

annabel = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=152341&target=after&page=")

spiderman = crawling("http://movie.naver.com/movie/point/af/list.nhn?st=mcode&sword=135874&target=after&page=")


movies = [taxi, gunhamdo, young_police, war_of_species, nomuhyun, summer_500, dung, sunshine, annabel, spiderman]

# 한 영화에 대한 모든 리뷰들이 1개의 스트링으로 되어있다. movies는 총 10개의 스트링이 있는 리스트다.


# 가장 많이 언급된 단어들을 확인해보자.

words_basket =[]

for movie in movies :

    words = twitter.pos(movie)

    for word in words :

        if word[1] in ["Noun", "Adjective"] and len(word[0]) >=2 :

            words_basket.append(word[0])

Counter(words_basket).most_common(30)

[('영화', 1707),
 ('너무', 519),
 ('인형', 517),
 ('커밍', 503),
 ('주인', 490),
 ('정말', 254),
 ('사람', 237),
 ('다시', 224),
 ('감동', 220),
 ('사랑', 220),
 ('보고', 217),
 ('진짜', 214),
 ('입니', 214),
 ('생각', 210),
 ('그냥', 200),
 ('최고', 187),
 ('썸머', 186),
 ('재미', 161),
 ('아니', 145),
 ('시간', 142),
 ('노무현', 141),
 ('있는', 138),
 ('재밌었', 132),
 ('대통령', 131),
 ('역사', 130),
 ('역시', 129),
 ('있었', 128),
 ('무섭', 127),
 ('스토리', 124),
 ('연기', 123)]


# 쓸 데 없다고 판단되는 단어들은 지워주자.

movies = [movie.replace("영화", "") for movie in movies]

movies = [movie.replace("너무", "") for movie in movies]

movies = [movie.replace("정말", "") for movie in movies]

movies = [movie.replace("진짜", "") for movie in movies]

movies = [movie.replace("그냥", "") for movie in movies]

movies = [movie.replace("아니", "") for movie in movies]

movies = [movie.replace("있는", "") for movie in movies]

movies = [movie.replace("역시", "") for movie in movies]

movies = [movie.replace("있었", "") for movie in movies]

movies = [movie.replace("입니", "") for movie in movies]

movies = [movie.replace("커밍", "") for movie in movies]

movies = [movie.replace("썸머", "") for movie in movies]


twitter = Twitter()

def word_separating(movies) :

    result=[]

    for movie in movies :      

        one_result = []

        words = twitter.pos(movie)

        for word in words:

            if word[1] in ["Noun", "Adjective"] and len(word[0]) >= 2 :

                one_result.append(word[0])

        one_result_a = " ".join(one_result)

        result.append(one_result_a)

    return(result)


word_list = word_separating(movies)

# 영화 한 개에 대해 언급된 두 글자 이상의 명사, 형용사들을 모두 모아 1개의 스트링에 넣었다. 

# word_list는 영화가 10개니 총 10개의 스트링이 있는 상태다.


count = CountVectorizer(min_df= 2)

tf_dtm = count.fit_transform(word_list).toarray()

tf_dtm = pd.DataFrame(tf_dtm, columns=count.get_feature_names(),

                     index= ['taxi', 'gunhamdo', 'young_police', 'war_of_species', 'nomuhyun', 'summer_500', 'dung','sunshine',

                              'annabel', 'spiderman'])

tf_dtm

가관가기가끔가나가나다가늠가능가능한가도가득...흥행희망희망이희생히어로히히히힐링힘든힘들힘들었
taxi0000000100...0007000012
gunhamdo1010000111...1001110122
young_police0001010000...1000002010
war_of_species1010000100...0101001100
nomuhyun0210010001...1020010122
summer_5000100001300...0200000013
dung0001000010...1113000112
sunshine0020101001...0100000330
annabel0020002300...1000000000
spiderman0000100000...0100900001

10 rows × 1784 columns

# 단어 빈도수에 따른 tf_dtm이다. 

# 하지만 문서 유사도를 구할 때는 단어들의 빈도수뿐만 아니라 단어들의 중요성까지 고려한 tfidf를 이용하는 것이 낫다. 구해보자.


idf_maker = TfidfVectorizer(min_df=2)

tf_idf = idf_maker.fit_transform(word_list).toarray()

tf_idf_dtm = pd.DataFrame(tf_idf, columns= idf_maker.get_feature_names(), 

                      index= ['taxi', 'gunhamdo', 'young_police', 'war_of_species', 'nomuhyun', 'summer_500', 'dung','sunshine',

                              'annabel', 'spiderman'])

tf_idf_dtm

가관가기가끔가나가나다가늠가능가능한가도가득...흥행희망희망이희생히어로히히히힐링힘든힘들힘들었
taxi0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0078570.0000000.000000...0.0000000.0000000.000000.0612410.0000000.0000000.0000000.0000000.0064500.014206
gunhamdo0.0125340.0000000.0087560.0000000.0000000.0000000.0000000.0087560.0125340.010966...0.0087560.0000000.000000.0097490.0125340.0125340.0000000.0087560.0143750.015831
young_police0.0000000.0000000.0000000.0119020.0000000.0119020.0000000.0000000.0000000.000000...0.0083140.0000000.000000.0000000.0000000.0000000.0238030.0000000.0068250.000000
war_of_species0.0117690.0000000.0082210.0000000.0000000.0000000.0000000.0082210.0000000.000000...0.0000000.0082210.000000.0091540.0000000.0000000.0117690.0082210.0000000.000000
nomuhyun0.0000000.0134200.0046870.0000000.0000000.0067100.0000000.0000000.0000000.005871...0.0046870.0000000.013420.0000000.0000000.0067100.0000000.0046870.0076960.008475
summer_5000.0000000.0078280.0000000.0000000.0000000.0000000.0068480.0164040.0000000.000000...0.0000000.0109360.000000.0000000.0000000.0000000.0000000.0000000.0044890.014830
dung0.0000000.0000000.0000000.0091200.0000000.0000000.0000000.0000000.0091200.000000...0.0063710.0063710.009120.0212820.0000000.0000000.0000000.0063710.0052300.011519
sunshine0.0000000.0000000.0102900.0000000.0073650.0000000.0064440.0000000.0000000.006444...0.0000000.0051450.000000.0000000.0000000.0000000.0000000.0154350.0126700.000000
annabel0.0000000.0000000.0031090.0000000.0000000.0000000.0038940.0046640.0000000.000000...0.0015550.0000000.000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
spiderman0.0000000.0000000.0000000.0000000.0103540.0000000.0000000.0000000.0000000.000000...0.0000000.0072330.000000.0000000.0931900.0000000.0000000.0000000.0000000.006539

10 rows × 1784 columns

# 이제 각 영화끼리 코사인 유사도를 구하자.

def cosin_similarity(doc1, doc2) :

    son = sum(doc1*doc2)

    mom = (sum((doc1)**2)*sum((doc2)**2))**0.5

    return(son/mom)


x = np.zeros((10,10))

for j in range(10) :  

    for i in range(10) :

        x[j,i] = cosin_similarity(tf_idf_dtm.iloc[j], tf_idf_dtm.iloc[i].values)

x = pd.DataFrame(x, index= ['taxi', 'gunhamdo', 'young_police', 'war_of_species', 'nomuhyun', 'summer_500', 'dung','sunshine',

                              'annabel', 'spiderman'],

                 columns = ['taxi', 'gunhamdo', 'young_police', 'war_of_species', 'nomuhyun', 'summer_500', 'dung','sunshine',

                              'annabel', 'spiderman'])

x

taxigunhamdoyoung_policewar_of_speciesnomuhyunsummer_500dungsunshineannabelspiderman
taxi1.0000000.6391570.3564810.3090790.2778650.1750520.2411200.2587270.0257990.140077
gunhamdo0.6391571.0000000.3549670.3208550.1466790.1867850.2746090.2045030.0372160.191905
young_police0.3564810.3549671.0000000.3423530.1145180.1858530.2146220.1821010.0481510.314894
war_of_species0.3090790.3208550.3423531.0000000.1375440.1787350.2882680.2128740.0557390.323105
nomuhyun0.2778650.1466790.1145180.1375441.0000000.1368690.0919010.1926140.0192700.043485
summer_5000.1750520.1867850.1858530.1787350.1368691.0000000.1414480.6597910.0258910.096942
dung0.2411200.2746090.2146220.2882680.0919010.1414481.0000000.1714080.0391130.133690
sunshine0.2587270.2045030.1821010.2128740.1926140.6597910.1714081.0000000.0290650.091735
annabel0.0257990.0372160.0481510.0557390.0192700.0258910.0391130.0290651.0000000.028342
spiderman0.1400770.1919050.3148940.3231050.0434850.0969420.1336900.0917350.0283421.000000



# 택시운전사, 군함도 두 영화가 유사도가 매우 높다. 두 영화 모두 조국의 역사와 관련하여 감동적인 내용을 다루기  때문이라고 생각해볼 수 있다.

# 스파이더맨은 청년경찰, 혹성탈출과 유사도가 높게 나왔다. 세 영화가 모두 액션 영화이고 통쾌한 내용을 다루기 때문이라고 짐작할 수 있다.

# 이터널선샤인과 500일의 썸머는 모두 로맨스 코미디로 사랑에 대한 내용이다. 이것이 둘 간의 유사도가 높은 이유라고 생각해본다.

# 노무현입니다는 민주화에 대한 내용을 공통으로 하는 택시운전사와 가장 유사도가 높게 나왔다.

# 애나벨은 위 10개 중에서 홀로 공포영화 장르이다. 실제로도 모든 영화들과 유사도가 매우 낮게 나왔다.

#  흥미로웠던 것은 청년경찰, 혹성탈출이 택시운전사, 군함도와 비교적 높은 유사도를 보였다는 것이다.  내용과 분위기가 아예 다른데 의외의 결과였다. 공통점을 찾아보니 네 영화 모두 관객이 300만 이상이거나 예매 순위가 3위 안에 드는 소위 '재미있는 영화''였음을 알 수 있었다. 아마 "재미"나 "최고"라는 단어들이 네 영화를 묶어낸 것이 아닌가 추측해본다. 덩케르크가 다른 영화들에 비해 이 네 영화들과 비교적 높고 비슷한 유사도를 보이는 것도 비슷한 이유리라 생각한다. 조사 결과, 덩케르크도 예매율이 2위, 관객수 약 3백만에 이를만큼 재밌고 인기있는 영화였다.


# 위 분석에 따르면 영화가 다루는 소재와 내용,  영화의 장르, 흥행도에 따라서 유사도가 결정됨을 알 수 있다.



List of Articles
번호 제목 글쓴이 날짜 조회 수
공지 R 소스 공유 게시판 이용 관련 공지사항 1 DataMarket 2014.05.21 13222
92 투빅스 7&8기 9주차 과제 Neural Network를 이용한 MNIST 분류 - 8기 김민정 민정e 2017.09.23 235
91 투빅스 7&8기 9주차 과제 Neural Network를 이용한 MNIST 분류 - 8기 최서현 최서현 2017.09.22 202
90 투빅스 7&8기 7주차 과제 유기동물 과제 - 8기 조양규 dial123 2017.09.14 308
89 투빅스 7&8기 7주차 과제 유기동물입양예측 - 8기 김강열 김강열 2017.09.14 325
88 투빅스 7&8기 6주차 과제 word2vec - 8기 황다솔 다솔 2017.08.31 479
» 투빅스 7&8기 6주차 과제 TF-IDF 문서유사도 측정 - 8기 최서현 최서현 2017.08.31 367
86 투빅스 7&8기 5주차 과제 Selenium Crawling - 8기 김강열 김강열 2017.08.24 506
85 투빅스 7&8기 5주차 과제 Image Augmentation - 8기 김민정 김소희 최수정 황다솔 file 민정e 2017.08.24 458
84 투빅스 7&8기 5주차 과제 Beautiful Soup 이용한 Crawling - 8기 류호성 file 류호성 2017.08.24 456
83 투빅스 7&8기 4주차 과제 tree, RF, bagging, boosting 이용 분석 - 8기 조양규 file dial123 2017.08.17 510
82 투빅스 7&8기 4주차 과제 의사결정나무&랜덤포레스트 - 8기 김강열 김강열 2017.08.17 514
81 투빅스 7&8기 3주차 과제 클러스터링 구현 - 8기 권문정 김강열 이현경 조양규 1 이현경 2017.08.10 571
80 투빅스 7&8기 3주차 과제 PCA - 8기 이현경 file 이현경 2017.08.12 560
79 투빅스 7&8기 2주차 과제 연관성 분석 - 8기 조양규 file dial123 2017.08.03 571
78 투빅스 7&8기 2주차 과제 나이브베이즈 구현 - 8기 이현경 file 이현경 2017.08.03 531
77 투빅스 7&8기 2주차 과제 로지스틱/Ridge/Lasso&알고리즘 - 8기 김강열 file 김강열 2017.08.03 626
76 투빅스 7&8기 1주차 과제 알고리즘 - 8기 김강열 file 김강열 2017.07.27 672
75 투빅스 7&8기 1주차 과제 회귀분석 - 8기 황다솔 file 다솔 2017.07.27 820
74 투빅스 6&7기 8주차 과제 PCA(주성분 분석) - 7기 이동수 1 탱탱볼 2017.03.18 1679
73 투빅스 6&7기 8주차 과제 LBP 알고리즘 구현 - 7기 이광록 1 file 2017.03.16 1423
Board Pagination ‹ Prev 1 2 3 4 ... 5 Next ›
/ 5

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5