<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jessy Min's blog</title>
    <description>Data is the most reliable partner on my journey.</description>
    <link>http://jessymin.github.io/</link>
    <atom:link href="http://jessymin.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 16 Mar 2023 01:17:02 +0000</pubDate>
    <lastBuildDate>Thu, 16 Mar 2023 01:17:02 +0000</lastBuildDate>
    <generator>Jekyll v3.9.3</generator>
    
      <item>
        <title>웹크롤링 시 여러 페이지를 수집하기 위한 UI 유형 구분</title>
        <description>&lt;p&gt;웹을 이용하다가 직접 분석해보고 싶은 텍스트가 생기면, 주로 크롤링을 하게 된다. 크롤링을 처음 시작했을 때는 수집하려는 요소(구매리뷰 제목, 본문, 날짜 등)을 각각 수집하는 코드를 우선 구현한다. 그런데 분석을 위해 많은 양의 데이터를 수집하려다 보면 여러 페이지를 수집하는 부분에서 막힐 때가 많았다. python이 익숙하지 않던 초반에는 특히 for문을 돌리는 것, 리스트로 수집한 값을 데이터프레임으로 방법 등을 어떻게 접근해야 할지 난감했다. 구글링을 해보아도 특정 요소를 크롤링하는 기초적인 부분을 다룬 글이 많고, 저런 내용이 있어도 자세한 설명을 생략하여 내 python 실력으로는 이해하기 어렵거나, 수집하려는 웹사이트/데이터 구조에 맞지 않는 경우도 있었다.&lt;/p&gt;

&lt;p&gt;최근에 사이드 프로젝트를 위해 몇몇 사이트의 구매리뷰, 상품명 등을 수집하려다 보니 사이트 UI별로 접근 방식이 다양한 것 같아 정리해 보았다. 이번 작업을 하면서 이전에 정리해둔 글을 참고하니 꽤 효율적이었어서 이 글도 미래의 작업을 위해 정리해본다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;1-여러-페이지-수집은-왜-어려운가&quot;&gt;1. 여러 페이지 수집은 왜 어려운가?&lt;/h4&gt;
&lt;p&gt;한 페이지를 수집하는 것은 쉽다. 구글링을 해보면 참고할만한 블로그 글이 많은 편이기 때문이다. 그러나 많은 웹사이트들이 첫 조회 화면에 보여주는 아이템의 개수를 100개, 적으면 20개 정도로 제한한다. 따라서 많은 양이 데이터를 수집하려면 필수적으로 스크롤다운, 버튼 클릭 등을 다루어야 하게 된다. 나도 이 부분 때문에 Selenium을 접하게 되었다.&lt;/p&gt;

&lt;p&gt;&amp;lt;잡아라! 텍스트마이닝 with 파이썬&amp;gt;에서 관련 내용을 인용해본다.&lt;/p&gt;

&lt;p&gt;“셀레니움은 브라우저가 웹사이트를 불러오고, 필요한 데이터를 가져오고…(중략)… 등의 행동을 자동화합니다. 따라서 BeautifulSoup보다는 더 복잡한 구조의 웹사이트를 크롤링할 수 있습니다.” (p.157)&lt;/p&gt;

&lt;p&gt;책에 언급된 케이스는 아래와 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;스크롤을 계속 내려야 새로운 텍스트가 보이는 웹구조&lt;/li&gt;
  &lt;li&gt;뒤로 가기/앞으로 가기가 필요한 웹구조&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;2-여러-페이지를-로딩하는-ui별-케이스&quot;&gt;2. 여러 페이지를 로딩하는 UI별 케이스&lt;/h4&gt;
&lt;p&gt;위의 케이스를 조금 더 세분화해보았다. 이번에 시도해 본 구글 플레이스토어, 네이버쇼핑, 예스24를 위주로 본 것이다.
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;1-스크롤-다운&quot;&gt;1) 스크롤 다운&lt;/h4&gt;

&lt;p&gt;스크롤을 내려서 ‘더 보기’ 버튼을 클릭해야 하거나, 무한 스크롤의 개념으로 계속 데이터가 로딩되는 경우가 있다. 구글 플레이의 앱 리뷰가 후자의 경우로 되어 있다. 
초보자여서 Selenium을 사용하기 부담스럽거나, 급한대로 몇십~몇백 건만 수집해보려는 경우라면 수동으로 스크롤다운해서 수집하는 것도 가능은 하다. 하지만 수집한 데이터를 살펴보면 오류가 있거나, 생각했던 것과 달라서 다시 수집해야 할 경우가 생길 수 있다. 이러한 시행착오 과정에서 비효율이 발생한다. 
또한 결과를 분석하다 보면 더 많은 양을 확보하고 싶어지기 마련인데, 몇천 건의 데이터를 수집하려 하면 수동으로 스크롤다운 하는 것도 오래 걸린다. 그래서 Selenium을 이용해 반복되는 스크롤다운을 자동화할 필요가 있다.&lt;/p&gt;

&lt;p&gt;관련해서 몇 번 시행착오를 해보니 top-down적인 접근이 효율적이라는 생각이 들었다. 자동이든 수동이든 스크롤다운을 한 뒤에는 수집하려는 요소만 수집하지 말고, 전체 웹요소를 먼저 수집한 뒤 그 안에서 필요한 데이터를 추출하는 접근법이 좋은 것 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;아래 글이 그런 접근법을 언급하고 있다. 전체 html 소스를 가져온 뒤, 필요한 요소를 정적수집하라고 한다.
    &lt;ul&gt;
      &lt;li&gt;https://coding-kindergarten.tistory.com/34&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;검색해본 글 중에 아래 글이 Selenium으로 구글플레이 앱리뷰를 무한 스크롤하는 코드를 포함하고 있었다.
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://heytech.tistory.com/293&quot;&gt;[Python] 구글 플레이 스토어 크롤러 코드 Version 2.0.3&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;2-페이지네이션이-있는-경우&quot;&gt;2) 페이지네이션이 있는 경우&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;2-1) ‘다음 페이지로 이동’ 버튼이 있는 경우&lt;/strong&gt;
&lt;br /&gt;
버튼을 눌렀을 때 지금 보고 있는 1페이지에서 2페이지로 이동하는 경우다. 한 페이지를 수집한 뒤, ‘다음’버튼을 누르도록 for문을 구성하면 된다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;아래는 ‘챗GPT로 검색한 네이버뉴스 결과 URL이다.
    &lt;ul&gt;
      &lt;li&gt;https://search.naver.com/search.naver?sm=tab_hty.top&amp;amp;where=news&amp;amp;query=%EC%B1%97GPT&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;오른쪽 화살표를 클릭하면 2페이지로 이동하는 것을 알 수 있다. 이 경우 한 페이지의 수집이 끝나면 화살표 버튼을 클릭하도록 for문을 구성하면 원하는 만큼 반복 수집할 수 있다. 네이버뉴스는 상대적으로 여러 페이지 크롤링이 용이해서인지, 구글링해보면 참고할 수 있는 블로그 글이 많은 편이다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2-2) ‘다음 페이지로 이동’ 버튼이 없어, 1,2,3….페이지를 각각 눌러야 하는 경우&lt;/strong&gt;
&lt;br /&gt;
네이버쇼핑의 쇼핑몰리뷰가 이렇게 되어 있다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://search.shopping.naver.com/catalog/20472074934&quot;&gt;데스커 노트북책상 쇼핑몰리뷰&lt;/a&gt;&lt;/p&gt;
&lt;image src=&quot;/assets/images/230312_naver_shopping.jpg&quot;&gt;

화면에 보이는 오른쪽 화살표 버튼은 1~10페이지에서 11~20페이지로 이동하는 버튼이다. (즉, 현재 보이는 10페이지를 기준으로 '다음 10페이지'를 로딩하는 버튼)

따라서 1페이지를 수집한 뒤에는 2페이지, 3페이지 버튼을 이어서 눌러주어야 한다. 이 부분은 아직 구현해보지 못해서 추가적인 검색과 시행착오가 필요하다. 아래 블로그 글을 보면 코드에 페이지 개념이 담겨있는데 직접 돌려보아야 이해가 될 것 같아서 일단 URL만 보관해 둔다. 2022년 3월 글이고 페이징 부분 캡처 이미지가 없어서, 당시에 네이버 쇼핑몰리뷰의 UI가 달랐을 가능성도 있어서 확인이 필요하다. 
&lt;a href=&quot;https://velog.io/@kjh1337/%EB%84%A4%EC%9D%B4%EB%B2%84-%EC%87%BC%ED%95%91%EB%AA%B0-%EB%A6%AC%EB%B7%B0-%ED%81%AC%EB%A1%A4%EB%A7%81&quot;&gt; 네이버 쇼핑몰 리뷰 크롤링&lt;/a&gt;

&lt;br /&gt;

#### 3) URL 주소를 활용할 수 있는 경우

오래된 사이트의 경우, URL이 로딩할 페이지나 한번에 로딩할 아이템 개수를 포함하는 경우가 있다. 이 경우 URL 주소 텍스트만 바꿔주면 되므로 조작하기 가장 용이하다. 그래서인지 초보자를 위한 크롤링 강의에서 위와 같은 사이트를 예시로 들 때가 있다. 

아래 예시의 예스24는 아이템 리스트의 상단/하단에 '20개씩 보기', '40개씩 보기' 등의 드랍다운 박스가 있다. 이 값을  URL을 통해 서버에 던지는 구조이기 때문에 활용이 가능하다.

&amp;lt;예시1 : 예스24&amp;gt;
- 예스24는 도서 카테고리별 보기 화면의 URL이 다음과 같다. (국내도서&amp;gt;IT&amp;gt;OS/데이터베이스)
    - http://www.yes24.com/24/Category/Display/001001003025
- 그러나 '20개씩 보기' 드랍다운의 값을 '40개씩 보기'로 바꾸면 URL이 해당 값을 포함한 값으로 바뀐다.
    - http://www.yes24.com/24/Category/Display/001001003025?FetchSize=40
- 이 값을 너무 큰 값으로 바꾸는 것은 주의해야 한다. 웹사이트 서버에 부담을 주지 않기 위해 자체적으로 제한값이 걸려있을 수 있고, 또한 예스24한테도 미안한 일이기 때문이다. 적절한 값을 주는게 좋을 것 같고, 내 경우 아래와 같이 1,000개까지는 정상적으로 수집되는 것을 확인했다. 

&lt;br /&gt;

```python
# 제어할 브라우저를 띄운다.
driver = webdriver.Chrome(service = Service(ChromeDriverManager().install()))

# 웹페이지에 접속한다. (로딩할 아이템 개수를 1000개로 지정)
url=&quot;http://www.yes24.com/24/category/display/001001001013?fetchsize=1000&quot;
driver.get(url)
```

&lt;br /&gt;

&amp;lt;예시2 : 교보문고&amp;gt;
- 교보문고의 도서 카테고리별 보기 화면의 URL은 다음과 같다.
    - https://product.kyobobook.co.kr/category/KOR/0707#?page=1&amp;amp;type=all&amp;amp;sort=new
- 여기서 페이지 번호를 2로 바꾸면 다음 페이지로 이동이 가능하다.
    - https://product.kyobobook.co.kr/category/KOR/0707#?page=1&amp;amp;type=all&amp;amp;sort=new


관심가는 어떤 분야의 텍스트를 빠른 시간에 수집해서 분석해보고 싶다면, 위와 같은 구조의 사이트를 찾아서 먼저 접근해보는 것도 좋을 것 같다. 여러모로 시간 효율을 높일 수 있다.

&lt;br /&gt;



#### 마무리하며
- 사례를 찾아보다 보니 Selenium만 사용하는 것보다는 (1) 여러 페이지 크롤링에 Selenium을 사용하고, (2) 필요시 BeautifulSoup을 병행 사용해서 데이터를 추출하는 게 좋아 보인다. 특히 무한 스크롤 방식일 경우 그런 것 같다. 
- 크롤링을 배우던 초반에는 정석대로만 따라했는데, 코드를 읽을 수 있게 된 지금은 for문을 사용하는 코드도 일부 차용해서 따라해볼 수 있을 것 같다. 다양한 사이트/많은 양의 데이터 크롤링을 많이 해보아서 노하우가 있는 분들의 블로그를 찾아서 갈무리해둬야겠다.
- 인프런에서 검색해보니 크롤링 강의가 예전보다 많이 늘었다. 강의별 목차를 훑어보며 전체 개념을 정리하고 내가 부족한 부분을 파악해두는 것도 좋을 것 같다. 
&lt;/image&gt;
</description>
        <pubDate>Sun, 12 Mar 2023 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/web-scraping/2023/03/12/web-scraping-multiple-pages.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/web-scraping/2023/03/12/web-scraping-multiple-pages.html</guid>
        
        
        <category>web-scraping</category>
        
      </item>
    
      <item>
        <title>Selenium 버전 4에서 달라진 점</title>
        <description>&lt;p&gt;개인적으로 분석해 보고 싶은 주제가 생기면 웹사이트를 크롤링해 텍스트 데이터를 수집하는 경우가 있다. 처음에는 BeautifulSoup을 쓰다가 페이징, 스크롤다운 등 브라우저를 제어할 필요가 있어서 Selenium을 섞어서 쓰고 있다.&lt;/p&gt;

&lt;p&gt;그런데 작년에 셀레니움을 쓰려고 보니 버전 4로 업그레이드되어 이전에 짜둔 코드가 작동하지 않았다. 검색을 해서 당장 필요한 건 해결했지만, 셀레니움 3에서 4로 넘어가면서 달라진 부분들을 제대로 이해하진 못한 상태였다. 특히 라이브러리를 import하는 부분의 코드가 많이 달라져서, 한번은 공부해봐야겠다는 생각이 들었다. 그래서 이번에 사이드 프로젝트를 시작하는 김에 셀레니움 4에 대해 한번 이해하고 넘어가기로 했다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;what-셀레니움이란&quot;&gt;What 셀레니움이란?&lt;/h4&gt;
&lt;p&gt;데이터를 분석하는 입장에서는 주로 웹크롤링을 하는 과정에서 셀레니움을 접하게 되는데, 원래는 웹 테스트 자동화 툴로 개발되었다고 한다.&lt;/p&gt;

&lt;p&gt;위키피디어에서는 ‘software testing framework’라는 표현을 쓰고 있고, 정확한 설명은 아래와 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;‘셀레니움은 브라우저 자동화(browser automation)을 지원할 목적으로 만들어진 툴과 라이브러리들에 대한 오픈소스 프로젝트이다. 테스트 스크립트 언어를 배우지 않고도 대부분의 모던 웹 브라우저에서 기능 테스트를 할 수 있게 해준다.’&lt;/li&gt;
  &lt;li&gt;웹 애플리케이션 테스트 자동화의 개발을 지원하기 위해 여러 구성요소가 특정한 역할을 맡고 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;구성요소는 아래와 같다. 크롤링을 할 때는 Webdriver만 접해왔는데, 전체 구성이 궁금하니 위키를 기준으로 핵심 개념만 살펴보았다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Selenium IDE : 셀레니움 테스트를 위한 통합 개발환경. 기능 테스트를 녹화, 편집, 디버깅할 수 있다.&lt;/li&gt;
  &lt;li&gt;Selenium client API : 다른 프로그래밍 언어로 작성한 테스트를 이 API의 메소드를 사용해서 셀레니움과 커뮤니케이션할 수 있었다. 셀레니움 2부터는 WebDriver라는 새로운 Client API를 제공하고 있다.&lt;/li&gt;
  &lt;li&gt;Selenium Remote Control : Java로 만들어진 서버이다. 셀레니움 2부터는 웹드라이버로 인해 deprecated 되었다.&lt;/li&gt;
  &lt;li&gt;Selenium WebDriver : 웹드라이버는 명령을 받아서 브라우저에 보내준다. 대부분의 브라우저 드라이버들은 실제로 브라우저 어플리케이션(Firefox, Google Chrome, Safari, Edge) 등을 런치하고 접근한다.&lt;/li&gt;
  &lt;li&gt;Selenium Grid : 원격지 기기에서 실행되는 웹브라우저를 테스트하게 해주는 서버이다. 서버가 hub 역할을 하고, 웹드라이버는 node가 된다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(출처 : https://en.wikipedia.org/wiki/Selenium_(software)&lt;/p&gt;

&lt;p&gt;크롤링에 참조할 목적으로 셀레니움 4에 대해 구글링을 해보면, 영어 문서는 테스트 자동화에 대한 글들이 대다수를 이루고 있다.&lt;/p&gt;

&lt;p&gt;어쨌든 핵심은 브라우저를 제어한다는 점이고, 내 경우 여러 페이지를 넘기면서 수집해야 하거나 무한 스크롤되는 리스트를 스크롤다운해야 하는 경우에 셀레니움이 필요했다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;why-왜-셀레니움-4를-사용하려-하나-무엇이-더-좋아졌나&quot;&gt;Why 왜 셀레니움 4를 사용하려 하나? 무엇이 더 좋아졌나?&lt;/h4&gt;
&lt;p&gt;셀레니움 4 업데이트는 2021년 10월에 공개되었다고 한다. 별 생각없이 pip install selenium으로 설치하면 이전에 작성해 둔 코드가 작동하지 않는데,  크롤링에 쓰이는 문법이 바뀌었기 때문이다.&lt;/p&gt;

&lt;p&gt;하지만 바뀐 문법을 새로 배우는게 귀찮지 않을만큼 강력한 강점이 있다. 셀레니움 4에서는 웹드라이버 매니저를 이용할 수 있는데(WebDriver Manager), 이건 바뀐 문법을 찾아서 코드를 고치는 걸 감수할 만큼 강력한 장점이다.&lt;/p&gt;

&lt;p&gt;이전에는 브라우저 버전과 OS에 맞는 드라이버를 수동으로 직접 다운로드 받고, 코드 내에 파일이 위치한 경로를 지정해줘야 했다. 그래서 나처럼 1년에 1~2번 크롤링을 하느라 이전 코드를 재사용하거나, 다른 컴퓨터에 셀레니움을 다시 설치하는 경우, 크롬 버전을 확인하고 드라이버를 다시 찾아야 하는 번거로움이 있었다.&lt;/p&gt;

&lt;p&gt;하지만 셀레니움 4에서는 간단히 아래 2가지만 실행하면 된다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Webdriver manager를 설치한다.&lt;/li&gt;
  &lt;li&gt;코드 앞부분의 선언하는 내용을 작성해 놓고, 재사용한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;how-셀레니움-4는-버전3과-무엇이-달라졌나-어떻게-사용해야-하나&quot;&gt;How 셀레니움 4는 버전3과 무엇이 달라졌나? 어떻게 사용해야 하나?&lt;/h4&gt;
&lt;p&gt;테스트 자동화에 대해서는 잘 알지 못하므로, 웹크롤링에 관련된 부분만 확인하고 정리해 보았다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. 설치하기&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;셀레니움을 설치할 때, 웹드라이버도 함께 설치한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selenium&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver_manager&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;만약 셀레니움을 사용한 적이 있다면, 버전은 아래와 같이 확인할 수 있다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;selenium&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__version__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 설정하기&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;공식문서 : &lt;a href=&quot;https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/#2-driver-management-software&quot;&gt;Install browser drivers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;아래는 공식 문서를 번역한 내용이다.&lt;/p&gt;

&lt;p&gt;1) WebDriver Manager를 임포트한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;webdriver_manager.chrome&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;2) 매니저가 사용한 위치를 install()로 얻어와서, service 클래스 인스턴스에 넘겨준다.
전에는 드라이버가 위치한 경로를 인자로 직접 전달했으나, Service 객체를 전달하는 것으로 바뀌었다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ChromeService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executable_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chrome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Webdriver.Chrome() 함수가 Service 객체를 (파라미터로) 전달한다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
검색을 하다보면 간결하게 줄인 코드도 보이지만, 구조를 이해하기 위해 공식문서의 코드를 먼저 옮겼다. 아래는 좀더 간결하게 정리된 코드다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;webdriver_manager.chrome&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.chrome.service&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Service&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 제어할 브라우저를 띄운다.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chrome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 원하는 url에 접속한다. 
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.naver.com&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;어떤 블로그에서 아래와 같은 코드도 발견해 따라해보았다. 바로 경로값을 넘겨줘도 아직 작동은 하지만, Service 객체를 이용할 것을 권장하고 있다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;webdriver_manager.chrome&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chrome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;DeprecationWarning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;executable_path&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;been&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deprecated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;please&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Service&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(참고 : 코드잇 Q&amp;amp;A https://www.codeit.kr/community/threads/33729)&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. 웹 Element에 접근해서 값 가져오기&lt;/strong&gt;
By를 사용하는 것으로 문법이 바뀌었기 때문에, 아래와 같이 먼저 선언해야 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.common.by&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 클래스명이 'goods_name'인 elements를 모두 가져온다. 
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;elements&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CLASS_NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'goods_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 모두 출력
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 첫 번째 값만 출력
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;공식문서 : &lt;a href=&quot;https://www.selenium.dev/documentation/webdriver/elements/finders/&quot;&gt;Finding web elements&lt;/a&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;기존의 문법과 셀레니움 4의 문법을 비교해보면 아래와 같다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 기존 
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_elements_by_class_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'goods_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 셀레니움 4
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CLASS_NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'goods_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;전체 메소드 목록은 아래 문서에서 확인할 수 있다. 순서는 내가 사용해보았거나 익숙한 순서로 재정렬한 것이다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TAG_NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tag name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CLASS_NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;class name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSS_SELECTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;css selector&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XPATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;xpath&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LINK_TEXT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;link text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PARTIAL_LINK_TEXT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;partial link text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# fruits ID 안의 tomatoes 클래스를 가져온다.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSS_SELECTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#fruits .tomatoes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;참조 : https://selenium-python.readthedocs.io/locating-elements.html&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. 그 외 브라우저 제어 (클릭, 텍스트 입력 등)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;텍스트를 수집할 때 참고할 용도로, 자주 사용하는 것만 우선 찾아보았다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Keys를 선언한다.
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.common.by&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.common.keys&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# 검색창에 텍스트 입력하기
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SearchInput&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;query&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SearchInput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;파이썬&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# '검색' 버튼 클릭하기
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CLASS_NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'schBtn'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 입력된 텍스트 지우기
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SearchInput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# 또는 한번에 하기 : 검색창에 단어를 입력하여 검색하기
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;query&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;파이썬&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ENTER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;공식문서 : &lt;a href=&quot;https://www.selenium.dev/documentation/webdriver/elements/interactions/&quot;&gt;Interacting with web elements&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Webdriver Manager로 바뀐 부분이 어렵게만 느껴졌는데, 공식 문서와 국내 블로그를 오가며 자꾸 보다보니 조금은 알 것도 같다. 그 외에 셀레니움 4에서 달라진 점으로 브라우저 내에 새 창을 열 수 있다, 등의 장점도 있던데 사이드 프로젝트를 하면서 찾아 보아야겠다.&lt;/li&gt;
  &lt;li&gt;find_elements 했을 때 반환되는 객체를 다루는게 늘 어렵다. 아직 머릿속에 개념이 잘 정립되지 못한 것 같다. 공식문서에 관련된 내용이 있는지도 다음엔 확인해보자.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 20 Feb 2023 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/web-scraping/2023/02/20/selenium-4-update-overview.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/web-scraping/2023/02/20/selenium-4-update-overview.html</guid>
        
        
        <category>web-scraping</category>
        
      </item>
    
      <item>
        <title>글또 8기를 시작하며</title>
        <description>&lt;p&gt;글또 7기에 이어서 8기에도 참여 신청을 했다.&lt;/p&gt;

&lt;p&gt;3기 때 회사일에 치어 거의 작성을 못하고 중도하차했던 기억에, 7기 신청할 때는 해낼 수 있을까 반신반의 하는 마음이었던 것 같다. 그런데 이번에는 ‘당연히 해야지!’하는 마음으로 신청했다. 스스로 생각하는 ‘성장하고 싶은 사람’이라는 정체성에 글또가 큰 의미가 있어서인 것 같다.&lt;/p&gt;

&lt;p&gt;최근에 ‘자기다움’ 에 관한 페북 글을 읽었다. 가장 나다운 것이 무엇인지 알기 위해 가방 안의 물건을 20개만 적어보라는 미션이었다. 내 가방은 단촐한 편이라, 스마트폰 안에 들어있는 무형의 물건들도 적어보기 시작했다. 리디셀렉트, 퍼블리, DataCamp 같은 구독형 서비스도 있고, 그 중에는 글또와 블로그도 있다. 아직은 기술블로그라고 하기엔 부족하지만, 당당하게 ‘기술블로그를 운영하고 있습니다’ 할 정도가 되면 삶에 자신감이 높아질 것 같다.&lt;/p&gt;

&lt;p&gt;그래서 이제는 할 수 있을까 하는 마음보다는 당연히 해야지, 이번엔 조금 더 잘해봐야지, 하는 마음으로 글또에 참여하게 되었다. 
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;무엇을-하고-싶은가&quot;&gt;무엇을 하고 싶은가?&lt;/h4&gt;

&lt;p&gt;글또 8기 OJT때 성윤님이 보여주신 질문의 프레임이 머리를 띵하고 울렸다. 그래서 우선 그 프레임으로 생각을 정리해보았다. 자료를 다시 찾아보니 신규참여자를 위한 질문이었지만, 근본적인 부분이기 때문에 이 고민을 먼저 하는게 맞는 것 같다.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. 나는 글또를 통해 무엇을 이루고 싶은가?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;자기다움을 드러내는 퍼스널브랜딩을 하고 싶다. 블로그에 많은 사람이 유입되고 알려지기 보다는, 아 누구누구, 하고 기억되면 좋겠다.&lt;/p&gt;

&lt;p&gt;이 부분은 지난 기수에도 막연히 생각했던 거지만, 커리어체인지를 한지 오래되지 않아서 그럴만한 내공이 부족했던 것 같다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 그러기 위해 무엇을 해야 하는가?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;글 주제에 대해 선택과 집중을 해야할 것 같다. 업무에서 새로운 것을 접할 때마다 공부한 내용을 정리하는 것도 좋지만, 내용이 다양해지면 각 분야에 작성한 글의 누적값은 작을 수밖에 없다. 
시간활용이 쉽지 않다보니, 7기 때는 주로 업무와 관련된 내용을 글로 정리하는 경우가 많았다. 이 경우 단점은…당시 하고 있는 업무에 따라 글의 주제가 널뛰기를 할 수 있다는 점이다. 그러지 않고 어느 정도는 뭉쳐진 주제로 글을 써야 브랜딩이 될 것 같다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. 그 행동을 꾸준히 할 수 있는 방법은 무엇일까?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;개인사정으로 5월까지 3개월간 휴직 예정이다. 회사일을 잊고 내 생활을 돌아볼 마음의 여유가 있는 기간이다. 이 기간동안 평소 나의 시간사용 패턴을 살펴보고, 글 쓰는 프로세스를 셋업해볼 수 있겠다. 아래 단계 중에 미루게 되는 순간들을 포착해서 기록해두면, 나중에 분석했을 때 의미있을 것 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;글 주제를 잡는다. (평소/머리속)&lt;/li&gt;
  &lt;li&gt;초안을 쓴다. (이동시간, 자투리 시간, 카페에서도 가능/핸폰 메모장)
    &lt;ul&gt;
      &lt;li&gt;목차의 구조를 잡는 것에 해당한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;노션에 옮긴다. 자료를 조사하면서 채워나간다.&lt;/li&gt;
  &lt;li&gt;에디터에 글을 옮기고 다듬는다.&lt;/li&gt;
  &lt;li&gt;폰트/줄바꿈 등 포맷을 다듬고 퍼블리싱한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;8기-구체적인-목표&quot;&gt;8기 구체적인 목표&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;완주한다.&lt;/li&gt;
  &lt;li&gt;세이브원고를 만들어 본다.
    &lt;ul&gt;
      &lt;li&gt;마감이 끝나자마나 다음 회차 글을 제출하는 식으로, 2주일을 일찍 사시는 분들도 있다고 한다. 이렇게 다른 분들에게 자극을 받는게 글또의 좋은 점이다. 나도, 해봐야겠다.&lt;/li&gt;
      &lt;li&gt;웹툰 작가들처럼 전체적인 플롯이 잡혀있는 경우 세이브원고를 써놓기 더 좋을 것 같다. 나는 아직 어떤 내용으로 쓰겠다는 계획까지는 없는데, 주제를 생각해보면 좋을 것 같다.&lt;/li&gt;
      &lt;li&gt;노션에 ‘글또 8기 완주’ 폴더를 만들고, 그 밑에 세이브원고를 위한 회차별 빈페이지를 만들어뒀다.&lt;/li&gt;
      &lt;li&gt;글감이 쌓이면, 8기가 끝나더라도 9기까지의 사이에 글을 올릴 수 있을 것 같다. 그 단계로 넘어가보고 싶다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;마감일 다음 주에 글을 제출해본다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;p&gt;한 주제에 대해 집중된 노력으로 여러 개의 글을 생산할 수 있다면 좋을 것이다.. 라고 쓰다 보니, 글의 주제에 따라 다를 수 있겠다는 생각이 든다. 예를 들어, 앞뒤 맥락을 따지고 완결성을 높이려다 보면 시리즈글이 더 공수가 많이 들 수도 있겠다는 것이다. 그렇다면 글쓰기라는 작업에 대해 나는 너무나 모르고 있는 게 아닐까? 글의 주제별로, 나라는 사람의 특성과 성향상, 어떨 때 얼마나 공수가 드는지를 파악해보는 것도 필요한 작업일 것 같다.&lt;/p&gt;
</description>
        <pubDate>Sun, 12 Feb 2023 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/essay/2023/02/12/starting-gultto-8.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/essay/2023/02/12/starting-gultto-8.html</guid>
        
        
        <category>Essay</category>
        
      </item>
    
      <item>
        <title>글또 7기를 마무리하며</title>
        <description>&lt;p&gt;글또 7기 마지막 주간이다. 글또 회고 글을 쓸지, 2022년 회고를 하면서 중간점검을 하고 단기목표를 세워볼지 잠깐 고민했다. 
그런데 전에 썼던 글또 다짐글들을 읽어보니 나를 돌아보는 데에 도움되는 부분이 많아, 간단하게나마 회고를 남겨본다.
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;목표를-얼마나-이루었나&quot;&gt;목표를 얼마나 이루었나?&lt;/h4&gt;
&lt;p&gt;&lt;b&gt; 1. 완주하기&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;가급적 Pass 없이 완주하겠다고 목표를 세웠었는데, 결국 패스는 2번 다 사용했다.
하지만 오늘 글을 올림으로써 완주가 될테니 다행히 기본 목표는 성공이다.
중간에 글 제출이 3~4번 남았을 때 위기가 있었다. 패스권은 다 썼지, 회사 일은 버겁고 일주일 내내 완전히 소진된 채로 퇴근하지… 하지만 스스로 세운 목표가 있어서 그나마 어떻게든 해낼 수 있었던 것 같다. 
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;2. 글에 이미지 포함시키기&lt;/b&gt;
글에 이미지를 넣는 시도는 했고, 찾아낸 여러 방법중에 나한테 맞는 방법도 머릿속에 완전히 입력되었다. 하지만 아직 손이 선뜻 나설 정도로 손에 익지는 않아서, 절반의 성공이었다.&lt;/p&gt;

&lt;p&gt;이 블로그에 사용한 Github Jekyll은 글이 발행되지 않는 에러가 가끔 있어서, 이전 글 파일을 복사해서 내용만 수정하는 방식으로 작업하고 있다. 글 작성할 때 이미지 링크 코드를 바로 참고할 수 있으면 부담이 덜할 것 같아서, 빈 포맷을 하나 만들어 놓았다. 다음 기수에는 좀더 활발하게 이미지를 사용해서 데이터 시각화에 대한 글도 가볍게 써볼 수 있었으면 좋겠다. 
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt; 3. 텍스트마이닝 또는 모델링에 관해 공부한 글 작성하기&lt;/b&gt;
Konlpy를 직접 사용해보는 데에는 성공했다. 전에는 설치 문제로 하루 정도 씨름하다가 포기한 적이 있었는데, 이번에는 반나절 정도 시도로 성공했고, 그냥 최신 버전을 설치하면 된다는 걸 알게 되었다.&lt;/p&gt;

&lt;p&gt;하지만 모델링에 대한 공부는 거의 하지 못했다. 그 대신 업무 관련해서 기본적인 전처리와 형태소분석기 사용, 단어 추출 등에 대한 내용을 깊이 있게 알아나가는 중이다. 관련 글도 시리즈 같은 느낌으로 작성하는 중인데, 글또 7기가 마무리되면서 글쓰기의 흐름도 끊길까봐 염려되긴 한다. 하지만 피드백을 달아주신 분들의 질문과 응원에 힘입어 아직 쓰지 못한 글감들도 글로 정리해보고 싶다.&lt;/p&gt;

&lt;p&gt;글또 2기 다짐글을 보면 ‘배운 것을 정리한 글의 비중을 70%까지 높인다.’를 목표로 삼았던 적이 있다. 이번 7기에서는 궁금한 주제에 대해 찾아보고 정리한 글의 비중이 꽤 높았던 것 같아서 그 점은 다행스럽다. 
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;아쉬웠던-점&quot;&gt;아쉬웠던 점&lt;/h4&gt;
&lt;p&gt;&lt;b&gt; 1. 글쓰기 파이프라인을 만들지 못했다. &lt;/b&gt;
처음 목표를 세울 때 욕심내진 못했지만 글쓰기 파이프라인을 구축하고 싶다는 생각이 있었다. 하지만 이번 기수에서 안정적인 파이프라인을 만들지는 못한 것 같다. 그나마 나에게 편하고 부담없는 루틴은 생겼는데, 아래와 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(마감일이 지나자 마자) 대략적인 글감을 정해 본다.&lt;/li&gt;
  &lt;li&gt;평소 머릿속으로 그 주제에 대해 계속 생각한다.&lt;/li&gt;
  &lt;li&gt;틈틈이 궁금하거나 필요한 부분은 검색해본다.&lt;/li&gt;
  &lt;li&gt;본격적으로 자료를 검색할 때 메모장에 글 순서를 잡아본다.&lt;/li&gt;
  &lt;li&gt;자리잡고 앉아서 에디터에 전체 내용을 작성한다.&lt;/li&gt;
  &lt;li&gt;세부적인 내용을 정리/보완해서 퍼블리시한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;다만 회사일로 마음의 여유가 없을 때는 ‘글감을 정해야지’라는 생각조차 잊어버릴 때가 있어서, 저 루틴이 안정적으로 이루어지진 못했던 것 같다. 나의 에너지는 한정되어 있고 사이드 프로젝트나 블로그 글쓰기를 꾸준히 하려면 회사 일로 감정소모하는 일은 최소화해야겠다는 교훈을 얻은 올해였다.
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt; 2. 피드백을 잘 작성하지 못한 점&lt;/b&gt;
피드백을 쓰는 건 생각보다 어려운 일이었다.
아직은 내 글을 쓰는 것도 2주 안에 겨우 커버하고 있기 때문이다.
그래서 피드백을 기한 내에 쓰지 못한 경우가 많았다. 예치금 차감이야 이미 마음을 비워서 상관없지만, 피드백을 늦게 받거나 받지 못하신 분들께 죄송한 마음이다.
다음에는 ‘피드백 알림’이 뜨면 ‘그 글을 일단 읽어본다’는 습관을 형성해보면 어떨까 싶다. 일단 읽고 나면 주중에도 머릿속 한켠에서 그 생각이 돌아갈테니 말이다.
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;p&gt;올해 인상깊게 읽었던 책 중 하나가 자청님의 &lt;역행자&gt;였는데, 그 중에 '정체성 세우기'에 대한 얘기가 나온다. 나는 이런 사람이야, 라는 정체성을 먼저 세워놓으면 그에 맞는 행동과 생각을 하면서 발전하고 성장한다는 얘기이다.
내게 글또는 그런 존재인 것 같다. 일단 글또에 참여하는 일원이 되고 다른 분들이 열심히 사시는 모습을 보면서, 많은 자극을 받고 분발해야겠다는 생각을 하게 된다. 그런 점에서 글또 8기에는 더 나은 활동을 하게 되기를 기대해본다.&lt;/역행자&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 16 Oct 2022 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/essay/2022/10/16/epilogue-gultto-7th.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/essay/2022/10/16/epilogue-gultto-7th.html</guid>
        
        
        <category>Essay</category>
        
      </item>
    
      <item>
        <title>Kiwi 형태소분석기를 사용해보자.</title>
        <description>&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;/h3&gt;

&lt;p&gt;Konlpy 패키지의 형태소분석기들을 비교하느라 검색을 거듭할수록 텍스트 분야에 내공이 깊은 분들의 블로그를 발견하게 되었다. 그 중에 2009년경 ‘재미삼아 형태소분석기를 만들어보았다’는 글이 인상깊어서 나중에 다시 찾아보게 되었는데, 도대체 형태소분석기는 어떤 원리로 동작하는 거고 어떻게 만드는 거야? 하는 궁금증이 생겼기 때문이다. 
이 분의 블로그를 덕질해본 결과 이 형태소분석기에는 Kiwi라는 이름이 붙었고, 지금도 꾸준하게 업데이트되고 있다는 사실을 알게 되었다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;what--kiwi-형태소분석기란&quot;&gt;WHAT | Kiwi 형태소분석기란?&lt;/h4&gt;

&lt;p&gt;C++로 만들어져 Konlpy와 JDK를 설치할 때 같은 어려움 없이 정말 초간단하게 설치해서 사용해볼 수 있는 국문 형태소분석기이다. 
공식 문서에서도 다음과 같이 특징을 설명하고 있다. (https://lab.bab2min.pe.kr/kiwi)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;외부 라이브러리 의존 없이 순수 C++로만 작성되어 어떤 환경에서도 사용할 수 있습니다.&lt;/li&gt;
  &lt;li&gt;사용자가 필요에 따라 사전 내용을 추가할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;설치 과정은 아래 한 줄이 끝이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kiwipiepy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;why--왜-kiwi를-공부해보고-싶어졌나&quot;&gt;WHY | 왜 Kiwi를 공부해보고 싶어졌나?&lt;/h4&gt;

&lt;p&gt;지속적으로 관리되고 기능이 개선되는 형태소분석기를 사용하고 싶었다.&lt;/p&gt;

&lt;p&gt;Konlpy를 통해 사용해본 형태소분석기들은 깃허브를 보면 거의 최근에 업데이트가 없는 것처럼 보였다.&lt;/p&gt;

&lt;p&gt;이런 부분들은 아래 공식 페이지를 통해 확인할 수 있다. 형태소분석기마다 차이는 있지만 약 최근 2년간은 업데이트되지 않은 형태소분석기들이 많았다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Mecab : https://bitbucket.org/eunjeon/mecab-ko-dic/src/master/&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Okt (구. Twitter) : https://github.com/open-korean-text/open-korean-text/&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Komoran&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;깃허브 : https://github.com/shineware/KOMORAN&lt;/li&gt;
      &lt;li&gt;공식 문서 : https://docs.komoran.kr/&lt;/li&gt;
      &lt;li&gt;샤인웨어 홈페이지 : https://www.shineware.co.kr/products/komoran/&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;반면 Kiwi는 꾸준히 관리가 되고 있었다. 개발자 분이 리포팅된 이슈를 정말 성심성의껏 관리하고 하나씩 해결해나가고, 기능도 지속적으로 개선되고 있었다. 그래서 구글링을 해보니 이 형태소분석기를 만드신 개발자 님이 카카오 엔터프라이즈에서 관련 업무를 하고 계신 ‘실무자’이셨다. 아, 이건 써봐야 한다, 쓰면서 깊이 배워야겠단 생각이 들었다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;how--kiwi-형태소분석기-사용-방법&quot;&gt;HOW | Kiwi 형태소분석기 사용 방법&lt;/h4&gt;

&lt;p&gt;Konlpy를 통해 Mecab, Okt, Komoran을 사용하다 보면 아래와 같은 간결한 사용법과 결과에 익숙해지게 된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;konlpy.tag&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Okt&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;okt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Okt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;카카오워크를 효과적으로 사용하려면&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 품사 태깅
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;okt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'카카오'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Noun'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'워'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Noun'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'크를'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Verb'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'효과'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Noun'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'적'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Suffix'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'으로'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Josa'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'사용'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Noun'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'하려면'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Verb'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 명사만 추출하기
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;okt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nouns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'카카오'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'워'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'효과'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'사용'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;
그런데 Kiwi는 기본적인 토크나이징을 하면 아래와 같은 결과를 돌려준다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;kiwipiepy&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Kiwi&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 결과
[Token(form='카카오', tag='NNP', start=0, len=3),
 Token(form='워크', tag='NNG', start=3, len=2),
 Token(form='를', tag='JKO', start=5, len=1),
 Token(form='효과', tag='NNG', start=7, len=2),
 Token(form='적', tag='XSN', start=9, len=1),
 Token(form='으로', tag='JKB', start=10, len=2),
 Token(form='사용', tag='NNG', start=13, len=2),
 Token(form='하', tag='XSV', start=15, len=1),
 Token(form='려면', tag='EC', start=16, len=2)]

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;일단 복잡해보였다. 파이썬 중급자/고급자를 위한 기능들인 것 같아 어떻게 가공해야 할지 감이 오지 않았다. 
내용을 살펴보면 순서대로 토큰, 품사태그, 문서 내에서의 위치, 토큰 길이를 제공하고 있다. 
필요와 목적에 맞게 고도로 커스터마이징할 수 있지만, 처음 배울 때는 다소 어렵게 느껴져 진입장벽이 될 수 있을 것 같다.&lt;/p&gt;

&lt;p&gt;내가 필요로 하는 부분만 추출해서 가독성을 높이고 좀더 간단하게 활용하려면 어떻게 해야 할까? 
아직 파이썬을 자유자재로 쓸만큼 익숙하지는 않은 관계로, 오늘은 이 부분을 정리해보았다.&lt;/p&gt;

&lt;p&gt;&amp;lt;/br&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;1) 단어와 품사만 출력하고자 할 때&lt;/b&gt;
아래와 같이 token.form, token.tag로 뽑아낼 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;카카오&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;NNP&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;워크&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;NNG&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;를&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;JKO&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;효과&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;NNG&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;적&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;XSN&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;으로&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;JKB&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;사용&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;NNG&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;하&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;XSV&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;려면&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;EC&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;다음부터는 결과를 가공해서 활용하기 위해 정리해본 내용들이다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;2) 리스트 형태로 가공하기&lt;/b&gt;&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'카카오'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNP'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'워크'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'를'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'JKO'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'효과'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'적'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'XSN'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'으로'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'JKB'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'사용'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'하'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'XSV'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'려면'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'EC'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;3) 리스트 형태로 명사만 추출하기&lt;/b&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;okt.nouns(text)&lt;/code&gt;에 해당하는 코드이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'N'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;결과는 아래와 같이 출력된다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'카카오'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNP'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'워크'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'효과'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'사용'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NNG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;4) Counter로 빈도순 정렬하기&lt;/b&gt;
이번에는 Counter를 이용해 빈도를 카운트해 본다. 먼저 리스트 형태로 가공해야 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;현재 네이버는 클로바 스마트스피커, 클로바더빙, 클로바노트, 클로바 케어콜 등 다양한 AI 서비스에 음성 AI 기술을 활용하고 있다.&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 클로 / 바 로 잘려서 사용자 사전에 등록 
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_user_word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;클로바&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NNP&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 명사만 추출하여 리스트로 만들기
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'N'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'네이버'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'클로바'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'스마트'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'스피커'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'클로바'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'더빙'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'클로바'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'노트'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'클로바'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'케어콜'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'등'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'다양'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'서비스'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'음성'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'기술'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'활용'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이렇게 리스트로 만든 뒤, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Counter&lt;/code&gt;를 이용해 간단히 빈도를 계산할 수 있다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;top_nouns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most_common&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top_nouns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#결과
('클로바', 4)
('네이버', 1)
('스마트', 1)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;5) 데이터프레임으로 가공하기&lt;/b&gt;
마지막으로, 익숙한 dataframe 형식으로 가공하는 방법이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kiwi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/221001_dataframe_result_img.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;빈 리스트를 만들고 token들을 추가한 뒤, 마지막에 데이터프레임으로 변환했다. 
Counter를 사용하는 대신 이 결과를 groupby해서 활용해도 되겠다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;텍스트 분석 자체도 어려운지라 Kiwi의 공식문서를 처음 봤을 때는 너무 어렵고 복잡하게 느껴져 깊이 들여다보지 못했었다. 하지만 새로운 단어를 추출해내는 기능, 문서 내에서의 위치를 제공하는 부분 등이 매력적으로 느껴저 한번 사용해보기로 했다.&lt;/li&gt;
  &lt;li&gt;python을 배우는 여러가지 방법들이 있지만, 막상 문과생이 데이터를 엑셀처럼 자유자재로 사용하려기 위해 필요한 노하우는 따로 있는 것 같다. 그런 것들만 알짜배기를 모아서 하루 익혔으면 좋겠다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;참고-글&quot;&gt;참고 글&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;[KIWI] 좋아, 형태소 분석기를 만들어봅시다. https://bab2min.tistory.com/560&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 01 Oct 2022 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/text%20analysis/2022/10/01/text-analysis-using-kiwi.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/text%20analysis/2022/10/01/text-analysis-using-kiwi.html</guid>
        
        
        <category>Text Analysis</category>
        
      </item>
    
      <item>
        <title>Konlpy 형태소분석기의 사용자 사전 비교 </title>
        <description>&lt;p&gt;지난 글에 이어, 이번에는 형태소 분석기가 잘못 분석하는 단어를 &lt;b&gt;사용자 사전&lt;/b&gt;에 추가해 바로잡는 방법을 정리해보았다.&lt;/p&gt;

&lt;p&gt;이전 글 :&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://jessymin.github.io/text%20analysis/2022/08/07/realworld-problem-on-text-analysis-service.html&quot;&gt;텍스트 분석의 현실적인 문제들&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://jessymin.github.io/text%20analysis/2022/08/07/2022-08-21-text-analysis-korean-stem-analyzers.html&quot;&gt;한국어 형태소분석기를 비교하는 기준&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;/h3&gt;

&lt;p&gt;진행 중인 프로젝트에 어떤 형태소분석기를 적용할지 비교/분석해서 정하기 위해 틈틈이 공부하는 중이다. 비교하는 요소 중에는 ‘사용자 사전 관리가 얼마나 용이한가’라는 관점도 있다. 분석하려는 데이터의 특성상 복합명사나 외래어/신조어가 많고, 앞으로도 계속 생겨날 것 같아서다.&lt;/p&gt;

&lt;p&gt;이에 Konlpy가 지원하는 형태소분석기들 중 Okt, Mecab, Komoran의 사용자 사전 관련된 내용들을 찾아보고 정리해보았다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;what--형태소분석기의-사용자-사전이란&quot;&gt;WHAT | 형태소분석기의 사용자 사전이란?&lt;/h4&gt;

&lt;p&gt;형태소가 잘못 분석된 경우를 바로잡거나 복합명사를 분석 목적에 따라 하나의 단어로 처리하기 위해 사용한다.&lt;/p&gt;

&lt;p&gt;형태소분석기를 사용해 단어를 추출한 뒤에는, 분석 및 시각화 결과의 보정을 위해 원하는 단어를 사용자 사전에 추가하게 된다.&lt;/p&gt;

&lt;p&gt;보통 csv, txt 등의 사전 파일에 원하는 단어와 품사를 추가하게 된다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;(before) 카카오/NNG 톡/NNG → (after) 카카오톡/NNP&lt;/li&gt;
  &lt;li&gt;NNG : 일반명사, NNP : 고유명사&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;why--사용자-사전-왜-필요한가&quot;&gt;WHY | 사용자 사전, 왜 필요한가?&lt;/h4&gt;

&lt;p&gt;대부분의 형태소분석기는 커다란 말뭉치(코퍼스)를 이용해서 사전을 구축하고 이를 활용해 형태소를 분석한다. 하지만, 현실적으로는 어쩔 수 없이 분석 결과에 보정이 필요한 경우가 발생한다. 주로 아래와 같은 이유들 때문이다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;다양한 도메인의 전문용어를 모두 커버할 수가 없다. 
&lt;br /&gt;&lt;/li&gt;
  &lt;li&gt;기존 사전에 없는 신조어는 제대로 분석할 수 없다.
    &lt;ul&gt;
      &lt;li&gt;문법을 파괴하는 인터넷 용어, 축약어 등&lt;/li&gt;
      &lt;li&gt;비즈니스/마케팅 분야에서 새로 생겨나는 개념들 (예. 푸드테크, 핀테크, 욜로족, 홈파밍 등)&lt;/li&gt;
      &lt;li&gt;새로 생겨나는 기업명, 브랜드명, 서비스명 등
&lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;또한 복합명사의 경우,
    &lt;ul&gt;
      &lt;li&gt;하나의 의미로 묶어주는 게 분석이나 시각화에 더 나을 수 있다. (예. 격리해제, 자가진단)&lt;/li&gt;
      &lt;li&gt;다만 복합명사를 묶어주는 것은 일장일단이 있으므로, 분석 텍스트에 출현하는 단어들을 살펴보고 분석 목적에 맞게 적용할 필요가 있다. 
&lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그런데 잘못 분석된 단어를 꼭 바로잡아야 할까? 두 가지 경우로 나눠서 생각해볼 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1회성 분석을 하는 경우
    &lt;ul&gt;
      &lt;li&gt;해당 도메인에서 중요하고 자주 출현하는 단어가 잘못 잘려서 추출되면 제대로 분석하기가 어렵고 효율이 떨어진다.&lt;/li&gt;
      &lt;li&gt;커뮤니케이션을 위해 워드클라우드, 키워드 랭킹 등 분석 결과물을 전달할 때 신뢰성이 떨어지게 된다. (사실 인간은 오탈자를 바로잡는 본능이 있기 때문에, 일단 눈에 거슬린다)&lt;/li&gt;
      &lt;li&gt;심한 경우엔 원래 의미를 유추할 수 없을 정도로 잘못 잘라진다. (보는 순간 이게 뭐지?….하게 되는 단어들)
&lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;지속적인 서비스를 제공하는 경우
    &lt;ul&gt;
      &lt;li&gt;위와 마찬가지로, 서비스의 퀄리티와 신뢰도를 떨어뜨리는 요소가 된다.&lt;/li&gt;
      &lt;li&gt;또한 분석에 중요한 단어가 잘못 잘리면 정정 요청을 받을 수 있는데, 이를 지속적으로 유지보수하는 것은 서비스 운영에 부담이 된다. 따라서 초반에 셋팅을 잘 해놓는 것이 좋다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;how--사용자-사전에-단어-추가는-어떻게-할-수-있나&quot;&gt;HOW | 사용자 사전에 단어 추가는 어떻게 할 수 있나?&lt;/h4&gt;

&lt;p&gt;형태소 분석기에 따라 조금씩 차이는 있지만, 전체적인 순서는 아래와 같다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;사용자 사전 파일을 생성하거나, 이미 만들어져 있는 파일에 접근한다.&lt;/li&gt;
  &lt;li&gt;원하는 단어를 추가한다.
    &lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;카카오톡 [탭문자] NNP
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;파일을 저장한 뒤, 압축하여 다시 jar 파일로 만들거나 컴파일한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;형태소분석기별-비교&quot;&gt;형태소분석기별 비교&lt;/h4&gt;

&lt;p&gt;다음은 Konlpy 패키지가 지원하는 형태소분석기별로 사용자 사전에 대해 찾아본 내용이다.&lt;/p&gt;

&lt;p&gt;&lt;b&gt; Komoran &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;초보자도 가장 쉽고 간편하게 적용해볼 수 있는 편이다. 사용자 사전에 단어를 추가하는 방법은 아래와 같다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;사용자 사전 파일을 만든다. (.txt 또는 .tsv)&lt;/li&gt;
  &lt;li&gt;단어를 추가한다.&lt;/li&gt;
  &lt;li&gt;사전 파일 경로를 지정해준다.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;konlpy.tag&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Komoran&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;komoran&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Komoran&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userdic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'./my_dic.tsv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;참고한 글
    &lt;ul&gt;
      &lt;li&gt;Konlpy : https://ktae23.tistory.com/111&lt;/li&gt;
      &lt;li&gt;Java :  (&lt;a href=&quot;https://needjarvis.tistory.com/741&quot;&gt;[NLP] 코모란(Komoran) 사용자사전 만들기&lt;/a&gt;)
&lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;사용법이 간편한 대신, 정교한 부분까지 커스터마이징하기는 어렵다.
    &lt;ul&gt;
      &lt;li&gt;형태소분석기가 사전을 참고할 때의 우선순위를 직접 설정하여 조정할 수 없다. (Mecab과 달리)&lt;/li&gt;
      &lt;li&gt;공식 문서에 따르면 아래와 같다.
        &lt;ul&gt;
          &lt;li&gt;매뉴얼 : “문장 내에서 사용자 사전에 포함된 단어가 출현하면 사용자 사전에 정의된 품사를 우선적으로 갖게 됩니다.” (https://komorandocs.readthedocs.io/ko/latest/manual/manual.html)&lt;/li&gt;
          &lt;li&gt;FAQ : “setUserDic은 사용자 사전을 형태소 분석기에 로드하는 메소드입니다. 사용자 사전에 포함된 단어들은 형태소 분석 단계에서 가장 높은 우선 순위를 갖습니다. 사이드 이펙트가 발생할 수 있으니 주의하여 사용해야 합니다.” (https://komorandocs.readthedocs.io/ko/latest/faq/faq.html)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt; Okt (Open Korea Text) &lt;/b&gt;&lt;/p&gt;

&lt;p&gt;지난 번 글을 쓸 당시에는 okt의 사용자 사전 등록 방법을 찾지 못했었는데, 이후 검색을 통해 발견했다.
전체적인 순서는 아래와 같이 Komoran보다 조금 더 손이 가는 편이다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;jar 파일을 찾아서 임시 폴더에 압축을 푼다.&lt;/li&gt;
  &lt;li&gt;사전 파일을 열어 단어를 추가한다.&lt;/li&gt;
  &lt;li&gt;다시 jar 파일로 압축해 준다.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;참고한 글
    &lt;ul&gt;
      &lt;li&gt;KoNLPy 사용자 사전 추가 : https://sirzzang.github.io/ai/AI-konlpy-userdic/&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt; Mecab &lt;/b&gt;
윈도우 환경에서는 설치할 때와 마찬가지로 사전에 단어를 추가하는 과정도 복잡한 편이다. 하지만 다행히 현 시점에 구글링해서 참고할 자료는 많다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Mecab 패키지를 설치할 때 사전도 함께 설치한다.&lt;/li&gt;
  &lt;li&gt;사전 파일을 찾아서 단어를 추가한다.&lt;/li&gt;
  &lt;li&gt;사전을 빌드한다. (윈도우의 경우 powershell에서 컴파일, C:\mecab 폴더 &amp;gt; tool 폴더 &amp;gt; add-userdic-win.ps1 실행)&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;참고한 글
    &lt;ul&gt;
      &lt;li&gt;Konlpy 공식 문서 : &lt;a href=&quot;https://bitbucket.org/eunjeon/mecab-ko-dic/src/ce04f82ab0083fb24e4e542e69d9e88a672c3325/final/user-dic/?at=master&quot;&gt;Mecab 사용자 사전 추가&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;과정이 정리된 블로그 글
        &lt;ul&gt;
          &lt;li&gt;윈도우 환경 : https://lsjsj92.tistory.com/612 (관리자 권한으로 실행해야 함)&lt;/li&gt;
          &lt;li&gt;에러가 발생하는 경우 : https://joyhong.tistory.com/128&lt;/li&gt;
          &lt;li&gt;https://tape22.tistory.com/6
&lt;br /&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;검색해 보면 윈도우 환경에서의 Mecab 설치과정에 대해 정리한 블로그 글이 많은데, 그만큼 에러와 시행착오도 많다고 볼 수 있겠다.
    &lt;ul&gt;
      &lt;li&gt;이런 경험담도 있었는데, 매우 공감이 갔다.&lt;/li&gt;
      &lt;li&gt;“….일단은 가장 기본적인 Okt모델을 사용하려고 한다. mecab이 빠르고 좋다고 했는데, 내 실력부족인지 윈도우환경에서는 사용자단어를 추가하는게 너무 힘들었다.” (&lt;a href=&quot;https://haystar.tistory.com/11&quot;&gt;참고&lt;/a&gt;)&lt;/li&gt;
      &lt;li&gt;(내 경우 Konlpy 설치/JDK 연결에 어려움을 겪어서 버전을 맞추는 것으로 겨우 성공했는데, Mecab 사전을 설치하고 Wheel로 연결하려 하니 다시 낮은 버전의 python이 필요해서 한번 좌절했었다. 결국 가상환경을 설정해 어찌어찌 쓰고 있지만, 개발 지식이 얕은 입장에선 쉽지 않은 과정이었고 아직 안개 속을 헤매는 심정이다.)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;그럼에도 Mecab 사전의 장점은 가장 정교하게 커스터마이징할 수 있다는 것이다.
    &lt;ul&gt;
      &lt;li&gt;기존 사전의 단어와 새로 등록한 사용자 사전의 단어 중 어떤 것을 우선 고려할 것인지, 단어비용으로 가중치를 부여해 조정할 수 있다.&lt;/li&gt;
      &lt;li&gt;(Komoran은 위에 언급했듯이 항상 사용자 사전의 품사가 우선적으로 적용된다)&lt;/li&gt;
      &lt;li&gt;다만 형태소분석기를 처음 사용하는 입장에서는 조금 복잡하게 느껴질 수 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;그-외-참고할-링크&quot;&gt;그 외 참고할 링크&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;아래 Konlpy 공식 문서 페이지에 Mecab, Kkma, Hannanum의 시스템 사전에 대한 내용이 나와 있다.
    &lt;ul&gt;
      &lt;li&gt;https://konlpy.org/ko/latest/data/#mecab-system-dictionary&lt;/li&gt;
      &lt;li&gt;그러나 사용자 사전을 편집하는 방법은 Mecab만 링크가 연결되어 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;잘 정리된 Mecab 설치 방법 : https://lsjsj92.tistory.com/612&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;형태소분석기에 대해 처음 공부하기 시작했을 때는 막연하게 구글링을 시작했는데, 전체적인 개념이 좀 잡히고 나니 공식문서를 보면서 많은 걸 배울 수 있었다. 왜 공식문서로 공부하라는 건지 알 것 같다.&lt;/li&gt;
  &lt;li&gt;글을 정리하는 과정에서 kiwi라는 형태소분석기에 대해 자세히 찾아보게 되었는데, 코퍼스로부터 미등록단어를 추출/자동 등록하는 기능을 지원한다고 한다. 사용자 사전의 꾸준한 업데이트와 단어 추가 자동화를 염두에 둔 기능인 것 같다. &lt;a href=&quot;https://bab2min.tistory.com/609&quot;&gt;이 글&lt;/a&gt;을 읽으며 그 매력에 푹 빠져버렸는데 다음에는 이 부분도 공부하고 정리해봐야겠다.&lt;/li&gt;
  &lt;li&gt;Okt는 단어비용(가중치) 조정이 가능한지 아직 찾아내지 못했는데, Twitter에서 Okt로 넘어오면서 자리잡은 Github 페이지에는 관련 내용을 찾을 수가 없었다. 유지보수가 계속되지는 않는 것 같아서 안타깝다. (Okt 히스토리 https://needjarvis.tistory.com/645)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;font color=&quot;grey&quot; size=&quot;2px&quot;&gt;
위 형태소분석기들을 저도 이제 알아나가는 중이므로 내용에 부족한 부분이 있을 수 있습니다. 피드백 주시면 보완하겠습니다.&lt;br /&gt;
조사한 것을 정리하고 경험한 것을 남겨봅니다. 배우기 위해 씁니다. &lt;/font&gt;
</description>
        <pubDate>Thu, 15 Sep 2022 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/text%20analysis/2022/09/15/text-analysis-user-dictionary.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/text%20analysis/2022/09/15/text-analysis-user-dictionary.html</guid>
        
        
        <category>Text Analysis</category>
        
      </item>
    
      <item>
        <title>한국어 형태소분석기를 비교하는 기준</title>
        <description>&lt;p&gt;지난 글(&lt;a href=&quot;https://jessymin.github.io/text%20analysis/2022/08/07/realworld-problem-on-text-analysis-service.html&quot;&gt;텍스트 분석의 현실적인 문제들&lt;/a&gt;)에 이어서 이번에는 텍스트 분석의 전처리 및 단어 추출을 위해 필요한 형태소분석기에 대해 살펴보려 한다.&lt;/p&gt;

&lt;p&gt;지난 글 :&lt;/p&gt;

&lt;h3 id=&quot;motivation&quot;&gt;Motivation&lt;/h3&gt;

&lt;p&gt;진행 중인 프로젝트에서 전처리 과정을 셋팅할 때 어떤 형태소분석기를 적용해야 할지 고민 중이고, 9월 중에는 결정을 해야 하는 상황이다.&lt;/p&gt;

&lt;p&gt;처리 속도와 같은 기술적인 관점에서의 검토는 개발자 분들의 조언을 얻을 예정이다. 하지만 데이터의 특징과 분석 목적에 맞는 형태소분석기를 정하려고 하니, 각각을 사용해보고 검토하는 과정이 필요할 것 같다.&lt;/p&gt;

&lt;p&gt;실제로 예시 문장/단어를 넣고 형태소분석 결과를 비교하기에 앞서, 형태소분석기를 비교하는 기준들에 대해 정리해보았다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;why--형태소분석기-왜-필요한가&quot;&gt;WHY | 형태소분석기, 왜 필요한가?&lt;/h4&gt;

&lt;p&gt;텍스트 분석을 할 때는 우선 기초적인 집계를 위해 단어 추출을 하게 된다. 그리고 이 단어를 빈도 순으로 집계한 랭킹 테이블, 워드 클라우드 등이 흔히 시각화로 쓰인다.&lt;/p&gt;

&lt;p&gt;따라서 최소한의 의미 단위로 자르는 작업이 필요한데, 이 파싱(parsing) 작업은 단순히 띄어쓰기로 할 수가 없다. 
자연어는 아래와 같은 복잡한 특징을 가지고 있기 때문이다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;동사/부사/형용사에 어미 변화가 있다. 즉 어간(stem)과 어미로 구성되어 있다.&lt;/li&gt;
  &lt;li&gt;한국어는 조사가 붙는 형태의 교착어이다. (ex. 소식/명사 + 이/조사)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그래서 의미를 고려한 형태소분석기가 기본적으로 필요하게 된다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;what--한국어-형태소분석기-어떤-것들이-있나&quot;&gt;WHAT | 한국어 형태소분석기, 어떤 것들이 있나?&lt;/h4&gt;
&lt;p&gt;‘한국어 형태소분석기 비교’로 구글링하면 많은 글들을 찾아볼 수 있다. python을 이용한 텍스트 분석에 관심을 가지면 한번쯤 접해봤을 konlpy 라이브러리를 이용하는 방법들이다.&lt;/p&gt;

&lt;p&gt;하지만 나는 3년 전에 데이터 분석 관련 수업을 들을 때도 꼬박 반나절을 설치 문제로 고생해야 했고, 이번에도 몇 번을 설치하고 갈아엎는 시행착오를 겪어야 했다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;대부분의 형태소분석기들은 Java 등 다른 언어로 만들어져 있고,&lt;/li&gt;
  &lt;li&gt;이를 python으로 사용할 수 있게 감싸놓은 것이 konlpy 라이브러리이며,&lt;/li&gt;
  &lt;li&gt;Java와 konlpy 라이브러리를 연결하는 패키지를 설치하는 등&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;비개발자가 맞닥뜨리면 당황할 만한 수많은 오류들을 접하게 되었기 때문이다.&lt;/p&gt;

&lt;p&gt;따라서 이 글에서는 python을 이용한다는 전제 하에, 초보자도 접근할 수 있는지 설치 용이성 관점에서 3 그룹으로 분류해보려고 한다. (konlpy 설치는 다른 좋은 글들이 많으니 구글링해서 참조해주시기 바란다)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;1) KONLPY 패키지 설치를 통해 이용할 수 있는 형태소분석기&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;komoran (코모란)&lt;/li&gt;
  &lt;li&gt;okt (Open Korea Text, 구. 트위터 분석기)&lt;/li&gt;
  &lt;li&gt;kkma (꼬꼬마)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;2) KONLPY + 추가 설치 과정이 필요한 형태소분석기&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;mecab (구. 은전한닢 프로젝트)
    &lt;ul&gt;
      &lt;li&gt;이전 글들을 보면 Windows에서 사용할 수 없다고 되어 있으나, 최근에는 Windows에도 설치 가능하다.&lt;/li&gt;
      &lt;li&gt;검색어 ‘mecab windows 설치’로 구글링하면 관련 문서들을 쉽게 찾아볼 수 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;3) Linux에서 사용 가능한 형태소분석기&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;khaiii : 카카오 형태소분석기
    &lt;ul&gt;
      &lt;li&gt;C++로 개발되었고 리눅스에서 사용 가능하며, 2022년 8월 현재 Windows 환경을 지원하지 않는다.&lt;/li&gt;
      &lt;li&gt;Window에서 사용하려면 Cmake라는 컴파일러 설치가 필요하다.&lt;/li&gt;
      &lt;li&gt;공식 문서 : &lt;a href=&quot;https://github.com/kakao/khaiii&quot;&gt; https://github.com/kakao/khaiii&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위에서 언급한 것 외에도 다른 형태소분석기가 더 있겠지만 가장 많이 언급되고 관련 자료를 찾아보기 쉬운 것들만 정리해 보았다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;how--어떤-관점에서-비교할-것인가&quot;&gt;HOW | 어떤 관점에서 비교할 것인가?&lt;/h4&gt;

&lt;p&gt;분석할 텍스트를 갖고 혼자서 이런저런 실험을 해봐야 하는 데이터 분석가로서의 관점과, 서비스를 운영하고 유지보수해야 하는 서비스기획자의 관점이 녹아들어 있다는 점을 감안해주시기 바란다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;1. 처리 속도&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;데이터의 양이 많아지더라도 빠르게 처리할 수 있는가?&lt;/li&gt;
  &lt;li&gt;이를 분석한 관련 글들이 많으므로, konlpy 패키지 중에는 okt, komoran, mecab의 성능이 좋은 편이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;2. 설치 접근성&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;내 분석환경에서 설치가 가능한가? (Windows)&lt;/li&gt;
  &lt;li&gt;내 개발 지식/경험으로 덜 고생하고 설치/사용이 가능한가? (특히 mecab)&lt;/li&gt;
  &lt;li&gt;서비스 운영환경에 설치/운영이 가능한가? (Windows/Linux)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;3. 사용자 사전 관리 편리성&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;잘못 잘리는 복합명사/고유명사 관리를 위해 사용자 사전이 필요하다.
    &lt;ul&gt;
      &lt;li&gt;예를 들어 ‘카카오톡’이 하나의 명사로 인식되지 않고 ‘카카오’와 ‘톡’으로 잘리는 현상&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;사용자 사전을 지원하는가?
    &lt;ul&gt;
      &lt;li&gt;지원하는지 여부를 각 형태소분석기별로 확인하는 것 자체가 어려웠다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;사용자 사전 관리가 쉽고 편리한가?
    &lt;ul&gt;
      &lt;li&gt;사전에 단어를 등록하는 과정이 편리한지&lt;/li&gt;
      &lt;li&gt;다른 경로를 통해 확보된 단어를 자동 등록하도록 셋팅하는 게 용이한지&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;다음은 형태소분석기별로 사용자 사전에 대해 조사해본 내용이다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;mecab
    &lt;ul&gt;
      &lt;li&gt;현 시점에 구글링해서 참고할 자료가 가장 많다.&lt;/li&gt;
      &lt;li&gt;다만 설치과정과 마찬가지로, 사용자 사전 등록 과정도 비교적 복잡하다.&lt;/li&gt;
      &lt;li&gt;1)사전에 단어를 등록하고, 2)사전을 빌드하는 단계를 거치게 된다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;komoran :
    &lt;ul&gt;
      &lt;li&gt;사용자 사전 관리가 쉽고 간편하다.
        &lt;ul&gt;
          &lt;li&gt;python 코드 앞쪽에 사전 파일을 참고하도록 한 줄만 넣어주면 된다.&lt;/li&gt;
          &lt;li&gt;사전 파일은 txt로 ‘단어’,’품사’만 지정해주면 된다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;간편한 대신, 적용 우선순위 등 정교한 부분은 설정할 수 없는 것으로 보인다.&lt;/li&gt;
      &lt;li&gt;이 글에서 사용법을 확인할 수 있다. (&lt;a href=&quot;https://needjarvis.tistory.com/741&quot;&gt;[NLP] 코모란(Komoran) 사용자사전 만들기&lt;/a&gt;)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;okt
    &lt;ul&gt;
      &lt;li&gt;사용자 사전에 등록/관리하는 방법을 찾지 못했다. (알고 계시면 정정 부탁드립니다)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;4. 형태소 분석 성능&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;형태소 분석기의 본질적인 성능을 비교하는 부분이다.&lt;/li&gt;
  &lt;li&gt;데이터의 특징과, 분석 목적이 고려되어야 한다.
    &lt;ul&gt;
      &lt;li&gt;데이터의 특성 : 뉴스기사 등 장 정제된 문어체 vs. SNS 등 띄어쓰기 파괴, 신조어 등이 많은 구어체&lt;/li&gt;
      &lt;li&gt;따라서 정량적인 비교보다는 정성적인 비교 측면도 강하고, 사람에 따라 생각이 다를 수 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;조사를 통해 어떤 항목들을 비교해야 하는지 파악해가는 중이다.
    &lt;ul&gt;
      &lt;li&gt;지금까지 읽었던 글 중 가장 좋은 글 : &lt;a href=&quot;https://bab2min.tistory.com/672&quot;&gt;형태소 분석기의 모호성 해소 성능을 평가해보자&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;형태소분석기가 잘 헷갈려 하는 형태소 분류 : 동사-형용사 구분, 명사를 명사+조사로 분류하는 경우(종이 -&amp;gt; 종 / 이) 등&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;4번의 본격적인 비교는 다음 글에 이어서 하려 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;형태소분석기에 대해 공부하면서 느낀 점은, 표면적으로 가볍게 비교한 글은 많지만 데이터의 특징과 각 형태소분석기의 분석 원리까지 고려해서 깊이 다룬 자료는 적다는 점이었다. 글 쓰신 분의 내공이 깊다고 느껴지는 블로그는 차근차근 아카이브해놓고, 블로그 내의 글들을 차근차근 읽으며 공부하는 과정이 필요할 것 같다.&lt;/li&gt;
  &lt;li&gt;카카오는 khaiii를 오픈소스로 공개했는데, 네이버는 왜 공개하지 않을까? 우리가 사용하는 일반적인 오픈소스 형태소분석기 형태로 가공하는 데 공수가 들어서일지도 모르겠다. 긍/부정 분류 등의 API는 많이 공개하고 있는데, 공개 여부를 결정하는 기준이 궁금하다.&lt;/li&gt;
  &lt;li&gt;구매리뷰 등 구어체 특성이 강한 데이터를 분석할 때는 카카오의 khaiii도 한번 사용해보고 싶다.&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 21 Aug 2022 03:30:00 +0000</pubDate>
        <link>http://jessymin.github.io/text%20analysis/2022/08/21/text-analysis-korean-stem-analyzers.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/text%20analysis/2022/08/21/text-analysis-korean-stem-analyzers.html</guid>
        
        
        <category>Text Analysis</category>
        
      </item>
    
      <item>
        <title>텍스트 분석의 현실적인 문제들 - 전처리, 형태소분석, 후처리</title>
        <description>&lt;p&gt;1월 말에 새로운 팀으로 이동해서 적응한지 6개월이 지났다. 하반기 새로운 서비스를 준비하면서 필요에 의해 텍스트 분석의 전처리 과정에 대해 깊이 파고드는 중이다. 
기존에 운영 중인 서비스의 텍스트 데이터 수집 - 전처리 - 분석 - 집계 - 대시보드 시각화하는 파이프라인을 그대로 따른다고 생각하면 그리 큰 일은 아니다. 하지만 실무자의 관점에서 자세히 들여다보니 고려할 부분들이 많다는 생각이 슬슬 들고 있다. 
&lt;br /&gt;
텍스트 전처리에 대해 많은 블로그 글들이 다루고 있지만, 개인적인 필요에 의해 전체적인 큰그림을 정리해보고자 한다. 진행 중인 프로젝트는 아직 기획 단계에 있으므로, 이 글은 전체 프로세스를 경험하기 전 단계의 부족함이 반영되어 있음을 감안해주시기 바란다.
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;1-전처리---클린징&quot;&gt;1. 전처리 - 클린징&lt;/h4&gt;
&lt;p&gt;수집된 데이터 중 불필요한 내용을 제거하는 과정이다.
기사의 경우 대표적인 예로 아래와 같은 내용이 포함되어 있을 수 있다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- 이메일 패턴
- 전화번호 패턴
- 기사 앞머리에 오는 매체명/기자명
  - [데일리한국 OOO 기자] 카카오가 현재 유료로 운영되고 있는 ‘챗봇’ 서비스의 이용 요금을...
- 기사 뒷머리에 붙는 내용
  - ... 상생 방안을 모색할 계획이다”고 전했다. 저작권자 © 데이터넷 무단전재 및 재배포 금지
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;2-형태소분석&quot;&gt;2. 형태소분석&lt;/h4&gt;
&lt;p&gt;전에 다른 글에서도 언급했듯 텍스트 데이터는 다른 정량적인 데이터와 달리 평균, 표준편차 등의 숫자로 깔끔하게 집계되지 않는다. 따라서 전체 내용을 효율적으로 파악하기 위해 많이 출현한 단어들의 랭킹 테이블을 1차적으로 확인할 수 있다. 이를 위해 형태소분석기를 이용해 단어를 의미 단위로 짤라서 추출하게 된다.&lt;/p&gt;

&lt;p&gt;이 키워드 랭킹 테이블을 만들려면 문서/문장 내의 단어들이 잘 뽑혀나와야 한다. 예를 들어 아래 기사 제목들은 명사만 추출해서 다음과 같은 키워드 테이블로 집계할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- 카카오, '챗봇' 서비스 무료 전환...'소상공인' 지원 강화  
- 카카오, 소상공인 돕는 카카오톡 채널 챗봇 서비스 무료 전환
- 9월부터 카카오톡 채널 '챗봇' 일반상품 이용 요금 무료 
- 카카오, 내달부터 카톡 채널 '챗봇' 일반 상품 무료 제공 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;konlpy.tag&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Okt&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;okt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Okt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;noun&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;okt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nouns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;noun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;noun_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most_common&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;noun_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[결과]
('카카오', 5)
('챗봇', 4)
('무료', 4)
('채널', 3)
('서비스', 2)
('전환', 2)
('소상', 2)
('공인', 2)
('톡', 2)
('일반', 2)
('상품', 2)
('지원', 1)
('강화', 1)
('이용', 1)
('요금', 1)
('내달', 1)
('카톡', 1)
('제공', 1)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;그런데 언어는 계속 진화하기 때문에 그 어떤 형태소분석기도 완벽하게 우리 입맛에 맞게 단어를 짤라주지는 못한다. 심지어 뉴스 기사처럼 굉장히 정형화되고, 기자가 맞춤법에 꼭 맞는 언어를 구사하는 경우에도 그렇다.&lt;/p&gt;

&lt;p&gt;위의 단어들을 살펴보면 2가지 문제가 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;2-1-잘못-짤리는-복합명사--고유명사&quot;&gt;2-1. 잘못 짤리는 복합명사 / 고유명사&lt;/h4&gt;
&lt;p&gt;먼저 기사는 4개인데 ‘카카오’는 5번 출현하고 있다. 바로 ‘카카오톡’이 하나의 명사로 인식되지 않고 ‘카카오’와 ‘톡’으로 짤렸기 때문이다. 마찬가지로 ‘소상공인’도 ‘소상’과 ‘공인’으로 짤린 것을 볼 수 있다.&lt;/p&gt;

&lt;p&gt;이렇게 형태소가 잘못 분석되는 문제 때문에 사용자 사전을 만들고 관리하게 된다. 
‘카카오톡’을 사전에 등록해 놓고 형태소 분석 과정을 거치더라도 원형을 보존해  ‘카카오톡’으로 최종 표시되게끔 하는 것이다.&lt;/p&gt;

&lt;p&gt;문제는 배치(batch)성으로 한번만 데이터를 전처리하고 분석하고 끝내는 경우가 아니라, 파이프라인을 따라 지속적으로 데이터가 수집되고 처리/분석되어 사용자에게 제공되는 경우다. 문제를 발견하여 사용자 사전에 ‘카카오톡’을 등록하면 이후로 들어오는 데이터는 올바르게 처리되지만, 이전에 수집된 데이터는 이미 ‘카카오’와 ‘톡’으로 처리하여 저장된 상태다. 따라서 키워드 랭킹 테이블에는 여전히 ‘톡’이 노출되는 문제가 남아있게 된다.&lt;/p&gt;

&lt;p&gt;물론 일정 주기로 기존 데이터에 대한 재처리를 해주는 방법이 있으나, 데이터량이 방대해지면 이것도 쉬운 일은 아닐 것이다. 그래서 가급적이면, 서비스 도메인에 관련된 중요한 단어들은 초반에 파악해서 사전을 만들어두는 게 서비스 품질을 위해 필요한 부분인 것 같다. 
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;2-2-동의어&quot;&gt;2-2. 동의어&lt;/h4&gt;
&lt;p&gt;위의 키워드 목록에서 형태소가 잘못 짤리는 것 외에 또 하나의 문제가 있다. 바로 동의어가 따로 집계되는 문제다.
‘카카오톡’을 사용자 사전에 등록해 정확히 표기하게 되었더라도, 1회 출현한 ‘카톡’과는 따로 집계되고 있는 것이다.&lt;/p&gt;

&lt;p&gt;이런 경우, 실제로는 상위에 랭킹되어야 하는 키워드가 2~3개로 쪼개져 랭킹 아래쪽에 위치하는 문제가 생기게 된다.&lt;/p&gt;

&lt;p&gt;동의어는 수집된 문서를 검색할 때도 문제가 된다. 사용자가 ‘카카오톡’으로 검색했을 때, ‘카카오톡’이 아닌 ‘카톡’만으로 표현하고 있는 문서는 검색이 되질 않는 것이다.&lt;/p&gt;

&lt;p&gt;따라서 서비스 흐름의 어느 시점에 어떤 방법을 써서든 동의어는 치환 처리가 되어야 한다. 가장 간단한 방법은 본문을 복제하면서 ‘카톡’을 ‘카카오톡’으로 치환하는 방법도 있겠지만, 텍스트라는 특성상 맥락을 파악하기 위해 원문의 보존은 필요하고 어떤 컬럼을 어떻게 활용할지 복합적으로 고려가 되어야 할 것이다. 이 부분은 나도 아직 실무를 통해 배워나가는 중이므로 자세한 내용은 나중에 정리할 기회가 있을 것 같다. 
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;3-후처리---불용어&quot;&gt;3. 후처리 - 불용어&lt;/h4&gt;

&lt;p&gt;위의 테이블은 명사만 뽑았기 때문에 깔끔한 편이지만, 모든 품사를 포함해 키워드 테이블을 뽑아보면 정제가 필요한 경우가 있다.&lt;/p&gt;

&lt;p&gt;아래는 기사 본문으로부터 명사를 뽑아본 것이다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;기사 : &lt;a href=&quot;http://www.dt.co.kr/contents.html?article_no=2022080202109931820001&amp;amp;ref=naver&quot;&gt; &amp;lt;카카오, 유료운영 챗봇 서비스 무료 전환&amp;gt;, 디지털타임스&lt;/a&gt;
```
(‘챗봇’, 10)
(‘카카오’, 9)
(‘서비스’, 9)
(‘상품’, 6)
(‘톡’, 5)
(‘채널’, 5)
(‘비즈니스’, 4)
(‘활용’, 4)
(‘일반’, 4)
(‘이용’, 4)
(‘무료’, 3)
(‘제공’, 3)
(‘답변’, 3)
(‘파트너’, 3)
(‘수’, 3)
(‘현재’, 2)
(‘운영’, 2)
(‘등’, 2)
(‘대화’, 2)
(‘인터페이스’, 2)
(‘이용자’, 2)
(‘개설’, 2)
(‘초과’, 2)
(‘건’, 2)
(‘부과’, 2)
(‘사업자’, 2)
…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;```
한 글자짜리 ‘수’, ‘등’, ‘건’과 같은 의존명사들이 눈에 띈다. 이러한 의존명사는 어떤 문서에서나 보편적으로 등장하며, 구체적인 의미를 전달하지 않으므로 내용 파악에 도움이 되지 않는다. 따라서 통상적으로는 2글자 이상의 키워드만 사용하는 경우가 많은 것 같다. 물론 도메인에 따라 다를 수 있으니 사전에 1글자 단어들에 대한 검토가 한번 이뤄져야 하겠지만 말이다.&lt;/p&gt;

&lt;p&gt;그 외에, 너무 보편적인 의미를 담고 있어 분석에 도움이 되지 않는다면 불용어 사전 (stop-word dictionary)을 만들어 등록해두게 된다. 
위 내용에서 ‘현재’, ‘이용자’ 등이 해당될 수 있겠다. 물론 이 부분은 상당 부분 주관이 개입하는 부분이고 도메인에 따라서, 담당자의 관점에 따라서도 달라질 수 있으니 여러 명의 상호 체크가 필요하다고 생각된다. 
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;p&gt;텍스트 분석의 전처리/후처리 관련하여 더 많은 내용이 있을텐데 급하게 글을 작성하느라 디테일한 부분들을 다 아우르지는 못한 것 같다. 하지만 큰그림을 그리고자 했던 목표에 맞게 꼭 필요한 부분들은 정리를 해 보았다. 실제 서비스 운영에서는 품질을 무한히 올릴 수 있는게 아니라 운영 효율과 비용도 고려해야 하므로 더 디테일한 부분들이 고민되어야 할 것이다. 9월부터는 본격적으로 전처리나 사전 구축을 시작하게 될 것 같은데, 세부적인 부분들에서 많이 배울 수 있기를 기대한다.&lt;/p&gt;

</description>
        <pubDate>Sun, 07 Aug 2022 08:30:00 +0000</pubDate>
        <link>http://jessymin.github.io/text%20analysis/2022/08/07/realworld-problem-on-text-analysis-service.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/text%20analysis/2022/08/07/realworld-problem-on-text-analysis-service.html</guid>
        
        
        <category>Text Analysis</category>
        
      </item>
    
      <item>
        <title>그래프 DB란? 개요와 특징, 관계형DB와의 차이점</title>
        <description>&lt;p&gt;곧 시작하게 될 회사 프로젝트에서 텍스트 데이터를 지식 그래프(Graph Knowledge) 형식으로 시각화하는 방법을 검토해볼 일이 생겼다. 이걸 하려면 그래프 DB로 구현해야 한다는데, 관련해서 개인적으로 몇 가지 궁금한 점이 생겼다. 연관 키워드를 분석하는 시각화는 텍스트 분석 서비스들에서 종종 보이던데, 이걸 하는데에 꼭 그래프 DB를 이용해야 하나? 아니면 그래프 DB를 적용하면 기존에 불가능했던 어떤 점들이 가능해지는 건가?
&lt;br /&gt;
아직 급한 일은 아니지만 미리 공부해두면 나쁘진 않을 것 같아서 그래프 DB에 대해 찾아보았다. 아래의 궁금증이 가장 컸는데, 일부는 해결된 것도 있고 아직 더 살펴보아야 하는 것들도 있다. 그래도 기록 차원에서 남겨둔다.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;motivation&quot;&gt;Motivation&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;그래프 DB를 왜 써야 하는가? 이걸 쓰면 기존의 RDB(관계형 DB)와 다르게 무엇을 할 수 있게 되나? 어떤 점이 더 좋은가?&lt;/li&gt;
  &lt;li&gt;Knowledge Graph 형식의 시각화는 RDB로는 구현할 수 없나? 일부 구현한 사례가 있어 보이던데, 한계점은? (구현 측면, 활용 측면)&lt;/li&gt;
  &lt;li&gt;실제로 데이터는 어떤 형식으로 저장하게 되나? 수집한 데이터를 RDB로 먼저 적재해 놓는다면, 어떻게 준비해두어야 그래프 DB로 옮겨가기에 수월한가? 또는 네트워크 시각화를 하기에 용이한가?
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;what--그래프-db란&quot;&gt;WHAT | 그래프 DB란?&lt;/h4&gt;
&lt;p&gt;아래 내용은 DataCamp의 &lt;a href=&quot;https://app.datacamp.com/learn/courses/nosql-concepts&quot;&gt;NoSQL Concepts&lt;/a&gt; 코스의 4챕터 ‘Graph Databases’를 참고해 정리하였다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Graph DB란 무엇인가?
    &lt;ul&gt;
      &lt;li&gt;네트워크를 점과 선으로 연결하는 방식으로 저장하는 DB이다.&lt;/li&gt;
      &lt;li&gt;각각의 데이터뿐만 아니라 데이터 간의 관계도 똑같이 중요하게 다루기 위해 고안되었다.
        &lt;ul&gt;
          &lt;li&gt;수학의 Graph 이론에 근거하고 있으며, &lt;a href=&quot;https://rastalion.me/graph-db-%EA%B7%B8%EB%9E%98%ED%94%84-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4/&quot;&gt;이 글&lt;/a&gt;에 수학적 기원이 잘 정리되어 있음.&lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;구성 요소는 노드(Node, 또는 vertice)와 엣지(Edge, 또는 link, arc)로 구성된다.
    &lt;ul&gt;
      &lt;li&gt;노드는 entity를 뜻한다. 서울, 대전, 대구, 부산 등 각각의 도시는 노드가 될 수 있다.&lt;/li&gt;
      &lt;li&gt;엣지는 각 노드를 연결하고 노드 간의 관계를 정의한다. 서울과 부산을 오가는 항공편의 경로는 엣지가 될 수 있다.
        &lt;ul&gt;
          &lt;li&gt;또한 엣지는 property를 가질 수 있는데, 예를 들어 쿠팡과 우리집 사이에 배송이 이루어졌다면 이것은 구매일수도, 환불일수도 있다.&lt;/li&gt;
          &lt;li&gt;엣지에는 directed / undirected의 2종류가 있다. 
&lt;br /&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;삼성SDS 블로그에 실린 아래 이미지의 ‘Performance’ 부분을 보고 RBD와의 차이점을 이해할 수 있었다. &lt;br /&gt;
    &lt;ul&gt;
      &lt;li&gt;출처 : &lt;a href=&quot;https://www.samsungsds.com/kr/insights/techtoolkit_2021_knowledge_graph.html&quot;&gt;세상 모든 것들의 연결고리, 지식 그래프 안에 있습니다&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;image src=&quot;/assets/images/220724_knowledge_graph_img2.jpg&quot;&gt;&lt;br /&gt;&lt;br /&gt;
    

&lt;/image&gt;
  &lt;/li&gt;
  &lt;li&gt;저장 방식
    &lt;ul&gt;
      &lt;li&gt;모든 데이터를 하나의 큰 저장소에 저장한다. 즉, RBD처럼 여러 개의 테이블로 쪼개놓지 않는다.
        &lt;ul&gt;
          &lt;li&gt;RBD에서 10개 이상의 테이블을 조인하면 성능저하가 발생하지만, 그래프DB는 복잡한 연산도 효율적으로 가능&lt;/li&gt;
          &lt;li&gt;index free adjacency&lt;/li&gt;
          &lt;li&gt;고정된 스키마가 없어 스키마를 유연하게 변경할 수 있다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;검색을 고도화할 수 있다.
        &lt;ul&gt;
          &lt;li&gt;인덱스 조회 문제나 테이블 조인 문제를 해결할 수 있다고 한다. (참고 : &lt;a href=&quot;https://joey2the.tistory.com/m/80&quot;&gt;Google Cloud Database Week - Day 2&lt;/a&gt;)&lt;/li&gt;
          &lt;li&gt;시작점을 정한 뒤 연결만 따라가면 되기 때문이다. 
&lt;br /&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;쿼리 방식
    &lt;ul&gt;
      &lt;li&gt;Cyper, Gremlin 등 그래프에 특화된 쿼리 언어를 사용한다.
        &lt;ul&gt;
          &lt;li&gt;예) 두 개의 키워드를 포함한 뉴스 기사를 검색하고자 할 때&lt;/li&gt;
          &lt;li&gt;(:Keyword)&amp;lt;-[:Include]-(:Article)-[:Include]-&amp;gt;(:Keyword)
&lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;그래프-db의-장점한계점&quot;&gt;그래프 DB의 장점/한계점&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;어떤 때 사용하면 좋은가?
    &lt;ul&gt;
      &lt;li&gt;데이터 간의 연결이 매우 많을 때 사용하면 좋다.
        &lt;ul&gt;
          &lt;li&gt;예를 들어 소셜 네트워크, COVID-19와 같은 질병의 감염경로를 모델링할 때 등&lt;/li&gt;
          &lt;li&gt;장소와 거리를 표현할 수도 있다. 내비게이션 경로 찾기나 가까운 식당, 영화관, 병원을 추천해줄 때 등&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;추천시스템 구현에 용이하다.&lt;/li&gt;
      &lt;li&gt;실시간으로 이상 탐지(Fraud detection)가 필요할 때. 카드 사용 패턴, 여러명이 같은 IP 주소로 접속하는 것을 감지할 때 등
&lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;사용이 적절하지 않은 경우
    &lt;ul&gt;
      &lt;li&gt;일반적인 검색만 수행하는 애플리케이션에는 적절하지 않다. 특정한 시작점이 없이 전체 DB를 검색해야 하는 경우.&lt;/li&gt;
      &lt;li&gt;entity property가 극도로 큰 값을 가진 경우.
        &lt;ul&gt;
          &lt;li&gt;예를 들어 BLOB(Binary Large Object, 멀티미디어 데이터를 다룰 때 사용), CLOB(Charset Large Object, 매우 긴 문자열데이터)
&lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;how--사용해보려면-어떻게-해야-하나&quot;&gt;HOW | 사용해보려면 어떻게 해야 하나?&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;대표적인 Graph DB 업체인 Neo4j를 살펴보는 게 좋을 것 같다. (참고기사 : &lt;a href=&quot;https://byline.network/2021/06/22-129/&quot;&gt;그래프 DB가 뭐길래… Neo4j, 기업가치 2조원(2021.6)&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;제공 솔루션들
    &lt;ul&gt;
      &lt;li&gt;Neo4j Sandbox : 임시로 사용 가능한 클라우드 서비스. 생성 후 3일간 유지된다. (&lt;a href=&quot;https://pizzathief.oopy.io/graphdb-neo4j-introduction&quot;&gt;참조&lt;/a&gt;&amp;gt;)&lt;/li&gt;
      &lt;li&gt;Neo4j Desktop, Enterprise Server, Community Server 중에서 다운받아 사용할 수 있다.
        &lt;ul&gt;
          &lt;li&gt;Neo4j Desktop : 셋업 방법을 보니 나같은 분석가/기획자가 써보기에는 DB연결에 어려려워 보이는데, 한번 해봐야 알 수 있을 것 같다. 다음 과제로 남겨둔다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Neo4j Bloom : 시각화 툴. 일단 써보고 싶었는데, 공식 문서를 보니 Enterprise 계정이 있어야 하는 듯 하다. (&lt;a href=&quot; https://neo4j.com/docs/bloom-user-guide/current/bloom-quick-start/&quot;&gt;Bloom Quick Start&lt;/a&gt;)&lt;/li&gt;
      &lt;li&gt;Neo4j Aura : 클라우드 DB 서비스이며, Google Cloud에 연결할 수 있다. (&lt;a href=&quot;https://joey2the.tistory.com/m/80&quot;&gt;참고 : Google Cloud Database Week - Day 2&lt;/a&gt;)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;결론 : 나는 간단히 구조만 파악해보고 싶은데, 우선은 Desktop을 설치해서 해봐야겠다. 
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;그래프-db를-도입하지-않고-rdb를-바탕으로-지식-그래프를-구현할-수는-없나&quot;&gt;그래프 DB를 도입하지 않고, RDB를 바탕으로 지식 그래프를 구현할 수는 없나?&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;‘네트워크 시각화’로 검색해보았다. python의 networkx 라이브러리로도 네트워크 시각화는 가능하다. 그 외에 시각화 가능한 JavaScript 라이브러리들이 몇몇 있다.&lt;/li&gt;
  &lt;li&gt;실제로도 웹서비스로 제공되는 텍스트 분석 솔루션 중 썸트렌즈, 빅카인즈 등이 연관어 분석을 제공한다.
    &lt;ul&gt;
      &lt;li&gt;다만, 서로 비교할 검색어를 최대 3개까지만 입력할 수 있게 되어 있다.&lt;/li&gt;
      &lt;li&gt;성능 때문이던 구조 때문이던 유연하게 제공할 수 없는게 Graph DB와 RDB 기반으로 구현했을 때의 차이점인 것 같다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;결론 : 못하는 건 아니지만, 한계가 있어 보인다. 
&lt;br /&gt;
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;다음 스텝으로는 일단 Neo4j Desktop을 설치해서 써봐야겠다.
    &lt;ul&gt;
      &lt;li&gt;의외로 네이버에서 검색해보니 친절하게 정리해둔 블로그들이 꽤 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;비정형데이터, 특히 텍스트 데이터 분석에 활용한 케이스를 살펴보고 싶다.
    &lt;ul&gt;
      &lt;li&gt;Google Cloud Platform 관련 세미나에서는 비정형 데이터 분석에 유리하다고 발표했던데, 한두번 시도가 아닌 상용화된 사례가 있는지 알고 싶다.&lt;/li&gt;
      &lt;li&gt;https://neo4j.com/case-studies/&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이 조사를 하는 동안 알게 되었는데, GraphQL은 그래프 DB와는 상관없는 프론트엔드 쪽 기술이었다.. 
&lt;br /&gt; 
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;키워드 : graph dB, graph visualizations, Neo4j 
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;참고-글&quot;&gt;참고 글&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;DataCamep, &lt;a href=&quot;https://app.datacamp.com/learn/courses/nosql-concepts&quot;&gt;NoSQL Concepts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.samsungsds.com/kr/insights/techtoolkit_2021_knowledge_graph.html&quot;&gt;세상 모든 것들의 연결고리, 지식 그래프 안에 있습니다&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://rastalion.me/graph-db-%EA%B7%B8%EB%9E%98%ED%94%84-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4/&quot;&gt;Graph DB? 그래프 데이터베이스&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://slownews.kr/82043&quot;&gt;그래프 데이터베이스, 시장 현황과 분석 (2021.9, 슬로우 뉴스)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Neo4j 설치방법 총정리: https://blog.naver.com/kgh9080/222771221790&lt;/li&gt;
  &lt;li&gt;Neo4j 로컬 DBMS 만들기 https://blog.naver.com/kgh9080/222772603268&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 24 Jul 2022 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/text%20analysis/2022/07/24/graph-db-overview.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/text%20analysis/2022/07/24/graph-db-overview.html</guid>
        
        
        <category>Text Analysis</category>
        
      </item>
    
      <item>
        <title>텍스트 요약, 활용 목적에 따라 유형별로 분류해보기</title>
        <description>&lt;p&gt;텍스트 분석에서 요약은 어렵고도 중요한 문제 중의 하나다. 숫자로 된 데이터는 평균, 중앙값, 최빈값, 표준편차, 4분위수 등 다양한 방법을 통해 전체적인 경향을 파악할 수 있는 반면, 다양한 의미를 담은 문서와 문장들의 내용을 단시간에 파악할 수 있도록 압축하기가 난해하기 때문이다.&lt;/p&gt;

&lt;p&gt;얼마 전, 토픽 모델링을 통한 문서 요약 서비스를 기획하는 회의에 참석할 일이 있었다. 그런데 의논을 하다 보니, 요약에도 여러 종류가 있는데 각자 서로 다른 생각을 하면서 논의가 진척되지 않는다는 느낌이 들었다. 구매리뷰로부터 일부를 추출하는 것도 요약, 방대한 양의 리뷰들을 다 읽기 어려우니 간추려주는 것도 요약이라고 지칭하고 있었기 때문이다. 이에 기술적인 방법은 둘째치고, 요약의 대상이 되는 텍스트/문서의 유형별로 적합한 요약 방식 자체를 살펴보고 관점을 정리해봐야겠다는 생각이 들었다.&lt;/p&gt;

&lt;p&gt;우선은 유형을 분류하고 현재 상용화되었거나 서비스 초기에 있는 사례들을 찾아보았다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;접근-관점&quot;&gt;접근 관점&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;요약 대상
    &lt;ul&gt;
      &lt;li&gt;단일한 문서(ex. 뉴스 기사)&lt;/li&gt;
      &lt;li&gt;다수 개의 문서(ex. 뉴스 기사들, 구매 리뷰들)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;요약 방식
    &lt;ul&gt;
      &lt;li&gt;원문에서 일부를 추출하는 요약&lt;/li&gt;
      &lt;li&gt;추출한 내용을 merge해 새로운 텍스트를 생성하는 요약&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;1-단일-문서--추출-요약&quot;&gt;1. 단일 문서 / 추출 요약&lt;/h3&gt;
&lt;h4 id=&quot;뉴스-기사&quot;&gt;뉴스 기사&lt;/h4&gt;
&lt;p&gt;단일한 뉴스에서 일부를 추출해 요약문을 생성하는 방법은 가장 접근하기 쉽고 많은 시도가 이루어지는 것으로 보인다. 문서 자체가 잘 구조화되어 있기 때문이다. 요즘은 매일매일 워낙 방대한 정보가 쏟아지고 있으므로 사용자들이 간편하게 정보를 파악할 수 있게 해준다는 의의도 물론 있다. 그렇다면 뉴스 요약문의 기능은 본문을 자세히 읽지 않더라도 핵심 정보를 빠르게 파악할 수 있도록 해주는 것이 되겠다. 
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;[관련 사례]
‘텍스트 요약’으로 구글링했을 때 상위권에서 줌인터넷 &amp;amp; 연합뉴스의 &amp;lt;AI 기반 뉴스 3줄 요약 서비스 개발기&amp;gt;를 발견할 수 있었다.&lt;/p&gt;

&lt;p&gt;하지만 연합뉴스 사이트에 가서 몇몇 기사를 눌러본 결과, 뉴스의 특성상 제목을 많이 참조하도록 되어 있어 전체적인 핵심보다는 일부 내용에만 경도되는 경향도 보인다.&lt;/p&gt;

&lt;p&gt;예를 들어 &lt;a href=&quot;https://www.yna.co.kr/view/AKR20220620130151002?section=economy/all&quot;&gt;&amp;lt;국내 금융시장 또 ‘검은 월요일’…증시 연저점·환율 연고점(종합)&amp;gt;&lt;/a&gt;같이 객관적인 제목의 기사는 3줄 요약도 전체 내용을 고르게 포함했다. 하지만 &lt;a href=&quot;https://www.yna.co.kr/view/AKR20220620081000089?section=economy/all&quot;&gt;&amp;lt;’사교육 금지’로 망한 中 최대 학원, 라이브커머스 ‘벼락 인기’&amp;gt;&lt;/a&gt;와 같은 스토리성 기사는 앞쪽 문장 위주로 추출해 전체 스토리를 잘 요약하지 못하고 있다. 경제면 기사이기는 하지만 기업의 스토리를 담고 있는데, 기승전결이 잘 담기지 못하고 있다.&lt;/p&gt;

&lt;p&gt;[개인적인 의견]&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;뉴스 요약의 경우 문장을 기계적으로 추출하기 보다는, 각 문장을 5W1H 등 기사 내에서의 역할로 분류하는 과정이 먼저 적용되어야 하지 않을까 싶다.&lt;/li&gt;
  &lt;li&gt;기사를 요약한다면 가장 중요한 내용은 아래 덩어리라고 생각한다.
    &lt;ul&gt;
      &lt;li&gt;(1) what/who/when/where : 어떤 일이 벌어졌다.&lt;/li&gt;
      &lt;li&gt;(2) why : 이유는 이러하다.&lt;/li&gt;
      &lt;li&gt;(3) how : 보다 상세한 상황은 이렇게 전개되었다.&lt;/li&gt;
      &lt;li&gt;(4) what if : 앞으로 이러이러하게 될 것으로 전망된다. 
&lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-단일-문서--생성-요약&quot;&gt;2. 단일 문서 / 생성 요약&lt;/h3&gt;
&lt;p&gt;뉴스기사 요약에서도 생성요약은 활용되는 것으로 보이지만, 조금 결이 다른 분야를 나눠서 살펴보고 싶었다.&lt;/p&gt;

&lt;h4 id=&quot;이야기책&quot;&gt;이야기/책&lt;/h4&gt;
&lt;p&gt;스토리가 있는 소설 등의 줄거리를 요약하는 경우다. 이 경우의 목적은 무엇일까? 솔직히 잘 모르겠다. 아직은 사람이 요약하는 게 더 고퀄리티의 만족스런 결과를 낼 수 있고, 이 분야에서는 그게 더 중요하다고 생각되기 때문이다.  &lt;br /&gt;
다만 예전에 한창 만화책을 보던 시절에, 매권 앞부분에 있는 지난 줄거리 요약 부분이 인상깊었던 기억이 난다. 만화책 권수가 뒤로 갈수록 이야기는 방대해지는데, 그 방대한 이야기를 또 기가 막히게 요약하는 게 대단해 보이고 흥미로웠다.&lt;/p&gt;

&lt;p&gt;[관련 사례]&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&amp;lt;오픈AI, 수천 페이지 책 한번에 요약하는 AI 모델 개발… 상용화는 글쎄?&amp;gt;&lt;/li&gt;
  &lt;li&gt;소설을 요약했는데 맥락을 이해하지 못해 한계가 있다고 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[개인적인 의견]&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;과연 이야기를 요약하는 것은 어떤 의미가 있을까?
    &lt;ul&gt;
      &lt;li&gt;스토리/줄거리를 요약하는 게 상용화됐을 때 어떤 가치를 줄 수 있을까?&lt;/li&gt;
      &lt;li&gt;여가를 위한 소설이나 에세이를 굳이 요약하는 건 큰 의미가 없어 보인다. 읽는데 들이는 시간과 그 과정에서의 즐거움 자체가 목적이기 때문이다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;경제경영서는 상대적으로 수요가 더 클 것 같다.
    &lt;ul&gt;
      &lt;li&gt;내용이 잘 구조화되어 있기 때문에 요약하기 더 용이할 수 있다.&lt;/li&gt;
      &lt;li&gt;그런데 이 경우 스토리라기 보다는 메시지/근거 요약에 가깝다.&lt;/li&gt;
      &lt;li&gt;한 인물이 살아온 과정을 단시간에 파악하고 싶다면 유용할 수도 있겠다. 제프 베조스의 일생, 마윈의 인생역정 같은 내용이 될 듯. 
&lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-복수-문서--추출-요약&quot;&gt;3. 복수 문서 / 추출 요약&lt;/h3&gt;
&lt;p&gt;여러 개의 문서를 요약하는 것이다. 사람이 다 읽을 수 없을 만큼 데이터량이 많은 경우에 필요하다. 여러 문서들이 비교적 동질한 내용을 담은 경우와, 서로 다른 내용을 담은 경우로 구분할 수 있을 것이다.
&lt;br /&gt;&lt;/p&gt;

&lt;h4 id=&quot;1-다양한-내용들을-담은-경우&quot;&gt;1) 다양한 내용들을 담은 경우&lt;/h4&gt;
&lt;h4 id=&quot;쇼핑몰-리뷰-요약&quot;&gt;쇼핑몰 리뷰 요약&lt;/h4&gt;
&lt;p&gt;구매리뷰가 대표적인 분야다. 하나의 상품에 대해 고객들은 다양한 의견과 사용경험을 리뷰로 작성한다. 또한 이를 읽는 사용자도 많은 내용 중에서 궁금한 내용을 간편하게 확인하고 싶다는 니즈가 명확한 편이다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;긍정적 평가 / 부정적 평가&lt;/li&gt;
  &lt;li&gt;제품의 다양한 속성에 대한 언급 (디자인, 성능, 편의성, 유지관리 등)&lt;/li&gt;
  &lt;li&gt;제품 외 요소에 대한 언급 (문의응대, 배송, 설치과정, 서비스 등)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[관련 사례]
국내에서는 네이버 쇼핑몰 리뷰 요약이 최근에 적용된 대표적인 사례인 것 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://biz.newdaily.co.kr/site/data/html/2021/07/30/2021073000036.html&quot;&gt;네이버, ‘긴 쇼핑 리뷰 한 줄로’… ‘Ai리뷰 요약’ 선봬&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://noelle-world.tistory.com/39&quot;&gt;AI 모델 HyperCLOVER를 기반한 네이버 쇼핑 상품리뷰 요약&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;‘하나의 대표 리뷰를 보여주는 것이 아닌, 전반적인 의견을 분류 및 종합하여’ 보여주는 것이 이전과의 차이라고 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
[개인적인 의견]&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;구매리뷰를 읽는 방식은 사람마다 다를 것이다. 그에 따라 네이버 방식에 대한 만족도도 다를 수 있다.&lt;/li&gt;
  &lt;li&gt;나같은 경우는 성의없는 후기, 판매자 작업에 의한 가짜후기가 많다고 생각하기 때문에 1-2점 후기만 추려서 먼저 보는 편이다. 또 디테일한 내용을 언급한 리뷰를 신뢰하는 편이다. 그렇기 때문에 긍정/부정을 나누지 않고 전체를 요약해서 보여주는 네이버 리뷰 요약은 너무 일반적인 얘기, 뻔한들만 보여져서 큰 임팩트가 없게 느껴졌다.&lt;/li&gt;
  &lt;li&gt;하지만 이는 개인적 성향이고, 이를테면 요새 조금씩 화두가 되고 있는 A세대 (45-65세 중년 세대)에게는 큼직한 글씨로 보여지는 요약 서비스가 편의성을 크게 높여주는 요소가 될 수도 있을 것으로 보인다.
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;2-비교적-동질하지만-조금씩-다른-내용을-담은-경우&quot;&gt;2) 비교적 동질하지만 조금씩 다른 내용을 담은 경우&lt;/h4&gt;
&lt;h4 id=&quot;언론사별-뉴스-기사&quot;&gt;언론사별 뉴스 기사&lt;/h4&gt;
&lt;p&gt;여러 활용분야가 있을 수 있겠지만, 내가 생각해본 것은 한 가지 사안에 대해 다수 언론사로부터 뉴스가 생성되는 경우 이를 요약하는 것이다. 잠시 구글링해본 것으로는 사례를 찾아내지 못했지만, 관련된 시도들이 분명히 많이 있었을 거라고 생각한다. &lt;br /&gt;
앞으로의 시대에 중요하게 여겨지는 핵심역량인 4C 중 비판적 사고력(Critical Thinking)을 기르려면 한 가지 사안에 대한 상반되는 의견을 접해보고 균형잡힌 시각을 갖는 것이 필요하다. 그래서 이 분야에 텍스트 요약이 적용되면 좋을 것 같다. &lt;br /&gt;
AI를 통한 요약은 아니지만 이상적이라고 생각되는 케이스는 최근 리멤버에서 제공하는 프리미엄 컨텐츠다. 논란의 여지가 있는 사안의 경우 A 의견, 그에 반대되는 B 의견, 보다 전체적인 시각에서 바라보는 C 의견 등으로 구성하고 있어서, 그 배치에 감탄하며 읽을 때가 많다. 
단순한 사건사고 사실의 요약보다는, 그에 대한 다양한 의견의 요약이 더 유용하지는 않을까? 물론 수요로는 단순 요약이 더 볼륨이 크겠지만 말이다.&lt;/p&gt;

&lt;h4 id=&quot;마무리하며&quot;&gt;마무리하며&lt;/h4&gt;
&lt;p&gt;요약은 굉장히 어려운 분야인 것 같다. 최근 문해력이 화두가 되고 있지만 ‘문해력’이나 ‘글쓰기 능력’은 사람마다 천차만별이고 이를 척도화하기도 어렵기 때문이다.&lt;/p&gt;

&lt;p&gt;이번 조사를 하면서 좋은 글들을 몇 개 발견했다. 그 중 아래 글은 다시금 정독해볼 필요가 있어 보인다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://mediagotosa.com/nokeosnyuseuyi-gisa-haegsimyoyag-aiyi-daece-ganeungseong/&quot;&gt;노컷뉴스의 기사 ‘핵심요약’, AI의 대체 가능성은?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;“최숙기의 논문에서도 드러나듯, 전문성을 갖춘 평가 교사들에게 평가 항목을 제시했음에도 좋은 요약문을 평가하는 데 오차 범위가 제법 있었습니다.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;‘좋은 요약문’의 정의를 문자로 지정했음에도 불구하고 사람마다 생각이 달랐다는 것이다. &lt;br /&gt;
요약 모델을 만들고 평가하는 과정에서는 “문해력과 글쓰기 능력을 갖춘 이들이 작성한 ‘좋은 요약문’ 데이터 및 이를 판단하는 기준”이 필수적이지 않을까 싶다. &lt;br /&gt;
만약 법률문서의 요약 모델을 만든다면 적어도 법률 지식이 있는 사람을 모아서 학습셋을 만들 것이다. 하지만 뉴스 기사나 스토리 요약에는 일반인을 모집해서 학습셋을 만드는 것 같은데 이들의 문해력을 측정하고 비교하는 적절한 도구가 있는지, 적절히 활용되고 있는지 궁금해진다.&lt;/p&gt;
</description>
        <pubDate>Sat, 25 Jun 2022 00:00:00 +0000</pubDate>
        <link>http://jessymin.github.io/text%20analysis/2022/06/25/text-summarization-types.html</link>
        <guid isPermaLink="true">http://jessymin.github.io/text%20analysis/2022/06/25/text-summarization-types.html</guid>
        
        
        <category>Text Analysis</category>
        
      </item>
    
  </channel>
</rss>
