코딩코딩코딩

파이썬 네이버 뉴스 일일 기사 크롤링 - 2 본문

파이썬/텍스트마이닝

파이썬 네이버 뉴스 일일 기사 크롤링 - 2

hanshow113 2020. 7. 20. 18:16

 

지난번 크롤링 했던 내용들을 바탕으로 기사 간 클러스터링 진행

 

제목 + 요약내용 리스트를 Konlpy 를 통해 명사화 시킨 후 클러스터링을 진행할 예정입니다.

 

TitDesc_okt = []

for item in TitDesc_list:
  item_nouns = ' '.join(okt.nouns(item))
  TitDesc_okt.append(item_nouns)

  tfidf_vectorizer = TfidfVectorizer()
  tfidf_matrix_okt = tfidf_vectorizer.fit_transform(TitDesc_okt)
TitDesc_okt[:3]
#Vectorization

완벽하게 명사가 추출되진 않았지만 가지고 있는 데이터를 명사화했을 때는 Okt가 가장 성능이 좋은 모델이었음.   ( 한 글자 명사는 제외할 예정 )

okt, komoran, kkma, Hannanum등의 tokenizing 모델들이 있지만 개인적으로 모두 진행해본 결과 okt가 명사 추출 성능이 가장 좋아 okt를 사용했습니다.

 

''' < 자연어 처리 성능 비교 >

빠른 속도와 보통의 정확도를 원한다면 "Komoran" 또는 "Hannanum"
(이번 분석 중 Komoran의 놀라운 발전에 감짝 놀랐습니다.)
속도는 느리더라도 정확하고 상세한 품사 정보를 원한다면 "
Kkma"
어느 정도의 띄어쓰기 되어 있는 "인터넷" 영화평/상품명을 처리할 땐 "
Okt"
(만약 띄어쓰기가 없다면 느린 처리속도는 감수해야함)

'''

[출처] [자연어처리] Komoran, Hannanum, Kkma, Okt 성능 비교|작성자 똑똑이

 

# 토큰화 된 문장 리스트를 단어별로 split한 후 2차원 리스트로 저장
WordVoca_list = []
for item in TitDesc_okt:
    WordVoca_list.append(item.split(' '))

# split된 2차원 리스트 중에서 한 글자짜리 단어들을 모두 제외시키고 WordVoca 리스트 생성
# Word2Vec 모델 학습 데이터로 활용됨
WordVoca = []
for i in range(len(WordVoca_list)):
    element = []
    for j in range(len(WordVoca_list[i])):
        if len(WordVoca_list[i][j]) > 1:
            element.append(WordVoca_list[i][j])
    WordVoca.append(element)

원래 한 기사의 내용이었다는 것을 나타내기 위해서 1차원 리스트에 모두 넣지 않고 2차원 리스트를 생성하여 저장

WordVoca 리스트는 이후에 사용될 예정

 

 

df_dict = {'TokenizedTitDesc':TitDesc_okt,
           'TitDesc':TitDesc_list}
doc_df = pd.DataFrame(df_dict)
doc_df['title'] = 0
doc_df['num']=0

for i in range(len(doc_df)):
  doc_df.iloc[i, 3] = i
  doc_df.iloc[i, 2] = title_list[i]
doc_df.head()

topic_df = doc_df  # 이후 클러스터별 키워드 추출에 사용될 데이터프레임

명사화된 제목+내용, 제목+내용, 제목, 숫자 총 네 개의 열로 이루어진 데이터프레임 생성

 

x = normalize(tfidf_matrix_okt)
# L2 정규화

def elbow(normalizedData, Clusters):
    sse = []
    for i in range(1,Clusters):
        kmeans = KMeans(n_clusters=i, init='k-means++', random_state=0)
        kmeans.fit(normalizedData)
        sse.append(kmeans.inertia_)
    plt.figure(figsize=(7,6))
    plt.plot(range(1,Clusters), sse, marker='o')
    plt.xlabel('number of cluster')
    plt.xticks(np.arange(0,Clusters,1))
    plt.ylabel('SSE')
    plt.title('Elbow Method - number of cluster : '+str(Clusters))
    plt.show()
elbow(x, 35)

클러스터 개수를 지정하기 위한 Elbow Method

팔꿈치 처럼 접히는 부분이 있지는 않지만.. 우선 15개 지점을 클러스터 개수로 지정하고 KMeans 진행

 

tfidf_vect = TfidfVectorizer(tokenizer=LemNormalize)
feature_vect = tfidf_vect.fit_transform(topic_df['TokenizedTitDesc'])

clusters_num = 15
km_cluster = KMeans(n_clusters=clusters_num, max_iter=10000, random_state=0)
km_cluster.fit(feature_vect)
cluster_label = km_cluster.labels_
cluster_centers = km_cluster.cluster_centers_


topic_df['cluster_label'] = cluster_label
topic_df.head()
for i in range(clusters_num):
  print('<<Clustering Label {0}>>'.format(i)+'\n')
  print(topic_df.loc[topic_df['cluster_label']==i])

클러스터별로 라벨링된 기사 확인

대부분 비슷한 개념의 기사들이 클러스터링된 것을 확인할 수 있음

Comments