<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>데이터 분석 기록</title>
    <link>https://hr1588.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 22 May 2026 18:22:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>머동</managingEditor>
    <item>
      <title>[API] 어디까지 가능한 걸까?</title>
      <link>https://hr1588.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 포스팅에서 API의 정의와 원리에 대해서 정리했습니다. 혹시 API라는 개념을 처음 접해보셨다면, 해당 포스트를 읽고 오시는걸 권장드립니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1758355279765&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[API] API의 정의와 원리&quot; data-og-description=&quot;API, 어디까지 가능한 걸까?업무를 진행하다보면 종종 이런 질문을 듣습니다.&amp;quot;API로 연결하면 다 되는거 아닌가요?&amp;quot; 처음에는 저도 고객을 끄덕였는데, 생각해보면 어디까지 연결되는지, 그 연결&quot; data-og-host=&quot;hr1588.tistory.com&quot; data-og-source-url=&quot;https://hr1588.tistory.com/122&quot; data-og-url=&quot;https://hr1588.tistory.com/122&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c1jNrU/hyZI16L2Ca/Rf0bM5eP4fO9tHvdltkTEK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bgOSPt/hyZJkq5sGv/FnGFfOPJHFDv0pTQ6Fxe90/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hr1588.tistory.com/122&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hr1588.tistory.com/122&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c1jNrU/hyZI16L2Ca/Rf0bM5eP4fO9tHvdltkTEK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bgOSPt/hyZJkq5sGv/FnGFfOPJHFDv0pTQ6Fxe90/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[API] API의 정의와 원리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;API, 어디까지 가능한 걸까?업무를 진행하다보면 종종 이런 질문을 듣습니다.&quot;API로 연결하면 다 되는거 아닌가요?&quot; 처음에는 저도 고객을 끄덕였는데, 생각해보면 어디까지 연결되는지, 그 연결&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hr1588.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 이전 포스팅에 이어, API의 종류와 적용 범위에 대해 말씀드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;API의 종류 : 약속이 있어야 대화가 된다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API가 무엇인지는 이제 감이 오는데, 이러한 API도 여러가지 방식이 있습니다. 쉽게 말하자면, 대화할 때 어떤 언어를 쓸지 정하는 거죠. 예를 들어, 제가 한국어로 말하는데 상대방이 영어만 한다면 당연히 대화가 안되겠죠? API도 마찬가지입니다. 서로 데이터를 주고받을 때, 어떤 형식과 규칙으로 대화할지 정해둔 게 바로 API 규격입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;대표적인 규격들&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. REST API&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지금 웹에서 가장 많이 쓰이는 방식&lt;/li&gt;
&lt;li&gt;주소(URL)로 자원(Resource)을 표현하고, HTTP 메서드(GET,POST 등)로 행동을 정합니다.&lt;/li&gt;
&lt;li&gt;예 : /weather?city=seoul =&amp;gt; GET이면 날씨 조회, POST면 새 날씨 데이터 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. SOAP&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;XML 기반, 무겁지만 보안과 트랜잭션 기능이 탄탄해서 금융권에서 주로 사용&lt;/li&gt;
&lt;li&gt;트랜잭션(Transaction) : DB나 시스템에서 여러 작업을 하나로 묶어서 모두 성공하거나 모두 실패하게 보장하는 단위로, 은행 계좌 이체처럼 절대로 반쪽만 성공하면 안 되는 작업에서 핵심적으로 쓰이는 개념&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. GraphQL&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원하는 데이터만 골라서 가져올 수 있는 방식&lt;/li&gt;
&lt;li&gt;예 : 날씨는 기온만, 뉴스는 제목만 달라 하고 필요한 정보만 요청할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. OpenAPI (Swagger)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API 문서를 기계가 읽을 수 있는 형식으로 표준화한 것&lt;/li&gt;
&lt;li&gt;테스트 UI나 자동화된 코드 생성을 쉽게 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면, API 규격은 대화의 문법이에요. 문법이 맞아야 시스템끼리 말이 통합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;API의 권한 : 누가 쓸 수 있을까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 모든 API를 우리는 사용할 수 있을까요? 정답은 아니다 입니다. 공개 범위에 따라 API는 크게 3가지로 구분됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Private API (내부망)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기업/기관 내부에서만 사용되는 API&lt;/li&gt;
&lt;li&gt;예 : 사내 인사 시스템, 내부 전용 대시보드 등&lt;/li&gt;
&lt;li&gt;외부에 노출되면 안되는 민감한 데이터에 주로 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.&amp;nbsp;Partner&amp;nbsp;API&amp;nbsp;(제휴)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 파트너사만 접근할 수 있는 API&lt;/li&gt;
&lt;li&gt;예 : 카드사와 제휴된 쇼핑몰이 결제 API를 쓰는 경우&lt;/li&gt;
&lt;li&gt;비즈니스에서 많이 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3.&amp;nbsp;OPEN&amp;nbsp;API&amp;nbsp;(Public/공개)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;누구나 신청만 하면 쓸 수 있는 API&lt;/li&gt;
&lt;li&gt;예 : 기상청 날씨 API, 카카오맵 API, 공공데이터포탈 API&lt;/li&gt;
&lt;li&gt;이런 API 덕분에 스타트업이나 개인 개발자가 새로운 서비스를 쉽게 제작&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, API는 누가 접근할 수 있느냐에 따라 3가지로 나뉩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서&amp;nbsp;&quot;OPEN&amp;nbsp;API&quot;와&amp;nbsp;&quot;OpenAPI&quot;가&amp;nbsp;헷갈리실&amp;nbsp;수&amp;nbsp;있는데요,&amp;nbsp;두&amp;nbsp;가지는&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;맥락에서&amp;nbsp;사용됩니다. &lt;br /&gt;&lt;br /&gt;OPEN&amp;nbsp;API(공개&amp;nbsp;API)는&amp;nbsp;누구나&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;공개된&amp;nbsp;API를&amp;nbsp;의미하고,&amp;nbsp;OpenAPI(Swagger)는&amp;nbsp;API를&amp;nbsp;문서화하는&amp;nbsp;규격을&amp;nbsp;의미합니다.&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;구체적으로&amp;nbsp;말씀드리자면,&amp;nbsp;개발자들이&amp;nbsp;API를&amp;nbsp;기계가&amp;nbsp;읽을&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;형태로&amp;nbsp;정의해두면&amp;nbsp;자동으로&amp;nbsp;문서/UI/SDK&amp;nbsp;코드까지&amp;nbsp;생성할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;하는&amp;nbsp;개념입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;API, 어디까지 가능할까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종류와 규격을 살펴봤으니, 이제 본격적으로 포스팅의 핵심인 적용 범위를 같이 확인해볼까요? 이전 포스팅에서 말씀드렸듯이, API는 메뉴판에 있는 요리만 주문할 수 있다가 핵심입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무슨 말이냐면, API는 엄청 강력한 도구지만 그렇다고 무한정 모든게 다 되는 건 아니라는 겁니다. 기본적으로는 문서(API DOCS)에 정의된 기능만 쓸 수 있어요. 예를 들어, 김치찌개 집에 가서 메뉴판에 있는 김치찌개는 주문할 수 있지만, 메뉴판에 없는 닭발은 주문할 수가 없는 거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇지만, 만약 닭발과 관련된 주문 문의가 계속 들어온다면 주방에서도 메뉴 개발을 고민하겠죠. API 개발도 동일한 원리입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;메뉴판에 있는 것 : API로 가능한 영역&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 데이터 조회&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API로 제일 많이 하는 게 데이터 조회입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;날씨 앱이 기상청 API에서 &quot;서울 날씨&quot;를 불러오는 것&lt;/li&gt;
&lt;li&gt;주식 앱이 한국거래소 API로 삼성전자 현재가를 가져오는 것&lt;/li&gt;
&lt;li&gt;뉴스 앱이 특정 키워드에 맞는 기사 목록을 불러오는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약하면 있는 데이터를 읽어오기가 API의 특기라고 생각하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 기능 실행&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 조회를 넘어, 실제 행동도 가능합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카카오에서 로그인 버튼을 누르면 카카오 API가 인증을 처리하고, 토큰을 발급해주죠.&lt;/li&gt;
&lt;li&gt;결제 API를 호출하면 카드사 서버에서 결제 승인을 내려줍니다.&lt;/li&gt;
&lt;li&gt;뉴스 앱이 특정 키워드에 맞는 기사 목록을 불러오는 것도 가능하죠.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 데이터를 보는게 아니라, 시스템을 움직이는 역할을 수행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 서비스 확장&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 직접 만들기 부담스러운 기능을 외부 API로 끌어올 수도 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지도 API를 붙이면 내 앱에서 바로 길찾기가 됩니다.&lt;/li&gt;
&lt;li&gt;번역 API를 붙이면 내가 번역기를 따로 만들 필요가 없죠.&lt;/li&gt;
&lt;li&gt;요즘은 이미지 분석, 챗봇, OCR과 같은 기능도 API로 손쉽게 붙입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프리랜서 혹은 스타트업이 빠르게 서비스를 확장할 때 주로 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;메뉴판에 없는 것 : API로 불가능한 영역&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 못하는 건 뭘까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 없는 건 못 한다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;날씨 API는 현재 날씨와 예보를 알려줄 수 있습니다. 하지만, &quot;내일 비가 오게 해주세요&quot;와 같은 요청은 API가 못하죠. API는 정보를 불러오거나 기능을 실행하는 창구이지, 세상을 바꾸는 마법이 아니거든요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 권한 밖은 못 본다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 API의 권한에 대해 말씀드렸죠? 설령 API가 있더라도, 권한이 없으면 접근할 수 없습니다. 보편적으로 API는 사용자별로 고유한 Secret Key를 발급하는데, 내부 직원 전용 API를 외부 고객이 호출하면 Unauthorized(401)과 같은 에러가 return 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 성능 및 용량의 한계&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API마다 다르지만, 보통 한 번에 가져올 수 있는 데이터 양이 제한돼 있거나 호출 횟수에 제한(LIMIT)이 걸려 있을 수 있습니다. 예를 들어, 이 API는 하루에 1만 번까지만 호출 가능과 같은 조건이 있죠. 만약 1만번을 넘어가면 서비스가 느려지거나, 호출 자체가 차단당하기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;신규 주문 : AI 챗봇과 그룹웨어 연동&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 확장의 사례를 하나 들어볼게요. 고객사에서 AI 챗봇 도입을 희망하는데, 그룹웨어를 연동하고 싶은 니즈가 있다고 가정해보죠. &quot;우리 회사 그룹웨어에 있는 일정이나 결재 현황을 챗봇에서 바로 불러올 수 없을까? 라는 요구는 실제 필드에서 자주 요구되는 주문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원리 자체는 간단합니다. 그룹웨어에서 API를 제공한다면, 챗봇이 그 API를 호출해 데이터를 가져올 수 있습니다. 예를 들어 사용자가 &quot;오늘 내 일정 알려줘&quot;라고 챗봇에 입력하면, 챗봇은 그룹웨어의 &lt;b&gt;캘린더 API&lt;/b&gt;를 호출합니다. 응답으로 돌아온 일정 데이터를 챗봇이 다른 데이터에서 가져온 정보와 함께 가공해서 사용자에게 보여주죠. 비슷하게 &quot;휴가 신청해줘&quot;라고 말했을 때, 챗봇이 그룹웨어의 &lt;b&gt;휴가 신청 API&lt;/b&gt;를 호출해 전자결재 문서를 자동으로 생성하는 것도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단,&amp;nbsp;여기에는&amp;nbsp;중요한&amp;nbsp;전제가&amp;nbsp;있습니다. &lt;br /&gt;바로 그룹웨어가 공식적으로 API를 제공해야 한다는 것이죠. 말씀드렸듯이, 메뉴판에 &quot;캘린더&quot;라는 항목이나 &quot;휴가 신청&quot;이라는 항목이 없는데 주문할 수는 없습니다. &lt;br /&gt;&lt;br /&gt;또한, 설령 메뉴판이 있다고 해도 몇 가지 확인할 점이 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;권한 문제: 관리자 전용 API인지, 일반 사용자도 호출 가능한 API인지 구분해야 합니다.&lt;/li&gt;
&lt;li&gt;호출 한도: 하루 몇 번까지 호출 가능한지, 동시 요청 제한이 있는지 체크가 필요합니다.&lt;/li&gt;
&lt;li&gt;보안 정책: 민감한 데이터가 노출되지 않도록 토큰 인증, 암호화 방식이 제대로 적용되어 있는지 살펴야 합니다.&lt;/li&gt;
&lt;li&gt;응답 구조 차이: 그룹웨어 API가 반환하는 데이터 형식이 챗봇이 이해하는 구조와 다르면, &lt;b&gt;중간 변환 계층(어댑터)&lt;/b&gt;을 별도로 만들어서 맞춰줘야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;챗봇과 그룹웨어 연동은 단순히 &amp;ldquo;API가 있다더라&amp;rdquo;로 끝나는 게 아니라, 권한&amp;middot;한도&amp;middot;보안&amp;middot;데이터 구조까지 종합적으로 검토해야 안정적으로 돌아갑니다. 즉, &lt;b&gt;챗봇과 그룹웨어 연동은 &quot;API 메뉴판에 항목이 있느냐&quot;&lt;/b&gt;에 따라 달려 있습니다. 메뉴판에 일정/결재/메신저 API가 있다면 챗봇이 호출해 바로 연동할 수 있고, 없는 기능이라면 별도 개발이 필요합니다. 결과적으로 이러한 연동은 단순한 챗봇을 넘어서, 업무 자동화와 생산성 향상으로 이어지는 강력한 서비스 확장 포인트가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API는 사실 이미 우리 일상 속에 깊숙이 들어와 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;날씨 앱은 기상청 API를, 카카오 로그인은 카카오 인증 API를, 배달 주문은 결제/메세지 API를 사용하죠.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;규격(문법)&lt;/b&gt;을 이해하면 개발자와 구체적으로 요건 사항을 논의할 수 있고,&lt;/li&gt;
&lt;li&gt;&lt;b&gt;종류(공개 범위)&lt;/b&gt;를 이해하면 어떤 비즈니스 모델을 만들 수 있을지 감이 오며,&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적용 가능 범위&lt;/b&gt;를 이해하면 고객에게 &quot;이건 API로 바로 가능합니다 / 이건 별도 개발이 필요합니다&quot;라고 명확하게 설명할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;API는 만능은 아니지만, 제대로 이해하고 설명할 수 있다면 영업과 기획에서 정말 강력한 무기가 됩니다.&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;이번&amp;nbsp;포스팅은&amp;nbsp;여기까지&amp;nbsp;하고&amp;nbsp;마무리하겠습니다. &lt;br /&gt;읽으시면서&amp;nbsp;추가로&amp;nbsp;궁금한&amp;nbsp;점이나,&amp;nbsp;다른&amp;nbsp;시각에서의&amp;nbsp;의견&amp;middot;비판도&amp;nbsp;언제든&amp;nbsp;환영합니다!&lt;/p&gt;</description>
      <category>Data Science</category>
      <category>API</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/123</guid>
      <comments>https://hr1588.tistory.com/123#entry123comment</comments>
      <pubDate>Sat, 20 Sep 2025 18:03:30 +0900</pubDate>
    </item>
    <item>
      <title>[API] API의 정의와 원리</title>
      <link>https://hr1588.tistory.com/122</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;API, 어디까지 가능한 걸까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업무를 진행하다보면 종종 이런 질문을 듣습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;API로 연결하면 다 되는거 아닌가요?&quot;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 저도 고개를 끄덕였는데, 생각해보면 어디까지 연결되는지, 그 연결이 어떤 방식으로 진행되는지 잘 모르겠더라고요. 그래서 오늘은 API가 뭔지, 그리고 어디까지 가능한지를 정리해서 공유드리려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;API, 사실은 어렵지 않다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IT 업계에 종사하시는 분들이 아니라면, API(Application Programming Interface)라는 단어 자체가 생소할 수 있습니다. 이름은 길지만, 사실 일상적인 비유로 풀면 생각보다 간단하게 이해할 수 있어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 들어보겠습니다. 레스토랑에 갔을 때 우리는 직접 주방에 들어가 요리하지 않습니다. 당연히 메뉴판을 보고 주문을 하죠. API도 똑같습니다. 시스템 안에 무슨 일이 일어나는지 몰라도, 메뉴판(API 문서)에 적힌 대로 요청만 하면 결과를 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나의 비유는 콘센트와 플러그입니다. 전기는 보이지 않지만, 규격이 맞으면 플러그를 꽂아 전기를 쓸 수 있습니다. API도 마찬가지입니다. 정해진 규격을 통해 데이터를 주고받을 수 있죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그럼, 어떻게 작동할까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱에서 &quot;서울 날씨&quot; 버튼을 눌렀다고 가정해봅시다. 우리 눈에는 그냥 결과만 바뀌는 것 처럼 보이지만, 그 안에서는 이런 일이 벌어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Request(요청)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱이 서버로 &quot;서울 날씨를 알려줘!&quot;라는 메세지를 보냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 메세지는 인터넷을 타고, HTTP/HTTPS라는 약속된 언어를 통해 전달됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP : 웹에서 주고받는 기본 규칙&lt;/li&gt;
&lt;li&gt;HTTPS : HTTP에 보안을 더한 것(자물쇠가 채워진 통신)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Processing(처리)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버가 데이터베이스를 확인합니다. &quot;서울의 오늘 날씨는 27도, 맑음이구나.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Response(응답)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버가 앱으로 결과를 돌려주면, 앱은 이 데이터를 화면에 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 우리가 보는 건 단순한 &quot;화면 변화&quot;이지만, 사실은 그 속에 요청-응답의 대화가 숨어 있는 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;GET과 POST, 대화 방식의 차이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 조금 더 깊이 들어가보겠습니다. HTTP라는 규칙 안에는 여러 동사(Verb)가 있습니다. 그중에서도 가장 많이 쓰이는 게 &lt;b&gt;GET과 POST&lt;/b&gt;에요. 둘 다 서버에 무언가를 요청하는 방식이지만, 쓰임새가 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;GET - 정보를 가져올 때&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GET은 조회용입니다. 이미 서버에 있는 데이터를 그냥 &quot;읽어오기&quot;만 하죠. 즉, 서버의 상태를 바꾸지 않고, 그냥 &quot;지금 가지고 있는 정보&quot;를 요청하는 것입니다. 예를 들어, 서울 날씨를 보고 싶다고 해봅시다. 이럴 때는 GET 요청을 보냅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1758349947187&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Request(요청)

GET /weather?city=seoul HTTP/1.1
Host: api.example.com&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1758349957722&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Response(응답)

{
  &quot;city&quot;: &quot;Seoul&quot;,
  &quot;temp&quot;: 27,
  &quot;condition&quot;: &quot;sunny&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 요청을 받으면 서버는 날씨 데이터베이스에서 서울 정보를 찾아서 응답을 줍니다. 여기서 중요한 건, 내가 단순히 날씨 정보를 조회했을 뿐 서버의 데이터는 바뀌지 않았다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;POST - 새로운 걸 생성하거나 처리할 때&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;POST는 단순 조회가 아니라, 무언가를 새로 등록하거나 행동을 요청할 때 씁니다. 즉, 서버의 상태를 바꾸는 요청이죠. 예를 들어, 오늘 점심 도시락 주문을 넣는 상황을 생각해봅시다. 이때는 POST 요청으로 주문 데이터를 서버에 보냅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1758350279687&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;POST /order HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  &quot;menu&quot;: &quot;김치찌개&quot;,
  &quot;count&quot;: 2
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1758350286710&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;orderId&quot;: 1234,
  &quot;status&quot;: &quot;confirmed&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버는 이 요청을 처리하고, 새로운 주문을 만들어서 응답을 줍니다. 이 경우는 단순 조회가 아니라, 실제로 서버에 새로운 데이터(주문)가 추가된 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로는 &lt;b&gt;HTTP 메서드(GET/POST)가 DB의 CRUD와 상당히 유사&lt;/b&gt;하다고 생각했는데요, 추가적인 사항을 표로 정리했습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;SQL (DB)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;의미&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;HTTP 메서드 (API)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;CREATE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터 생성&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;POST&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;새로운 데이터를 등록할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;READ (SELECT)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터 조회&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;GET&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터를 불러올 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;UPDATE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터 수정&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;PUT&lt;/b&gt; (전체 교체) / &lt;b&gt;PATCH&lt;/b&gt; (부분 수정)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;기존 데이터를 변경할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;DELETE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터 삭제&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;DELETE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터를 제거할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* CRUD(Create, Read, Update, Delete)는 데이터베이스에서 데이터를 다루는 4가지 기본 동작을 뜻합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원리는 비슷하지만, DB에서의 CRUD는 &quot;데이터와 직접 대화&quot;라면, HTTP의 메서드는 &quot;서버와 메뉴판을 통해 대화&quot;하는 방식인거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;HTTPS는 어떻게 안전할까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;두괄식으로 먼저 말씀드리자면, HTTP와 달리 HTTPS가 안전한 이유는 단순한 암호화 때문이 아니라 인증서와 CA 덕분에 &quot;진짜 서버와 대화하고 있다&quot;라는 것을 보장받기 때문입니다.&lt;/b&gt;&amp;nbsp;HTTP는 편지 엽서라고 생각하시면 되는데요, 우리가 &quot;서울 날씨 알려줘&quot; 요청을 보내면 이 요청이 인터넷을 타고 여러 서버와 라우터를 거져 전달됩니다. 문제는 &lt;b&gt;이 내용이 암호화되지 않은 평문&lt;/b&gt;이라는 거예요. 즉, 중간에 누가 훔쳐보면 &quot;GET/weather?city=seoul&quot; 같은 내용이 그대로 노출됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;날씨 요청은 개인 정보가 아니지만, 만약 로그인/비밀번호/카드번호 같은 민감한 정보인 경우 문제가 발생할 수 있죠. 심지어 중간에서 내용을 바꿔치기 하는 것도 가능합니다. 내가 서울 날씨를 요청했는데, 누군가 부산 날씨로 바꿔치기 할 수도 있죠. 이게 HTTP의 치명적인 단점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;HTTPS의 원리 : TLS&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 단점을 해결하기 위해, HTTP에 보안(SSL/TLS)을 입힌 버전(HTTPS)를 활용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작동 원리는 HTTP와 똑같이 GET/POST 같은 요청/응답이지만, 그 내용이 전부 암호화돼서 오갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 &lt;b&gt;TLS Handshake&lt;/b&gt;라는 과정이에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 클라이언트(브라우저)가 서버에게 &quot;너 진짜 맞아?&quot; 하고 신분을 확인합니다.&lt;br /&gt;2. 서버는 &lt;b&gt;인증서(SSL 인증서)&lt;/b&gt;를 내밀고, 브라우저는 공인된 기관(CA)을 통해 신뢰성을 확인합니다. &lt;br /&gt;3. 둘은 어떤 암호화 방식을 쓸지 합의합니다. &lt;br /&gt;4. 이후에는 두 쪽만 아는 &lt;b&gt;비밀키(대칭키)&lt;/b&gt;를 공유합니다. &lt;br /&gt;5. 이제부터 주고받는 모든 GET/POST 요청은 암호화되어, 중간에서 엿보더라도 의미 없는 암호문으로만 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;갑자기 알 수 없는 용어들이 굉장히 많이 나왔는데요, 하나씩 같이 살펴볼까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SSL 인증서란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL 인증서는 쉽게 말해 서버의 신분증이에요. 우리가 브라우저로 &lt;a href=&quot;https://www.naver.com에&quot;&gt;https://www.naver.com&lt;/a&gt;에 접속했을 때, 네이버 서버는 &quot;나는 진짜 네이버야!&quot;라는 증명서를 제시합니다. 이 증명서에는 서버 도메인 이름, 발급자, 만료일, 공개키(public key) 등이 들어 있습니다. 브라우저는 이 인증서를 확인하고, 신뢰할 만한 기관이 발급한 것인지 검증합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 인증서가 있으면 중간에 가짜 서버가 끼어들어도 쉽게 속지 않습니다. 내가 보낸 비밀번호가 진짜 네이버로 가는지, 아니면 가짜 서버로 새어나가는지를 확인하는 역할이죠.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TLS?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 SSL(Secure Sockets Layer)라는 이름으로 시작했는데, 취약점이 발견되면서 개선된 버전이 TLS(Transport Layer Security)에요. 현재 우리가 쓰는 건 사실상 TLS 인증서입니다. 다만, 사람들이 습관적으로 아직도 SSL 인증서라고 부르는 거에요. 즉, 둘다 보안 프로토콜의 일종이지만 TLS가 SSL의 개선된 버전이라고 생각하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CA?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CA는 말 그대로 공인된 증명서 발급기관이에요. 서버가 자기 스스로 &quot;나는 진짜 네이버다&quot; 라고 주장하면 아무도 못 믿겠죠? 그래서 제 3자인 CA가 서버의 신원을 확인한 뒤 인증서를 발급합니다. 브라우저와 운영체제(OS)는 이미 신뢰할 수 있는 CA 목록을 내장하고 있습니다. 따라서 서버가 제시한 인증서가 해당 목록에 있는 CA가 발급한 것이라면 신뢰하는 프로세스에요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TLS는 TCP 3-Way Handshake와 유사한 개념 아닌가요?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Handshake라는 용어를 보니 TCP에서 활용되는 3-Way Handshake와 유사한 개념인가? 라는 생각이 들더라고요. 하지만 관련된 사항을 찾아보니, 전혀 다른 프로세스였습니다. 정보통신 관련 사항은 포스팅의 메인 주제는 아니니, 가볍게 정리하고 넘어가도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TCP 3-Way Handshake&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 연결을 맺는 과정&lt;/li&gt;
&lt;li&gt;전화기가 서로 연결됐는지 확인하는 단계&lt;/li&gt;
&lt;li&gt;보안과는 전혀 무관&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TLS Handshake(HTTPS)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이미 연결된 통로 위에서, 우리끼리 암호 언어를 정하자는 협상&lt;/li&gt;
&lt;li&gt;서버 신분 확인(인증서), 암호화 방식 결정, 대칭키 공유&lt;/li&gt;
&lt;li&gt;이후 모든 HTTP 요청/응답이 암호화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 API의 정의 및 원리에 대해서 알아보았습니다. 글이 너무 길어져서, 다음 포스팅에서 API의 종류 및 적용 가능 범위에 대해서 소개드릴 수 있도록 하겠습니다. 오늘도 방문해주셔서 감사합니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data Science</category>
      <category>API</category>
      <category>HTTP</category>
      <category>https</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/122</guid>
      <comments>https://hr1588.tistory.com/122#entry122comment</comments>
      <pubDate>Sat, 20 Sep 2025 14:43:44 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 소버린 AI</title>
      <link>https://hr1588.tistory.com/121</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1750859337009&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;'챗GPT의 95%' 기술론 경쟁력 없어&amp;hellip;유연한 '소버린 AI' 전략 짜야&quot; data-og-description=&quot;지난 4월 네이버와 KT 간 &amp;lsquo;소버린 AI(인공지능)&amp;rsquo; 논쟁이 붙었다. 김유원 네이버클라우드 대표가 &amp;ldquo;외산을 들여와 우리 상표를 붙였다고 소버린이라고 칭하는 건 언어도단&amp;rdquo;이라고 KT를 저격했&quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/015/0005148976?date=20250625&quot; data-og-url=&quot;https://n.news.naver.com/article/015/0005148976&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qGIy5/hyZbDSaTQB/bFInED2BCcHCp9vnrbvvok/img.jpg?width=800&amp;amp;height=687&amp;amp;face=0_0_800_687,https://scrap.kakaocdn.net/dn/bsJn3q/hyZcmippvI/ycGEKWilTNlKm72HTTaAyK/img.jpg?width=800&amp;amp;height=687&amp;amp;face=0_0_800_687&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/015/0005148976?date=20250625&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/015/0005148976?date=20250625&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qGIy5/hyZbDSaTQB/bFInED2BCcHCp9vnrbvvok/img.jpg?width=800&amp;amp;height=687&amp;amp;face=0_0_800_687,https://scrap.kakaocdn.net/dn/bsJn3q/hyZcmippvI/ycGEKWilTNlKm72HTTaAyK/img.jpg?width=800&amp;amp;height=687&amp;amp;face=0_0_800_687');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;'챗GPT의 95%' 기술론 경쟁력 없어&amp;hellip;유연한 '소버린 AI' 전략 짜야&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;지난 4월 네이버와 KT 간 &amp;lsquo;소버린 AI(인공지능)&amp;rsquo; 논쟁이 붙었다. 김유원 네이버클라우드 대표가 &amp;ldquo;외산을 들여와 우리 상표를 붙였다고 소버린이라고 칭하는 건 언어도단&amp;rdquo;이라고 KT를 저격했&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국 정부는 &lt;b&gt;&quot;소버린 AI(Sovereign AI, 자주적 인공지능)&quot; 개발&lt;/b&gt;을 추진 중이나, 글로벌 빅테크 대비 &lt;b&gt;95% 성능 목표&lt;/b&gt;에 대해 &amp;ldquo;경쟁력 없다&amp;rdquo;는 우려가 업계 전반에 확산되고 있음. 전문가들은 100% 이상의 초과 성능이 아니라면 독자 개발은 낭비라고 지적하는 한편, 데이터 통제권과 보안 확보의 관점에서 국산 모델의 필요성을 강조함. &lt;br /&gt;&lt;br /&gt;또한&amp;nbsp;&quot;토종&quot;을&amp;nbsp;외치기보다는&amp;nbsp;글로벌&amp;nbsp;기술을&amp;nbsp;유연하게&amp;nbsp;융합해&amp;nbsp;실용성&amp;nbsp;있는&amp;nbsp;소버린&amp;nbsp;전략을&amp;nbsp;짜야&amp;nbsp;한다는&amp;nbsp;주장이&amp;nbsp;확산되고&amp;nbsp;있음.&amp;nbsp;특히&amp;nbsp;LLM(대규모&amp;nbsp;언어모델)&amp;nbsp;자체&amp;nbsp;개발보다,&amp;nbsp;AI&amp;nbsp;응용&amp;nbsp;서비스&amp;nbsp;분야에서의&amp;nbsp;비교우위&amp;nbsp;전략이&amp;nbsp;현실적인&amp;nbsp;대안으로&amp;nbsp;부상.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수치&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;한국형 LLM 성능 목표&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;챗GPT 대비 95%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;과기정통부 &amp;lsquo;국가 LLM&amp;rsquo; 목표 수치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;국내 토종 LLM 수&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;14개&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;네이버&amp;middot;LG 등 6개 기업이 개발&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;미국 LLM 수&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;128개&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;글로벌 경쟁 상황&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;중국 LLM 수&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;95개&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;글로벌 경쟁 상황&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;a16z 발표 AI 서비스 Top 50 내 한국 모델 수&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;0건&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;글로벌 경쟁력 부재 사례&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;소버린 AI&lt;/b&gt; : 외국 기술에 의존하지 않고, 자국 내에서 데이터/모델/인프라를 독립적으로 통제 및 운영할 수 있는 AI 체&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LLM(Large Language Model)&lt;/b&gt; : 대규모 텍스트 데이터를 학습해 자연어를 이해하고 생성할 수 있는 AI 모델 (GPT-4, 하이퍼클로바X 등&lt;/li&gt;
&lt;li&gt;&lt;b&gt;육수론&lt;/b&gt; : 파운데이션 모델을 국가가 개발해, 기업이 응용 서비스에 활용하도록 하자는 전략 (국가 AI 수석 주장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;AI 갈라파고스&lt;/b&gt; : 국제 표준과 동떨어진 기술 생태계가 고립되는 현상, 자국만의 생태계 구축이 시장성과 연결되지 않으면 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;A16Z TOP 50 AI 서비스?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정식 명칭은 a16z &quot;Top 100 Gen AI Consumer Apps &amp;ndash; 4th Edition&quot;으로, a16z (Andreessen Horowitz, 실리콘밸리 대표 VC)에서 발간된다. 이번에 발표된 버전은 2025년 3월에 발표된 4판으로, 생성형 AI앱의 시장 트렌드, 성장성, 사용자 기반 등을 종합 분석했다.&lt;b&gt;&lt;br /&gt;&lt;br /&gt;목표:&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소비자 대상 Gen AI 앱의 실사용 지표 기반 순위화&lt;/li&gt;
&lt;li&gt;산업 내 성공 가능성 있는 스타트업 및 트렌드 파악&lt;/li&gt;
&lt;li&gt;Big Tech 외 스타트업 생태계 확장 여부 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;71&quot; data-start=&quot;44&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  2025년 3월 Top 50 대표 사례&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;615&quot; data-start=&quot;73&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;172&quot; data-start=&quot;73&quot;&gt;&lt;b&gt;ChatGPT&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;172&quot; data-start=&quot;93&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;172&quot; data-start=&quot;93&quot;&gt;&lt;span&gt;&lt;b&gt;웹 순위 1위&lt;/b&gt;, 400 M+ 주간 사용자 &amp;rarr; 전체 AI 서비스 중 절대 강자&lt;/span&gt; &lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;274&quot; data-start=&quot;174&quot;&gt;&lt;b&gt;DeepSeek&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;274&quot; data-start=&quot;195&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;274&quot; data-start=&quot;195&quot;&gt;&lt;span&gt;&lt;b&gt;웹 순위 2위&lt;/b&gt;로 급등, 출시 첫 달에 10 M 사용자 돌파. 특히 중국, 미국, 인도에서 빠르게 성장 중&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;380&quot; data-start=&quot;276&quot;&gt;&lt;b&gt;Character.AI&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;380&quot; data-start=&quot;301&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;380&quot; data-start=&quot;301&quot;&gt;&lt;span&gt;&lt;b&gt;웹 순위 상위권&lt;/b&gt;, 사용자 생성 캐릭터와의 몰입형 대화 제공. &amp;ldquo;web 기준 2위&amp;rdquo;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;484&quot; data-start=&quot;382&quot;&gt;&lt;b&gt;Perplexity&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;484&quot; data-start=&quot;405&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;484&quot; data-start=&quot;405&quot;&gt;&lt;span&gt;&lt;b&gt;웹 순위 3위&lt;/b&gt;, 실시간 인용 기반 검색-대화 서비스. 평균 체류 시간 7분 이상&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;615&quot; data-start=&quot;486&quot;&gt;&lt;span&gt;&lt;b&gt;Claude (by Anthropic)&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;615&quot; data-start=&quot;532&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;615&quot; data-start=&quot;532&quot;&gt;&lt;span&gt;&lt;b&gt;웹 순위 4위&lt;/b&gt;로 빠르게 부상, Anthropic의 LLM 서비스 대표 격&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;b&gt;Anthropic&lt;/b&gt; : 구글이 전략적으로 투자하고 협력하는 생성형 AI 스타트업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[한국형 AI는 모델 개발보다 &quot;문제 해결&quot;에 집중해야 한다]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 정부와 기업들이 &amp;lsquo;소버린 AI&amp;rsquo;라는 이름 아래, 한국형 대규모 언어모델(LLM) 개발에 집중하고 있다. 하지만 나는 이 흐름에 조금 다른 생각이 든다. 단순히&amp;nbsp;자체&amp;nbsp;LLM을&amp;nbsp;개발하는&amp;nbsp;것보다는,&amp;nbsp;한국만의&amp;nbsp;문제에&amp;nbsp;특화된&amp;nbsp;AI&amp;nbsp;응용&amp;nbsp;서비스를&amp;nbsp;개발해&amp;nbsp;비교우위를&amp;nbsp;확보하는&amp;nbsp;것이&amp;nbsp;훨씬&amp;nbsp;더&amp;nbsp;전략적이라고&amp;nbsp;생각한다. &lt;br /&gt;&lt;br /&gt;물론 독자적인 AI 인프라와 기술력을 갖추는 것은 중요하다. 특히 데이터 주권이나 보안 이슈, 공급망 불확실성 등을 고려할 때 자체 모델의 필요성은 부정할 수 없다. 하지만 이미 글로벌 빅테크 기업들은 고성능 AI 모델을 범용 플랫폼으로 제공하고 있으며, 이들과의 성능 격차는 점점 더 벌어지고 있다. 이런 상황에서 95% 수준의 성능을 목표로 모델을 새로 만드는 것이 과연 효율적인지 의문이다. 오히려 제한된 자원을 &quot;정확히 필요한 곳&quot;에 집중하는 것이 더 실용적인 전략이 아닐까? &lt;br /&gt;&lt;br /&gt;과거 경제 지식그래프를 구축하는 프로젝트를 진행하며, 한국어 문법의 복잡성과 형태소 분석의 어려움을 경험했다. 예를 들어, NNG(일반 명사)와 NP(대명사) 조합 같은 문법 구조는 영어보다 훨씬 해석이 까다롭다. 게다가 한국어 관련 학습 데이터나 레퍼런스 자료도 해외 언어에 비해 비교적 부족한 편이다. 이처럼 언어적 특수성이 존재하는 상황에서, 이미 많은 연구가 진행된 범용 모델을 무작정 따라가는 것은 기술적&amp;middot;경제적으로 모두 비효율적일 수 있다. &lt;br /&gt;&lt;br /&gt;그렇다면 한국형 AI는 어떤 방향을 추구해야 할까? &quot;문제 중심의 AI&quot;가 해답이라고 본다. 예를 들어, 작년 말 기사에 따르면 정부가 12억 원을 들여 도입한 포트홀 탐지 AI 시스템의 오작동률이 무려 85%에 달했다고 한다. 기술은 도입됐지만, 정작 현장에서 문제 해결에는 큰 도움이 되지 못한 사례다. 이런 경우, 단순히 외산 모델을 적용하는 것이 아니라 국내 도로 환경과 인프라 특성에 맞춘 특화 AI 모델을 개발하는 것이 진정한 경쟁력이다. 나아가 이러한 현장 특화 AI가 글로벌에서도 통용될 수 있는 &quot;공통의 문제&quot;를 다룬다면, 한국형 AI는 단순한 독립성을 넘어서 수출 가능한 전략 산업이 될 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면, 기술 중심이 아니라 문제 중심의 전략이 필요하다. 그리고 그 문제는 한국의 언어, 사회, 산업 구조에서 출발해야 한다. 단순히 LLM을 만드는 것에 집착하기보다는, 어떤 문제를 어떻게 해결할 수 있는가에 더 집중해야 한다. 그것이야말로 한국이 AI 분야에서 후발대임에도 독창성과 실용성을 동시에 잡을 수 있는 길이라고 생각한다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/121</guid>
      <comments>https://hr1588.tistory.com/121#entry121comment</comments>
      <pubDate>Wed, 25 Jun 2025 23:27:31 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 검색 시장을 위협하는 생성형 AI</title>
      <link>https://hr1588.tistory.com/120</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1750131089510&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;'검색' 침범한 생성AI&amp;hellip;구글 의존 기업들 타격&quot; data-og-description=&quot;생성형 인공지능(AI)이 보급되면서 기존 인터넷 검색 시장이 급속도로 쪼그라들고 있다. 시장 1위 검색 엔진인 구글이 최대 피해자가 될 것이라는 예상과 달리 검색에 의존하는 인터넷 기업이 가&quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/015/0005145223?date=20250617&quot; data-og-url=&quot;https://n.news.naver.com/article/015/0005145223&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cgTfC6/hyY78dFEdo/GRMmZWecNyebZnpsDDl4pK/img.jpg?width=300&amp;amp;height=302&amp;amp;face=0_0_300_302,https://scrap.kakaocdn.net/dn/sKYWD/hyY716HtpR/Bp1tcwolfJm7VkITKxOnr0/img.jpg?width=300&amp;amp;height=302&amp;amp;face=0_0_300_302&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/015/0005145223?date=20250617&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/015/0005145223?date=20250617&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cgTfC6/hyY78dFEdo/GRMmZWecNyebZnpsDDl4pK/img.jpg?width=300&amp;amp;height=302&amp;amp;face=0_0_300_302,https://scrap.kakaocdn.net/dn/sKYWD/hyY716HtpR/Bp1tcwolfJm7VkITKxOnr0/img.jpg?width=300&amp;amp;height=302&amp;amp;face=0_0_300_302');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;'검색' 침범한 생성AI&amp;hellip;구글 의존 기업들 타격&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;생성형 인공지능(AI)이 보급되면서 기존 인터넷 검색 시장이 급속도로 쪼그라들고 있다. 시장 1위 검색 엔진인 구글이 최대 피해자가 될 것이라는 예상과 달리 검색에 의존하는 인터넷 기업이 가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성형 AI의 대중화로 &lt;b&gt;검색 기반 트래픽에 의존하는 인터넷 기업들&lt;/b&gt;이 타격을 입고 있다. 여행, 전자상거래, 금융 등 전통적으로 &lt;b&gt;검색 유입에 기반한 산업군&lt;/b&gt;에서 방문자 수가 크게 줄었으며, 대표적으로 트립어드바이저는 검색 유입 감소로 웹사이트 방문이 38% 급감했다. 반면 &lt;b&gt;구글은 클라우드컴퓨팅과 자율주행 등의 사업 다각화와 자체 AI 경쟁력(Gemini)&lt;/b&gt; 덕분에 상대적으로 타격이 적었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수치&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;美 여행사이트 검색 유입&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;▼20.2%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전년 동월 대비&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;뉴스&amp;middot;미디어 검색 유입&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;▼17.1%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전년 동월 대비&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이커머스 검색 유입&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;▼9.2%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전년 동월 대비&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;금융업 검색 유입&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;▼7.4%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전년 동월 대비&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;트립어드바이저 유입 감소&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;▼38%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전체 웹사이트 트래픽&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;익스피디아 AI 검색 유입&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;8.8만 건&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;기존 검색 유입 3400만 건의 0.25%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;체그 주가 하락률&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;▼98.81%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2021년 고점 대비&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;검색 트래픽 : 구글, 네이버 등 검색 엔진을 통해 유입된 방문자 수. 대부분의 정보 서비스는 검색 유입에 크게 의존함&lt;/li&gt;
&lt;li&gt;생성형 AI : 텍스트,&amp;nbsp;오디오,&amp;nbsp;이미지&amp;nbsp;또는&amp;nbsp;동영상&amp;nbsp;형태의&amp;nbsp;새로운&amp;nbsp;컨텐츠를&amp;nbsp;생성하도록&amp;nbsp;설계된&amp;nbsp;인공&amp;nbsp;지능&amp;nbsp;모델&lt;/li&gt;
&lt;li&gt;AI 검색 : 사용자의 질문에 맞춰 AI가 정제된 답변을 제공하는 방식. 검색 링크 클릭이 아닌 직접 응답으로 연결됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실제 사례&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;트립어드바이저&lt;/b&gt;: 전체 유입의 58%를 검색에 의존 &amp;rarr; AI 확산 이후 유입량 38% 급감&lt;/li&gt;
&lt;li&gt;&lt;b&gt;체그(Chegg)&lt;/b&gt;: 대학생 대상 문제풀이 서비스. GPT 등장 이후 핵심 비즈니스 모델 붕괴, 시가총액 151억달러 &amp;rarr; 98% 증발&lt;/li&gt;
&lt;li&gt;&lt;b&gt;구글(Google)&lt;/b&gt;: Gemini(생성형 AI), Waymo(자율주행), GCP(클라우드) 등 다각화 &amp;rarr; 상대적 안정&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;생성형 AI(Generative AI)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: ;&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;전통적 AI&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;생성형 AI&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: ;&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;목적&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;분류&amp;middot;예측&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;창작&amp;middot;생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: ;&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;입력 &amp;rarr; 출력&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;입력에 대한 정답 찾기&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;입력에 따라 다양한 결과 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: ;&quot;&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;예시&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;스팸 분류, 고객 이탈 예측&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;동화 쓰기, 광고 이미지 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성형 AI는 텍스트, 오디오, 이미지, 영상 등 인간이 만들어내는 다양한 콘텐츠를 자동으로 생성할 수 있는 인공지능 기술을 의미한다. 기존의 AI가 규칙 기반 혹은 분류(Classification)에 머물렀다면, 생성형 AI는 실제 창작을 수행한다. &lt;b&gt;주어진 데이터를 바탕으로 새로운 것을 만들어내는 능력&lt;/b&gt;이 생성형 AI의 핵심이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;모델명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;GPT (OpenAI)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Transformer 기반 텍스트 생성 모델. 자연어처리(NLP) 분야에서 선도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Diffusion 모델 (Stable Diffusion)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;노이즈 제거 방식으로 이미지 생성. 시각 AI의 대표주자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;GAN (생성적 적대 신경망)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Generator(생성자)와 Discriminator(판별자)가 경쟁하여 정교한 결과물 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Multimodal AI (Gemini, GPT-4o)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;텍스트&amp;middot;이미지&amp;middot;음성&amp;middot;영상 등 여러 데이터 타입을 동시에 처리 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 외에도 음성, 음악, 영상, 3D 모델 등 다양한 형태의 콘텐츠를 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;산업별 활용 사례&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;산업&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;적용 예시&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;금융&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;투자 보고서 요약, 챗봇 상담, 금융상품 마케팅 문안 자동 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;의료&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;영상 판독 보조, 환자 기록 자동 생성, 맞춤형 건강 콘텐츠&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;교육&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;맞춤형 문제 출제, 학생 피드백 자동 생성, 학습 요약&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;마케팅&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;광고 문구&amp;middot;배너 생성, 고객 세분화에 따른 콘텐츠 자동화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;콘텐츠&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;뉴스 자동 작성, 웹소설 생성, 유튜브 영상 스크립트 제작&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;IT개발&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;코드 자동 생성, 버그 수정 추천, 문서 자동화&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성형 AI는 단순히 정보를 요약해주는 도구가 아니다. 이제는 정보를 직접 만들어내고, 의사결정을 보조하며 콘텐츠를 자동화하는 동료로 자리잡고 있다. 하지만 이 거대한 변화의 중심에서, 우리가 던져야 할 가장 본질적인 질문은 다음과 같다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;b&gt;&quot;이제 우리는 어떤 역할을 해야할까?&quot;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단지 기술의 문제가 아니라, AI를 어떻게 활용하고 어디까지 맡길 것인가에 대한 인간의 책임과 기준에 대해 생각해보자. 그리고, 기존의 비즈니스 모델을 어떻게 개편해야 격편하는 시장에서 생존할 수 있을지도 함께 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. '통제'의 책임은 인간에게 있다&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;허위&amp;nbsp;정보&amp;nbsp;생성&lt;/b&gt; &lt;br /&gt;생성형 AI는 놀랍도록 자연스러운 문장을 만들어내지만, 그 정보가 실제와 다를 수 있다. 이는 의사결정의 신뢰성을 크게 해친다. 우리가 직접 교차검증을 해야하는 이유이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;저작권 이슈와 개인정보 노출&lt;/b&gt; &lt;br /&gt;AI가 생성한 텍스트와 이미지가 누구의 창작물인가? 어디까지가 &amp;lsquo;참고&amp;rsquo;이고 어디서부터가 &amp;lsquo;침해&amp;rsquo;인가? 이에 대한 법적&amp;middot;윤리적 경계 설정 역시 사람의 몫이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;편향과 검열의 위험성&lt;/b&gt; &lt;br /&gt;AI는 인간이 만든 데이터를 학습한다. 따라서 기존 사회의 편향을 그대로 재현하거나, 때로는 검열과 악용의 가능성을 동반할 수 있다. 따라서&amp;nbsp;기술&amp;nbsp;자체보다&amp;nbsp;중요한&amp;nbsp;것은&amp;nbsp;그&amp;nbsp;기술을&amp;nbsp;감시하고&amp;nbsp;조정할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;사람의&amp;nbsp;존재다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 기술의 미래는 '기획자'로서의 역할을 요구한다.&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;멀티모달 (Multimodal)&lt;/b&gt;&lt;br /&gt;텍스트뿐 아니라 이미지, 음성, 영상까지 동시에 이해하고 생성하는 시대가 오고 있다. 이때 우리는 어떤 방식으로 업무&amp;middot;서비스를 재설계할 것인가? 즉, AI를 어디에, 어떻게 접목할지를 설계하는 기획자의 역할이 중요해진다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;에이전트 (Agent)&lt;/b&gt;&lt;br /&gt;단순한 응답을 넘어, 작업을 스스로 계획하고 수행하는 AI가 도입되고 있다. 이때 사람은 실행자가 아니라, 업무 흐름과 목적을 정의하고 조정하는 관리자로서 중심에 서야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개인화 (Customization) &lt;/b&gt;&lt;br /&gt;나를&amp;nbsp;닮은&amp;nbsp;AI,&amp;nbsp;내&amp;nbsp;업무를&amp;nbsp;대신하는&amp;nbsp;AI가&amp;nbsp;확산된다면,&amp;nbsp;그만큼&amp;nbsp;데이터&amp;nbsp;관리와&amp;nbsp;보안,&amp;nbsp;윤리&amp;nbsp;설계가&amp;nbsp;중요해진다.&amp;nbsp;기술을&amp;nbsp;단순히&amp;nbsp;사용하는&amp;nbsp;소비자가&amp;nbsp;아니라,&amp;nbsp;설정하고&amp;nbsp;제한하는&amp;nbsp;설계자로서의&amp;nbsp;역할이&amp;nbsp;커진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 중요한 건 우리의 역할이라고 생각한다. 기술은 도구이고, 중요한 것은 그 도구를 어떻게 활용할지를 결정하는 주체로서의 인간이다. 단순히 생성형 AI의 소비자를 넘어서, 통제/기획/설계/책임자로서 역할을 다할 때 비로소 생성형 AI는 사회와 인간을 위한 자연스러운 도구가 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/120</guid>
      <comments>https://hr1588.tistory.com/120#entry120comment</comments>
      <pubDate>Tue, 17 Jun 2025 12:53:01 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] AI 혁신 &amp;amp; 바이브 코딩</title>
      <link>https://hr1588.tistory.com/119</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1750042346042&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;&amp;quot;AI의 파괴적 혁신&amp;hellip;제약부터 유통까지 산업 지형 바꾼다&amp;quot;&quot; data-og-description=&quot;신기술 향연 '비바테크' 폐막 다양한 AI 활용 사례 소개 지난 11~14일 프랑스 파리에서 열린 유럽 최대 스타트업 행사인 '비바테크 2025'에서는 제약부터 우주까지 산업 전반의 지형을 바꾸고 있는 &quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005509021?date=20250616&quot; data-og-url=&quot;https://n.news.naver.com/article/009/0005509021&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhjTMr/hyY78YKGi3/sK5bnJ4VvSAzcqbQQroO4k/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356,https://scrap.kakaocdn.net/dn/dsUNjs/hyY8WwY2wo/z9lGVRAgRBkVjKkzQZAlyk/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/009/0005509021?date=20250616&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005509021?date=20250616&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhjTMr/hyY78YKGi3/sK5bnJ4VvSAzcqbQQroO4k/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356,https://scrap.kakaocdn.net/dn/dsUNjs/hyY8WwY2wo/z9lGVRAgRBkVjKkzQZAlyk/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;&quot;AI의 파괴적 혁신&amp;hellip;제약부터 유통까지 산업 지형 바꾼다&quot;&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;신기술 향연 '비바테크' 폐막 다양한 AI 활용 사례 소개 지난 11~14일 프랑스 파리에서 열린 유럽 최대 스타트업 행사인 '비바테크 2025'에서는 제약부터 우주까지 산업 전반의 지형을 바꾸고 있는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프랑스 파리에서 열린 &amp;lsquo;비바테크 2025&amp;rsquo; 행사에서 AI의 산업 융합 사례가 집중 조명되었다. AI는 제약 산업에서 임상 성공률을 높이고, 유통업에서는 스마트 쇼핑 경험을 구현하는 등 다양한 분야에서 인간의 업무를 보조하는 기술로 주목받고 있음. 특히 AI가 일자리를 대체하는 것이 아니라, 보완적 도구로 작용한다는 인터뷰를 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RWD(Real World Data): 실제 병원 등 현장에서 수집되는 비정형 의료 데이터. 임상시험 데이터와 달리 현실성이 높아 AI 학습에 유용&lt;/li&gt;
&lt;li&gt;AI 스마트 카트: 카메라&amp;middot;센서&amp;middot;디스플레이가 부착된 쇼핑카트로, 상품 인식 및 셀프 결제를 지원. 인스타카트의 &amp;lsquo;케이퍼 카트&amp;rsquo;가 대표적&lt;/li&gt;
&lt;li&gt;바이옵티머스: 프랑스 AI 바이오테크 스타트업으로, 세포~환자 단계의 생물학적 반응 시뮬레이션 기반 신약개발 솔루션 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실제 사례&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아스트라제네카: AI 기반 병리 이미지 분석으로 암 환자 선별 정확도 향상. 신약 개발 초기 단계에서 효율성 제고&lt;/li&gt;
&lt;li&gt;인스타카트: 미국 유통기업. AI 쇼핑카트 '케이퍼'로 오프라인 매장 자동화 시도&lt;/li&gt;
&lt;li&gt;깃허브 Copilot: 마이크로소프트 계열. AI가 코드 초안을 생성하고 개발자는 리뷰 및 수정. 인간-기계 협업 모델로 주목&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브 Copilot에 대해 추가 정보를 찾던 도중, &lt;b&gt;바이브 코딩&lt;/b&gt;이라는 개념이 흥미로워서 추가적으로 내용을 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;바이브 코딩(Vibe Coding)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이브 코딩이란, AI가 코드를 쓰고 사람은 설계 및 검토에 집중하는 새로운 개발 패러다임이다. 즉, 개발자가 자연어로 원하는 기능을 설명하면 AI가 코드를 자동으로 생성하고, 개발자는 그것을 검토 및 테스트하는 방식의 프로그래밍이다. 2025년 초, 전 테슬라 AI 책임자 안드레이 카르파티가 &quot;코드를 의식하지 않고 개발하는 법&quot;이라며 바이브 코딩이라는 이름을 처음 언급했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;전통적 프로그래밍&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;바이브 코딩&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;직접 코드 작성&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;자연어로 기능 설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;디버깅 직접 수행&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;AI가 코드 생성 후 실행 결과 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;수동 테스트&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;피드백 기반 반복 수정&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 : &quot;사용자 이름을 입력받고, 길이가 3자 미만이면 오류 메세지를 출력해줘.&quot; =&amp;gt; AI가 완전한 코드 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅&amp;nbsp;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비개발자도 접근 가능: 기초 코딩 없이도 자동화 가능&lt;/li&gt;
&lt;li&gt;생산성 극대화: 반복적인 코드 작성 업무를 AI가 대체&lt;/li&gt;
&lt;li&gt;빠른 MVP(Minimum Viable Product) 구현: 아이디어가 프로토타입으로 전환되는 속도 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;❌ 단점 &lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 이해도 부족: 생성된 코드 구조를 파악 못하면 유지보수에 취약&lt;/li&gt;
&lt;li&gt;보안 이슈: 외부 LLM 활용 시, 코드 유출 가능성&lt;/li&gt;
&lt;li&gt;복잡 시스템에는 한계: 설계 복잡도가 높을수록 AI 자동화 비효율적&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;기업명&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;GitHub&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Copilot으로 코드 70~99% 자동화. 그러나 최종 검토는 인간 몫&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Amazon AWS&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;개발자 생산성 향상 도구로 &amp;lsquo;CodeWhisperer&amp;rsquo; 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Y Combinator&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;스타트업의 25% 이상이 AI 생성 코드 비중 95% 이상&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Apple&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Xcode에 바이브 코딩 기능 통합 예정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;GitLab&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;CEO 발언: &amp;ldquo;AI로 코딩은 쉬워지지만, 오히려 개발자 수요는 늘 것.&amp;rdquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 글로벌 대기업에서도 AI를 활용한 코딩이 확대되고 있음을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI는 이제 산업의 경계를 넘어 모든 직무에 새로운 패러다임을 제시하고 있다. 사람이 수년, 수십 년에 걸쳐 학습해온 지식과 통찰을 AI는 단기간에 압축해 실행하며, 나아가 우리가 한 번도 상상하지 못한 방식으로 문제를 재정의하고 있다. &lt;br /&gt;&lt;br /&gt;이제 우리는 단순한 &amp;lsquo;직무 수행자&amp;rsquo;를 넘어, AI를 현업에 어떻게 접목할지 고민하는 전략적 사고가 필요하다고 생각한다. 그 핵심은 도메인 지식 + 프롬프트 역량 + 문제해결력이다. AI는 도구이지 대체자가 아니라는 말이 현실감 없어 보일 수도 있다. 실제로 많은 업무에서 AI가 나보다 더 빠르고 정확하게 결과를 도출하기 때문이다. 그러나 그 결과물을 검토하고, 적용하며, 최종 책임지는 것은 여전히 사람의 역할이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;개발자&lt;/b&gt;의 관점에서는, 설령 AI가 코드의 99%를 작성하더라도 그것을 검토하고 설계한 의도를 반영해 조정하는 사람의 판단력이 필수적이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기획 및 마케팅&lt;/b&gt; 측면에서는, AI에게 업무를 지시하는 &amp;lsquo;프롬프트 설계 능력&amp;rsquo;이 곧 기획력이 됩니다. 단순한 아이디어가 아닌 실행 가능한 언어로 설계하는 능력이 경쟁력이 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;세일즈 직무&lt;/b&gt;에서도 변화는 명확하다. 과거에는 고객 요구사항을 수집해 개발팀에 전달하는 데 그쳤다면, 이제는 AI 기반 프로토타이핑을 통해 바로 기능을 제안하고 시연할 수 있다. 이로써 솔루션 중심 세일즈에서 실행 중심 세일즈로 직무가 전환되고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이제 모든 직무에서 중요한 것은 프롬프트 설계 역량, 즉 AI를 실험 도구로 활용하고, 현장의 문제를 빠르게 검증할 수 있는 사고력과 실행력이다. 앞으로는 &quot;무엇을 할 수 있는가&quot;보다, &lt;b&gt;&quot;AI를 통해 어떻게 더 빠르고 똑똑하게 해낼 수 있는가&quot;&lt;/b&gt;가 진짜 경쟁력이 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/119</guid>
      <comments>https://hr1588.tistory.com/119#entry119comment</comments>
      <pubDate>Mon, 16 Jun 2025 12:17:28 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 블록체인과 디지털 자산</title>
      <link>https://hr1588.tistory.com/118</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749812565756&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;블록체인이 '투자 민주화' 촉발시켜 [토크노미 코리아 2025]&quot; data-og-description=&quot;&amp;quot;최근 촉발된 자산의 디지털화는 소액으로도 참여 가능한 투자 민주화와 유동성의 획기적 증대를 이끌었다.&amp;quot; 김경호 한국딜로이트그룹 디지털자산센터 센터장&amp;hellip;은 파이낸셜뉴스와 디지털자산 &quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/014/0005362598?date=20250613&quot; data-og-url=&quot;https://n.news.naver.com/article/014/0005362598&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rzJkj/hyY45BRyEh/oookru5f9OqwkcYZyiBqrk/img.jpg?width=570&amp;amp;height=474&amp;amp;face=198_92_343_251,https://scrap.kakaocdn.net/dn/bt4OUd/hyY5cAZK2n/KckP0XPpIHBdSxd8HkFXt1/img.jpg?width=570&amp;amp;height=474&amp;amp;face=198_92_343_251&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/014/0005362598?date=20250613&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/014/0005362598?date=20250613&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rzJkj/hyY45BRyEh/oookru5f9OqwkcYZyiBqrk/img.jpg?width=570&amp;amp;height=474&amp;amp;face=198_92_343_251,https://scrap.kakaocdn.net/dn/bt4OUd/hyY5cAZK2n/KckP0XPpIHBdSxd8HkFXt1/img.jpg?width=570&amp;amp;height=474&amp;amp;face=198_92_343_251');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;블록체인이 '투자 민주화' 촉발시켜 [토크노미 코리아 2025]&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&quot;최근 촉발된 자산의 디지털화는 소액으로도 참여 가능한 투자 민주화와 유동성의 획기적 증대를 이끌었다.&quot; 김경호 한국딜로이트그룹 디지털자산센터 센터장&amp;hellip;은 파이낸셜뉴스와 디지털자산&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;토크노미&amp;nbsp;코리아&amp;nbsp;2025&amp;rsquo;에서&amp;nbsp;김경호&amp;nbsp;한국딜로이트&amp;nbsp;디지털자산센터장은&amp;nbsp;블록체인&amp;nbsp;기술이&amp;nbsp;고액&amp;nbsp;자산의&amp;nbsp;디지털화와&amp;nbsp;토큰화를&amp;nbsp;통해&amp;nbsp;소액&amp;nbsp;투자자의&amp;nbsp;참여를&amp;nbsp;확대하고,&amp;nbsp;중개기관&amp;nbsp;없는&amp;nbsp;거래,&amp;nbsp;24시간&amp;nbsp;글로벌&amp;nbsp;거래&amp;nbsp;등&amp;nbsp;투자&amp;nbsp;민주화를&amp;nbsp;촉진하고&amp;nbsp;있다고&amp;nbsp;강조했다.&amp;nbsp;디지털&amp;nbsp;자산은&amp;nbsp;지리적&amp;middot;시간적&amp;nbsp;한계를&amp;nbsp;넘어,&amp;nbsp;기존&amp;nbsp;전통금융의&amp;nbsp;구조를&amp;nbsp;변화시키며&amp;nbsp;&lt;b&gt;국경&amp;nbsp;없는&amp;nbsp;금융&amp;nbsp;생태계&lt;/b&gt;로&amp;nbsp;확장되고&amp;nbsp;있다는&amp;nbsp;점도&amp;nbsp;부각되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관련 지표&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수치&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;24시간 거래 가능&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;상시&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;블록체인 기반 디지털자산 특성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;토큰화 자산&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;소액 참여 가능&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;고액 자산(부동산, 예술품 등) 분할&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;토크노미 코리아 개최일&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;6월 12일&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;파이낸셜뉴스&amp;middot;DAXA 공동 주최&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;디지털 자산 : 블록체인 기술을 기반으로 발행된 자산. 암호화폐, 토큰증권, NFT 등이 포함&lt;/li&gt;
&lt;li&gt;NFT : 대체 불가능한 토큰의 약자로, 디지털 자산의 소유주를 증명하는 가상의 토큰&lt;/li&gt;
&lt;li&gt;토큰화(Tokenization) : 실물 자산(부동산, 미술품 등)을 디지털 토큰으로 변환하여 블록체인에 등록하는 과정&lt;/li&gt;
&lt;li&gt;탈중앙화 거래구조 : 중앙기관 없이 블록체인 네트워크 참여자 간 직접 거래가 가능한 구조&lt;/li&gt;
&lt;li&gt;프로토콜 표준 : 특정 네트워크 내에서 토큰 발행 및 운영을 위한 기술/운영상의 규약&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실제 사례&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 삼성증권 STO 플랫폼&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시점 : 2025년 2월부터 금융위 규제 샌드박스 기반 조각투자 발행 플랫폼 제도화 진행&lt;/li&gt;
&lt;li&gt;발행 플랫폼 : 스몰 라이선스를 취득한 증권사(예: 삼성증권)가 부동산&amp;middot;미술품 등 기초자산을 신탁수익증권 형태로 토큰 발행&lt;/li&gt;
&lt;li&gt;유통 플랫폼 : 토큰증권은 KRX, 장외거래, 자체 플랫폼 등에서 유통됨(30억 원 기준 구분됨)&lt;/li&gt;
&lt;li&gt;법제화 흐름 : 2023년 &amp;rarr; 2025년: 전자증권법&amp;middot;자본시장법 개정, 발행 플랫폼 제도화, 유통 플랫폼 제도화 순차 진행&lt;/li&gt;
&lt;li&gt;특징 : 중앙집중형 계좌관리기관&amp;rarr;전자등록기관&amp;rarr;장외 중개업자 중심의 분산원장 기반 발행&amp;middot;유통 체계&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 신한은행 X 블록체인 스타트업 (부동산 NFT)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사례 시점: 대략 2022년 전후로 '원신한 커넥트' 펀드 투자 및 NFT 기반 파일럿 수행 \&lt;/li&gt;
&lt;li&gt;구조 및 파트너십
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신한금융은 블록체인&amp;middot;NFT 기술 기업인 '블록오디세이'에 50억 투자&lt;/li&gt;
&lt;li&gt;신한은행, 헥슬란트&amp;middot;버클 등과 협력해 정품 인증 및 부동산&amp;middot;예술품 NFT 발행 사업 진행&lt;/li&gt;
&lt;li&gt;인천시와 공동으로 행사 입장권&amp;middot;쿠폰 기능 포함 NFT도 도입&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;목적
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부동산 수익권을 분할 소유 형태로 NFT화하여 소액 투자자에게 기회 제공&lt;/li&gt;
&lt;li&gt;대고객 서비스 강화 및 디지털 자산 생태계 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거에는&amp;nbsp;고부가가치&amp;nbsp;자산,&amp;nbsp;예컨대&amp;nbsp;부동산이나&amp;nbsp;예술품&amp;nbsp;등에&amp;nbsp;투자하기&amp;nbsp;위해&amp;nbsp;수억&amp;nbsp;원의&amp;nbsp;자본금,&amp;nbsp;법률&amp;nbsp;지식,&amp;nbsp;그리고&amp;nbsp;오랜&amp;nbsp;거래&amp;nbsp;시간이&amp;nbsp;필수적이었다.&amp;nbsp;이는&amp;nbsp;일반&amp;nbsp;개인&amp;nbsp;투자자,&amp;nbsp;특히&amp;nbsp;자본금이&amp;nbsp;부족한&amp;nbsp;투자자들에게는&amp;nbsp;극복하기&amp;nbsp;어려운&amp;nbsp;장벽이었다. &lt;br /&gt;&lt;br /&gt;이러한 구조를 바꾼 것이 블록체인 기술이다. 고가의 실물 자산을 디지털 토큰으로 쪼개어 발행함으로써, 자산을 소수점 단위로 거래할 수 있게 되었다. 예를 들어, 100억 원짜리 빌딩을 100만 개 토큰으로 분할해 1개당 1만 원에 판매할 수 있다면, 누구나 부동산 자산에 접근할 수 있게 된다. 이것이 바로 &lt;b&gt;토큰화(Tokenization)의 힘&lt;/b&gt;이다. 토큰화는 투자 대상을 다양화하고, 참여 문턱을 낮추며, 국경과 시간의 제약마저 허물었다. 24시간 글로벌 거래가 가능한 디지털 자산은 더 이상 소수의 특권이 아닌 대중의 기회로 전환되고 있다. 특히, WM(Wealth Management) 고객부터 개미 투자자까지 동일한 장에서 경쟁하고 협력할 수 있는 구조가 만들어졌다고 생각한다. &lt;br /&gt;&lt;br /&gt;하지만, 기술 수용도가 낮거나 정보 접근이 어려운 X세대 이상의 투자자들은 여전히 국내 주식 위주의 자산 운영에 머무르는 경향이 있다. 이에 따라, 토큰화된 글로벌 자산 상품을 중심으로 한 디지털 투자 상품 교육 및 프로모션이 필요하다. 예컨대,&amp;nbsp;&quot;1만&amp;nbsp;원으로&amp;nbsp;뉴욕&amp;nbsp;부동산에&amp;nbsp;투자하세요&quot;와&amp;nbsp;같은&amp;nbsp;직관적인&amp;nbsp;메시지를&amp;nbsp;통해&amp;nbsp;진입장벽을&amp;nbsp;낮추고,&amp;nbsp;글로벌&amp;nbsp;투자&amp;nbsp;기회를&amp;nbsp;확장시킬&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/118</guid>
      <comments>https://hr1588.tistory.com/118#entry118comment</comments>
      <pubDate>Fri, 13 Jun 2025 20:36:00 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] CPI(소비자 물가지수)</title>
      <link>https://hr1588.tistory.com/117</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749731291918&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;'관세 쇼크'는 없었다&amp;hellip;美 5월 CPI 2.4% 상승, 전망치 소폭 밑돌아&quot; data-og-description=&quot;미국의 소비자물가 상승률이 5월 들어 소폭 뛰었다. 도널드 트럼프 행정부의 고율 관세 정책에도 불구하고 당초 전문가들이 우려했던 만큼 상승폭이 크지 않은 것으로 나타났다. 11일 미 노동부&quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/015/0005143552?date=20250612&quot; data-og-url=&quot;https://n.news.naver.com/article/015/0005143552&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cZALAx/hyY5fqQif7/qLeub8JOZ7sCwkjHprxrHk/img.jpg?width=300&amp;amp;height=293&amp;amp;face=0_0_300_293,https://scrap.kakaocdn.net/dn/DVHPh/hyY4cOyJnp/29OWvwWcu2qLGWkgCeQdS1/img.jpg?width=300&amp;amp;height=293&amp;amp;face=0_0_300_293&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/015/0005143552?date=20250612&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/015/0005143552?date=20250612&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cZALAx/hyY5fqQif7/qLeub8JOZ7sCwkjHprxrHk/img.jpg?width=300&amp;amp;height=293&amp;amp;face=0_0_300_293,https://scrap.kakaocdn.net/dn/DVHPh/hyY4cOyJnp/29OWvwWcu2qLGWkgCeQdS1/img.jpg?width=300&amp;amp;height=293&amp;amp;face=0_0_300_293');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;'관세 쇼크'는 없었다&amp;hellip;美 5월 CPI 2.4% 상승, 전망치 소폭 밑돌아&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;미국의 소비자물가 상승률이 5월 들어 소폭 뛰었다. 도널드 트럼프 행정부의 고율 관세 정책에도 불구하고 당초 전문가들이 우려했던 만큼 상승폭이 크지 않은 것으로 나타났다. 11일 미 노동부&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년&amp;nbsp;5월&amp;nbsp;미국&amp;nbsp;소비자물가(CPI)는&amp;nbsp;전년&amp;nbsp;대비&amp;nbsp;2.4%&amp;nbsp;상승하며&amp;nbsp;시장&amp;nbsp;예상치(2.5%)를&amp;nbsp;하회했다.&amp;nbsp;트럼프&amp;nbsp;행정부의&amp;nbsp;고율&amp;nbsp;관세&amp;nbsp;정책에도&amp;nbsp;&amp;lsquo;관세&amp;nbsp;쇼크&amp;rsquo;는&amp;nbsp;없었으며,&amp;nbsp;근원&amp;nbsp;CPI도&amp;nbsp;안정적인&amp;nbsp;수준을&amp;nbsp;유지했다.&amp;nbsp;이에&amp;nbsp;따라&amp;nbsp;연방준비제도(Fed)의&amp;nbsp;기준금리&amp;nbsp;동결&amp;nbsp;가능성은&amp;nbsp;사실상&amp;nbsp;확정적이며,&amp;nbsp;연내&amp;nbsp;금리&amp;nbsp;인하&amp;nbsp;기대가&amp;nbsp;지속되고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만,&amp;nbsp;대부분의&amp;nbsp;미국&amp;nbsp;소매업체가&amp;nbsp;관세&amp;nbsp;부과&amp;nbsp;전&amp;nbsp;쌓아둔&amp;nbsp;재고를&amp;nbsp;판매하고&amp;nbsp;있어&amp;nbsp;미국&amp;nbsp;물가가&amp;nbsp;느리게&amp;nbsp;반응한&amp;nbsp;것이라고&amp;nbsp;분석된&amp;nbsp;결과도&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;향후&amp;nbsp;추세를&amp;nbsp;지켜볼&amp;nbsp;필요가&amp;nbsp;있다.&amp;nbsp;트럼프&amp;nbsp;정부의&amp;nbsp;고율&amp;nbsp;관세에도&amp;nbsp;불구하고,&amp;nbsp;아직은&amp;nbsp;관세&amp;nbsp;부과&amp;nbsp;전&amp;nbsp;확보한&amp;nbsp;제고로&amp;nbsp;인해&amp;nbsp;단기적&amp;nbsp;가격&amp;nbsp;상승이&amp;nbsp;억제되고&amp;nbsp;있다.&amp;nbsp;또한,&amp;nbsp;미국과&amp;nbsp;중국이&amp;nbsp;90일간&amp;nbsp;관세율&amp;nbsp;대폭&amp;nbsp;인하에&amp;nbsp;합의하며&amp;nbsp;현재는&amp;nbsp;물가&amp;nbsp;압력이&amp;nbsp;완화된&amp;nbsp;상태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관련 지표&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수치&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;5월 CPI 상승률(전년比)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2.4%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전문가 전망치 2.5% 하회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;5월 CPI 상승률(전월比)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;0.1%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전망치 0.2% 하회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;5월 근원 CPI(전년比)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2.8%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전망치 하회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;5월 근원 CPI(전월比)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;0.1%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전망치 하회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;FOMC 금리 동결 가능성&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;99.8%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;CME 페드워치 기준&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;현재 기준금리&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;4.25~4.5%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;동결 유지 전망&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPI(소비자 물가지수) : 일반 소비자가 구매하는 상품과 서비스의 가격 변동을 측정하는 지표&lt;/li&gt;
&lt;li&gt;근원 CPI(Core CPI) : CPI에서 에너지/식품을 제외한 지표로, 물가의 기조적 흐름을 파악&lt;/li&gt;
&lt;li&gt;CME 페드워치 : 시카고 상품거래소에서 금리선물 시장 데이터를 바탕으로 향후 금리 변동 확률을 예측하는 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금리와 소비자물가지수(CPI)는 중앙은행의 통화정책 관점에서 일반적으로 '정책 반응 관계'를 보인다. 인플레이션이 발생하면 중앙은행은 이를 억제하기 위해 기준금리를 인상하고, 반대로 물가가 하락하거나 경기 침체가 우려되면 금리를 인하하는 방식이다. 이는 단순한 숫자 간의 비례라기보다는, 수요를 조절하여 물가를 안정시키려는 정책적 대응이라고 생각할 수 있다. 최근 CPI 상승은 코로나 시기와 달리 공급망 차질보다는, 유가 변동성, 미중 무역 긴장 재점화 등 지정학적 리스크의 영향이 더 컸다고 볼 수 있다. 공급망은 대부분 정상화된 상태이며, 현재는 고율 관세와 에너지 가격이 물가에 영향을 주는 주요 변수로 작용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPI는 단순한 물가 지표가 아니라, 금융시장 전반에 영향을 주는 정책 신호의 출발점이라고 생각한다. CPI 변화에 따라 금리가 결정되고, 금리는 자산 가격, 대출 금리, 소비 패턴에 직접 영향을 미치기 때문이다. 특히 대부분의 금융 플랫폼과 서비스가 금리 민감 상품(예적금, 대출, 펀드)의 사용자 행동 데이터에 기반해 운영되기 때문에, 금리 상승이 예측될 경우 사용자별 대출 수요 감소 및 예금 선호 증가 등의 행태를 사전에 예측해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 금리 변화는 신용평가, 리스크 관리, 자산 배분 전략에도 영향을 주기 때문에, 그 파급효과를 데이터 기반 모델로 예측하고 대응 전략을 수립하는 역량도 필요할 것 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/117</guid>
      <comments>https://hr1588.tistory.com/117#entry117comment</comments>
      <pubDate>Thu, 12 Jun 2025 16:05:48 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 결합상품 마케팅</title>
      <link>https://hr1588.tistory.com/116</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749639371199&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;배민&amp;middot;티빙 손잡고 '결합상품 마케팅'&quot; data-og-description=&quot;결합상품 가입자 대상 양사 무료이용권 증정 배달의민족이 티빙과 손잡고 배민상품권 1200장과 티빙 프리미엄 연간 이용권을 증정하는 이벤트를 진행한다. 10일 우아한형제들이 운영하는 배달의&quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005506500?date=20250611&quot; data-og-url=&quot;https://n.news.naver.com/article/009/0005506500&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lNJ4f/hyY5aQsUgB/fC8ThnG7ndkjKYqGfhtvV0/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356,https://scrap.kakaocdn.net/dn/bBkCgj/hyY5awa5hU/c3ATlPATHs5WzvmOphzlE0/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/009/0005506500?date=20250611&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005506500?date=20250611&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lNJ4f/hyY5aQsUgB/fC8ThnG7ndkjKYqGfhtvV0/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356,https://scrap.kakaocdn.net/dn/bBkCgj/hyY5awa5hU/c3ATlPATHs5WzvmOphzlE0/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;배민&amp;middot;티빙 손잡고 '결합상품 마케팅'&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;결합상품 가입자 대상 양사 무료이용권 증정 배달의민족이 티빙과 손잡고 배민상품권 1200장과 티빙 프리미엄 연간 이용권을 증정하는 이벤트를 진행한다. 10일 우아한형제들이 운영하는 배달의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배달의민족과 티빙이 결합상품 가입자 대상 공동 마케팅을 통해 배민상품권 및 티빙 연간 이용권을 증정하는 이벤트를 시작했다. 첫 달 100원을 추가 결제하면 배민클럽으로 무료배달을 이용하면서 프로야구 중계도 시청할 수 있는 결합상품이다. 야구 시즌과 연계해 '배달 + 스포츠 중계 + 콘텐츠'라는 소비 트렌드를 반영한 프로모션으로, 결합상품의 체험률을 높이고 양사의 시너지 효과를 노리고 있다. 향후 배민은 티빙의 대표 예능 지식재산권(IP)을 활용한 콘텐츠 광고도 지속해서 선보일 예정이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;관련 지표&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수치&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;배민상품권 수량&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;100장/주 &amp;times; 4주 = 400장&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;주당 3명 추첨, 각 100장 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;티빙 연간 프리미엄 이용권&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;4장&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;매주 1장씩 증정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;배민상품권 금액&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;각 1만5천원&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;총 600만원 상당&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;첫 달 결합상품 이용료&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;100원&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;프로모션 특가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결합상품 : 두 개 이상의 서비스를 묶어 할인 또는 부가 혜택을 제공하는 마케팅 상품으로, 기사에서는 배민상품권 + 티빙 프리미엄이 예시&lt;/li&gt;
&lt;li&gt;지식재산권 예능 : 방송 프로그램이나 콘텐츠의 독창적인 요소에 대한 법적 보호 (저작권 관련)&lt;/li&gt;
&lt;li&gt;배민클럽 : 배달의민족 월 구독 유료 멤버십으로, 일정 금액 이상의 주문 시 무료배달 혜택을 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국내&amp;nbsp;내수&amp;nbsp;플랫폼&amp;nbsp;시장은&amp;nbsp;이미&amp;nbsp;포화&amp;nbsp;상태이며,&amp;nbsp;사용자들은&amp;nbsp;익숙한&amp;nbsp;서비스를&amp;nbsp;쉽게&amp;nbsp;이탈하지&amp;nbsp;않는다.&amp;nbsp;이러한&amp;nbsp;환경에서는&amp;nbsp;&amp;lsquo;서로&amp;nbsp;다른&amp;nbsp;산업&amp;nbsp;간의&amp;nbsp;결합&amp;nbsp;마케팅&amp;rsquo;이&amp;nbsp;유의미한&amp;nbsp;돌파구가&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있다고&amp;nbsp;생각한다.&amp;nbsp;배달과&amp;nbsp;OTT는&amp;nbsp;산업&amp;nbsp;구조상&amp;nbsp;다르지만,&amp;nbsp;사용자&amp;nbsp;경험에서&amp;nbsp;보면&amp;nbsp;매우&amp;nbsp;밀접하게&amp;nbsp;연결된&amp;nbsp;상품이다.&amp;nbsp;치킨이나&amp;nbsp;떡볶이를&amp;nbsp;시켜&amp;nbsp;먹으며&amp;nbsp;스포츠나&amp;nbsp;드라마를&amp;nbsp;시청하는&amp;nbsp;문화는&amp;nbsp;한국에서&amp;nbsp;매우&amp;nbsp;일반적이며,&amp;nbsp;이처럼&amp;nbsp;눈과&amp;nbsp;귀,&amp;nbsp;입을&amp;nbsp;동시에&amp;nbsp;만족시키는&amp;nbsp;소비&amp;nbsp;구조는&amp;nbsp;높은&amp;nbsp;시너지&amp;nbsp;효과를&amp;nbsp;발휘할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;이번&amp;nbsp;배민&amp;middot;티빙&amp;nbsp;결합&amp;nbsp;마케팅&amp;nbsp;사례는&amp;nbsp;단순한&amp;nbsp;혜택&amp;nbsp;제공을&amp;nbsp;넘어,&amp;nbsp;소비&amp;nbsp;채널의&amp;nbsp;확장과&amp;nbsp;사용자&amp;nbsp;체류시간&amp;nbsp;증가라는&amp;nbsp;전략적&amp;nbsp;효과를&amp;nbsp;낳을&amp;nbsp;수&amp;nbsp;있다고&amp;nbsp;본다.&amp;nbsp;티빙은&amp;nbsp;배달앱이라는&amp;nbsp;새로운&amp;nbsp;유입&amp;nbsp;채널을&amp;nbsp;확보하고,&amp;nbsp;배민은&amp;nbsp;티빙&amp;nbsp;콘텐츠를&amp;nbsp;통해&amp;nbsp;자사&amp;nbsp;고객의&amp;nbsp;앱&amp;nbsp;체류시간과&amp;nbsp;리텐션을&amp;nbsp;높일&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;특히&amp;nbsp;&amp;lsquo;프로야구&amp;nbsp;중계&amp;nbsp;+&amp;nbsp;배달&amp;nbsp;음식&amp;rsquo;이라는&amp;nbsp;조합은&amp;nbsp;한국의&amp;nbsp;라이프스타일에&amp;nbsp;최적화된&amp;nbsp;UX를&amp;nbsp;제공한다. &lt;br /&gt;&lt;br /&gt;이러한 상생 효과가 지속되기 위해서는 다음과 같은 요소에 주목해야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;티빙은 양질의 콘텐츠, 특히 배달과 잘 어울리는 스포츠 중계나 예능 IP를 안정적으로 확보&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;배달의민족은 가맹점 음식의 품질관리, 배달 정확도 및 속도를 철저히 관리해 고객의 기대 타이밍에 맞춘 경험 제공&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 야구 경기 시작 직전 배달을 원한 고객에게 경기 종료 후에 음식이 도착하면 결합상품의 의미가 퇴색될 수 있다. 결국, &lt;b&gt;고객의 생활 문맥 속에서 서비스를 얼마나 정교하게 연결시키는지가 관건&lt;/b&gt;이다. 서로 다른 산업이지만 &lt;b&gt;사용자의 &amp;lsquo;하루&amp;rsquo;를 함께 구성&lt;/b&gt;한다는 관점에서, 이러한 마케팅은 단순한 제휴를 넘어 사용자 경험 중심의 플랫폼 전략으로 확장될 수 있다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/116</guid>
      <comments>https://hr1588.tistory.com/116#entry116comment</comments>
      <pubDate>Wed, 11 Jun 2025 20:05:13 +0900</pubDate>
    </item>
    <item>
      <title>[MySQL] 주요 함수 및 연산자</title>
      <link>https://hr1588.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래머스 코딩테스트를 풀면서 몰랐거나 문제를 풀기 위해 검색해본 함수를 정리했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 조건 및 NULL 처리 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ IFNULL(expr1, expr2)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : expr1이 NULL이면 expr2를 반환&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT, WHERE, ORDER BY, HAVING 등 값이 들어가는 위치에서 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;SELECT IFNULL(score, 0) AS final_score FROM students;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 문자열 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ LOCATE(SUBSTR, STR)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : STR 문자열 내에 SUBSTR이 처음 당장하는 위치를 반환 (1부터 시작)&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT, WHERE, ORDER BY&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT LOCATE('world', 'Hello world'); -- 결과: 7&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ GROUP_CONCAT(EXPR)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 그룹별 데이터를 하나의 문자열로 결합&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT 절에서 GROUP BY와 함께 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;SELECT department, GROUP_CONCAT(employee_name) AS members
FROM employees
GROUP BY department;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 날짜/시간 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ DATE_FORMAT(DATE, FORMAT)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 날짜를 지정한 포맷으로 문자열로 변환&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT, WHERE, ORDER BY, GROUP BY&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT DATE_FORMAT(birthdate, '%Y-%m-%d') AS formatted_date FROM employees;
-- 출력 결과 : 2025-06-11

SELECT DATE_FORMAT(NOW(), '%H:%i:%s %p');
-- 출력 결과 : 15:30:45 PM&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt; 포맷 코드 &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt; 의미 &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt; 예시 출력 (2025-06-11 15:30:45 기준) &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%Y&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;4자리 연도&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%y&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2자리 연도&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%m&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2자리 월 (01~12)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;06&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%c&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;월 (숫자, 1~12)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%d&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2자리 일 (01~31)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%e&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;일 (숫자, 1~31)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%H&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;24시간 형식의 시 (00~23)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%h / %I&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;12시간 형식의 시 (01~12)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;03&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%i&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;분 (00~59)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%s / %S&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;초 (00~59)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;45&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%p&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;AM 또는 PM&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;PM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%W&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;요일 (영어)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Wednesday&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;%a&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;요일 (짧은 영어)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Wed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ DATEDIFF(DATE1, DATE2)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : DATE1 - DATE2 결과를 일 수로 반환&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT, WHERE&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT DATEDIFF('2024-05-05', '2024-05-01'); -- 결과: 4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 숫자 처리 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;FLOOR(num) / CEIL(NUM)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : FLOOR는 &lt;b&gt;내림&lt;/b&gt;, CEIL는 &lt;b&gt;올림&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT, WHERE, ORDER BY&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;SELECT FLOOR(5.7), CEIL(5.2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 윈도우 함수 (WINDOW FUNCTIONS)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 함수는 OVER() 절을 필수로 동반하며, 집계(GROUP BY) 없이도 행별 계산을 수행할 수 있는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OVER() 내부에는 정렬조건(ORDER BY), 파티션(PARTITION BY), 범위 제약(ROWS BETWEEN...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ RANK(), PERCENT_RANK()&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 행의 순위를 구하며, 동일값 존재시 동일 순위(순위 건너뜀)&lt;/li&gt;
&lt;li&gt;PERCENT_RANK()는 순위를 백분률로 변환&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT 절에서 OVER(ORDER BY)와 함께 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT name, score,
       RANK() OVER (ORDER BY score DESC) AS rank,
       PERCENT_RANK() OVER (ORDER BY score DESC) AS percent_rank
FROM exams;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ LEAD(EXPR, OFFSET, DEFAULT), LAG(EXPR, OFFSET, DEFAULT)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 현재 행을 기준으로 다음(LEAD) 또는 이전(LAG) 행의 값을 가져옴&lt;/li&gt;
&lt;li&gt;기본값은 생략 가능 (NULL 반환)&lt;/li&gt;
&lt;li&gt;사용 위치 : SELECT 절에서 OVER(ORDER BY)와 함께 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;SELECT name,
       score,
       LEAD(score) OVER (ORDER BY exam_date) AS next_score,
       LAG(score) OVER (ORDER BY exam_date) AS prev_score
FROM results;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 집계함수 OVER(...) + 범위 지정&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 윈도우 함수의 범위 조정&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 139px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;키워드&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;UNBOUNDED PRECEDING&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;첫 행부터 현재 행까지&lt;/b&gt; 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;1 PRECEDING&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;현재 행 기준 &lt;b&gt;앞의 한 행&lt;/b&gt; 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;CURRENT ROW&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;현재 행만 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;1 FOLLOWING&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;현재 행 기준 &lt;b&gt;다음 한 행&lt;/b&gt; 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;UNBOUNDED FOLLOWING&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;현재 행부터 &lt;b&gt;끝 행까지&lt;/b&gt; 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ROWS BETWEEN과 RANGE BETWEEN의 차이&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ROWS BETWEEN : &lt;b&gt;정확한 행 수 기준 범위 지정&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;RANGE BETWEEN : &lt;b&gt;값 기준&lt;/b&gt;으로 범위 지정 (동일 값 포함 가능, MySQL에서는 RANGE는 제한적 지원)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 누적 합 (처음 ~ 현재 행)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT
    NAME,
    SCORE,
    SUM(SCORE) OVER (ORDER BY EXAM_DATE
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RUNNING TOTAL)
FROM RESULTS;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 이동 평균&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT
    NAME,
    SCORE,
    AVG(SCORE) OVER (ORDER BY EXAM_DATE
    ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS MOVING_AVG
FROM RESULTS;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 부분 합계(그룹별 총합)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT
    DEPARTMENT,
    NAME,
    SUM(SALARY) OVER (PARTITION BY DEPARTMENT) AS DEPT_TOTAL_SALARY
FROM EMPLOYEES;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ROWS BETWEEN은 물리적 행 순서 기준이라 ORDER BY가 꼭 필요하다. (기본값은 RANGE BETWEEN)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 비트 연산자 및 진수 처리 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;CONV(EXPR, FROM_BASE, TO_BASE)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 진법 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;SELECT CONV('1010', 2, 10); -- 2진수 &amp;rarr; 10진수 변환 &amp;rarr; 결과: 10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;BIN(NUMBER)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 10진수를 2진수 문자열로 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT BIN(10); -- 결과: '1010'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;비트 연산자 (Bitwise Operators)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트 연산은 정수 값을 비트 단위로 조작한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7984%;&quot;&gt;연산자&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%;&quot;&gt;기능&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;예시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7984%;&quot;&gt;&amp;amp;&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%;&quot;&gt;대응되는 비트가 모두 1이면 1을 반환 (비트 AND 연산)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;5 &amp;amp; 3 &amp;rarr; 101 &amp;amp; 011 = 001 &amp;rarr; 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7984%;&quot;&gt;|&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%;&quot;&gt;대응되는 비트 중 하나라도 1이면 1을 반환 (비트 OR 연산)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;5 | 3 &amp;rarr; 101 | 011 = 111 &amp;rarr; 7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7984%;&quot;&gt;^&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%;&quot;&gt;대응되는 비트가 서로 다르면 1을 반환 (비트 XOR 연산)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;5 ^ 3 &amp;rarr; 101 ^ 011 = 110 &amp;rarr; 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7984%;&quot;&gt;~&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%;&quot;&gt;비트를 1이면 0으로, 0이면 1로 반전시킴 (비트 NOT 연산)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;~5 &amp;rarr; ~00000101 = 11111010&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7984%;&quot;&gt;&amp;lt;&amp;lt;&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%;&quot;&gt;비트를 왼쪽으로 지정한 수만큼 이동 (LEFT SHIFT 연산)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;5 &amp;lt;&amp;lt; 1 &amp;rarr; 101 &amp;rarr; 1010 &amp;rarr; 10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7984%;&quot;&gt;&amp;gt;&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%;&quot;&gt;부호를 유지하며 비트를 오른쪽으로 이동 (RIGHT SHIFT 연산)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;5 &amp;gt;&amp;gt; 1 &amp;rarr; 101 &amp;rarr; 10 &amp;rarr; 2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;실용 예시 : 유전자 정보 비교 (부분집합 관계 판단)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;(E1.GENOTYPE &amp;amp; E2.GENOTYPE) = E1.GENOTYPE&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;E1의 유전자 정보가 E2에 포함되는지(부분집합) 검사&lt;/li&gt;
&lt;li&gt;E1의 비트가 모두 E2에도 존재해야 AND 결과가 E1과 동일함&lt;/li&gt;
&lt;li&gt;5 &amp;amp; 7 = 5 =&amp;gt; 0101 &amp;amp; 0111 = 0101로, 5는 7의 부분집합임을 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. 조인 관련 (JOIN)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;NATURAL JOIN&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 공통 컬럼을 기준으로 자동 조인&lt;/li&gt;
&lt;li&gt;제약사항 : 공통 컬럼명이 정확히 일치해야 하며, 수동 제어 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM table1 NATURAL JOIN table2;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;SELF JOIN&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 : 동일 테이블을 자기 자신과 조인&lt;/li&gt;
&lt;li&gt;사용 목적 : 계층 구조, 상하관계 표현 시 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;SELECT e1.name, e2.name AS manager
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.id;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>코딩 테스트/SQL</category>
      <category>mysql</category>
      <category>코딩테스트</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/115</guid>
      <comments>https://hr1588.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 11 Jun 2025 01:35:36 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 퇴직연금</title>
      <link>https://hr1588.tistory.com/114</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749525182148&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;&amp;quot;원금보장서 투자로&amp;quot;&amp;hellip;퇴직연금 400조 돌파&quot; data-og-description=&quot;퇴직연금 적립금 431조7천억 근로자 직접 운용 계좌 늘어 IRP 2년새 17.2%서 22.9% 적립상위 펀드는 TDF가 대세 ETF는 美주식 투자하는 상품 작년 원금보장 수익률 3.67% 실적배당형은 9.96%로&quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005505812?date=20250610&quot; data-og-url=&quot;https://n.news.naver.com/article/009/0005505812&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/0Rqya/hyY48Zdc78/kbfFiqbi760QK7cY70B6l0/img.jpg?width=800&amp;amp;height=398&amp;amp;face=0_0_800_398,https://scrap.kakaocdn.net/dn/doOJTV/hyY48x8sdI/PnEaaT7W8SgcfCF4rl6Huk/img.jpg?width=800&amp;amp;height=398&amp;amp;face=0_0_800_398&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/009/0005505812?date=20250610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005505812?date=20250610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/0Rqya/hyY48Zdc78/kbfFiqbi760QK7cY70B6l0/img.jpg?width=800&amp;amp;height=398&amp;amp;face=0_0_800_398,https://scrap.kakaocdn.net/dn/doOJTV/hyY48x8sdI/PnEaaT7W8SgcfCF4rl6Huk/img.jpg?width=800&amp;amp;height=398&amp;amp;face=0_0_800_398');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;&quot;원금보장서 투자로&quot;&amp;hellip;퇴직연금 400조 돌파&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;퇴직연금 적립금 431조7천억 근로자 직접 운용 계좌 늘어 IRP 2년새 17.2%서 22.9% 적립상위 펀드는 TDF가 대세 ETF는 美주식 투자하는 상품 작년 원금보장 수익률 3.67% 실적배당형은 9.96%로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 말 기준 국내 퇴직연금 적립금이 사상 처음 400조원을 넘어 431.7조원을 기록했다. 특히 근로자가 직접 운용하는 DC형&amp;middot;IRP형 계좌의 비중과 실적배당형 상품 투자 비율이 빠르게 확대되면서, 퇴직연금이 &amp;lsquo;저축 중심&amp;rsquo;에서 &amp;lsquo;투자 중심&amp;rsquo;으로 전환되고 있다. 실적배당형 상품은 TDF(목표시점펀드)와 미국 주식형 ETF가 높은 비중을 차지하며 수익률도 원리금보장형(3.67%) 대비 월등히 높게 나타났다(9.96%). 또한 디폴트옵션제도 등 투자 경험이 적거나 익숙하지 않은 가입자를 위한 제도적 장치도 확대되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 디폴트옵션제도 : 퇴직연금(DC,&amp;nbsp;IRP)&amp;nbsp;가입자가&amp;nbsp;일정기간&amp;nbsp;동안&amp;nbsp;퇴직연금&amp;nbsp;적립금으로&amp;nbsp;금융상품을&amp;nbsp;매수하지&amp;nbsp;않을&amp;nbsp;경우,&amp;nbsp;(가입자가)&amp;nbsp;사전에&amp;nbsp;지정한&amp;nbsp;운용방법으로&amp;nbsp;적립금이&amp;nbsp;자동&amp;nbsp;운용되는&amp;nbsp;제도&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;퇴직연금 관련 지표&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수치&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;퇴직연금 적립금 총액&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;431.7조원&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전년比 ▲12.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;IRP 비중&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;22.9%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2년 간 ▲5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;실적배당형 투자금&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;75.2조원&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전년比 ▲53.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;원리금보장형 수익률&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;3.67%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2023년 기준&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;실적배당형 수익률&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;9.96%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2023년 기준&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;제도별 수익률 - IRP&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;5.86%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;개인운용&amp;middot;투자형 상품 중심&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;제도별 수익률 - DC&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;5.18%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;개인운용형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;제도별 수익률 - DB&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;4.04%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;회사운용형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;증권사 수익률 10% 초과 계좌 비중&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;31.7%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;DC+IRP 기준&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴직연금(DC/DB/IRP)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB형: 회사가 운용, 퇴직 시 확정된 금액 지급&lt;/li&gt;
&lt;li&gt;DC형: 근로자가 운용, 성과에 따라 금액 달라짐&lt;/li&gt;
&lt;li&gt;IRP형: 개인이 추가로 퇴직금이나 자산을 적립하는 계좌&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;원리금보장형 VS 실적배당형&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;원리금보장형&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;실적배당형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수익 구조&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;약정 금리 제공 (고정 수익)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;운용 실적에 따라 변동 (변동 수익)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;리스크 수준&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;매우 낮음 (사실상 없음)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;중~고위험 (시장 리스크 존재)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수익률(2023년)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;3.67%&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;9.96%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;운용 주체&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;주로 금융기관&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;투자자 또는 간접 운용 (TDF 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;적합 대상&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;안정적 자산 선호자, 고령층&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;수익 추구형, 장기 투자자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;대표 상품&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;정기예금, 적립형 보험&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;글로벌 ETF, TDF, 액티브 펀드&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원리금보장형: 원금과 약정이자를 보장하는 안정형 상품으로, 금융기관이 손실을 부담함 (예금처럼 안전한 연금)&lt;/li&gt;
&lt;li&gt;실적배당형 : 투자 성과에 따라 수익률이 결정되는 상품으로, 손실 위험이 있으나 고수익 가능성도 존재 (펀드처럼 수익을 추구하는 연금)&lt;/li&gt;
&lt;li&gt;TDF (Target Date Fund): 투자자의 은퇴 시점에 맞춰 자동으로 자산 배분을 조정하는 펀드. 시간이 지날수록 안정 자산 비중 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;그렇다면, DB는 원리금보장형, DC와 IRP는 실적배당형인가?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반드시 그런건 아니다. DB/DC/IRP는 '제도 유형' 이고, 원리금보장형/실적배당형은 '운용 방식' 이다. 즉, DB형이라고 해서 무조건 원리금보장형은 아니고, DC/IRP도 원리금보장형으로 운용 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 25.3488%;&quot;&gt;&lt;b&gt;제도 유형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.3953%;&quot;&gt;&lt;b&gt;운용 주체&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 26.2791%;&quot;&gt;&lt;b&gt;선택 가능한 운용 방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 36.8605%;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 25.3488%;&quot;&gt;&lt;b&gt;DB형&lt;/b&gt; (Defined Benefit)&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.3953%;&quot;&gt;&lt;b&gt;회사&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 26.2791%;&quot;&gt;주로 &lt;b&gt;원리금보장형&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 36.8605%;&quot;&gt;퇴직 시 받을 금액이 사전에 정해짐. 운용 책임은 회사가 짐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 25.3488%;&quot;&gt;&lt;b&gt;DC형&lt;/b&gt; (Defined Contribution)&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.3953%;&quot;&gt;&lt;b&gt;근로자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 26.2791%;&quot;&gt;원리금보장형 + 실적배당형 중 &lt;br /&gt;&lt;b&gt;자율 선택&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 36.8605%;&quot;&gt;적립금 운용 결과에 따라 퇴직금 변동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 25.3488%;&quot;&gt;&lt;b&gt;IRP형&lt;/b&gt; (Individual Retirement Pension)&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 11.3953%;&quot;&gt;&lt;b&gt;개인(근로자)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 26.2791%;&quot;&gt;원리금보장형 + 실적배당형 중 &lt;br /&gt;&lt;b&gt;자율 선택&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 36.8605%;&quot;&gt;개인퇴직계좌로, 본인이 직접 운용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A기업의 DB형 퇴직연금은 회사가 직원 퇴직금 전액을 &amp;lsquo;정기예금&amp;rsquo;에 넣어둔다면 원리금보장형 운용&lt;/li&gt;
&lt;li&gt;B직원의 IRP 계좌에서 미국 ETF에 투자한다면 실적배당형 운용&lt;/li&gt;
&lt;li&gt;C직원은 DC 계좌에 일부는 정기예금(보장형), 일부는 펀드(실적배당형)에 나눠 운용할 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 누가 운용하고, 어디에 넣느냐에 따라서 차이가 발생하는 것이지 운용 방식이 지정된 것은 아니다. 다만, 최근에는 근로자가 주체적으로 투자 상품을 선택하는 실적배당형 상품의 비중이 증가하고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴직연금이 &quot;저축&quot; 중심에서 &quot;투자&quot; 중심으로 이동하고 있다는 점은 단순히 금융상품의 변화에 그치지 않고, 은퇴 세대의 자산 운용 철학 자체가 변화하고 있음을 보여준다. 과거에는 원금 보장을 중시하는 안전 지향적 성향이 강했다면, 이제는 리스크를 감수하더라도 더 나은 수익을 추구하는 경향이 뚜렷해지고 있다. 실제로 기사 원문을 보면 2023년 기준 실적배당형 수익률은 약 10%로, 원리금보장형 대비 2배 이상 높은 수익률을 기록했음을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 맥락에서 개인이 수익률을 극대화하고자 한다면 DC형 또는 IRP 계좌에서 실적배당형 상품에 자산을 배분하는 전략이 타당하다고 생각된다. 특히 IRP는 근로자가 전적으로 운용 결정을 내릴 수 있고, ETF와 TDF와 같은 다양한 상품 선택이 가능하므로, 장기적으로 목표 기반의 투자 전략을 실행하기에 유리한 구조이다. 단, 투자 상품에 대한 기본적인 이해도 및 리스크 관리 능력이 전제되어야 함을 잊으면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금융 서비스 제공자의 관점에서도 변화에 대응할 전략이 요구된다. 단순한 상품 제공에서 벗어나, 퇴직연금 전용 TDF / 글로벌 ETF 포트폴리오 등 개인화된 투자형 상품을 기획해야한다. 동시에, 현재 발전하고 있는 AI를 활용한 포트폴리오 추천, 리밸런싱 및 리스크 진단 등의 디지털 자산관리 서비스를 경쟁사 대비 어떤 부분에서 차별점을 강조할지도 고민해야 한다. 결국 저축이 아닌 투자로서의 연금은 금융사의 비즈니스 모델 변화까지 요구하고 있다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/114</guid>
      <comments>https://hr1588.tistory.com/114#entry114comment</comments>
      <pubDate>Tue, 10 Jun 2025 12:13:17 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 스테이블 코인</title>
      <link>https://hr1588.tistory.com/113</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749428937178&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;주니어 생글생글&quot; data-og-description=&quot;한국경제신문이 만드는 어린이 경제신문. 경제, 독서, 논술, 어린이 기자단 운영&quot; data-og-host=&quot;jrsgsg.hankyung.com&quot; data-og-source-url=&quot;https://www.hankyung.com/article/202506079950E&quot; data-og-url=&quot;https://jrsgsg.hankyung.com/article/202506079950E&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hHwAw/hyY5exZMA4/ROOPWoPAg9nCj8C3IDu2k1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/iHsJz/hyY5iAoGb7/mc0X8MvBuqKWUmjRQ8EszK/img.jpg?width=4284&amp;amp;height=6158&amp;amp;face=0_0_4284_6158,https://scrap.kakaocdn.net/dn/bmGJtU/hyY5d6Wuac/Bbdj76Vt6rzwEkwOW6YTQK/img.png?width=771&amp;amp;height=1108&amp;amp;face=0_0_771_1108&quot;&gt;&lt;a href=&quot;https://www.hankyung.com/article/202506079950E&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hankyung.com/article/202506079950E&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hHwAw/hyY5exZMA4/ROOPWoPAg9nCj8C3IDu2k1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/iHsJz/hyY5iAoGb7/mc0X8MvBuqKWUmjRQ8EszK/img.jpg?width=4284&amp;amp;height=6158&amp;amp;face=0_0_4284_6158,https://scrap.kakaocdn.net/dn/bmGJtU/hyY5d6Wuac/Bbdj76Vt6rzwEkwOW6YTQK/img.png?width=771&amp;amp;height=1108&amp;amp;face=0_0_771_1108');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;주니어 생글생글&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;한국경제신문이 만드는 어린이 경제신문. 경제, 독서, 논술, 어린이 기자단 운영&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jrsgsg.hankyung.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트코인은&amp;nbsp;&amp;lsquo;디지털&amp;nbsp;자산&amp;rsquo;으로서&amp;nbsp;주목받지만,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1)&amp;nbsp;국가&amp;middot;중앙은행이&amp;nbsp;보증하지&amp;nbsp;않고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2)&amp;nbsp;가격&amp;nbsp;변동성이&amp;nbsp;커서&amp;nbsp;교환‧가치저장의&amp;nbsp;조건을&amp;nbsp;충족하지&amp;nbsp;못한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가격 안정성을 보완하려고 진짜 돈과 연결해 가치 변동성을 낮춘 스테이블 코인이 등장했으나, 발행&amp;middot;담보 구조가 불투명해 여전히 법정 화폐로 인정받지 못한다. 화폐로 쓰이려면 기술적‧제도적 안전장치와 신뢰 확보가 선결 과제다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;비트코인&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;스테이블 코인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;가치 기준&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;희소성(채굴량 한정)과 시장 수요&amp;middot;공급에 따라 자유롭게 변동&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;달러&amp;middot;유로&amp;middot;엔 등 &lt;b&gt;법정화폐&lt;/b&gt; 또는 금&amp;middot;국채 등 실물자산에 1 : 1로 연동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;가격 변동성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;매우 높음 - 하루에도 수 %~수십 % 변동 가능&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;연동 자산 가치에 맞춰 &lt;b&gt;낮도록 설계&lt;/b&gt; (1 달러 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;발행&amp;middot;운영 주체&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;탈중앙(비영리 재단 없음), 알고리즘&amp;middot;채굴자 네트워크&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;민간 발행사(테더, 서클 등) 또는 프로토콜(DAI)에서 담보&amp;middot;알고리즘 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;공급 메커니즘&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;블록체인 합의(비트코인 2,100만 개 상한)&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;발행사가 준비금 예치&amp;middot;소각, 알고리즘 담보 조정 등으로 유통량 조절&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;주요 사용처&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;디지털 &amp;lsquo;금&amp;rsquo; 성격의 가치 저장&amp;middot;투자 자산, &lt;br /&gt;일부 국가의 송금&amp;middot;결제&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;거래소 간 자금 이동, 디파이(DeFi) 담보, 크로스보더 결제&amp;middot;헤지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;신뢰 기반&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;네트워크 분산&amp;middot;암호화 기술 및 채굴자 합의&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;준비금 투명성(감사 보고서)&amp;middot;담보 초과율&amp;middot;스마트컨트랙트 안정성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;규제&amp;middot;감독&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;국가별 가상자산법 적용(자금세탁&amp;middot;세금 중심)&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;준비금&amp;middot;발행사 라이선스 등 &lt;b&gt;결제&amp;middot;자금결제 규제&lt;/b&gt;로 편입 시도 중&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; width: 13.1395%;&quot;&gt;&lt;b&gt;리스크 요인&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 34.1861%;&quot;&gt;가격 붕괴&amp;middot;채굴 집중&amp;middot;해킹&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 52.5581%;&quot;&gt;준비금 부실&amp;middot;연동 실패 (디패깅)&amp;middot;발행사 신용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;물품 화폐: 금&amp;middot;은 등 스스로 가치가 있는 물건을 화폐로 사용한 형태&lt;/li&gt;
&lt;li&gt;법화(法定 화폐): 국가가 법으로 &amp;lsquo;돈&amp;rsquo;임을 보증해 통용되는 화폐(현행 지폐&amp;middot;주화)&lt;/li&gt;
&lt;li&gt;디지털 자산: 블록체인 기반으로 발행&amp;middot;거래되는 전자적 형태의 자산&lt;/li&gt;
&lt;li&gt;스테이블 코인: 달러 등 실물 자산에 연동해 가치를 1:1로 고정하도록 설계한 암호자산&lt;/li&gt;
&lt;li&gt;가격 변동성: 자산 가격이 짧은 기간에 크게 오르내리는 특성으로, 화폐 기능 저해 요인&lt;/li&gt;
&lt;li&gt;크로스보더 결제 : 본인의&amp;nbsp;국가와&amp;nbsp;다른&amp;nbsp;국가&amp;nbsp;간에&amp;nbsp;이루어지는&amp;nbsp;결제&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스테이블 코인?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스테이블 코인이란 말 그대로 가격이 안정적인 가상화폐이다. 일반적으로 미국 달러(USD)가 기준으로 쓰이며, 1코인 = 1달러를 유지하는 암호화폐라고 보면 된다. 화폐 가치가 1달러로 고정되기 때문에 비트코인과 같은 기존 암호화폐보다 결제 수단으로는 유리하다. 하지만, 코인이 화폐로 사용되려면 많은 사람들이 이용해야하는데 가격 변동성이 심해 인정받지 못하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 코인 투자자 대부분은 수익을 위해 투자를 진행할텐데 화폐로서 가치가 고정된다면 해당 코인을 구매할 이유가 사라진다. 그래서 어떻게 화폐 가치를 고정시키는지 찾아보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1)&amp;nbsp;법정화폐&amp;nbsp;담보형&amp;nbsp;(Fiat-collateralized)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방식: 민간 발행사(거래소&amp;middot;핀테크)가 은행 계좌에 USD 등 실물 화폐를 예치 &amp;rarr; 같은 양의 토큰 발행&lt;/li&gt;
&lt;li&gt;장점: 구조 단순, 담보 가치 확인이 쉬워 가격 안정성 증가&lt;/li&gt;
&lt;li&gt;단점: 발행사를 반드시 신뢰해야 하는 중앙집중화&amp;middot;불투명성(감사&amp;middot;준비금 의혹)&lt;/li&gt;
&lt;li&gt;주요 용도: 거래소의 기축통화, 크로스보더 송금&lt;/li&gt;
&lt;li&gt;예시: USDT(Tether), TrueUSD, Digix Gold(금 담보)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 암호화폐 담보형 (Crypto-collateralized)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방식: 스마트 컨트랙트가 ETH‧BTC 등 변동성 큰 코인을 초과담보로 묶어 두고 스테이블코인 발행&lt;/li&gt;
&lt;li&gt;예: 150달러어치 ETH 예치 &amp;rarr; 100달러어치 DAI 발행(담보비율 150%)&lt;/li&gt;
&lt;li&gt;장점: 온체인 담보&amp;middot;거버넌스로 탈중앙화 구현, 투명성 확보&lt;/li&gt;
&lt;li&gt;단점: 담보 자체가 흔들리면 청산 위험, 자본 비효율(담보 과잉), 구조가 복잡&lt;/li&gt;
&lt;li&gt;주요 용도: 암호자산 담보 대출&amp;middot;레버리지, 디파이(DeFi) 결제(금융기관 없이 운영되는 결제 방식)&lt;/li&gt;
&lt;li&gt;예시: DAI(MakerDAO), Havven&amp;rarr;Synthetix&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3)&amp;nbsp;알고리즘/시뇨리지형&amp;nbsp;(Algorithmic&amp;nbsp;/&amp;nbsp;Seigniorage)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방식: 담보 없이 공급량을 자동 조절(주식&amp;middot;채권 토큰 발행/소각)해 1달러 목표를 유지&lt;/li&gt;
&lt;li&gt;장점: 담보 불필요 &amp;rarr; 자본 효율성 높고 완전 탈중앙 지향&lt;/li&gt;
&lt;li&gt;단점: 수요 신뢰가 흔들리면 연쇄 붕괴(뱅크런 위험), 설계가 난해&amp;middot;검증 사례 적음&lt;/li&gt;
&lt;li&gt;주요 용도: 아직 실험 단계, 투자&amp;middot;디파이 실험 토큰&lt;/li&gt;
&lt;li&gt;예시: Basis(Basecoin)(프로젝트 종료), Ampleforth, (과거) TerraUSD&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;STO(토큰증권) 법제화가 속도를 내고 스테이블 코인이 결제 수단으로 자리 잡기 시작하면, 전통적인 카드&amp;middot;간편결제 네트워크는 즉각적인 경쟁 압력에 직면할 가능성이 존재한다. 이런 환경에서 기업이 우위를 확보하려면 미리 토큰형 포인트와 같은 유사 시스템을 시범적으로 도입해 고객 이용 패턴과 혜택별 유입 효과를 정밀하게 측정하고, 그 데이터를 토대로 락인 전략을 고도화할 수 있겠다는 생각이 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 규제 세부안, 감독 권한 배분, 소비자 보호&amp;middot;과세 방식 등이 아직 확정되지 않아 사업 추진 속도가 제약될 수 있다는 점은 불확실성으로 남아 있다. 따라서 위험을 최소화하려면 내부 테스트넷에서 소액 결제 중심의 포인트 결제를 운영하면서 API&amp;middot;디지털 지갑 연동 구조를 먼저 정비하고, 향후 규제 가이드라인이 확정되는 즉시 범위를 확장해 나가는 단계적 로드맵을 제시해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정보 출처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외계어 없이 스테이블 코인 이해하기 : &lt;a href=&quot;https://brunch.co.kr/@bumgeunsong/55#comments&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://brunch.co.kr/@bumgeunsong/55#comments&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/113</guid>
      <comments>https://hr1588.tistory.com/113#entry113comment</comments>
      <pubDate>Mon, 9 Jun 2025 09:29:25 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] AI가 대체할 수 없는 것은?</title>
      <link>https://hr1588.tistory.com/112</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749401439410&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[금융라운지] &amp;quot;AI 먹거리 늘리자&amp;quot;&amp;hellip; 사활건 카드사&quot; data-og-description=&quot;우리&amp;middot;BC, 신사업 발굴팀 신설 생성형 AI 통해 광고 제작도 내수 부진에 수익성을 확보하기 위해 진땀을 흘리고 있는 카드사들이 대대적인 인공지능(AI) 전략 강화에 나선다. AI 사업을 전담하는 조&quot; data-og-host=&quot;n.news.naver.com&quot; data-og-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005505102?date=20250609&quot; data-og-url=&quot;https://n.news.naver.com/article/009/0005505102&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kuEvh/hyY4fqtifw/qqhji3bHss4US7WpbhhTHK/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356,https://scrap.kakaocdn.net/dn/OMkD3/hyY33wLOcx/YjTk170itHJ5MHisHTk7ik/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356&quot;&gt;&lt;a href=&quot;https://n.news.naver.com/article/newspaper/009/0005505102?date=20250609&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://n.news.naver.com/article/newspaper/009/0005505102?date=20250609&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kuEvh/hyY4fqtifw/qqhji3bHss4US7WpbhhTHK/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356,https://scrap.kakaocdn.net/dn/OMkD3/hyY33wLOcx/YjTk170itHJ5MHisHTk7ik/img.jpg?width=800&amp;amp;height=420&amp;amp;face=322_205_473_356');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[금융라운지] &quot;AI 먹거리 늘리자&quot;&amp;hellip; 사활건 카드사&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;우리&amp;middot;BC, 신사업 발굴팀 신설 생성형 AI 통해 광고 제작도 내수 부진에 수익성을 확보하기 위해 진땀을 흘리고 있는 카드사들이 대대적인 인공지능(AI) 전략 강화에 나선다. AI 사업을 전담하는 조&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;n.news.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot; data-start=&quot;532&quot; data-end=&quot;674&quot;&gt;국내&amp;nbsp;주요&amp;nbsp;카드사들이&amp;nbsp;생성형&amp;nbsp;AI&amp;nbsp;전담&amp;nbsp;조직을&amp;nbsp;속속&amp;nbsp;신설하며&amp;nbsp;비용&amp;nbsp;절감&amp;middot;영업&amp;nbsp;효율화&amp;middot;신사업&amp;nbsp;발굴에&amp;nbsp;속도를&amp;nbsp;내고&amp;nbsp;있다.&amp;nbsp;우리카드는&amp;nbsp;디지털본부에&amp;nbsp;AI추진팀을&amp;nbsp;신설해&amp;nbsp;광고&amp;nbsp;제작까지&amp;nbsp;AI로&amp;nbsp;대체했고,&amp;nbsp;삼성&amp;middot;롯데&amp;middot;BC&amp;middot;신한&amp;middot;하나카드&amp;nbsp;역시&amp;nbsp;별도&amp;nbsp;AI&amp;nbsp;조직을&amp;nbsp;운영하며&amp;nbsp;빅데이터&amp;nbsp;분석&amp;middot;외부&amp;nbsp;데이터&amp;nbsp;결합&amp;nbsp;등으로&amp;nbsp;경쟁력을&amp;nbsp;강화&amp;nbsp;중이다.&amp;nbsp;내수&amp;nbsp;부진&amp;nbsp;속&amp;nbsp;AI&amp;nbsp;기반&amp;nbsp;비용&amp;nbsp;절감과&amp;nbsp;신규&amp;nbsp;수익원&amp;nbsp;확보가&amp;nbsp;업계&amp;nbsp;공통&amp;nbsp;과제로&amp;nbsp;부상했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;수치&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;AI 전담 조직 운영 카드사&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;6곳&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;우리&amp;middot;삼성&amp;middot;롯데&amp;middot;BC&amp;middot;신한&amp;middot;하나 &amp;lsaquo;AI 사업을 전담&amp;rsaquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;삼성카드 AI 조직 출범&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2023년&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;카드사 중 가장 빠름 &amp;lsaquo;2023년 카드사 중&amp;rsaquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;롯데&amp;middot;BC AI 부서 신설&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2023.12&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;생성형 AI 사업 총괄 &amp;lsaquo;지난해 12월 롯데카드&amp;rsaquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;우리카드 AI추진팀 신설&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2025.06&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;업무 전반 AI 적용 &amp;lsaquo;최근 업무 전반에 AI&amp;rsaquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;광고 제작비 절감률&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;확실하지 않음&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;생성형 AI 광고 활용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성형 AI: 텍스트&amp;middot;이미지&amp;middot;음악 등 새 콘텐츠를 만들어내는 AI(예: GPT, DALL&amp;middot;E)&lt;/li&gt;
&lt;li&gt;AI추진팀: 사내 AI 전략&amp;middot;프로젝트를 전담하는 조직. 데이터&amp;middot;모델&amp;middot;서비스 통합 관리&lt;/li&gt;
&lt;li&gt;빅데이터 분석 고도화: 대규모 결제&amp;middot;소비 데이터를 AI로 분석해 인사이트&amp;middot;신사업 창출&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 금융권에서는 생성형 AI가 광고&amp;middot;마케팅처럼 전문성이 요구되던 분야까지 빠르게 침투하면서 인력 개편이 눈앞에 다가오고 있다. 카드사를 포함해 증권&amp;middot;보험&amp;middot;은행 등 각사에서는 AI 전담 조직을 만들어 비용을 절감하고 ROI를 높이는 동시에, 더 적은 인력으로 더 많은 콘텐츠를 생산하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 흐름 속에서 데이터를 다루는 인력은 전통적 분석 기술뿐 아니라 AI 모델을 활용&amp;middot;해석&amp;middot;감독하는 역량까지 갖추어야 한다. 특히 서비스 자체의 품질이 점차 상향 평준화되는 만큼, 고객이 언제&amp;middot;어디서&amp;middot;어떻게 서비스를 경험하는지를 정밀하게 추적&amp;middot;진단해 문제 구간을 찾아내는 &amp;lsquo;접점 분석&amp;rsquo;이 조직 경쟁력을 좌우할 가능성이 크다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/112</guid>
      <comments>https://hr1588.tistory.com/112#entry112comment</comments>
      <pubDate>Sun, 8 Jun 2025 18:46:34 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 안면인식 결제</title>
      <link>https://hr1588.tistory.com/111</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749309325099&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;&amp;ldquo;여기에 얼굴 가져다 대보세요&amp;rdquo;&amp;hellip;지갑도 휴대폰도 없어도 된다, 안면인식 결제 체험해보니 - &quot; data-og-description=&quot;카드&amp;middot;휴대전화 없이 1초만에 결제 토스, 페이스페이 시범 운영 나서 네이버페이&amp;middot;신한카드도 준비 AI기술&amp;middot;FDS 활용해 보안 고도화&quot; data-og-host=&quot;www.mk.co.kr&quot; data-og-source-url=&quot;https://www.mk.co.kr/news/economy/11336382&quot; data-og-url=&quot;https://www.mk.co.kr/news/economy/11336382&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bii2cn/hyY43CRW5n/kIqVdcy2YFfclb4kuUCmDk/img.jpg?width=1600&amp;amp;height=1386&amp;amp;face=0_0_1600_1386,https://scrap.kakaocdn.net/dn/tKMoP/hyY5ga85yG/VkLAQkolNwVYYYuFLMSyJ0/img.jpg?width=1600&amp;amp;height=1386&amp;amp;face=0_0_1600_1386,https://scrap.kakaocdn.net/dn/QFIyn/hyY32djPF5/YUYCIGTwkFBjNoXoAwxWEK/img.jpg?width=700&amp;amp;height=607&amp;amp;face=0_0_700_607&quot;&gt;&lt;a href=&quot;https://www.mk.co.kr/news/economy/11336382&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.mk.co.kr/news/economy/11336382&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bii2cn/hyY43CRW5n/kIqVdcy2YFfclb4kuUCmDk/img.jpg?width=1600&amp;amp;height=1386&amp;amp;face=0_0_1600_1386,https://scrap.kakaocdn.net/dn/tKMoP/hyY5ga85yG/VkLAQkolNwVYYYuFLMSyJ0/img.jpg?width=1600&amp;amp;height=1386&amp;amp;face=0_0_1600_1386,https://scrap.kakaocdn.net/dn/QFIyn/hyY32djPF5/YUYCIGTwkFBjNoXoAwxWEK/img.jpg?width=700&amp;amp;height=607&amp;amp;face=0_0_700_607');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;여기에 얼굴 가져다 대보세요&amp;rdquo;&amp;hellip;지갑도 휴대폰도 없어도 된다, 안면인식 결제 체험해보니 -&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;카드&amp;middot;휴대전화 없이 1초만에 결제 토스, 페이스페이 시범 운영 나서 네이버페이&amp;middot;신한카드도 준비 AI기술&amp;middot;FDS 활용해 보안 고도화&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.mk.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;674&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;토스&amp;middot;네이버&amp;middot;신한카드가 안면인식 결제를 앞다퉈 상용화하며 &amp;lsquo;휴대폰 없는 결제&amp;rsquo; 시장을 열고 있다. 토스는 전국 편의점까지 확대해 범용성을 확보했고, 각 사는 라이브니스&amp;middot;FDS&amp;middot;3D 카메라 토큰화 등으로 위&amp;middot;변조 방지와 개인정보 보호를 강화 중이다. 간편결제 수요가 급증하는 가운데, 서비스 선점과 제휴처 확대 경쟁이 본격화되고 있다.&lt;/p&gt;
&lt;p data-end=&quot;674&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 139px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;지표&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;수치&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;결제속도&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;1초&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;카페 결제속도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;간편지급 이용건수&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;3,072만건/일&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;2024년 말&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;간편지급 이용액&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;9,594억 원/일&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;2024년 말&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;이용액 증가율&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;+58 %&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;2021比&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;신한 페이스페이 출시&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;&lt;b&gt;2019년&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px; text-align: center;&quot;&gt;최초 상용화&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;라이브니스(Liveness): 사진&amp;middot;영상&amp;middot;마스크 등 위조 얼굴을 회피하도록 실제 생체 여부를 판단하는 기술&lt;/li&gt;
&lt;li&gt;FDS(이상거래탐지시스템): 24시간 거래 패턴을 모니터링해 의심&amp;middot;사기 결제를 차단하는 보안 시스템&lt;/li&gt;
&lt;li&gt;간편지급: 생체정보&amp;middot;비밀번호만으로 송금&amp;middot;결제가 가능한 지급결제 서비스(예: 페이스페이, 삼성페이)&lt;/li&gt;
&lt;li&gt;토큰화(Tokenization): 실물 카드번호를 무의미한 난수(토큰)로 대체해 결제 시 유출 위험을 낮추는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안면인식 결제는 편의점&amp;middot;대중교통처럼 &lt;b&gt;소액 다빈도 결제가 이뤄지는 생활밀착형 채널&lt;/b&gt;에 빠르게 확산되면 기존 스마트폰 NFC 결제를 대체할 잠재력이 크다. 생체정보 보호 규제와 단말기 구축&amp;middot;유지 비용이 초기 확산 속도를 늦출 수 있지만, 선점 효과가 가져올 &lt;b&gt;고객 락인과 결제&amp;middot;위치&amp;middot;소비 패턴 등 데이터 자산의 가치&lt;/b&gt;를 높게 평가해 비용 부담을 감수하면서도 가맹점 확보 경쟁에 나설 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결제 매커니즘(기술) 자체는 거의 비슷하기 때문에, 금융사 별로 치열한 경쟁이 예상된다. 범용성을 위해서는 결국 결제가 가능한 거래처가 확대되어야 한다. 지금은 애플페이 제휴처가 많이 확대되었지만, 초창기 도입 시기에는 편리한 시스템임에도 불구하고 결제가 가능한 매장이 부족해서 사용자들에게 많은 아쉬움을 남겼다. 초기에 발생할 단말기 비용 역시 무시 못할 수준이기 때문에 어떤 제휴처를 확보하느냐에 따라 경쟁력이 확보될 것으로 생각된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 안면인식 결제의 승부처는 3가지라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 단말기 설치 비용을 줄이거나 보조하는 파트너십 모델&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 대중교통, 프랜차이즈 등 네트워크 효과가 큰 가맹처 우선 제휴&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 사용자 혜택(쿠폰/포인트)로 초기 트래픽을 확보하는 인센티브 설계&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/111</guid>
      <comments>https://hr1588.tistory.com/111#entry111comment</comments>
      <pubDate>Sat, 7 Jun 2025 14:02:48 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] STO</title>
      <link>https://hr1588.tistory.com/110</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749213138709&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;가상자산 지원 정책 기대에 STO주 '쑥' - 매일경제&quot; data-og-description=&quot;토큰증권 조속한 법제화 등디지털자산 생태계 확대 전망&quot; data-og-host=&quot;www.mk.co.kr&quot; data-og-source-url=&quot;https://www.mk.co.kr/news/stock/11336266&quot; data-og-url=&quot;https://www.mk.co.kr/news/stock/11336266&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8feg0/hyY394gibs/mznYTPFPNZkcjHovz4citk/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/oM2uI/hyY34aPbkW/Ci2IM5g4PepseusyYsuuCk/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://www.mk.co.kr/news/stock/11336266&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.mk.co.kr/news/stock/11336266&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8feg0/hyY394gibs/mznYTPFPNZkcjHovz4citk/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/oM2uI/hyY34aPbkW/Ci2IM5g4PepseusyYsuuCk/img.jpg?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;가상자산 지원 정책 기대에 STO주 '쑥' - 매일경제&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;토큰증권 조속한 법제화 등디지털자산 생태계 확대 전망&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.mk.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot; data-start=&quot;532&quot; data-end=&quot;674&quot;&gt;6&amp;nbsp;일&amp;nbsp;대선에서&amp;nbsp;이재명&amp;nbsp;대통령이&amp;nbsp;당선되면서&amp;nbsp;비트코인&amp;nbsp;현물&amp;nbsp;ETF&amp;nbsp;도입&amp;middot;토큰증권(STO)&amp;nbsp;법제화&amp;middot;원화&amp;nbsp;스테이블코인&amp;nbsp;추진&amp;nbsp;등&amp;nbsp;친(親)&amp;nbsp;가상자산&amp;nbsp;공약이&amp;nbsp;탄력&amp;nbsp;받을&amp;nbsp;것이란&amp;nbsp;기대가&amp;nbsp;커지자,&amp;nbsp;STO&amp;nbsp;관련주들이&amp;nbsp;일제히&amp;nbsp;급등했다. &lt;br /&gt;&lt;br /&gt;대표적으로 핑거(STO 발행&amp;middot;유통 솔루션) 주가는 대선 레이스가 시작된 4월 4일 이후 6월5 일까지 56.12 % 상승했고, 아이티아이즈(발행 솔루션 FASTO-CS) 45.91 %, 갤럭시아머니트리(항공엔진 조각투자 준비) 22.54 %, 뱅크웨어글로벌(블록체인 기반 STO 소프트웨어 개발) 8.52 % 올랐다. &lt;br /&gt;&lt;br /&gt;업계는&amp;nbsp;&amp;ldquo;정치적&amp;nbsp;혼란만&amp;nbsp;없으면&amp;nbsp;STO&amp;nbsp;조기&amp;nbsp;법제화가&amp;nbsp;빠르게&amp;nbsp;진행될&amp;nbsp;것&amp;rdquo;이라며,&amp;nbsp;국채&amp;middot;미술품&amp;middot;특허&amp;nbsp;등&amp;nbsp;비정형&amp;nbsp;자산까지&amp;nbsp;제도권&amp;nbsp;거래가&amp;nbsp;가능해질&amp;nbsp;것으로&amp;nbsp;전망했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot; data-start=&quot;532&quot; data-end=&quot;674&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.2325%;&quot;&gt;&lt;b&gt;ETF(STO 기준)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 68.7209%;&quot;&gt;실제 비트코인을 보유해 &lt;b&gt;비트코인 현물 가격&lt;/b&gt;을 그대로 추적하는 상장지수펀드로, 투자자는 코인 직접 보관 없이 주식처럼 매매 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.2325%;&quot;&gt;&lt;b&gt;STO&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 68.7209%;&quot;&gt;&lt;b&gt;블록체인 기반 디지털 증권&lt;/b&gt; 발행&amp;middot;유통 방식. 기존 주식&amp;middot;채권뿐 아니라 부동산&amp;middot;미술품 등 실물 자산도 쪼개서 토큰 형태로 거래 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.2325%;&quot;&gt;&lt;b&gt;패스토(FASTO-CS)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 68.7209%;&quot;&gt;기초자산 등록&amp;rarr;공모&amp;rarr;청약&amp;rarr;매매까지 &lt;b&gt;토큰증권 전 과정을 지원&lt;/b&gt;하며, 기존 증권 시스템&amp;middot;블록체인 API를 통합한 기업용 소프트웨어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.2325%;&quot;&gt;&lt;b&gt;신탁수익증권&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 68.7209%;&quot;&gt;신탁재산(금전&amp;middot;부동산&amp;middot;항공엔진 등)을 운용해 발생한 &lt;b&gt;수익을 받을 권리&lt;/b&gt;를 표시한 증권. 조각투자에서 기초 자산을 신탁해 증권을 발행할 때 활용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.2325%;&quot;&gt;&lt;b&gt;블록체인&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 68.7209%;&quot;&gt;네트워크 참가자가 &lt;b&gt;공유&amp;middot;검증&amp;middot;불변&lt;/b&gt; 특성을 갖는 분산형 데이터베이스. 스마트계약으로 거래 자동화&amp;middot;추적 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.2325%;&quot;&gt;&lt;b&gt;STO &amp;harr; 블록체인&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 68.7209%;&quot;&gt;STO는 법적으로 &lt;b&gt;증권&lt;/b&gt;이지만, &lt;b&gt;블록체인에 기록&lt;/b&gt;해 투명성&amp;middot;상호운용성을 확보한다는 점이 핵심. 이상적인 구조는 공공기관이 유통을 관리하되 &lt;b&gt;퍼블릭 체인(누구나 자유롭게 접근하고 참여할 수 있는 네트워크)에 거래 기록&lt;/b&gt;을 남기는 모델&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜 블록체인이 굳이 필요한가?&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2498&quot; data-start=&quot;2251&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2307&quot; data-start=&quot;2251&quot;&gt;&lt;b&gt;시장 범위 확대&lt;/b&gt; &amp;ndash; 분할 + 국경 무관 유통으로 &lt;b&gt;새 투자자&amp;middot;발행자&lt;/b&gt; 풀을 개방&lt;/li&gt;
&lt;li data-end=&quot;2352&quot; data-start=&quot;2308&quot;&gt;&lt;b&gt;리스크 축소&lt;/b&gt; &amp;ndash; 원자적 결제로 &lt;b&gt;결제&amp;middot;청산 리스크&lt;/b&gt; 최소화&lt;/li&gt;
&lt;li data-end=&quot;2417&quot; data-start=&quot;2353&quot;&gt;&lt;b&gt;운영 효율&lt;/b&gt; &amp;ndash; 자동화&amp;middot;공유 원장으로 &lt;b&gt;인력‧IT 비용&lt;/b&gt; 절감, 특히 장외&amp;middot;사모&amp;middot;실물 자산 영역&lt;/li&gt;
&lt;li data-end=&quot;2498&quot; data-start=&quot;2418&quot;&gt;&lt;b&gt;혁신 플랫폼&lt;/b&gt; &amp;ndash; 자산이 &amp;lsquo;토큰 API&amp;rsquo;가 되면 &lt;b&gt;DeFi&amp;middot;AI 퀀트&amp;middot;콤포저블 파생&lt;/b&gt; 등 2차-3차 금융 상품이 빠르게 탄생&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;2540&quot; data-start=&quot;2500&quot; data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;STO가 &amp;ldquo;기존 주식&amp;middot;채권을 실물로 확장&amp;rdquo;&lt;/b&gt;하려 할 때,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2708&quot; data-start=&quot;2541&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2625&quot; data-start=&quot;2541&quot;&gt;&lt;b&gt;신뢰&amp;middot;속도&amp;middot;글로벌 유통&lt;/b&gt;을 동시에 만족시키는 가장 보편적 엔진이 현재로선 블록체인(DLT)이기 때문에 &amp;ldquo;핵심 기술&amp;rdquo;로 지목&lt;/li&gt;
&lt;li data-end=&quot;2708&quot; data-start=&quot;2626&quot;&gt;다만 기술만으로 해결되지 않는 &lt;b&gt;법&amp;middot;회계&amp;middot;거버넌스 과제&lt;/b&gt;(프라이버시, 스케일, 규제 정합성)는 여전히 숙제로 남아 있음을 잊지 말아야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투자 시장에 새로운 가능성이 열리고 있다. AI의 급속한 발전으로 여러 증권사가 AI 기반 포트폴리오를 앞다퉈 내놓고, 고객 경험(UX)도 빠르게 개선되고 있다. 결국 &lt;b&gt;&amp;ldquo;어떤 상품에 투자할 것인가&amp;rdquo;&lt;/b&gt;가 더욱 중요해지는 셈이다. 앞으로는 주식&amp;middot;채권을 넘어 부동산, 미술품, 백년가게 등 실물 자산까지 손쉽게 거래할 수 있는 환경이 조성될 것으로 예상된다. 유형 자산은 직관적인 가치를 지니므로, 투자자가 공감할 만한 스토리 있는 상품을 만들 수 있다는 점이 매력적이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기획&amp;middot;분석 관점에서는 &amp;ldquo;어떤 실물 자산이 매력적인가?&amp;rdquo;를 데이터로 입증해야 한다. 매력적인 상품의 예시로, S&amp;amp;P 500 ETF가 인기인 이유는 편입 종목이 꾸준히 흑자를 내는 기업으로 리밸런싱되며, 장기 보유 시 비교적 안정적인 수익을 기대할 수 있기 때문이다. &lt;br /&gt;&lt;br /&gt;STO(토큰증권) 법제화가 본격화되면&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. 실물 자산의 수익성&amp;middot;리스크&amp;middot;변동성 데이터를 표준화하고, &lt;/b&gt;&lt;br /&gt;&lt;b&gt;2. AI가 이를 학습해 종합 매력도 스코어를 산출하며, &lt;/b&gt;&lt;br /&gt;&lt;b&gt;3. 그 결과를 투자자 UX에 직관적으로 시각화하는&amp;nbsp;것이&amp;nbsp;&amp;lsquo;매력적인&amp;nbsp;상품&amp;rsquo;&amp;nbsp;설계의&amp;nbsp;핵심&amp;nbsp;과제가&amp;nbsp;될&amp;nbsp;것이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/110</guid>
      <comments>https://hr1588.tistory.com/110#entry110comment</comments>
      <pubDate>Fri, 6 Jun 2025 15:23:52 +0900</pubDate>
    </item>
    <item>
      <title>[경신스] 임베디드 금융</title>
      <link>https://hr1588.tistory.com/109</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기사 요약&lt;/b&gt;&lt;/h2&gt;
&lt;figure id=&quot;og_1749114088879&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;삼성&amp;middot;KB 협업 통했다&amp;hellip;'모니모 통장' 조기 완판&quot; data-og-description=&quot;삼성&amp;middot;KB 협업 통했다&amp;hellip;'모니모 통장' 조기 완판, 출시 40일 만에 20만좌 개설 연 4% 금리 혜택이 인기 비결 은행&amp;middot;비은행 1위 그룹 '시너지'&quot; data-og-host=&quot;www.hankyung.com&quot; data-og-source-url=&quot;https://www.hankyung.com/article/2025060455301&quot; data-og-url=&quot;https://www.hankyung.com/article/2025060455301&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/umpsj/hyY0qlXFPD/kMSDibH3n8DEauwklfHry1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.hankyung.com/article/2025060455301&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hankyung.com/article/2025060455301&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/umpsj/hyY0qlXFPD/kMSDibH3n8DEauwklfHry1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;삼성&amp;middot;KB 협업 통했다&amp;hellip;'모니모 통장' 조기 완판&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;삼성&amp;middot;KB 협업 통했다&amp;hellip;'모니모 통장' 조기 완판, 출시 40일 만에 20만좌 개설 연 4% 금리 혜택이 인기 비결 은행&amp;middot;비은행 1위 그룹 '시너지'&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hankyung.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;삼성금융네트웍스와 KB국민은행이 협업해 선보인 &lt;b&gt;모니모 KB매일이자 통장&lt;/b&gt;이 출시 40일 만에 &lt;b&gt;사전예약분 20만 개를 모두 소진&lt;/b&gt;하며 완판됐다. 이 통장은 삼성금융의 통합 플랫폼 모니모에 연동되는 수시입출식 통장(일명 파킹통장)으로, &lt;b&gt;예치금 200만 원까지 연 4%의 금리를 제공&lt;/b&gt;해 주목을 받았다. 이는 시중은행 평균 정기예금 금리(2.33%) 대비 월등히 높은 수준이다.&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;530&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;모니모 통장은 &lt;b&gt;지난해 금융위원회 혁신금융서비스로 지정&lt;/b&gt;된 바 있으며, 이번에 &lt;b&gt;총 계좌 발급 한도인 22.5만 개 중 21.5만 개가 이미 개설&lt;/b&gt;됐다. 대표적인 콜라보 파킹통장인 네이버페이 머니 하나통장이 20만 개 판매에 45일 걸린 것에 비하면, 판매 속도 역시 상당히 빠른 편이다.&lt;/p&gt;
&lt;p data-end=&quot;530&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;674&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;두 금융그룹은 이 인기에 힘입어 금융당국에 &lt;b&gt;계좌 판매 한도 확대&lt;/b&gt;를 요청할 예정이며, &lt;b&gt;향후에는 적금&amp;middot;외환 등 다양한 협업 상품 출시도 계획&lt;/b&gt;하고 있다. 이처럼 &lt;b&gt;은행권 1위와 비은행권 1위의 협업&lt;/b&gt;은 강력한 시너지로 이어지고 있다는 평가다.&lt;/p&gt;
&lt;p data-end=&quot;674&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추가 정보&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 101.279%; height: 173px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 42px;&quot;&gt;
&lt;td style=&quot;height: 42px; width: 20.5814%;&quot;&gt;&lt;b&gt;파킹통장&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 42px; width: 80.5815%;&quot;&gt;예금처럼 자금을 넣어두면서도 &lt;b&gt;언제든 출금 가능하고&lt;/b&gt;, 일정 금리를 제공하는 &lt;b&gt;수시입출식 통장&lt;/b&gt;. '자금을 잠시 세워두는(Parking) 용도'라는 뜻에서 유래. 예: 하루만 맡겨도 이자 발생(토스뱅크)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 55px;&quot;&gt;
&lt;td style=&quot;height: 55px; width: 20.5814%;&quot;&gt;&lt;b&gt;임베디드 금융&lt;/b&gt;&lt;br /&gt;&lt;b&gt;(Embedded Finance)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 55px; width: 80.5815%;&quot;&gt;금융 서비스(계좌, 결제, 대출 등)를 &lt;b&gt;비금융 플랫폼 내에 통합하여 제공&lt;/b&gt;하는 방식. 예: 삼성전자 앱에서 보험가입, 커머스 앱에서 계좌개설. 플랫폼 사용자 경험을 해치지 않고 금융 접근성 확대 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 42px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 42px;&quot;&gt;&lt;b&gt;혁신금융서비스&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.5815%; height: 42px;&quot;&gt;기존&amp;nbsp;금융서비스의&amp;nbsp;제공&amp;nbsp;내용&amp;middot;방식&amp;middot;형태&amp;nbsp;등&amp;nbsp;&lt;b&gt;차별성이&amp;nbsp;인정되는&amp;nbsp;금융업&amp;nbsp;&lt;/b&gt;또는&amp;nbsp;이와&amp;nbsp;관련된&amp;nbsp;업무를&amp;nbsp;수행하는&amp;nbsp;과정에서&amp;nbsp;제공되는&amp;nbsp;서비스에&amp;nbsp;대해&amp;nbsp;&lt;b&gt;규제&amp;nbsp;적용&amp;nbsp;특례&lt;/b&gt;를&amp;nbsp;인정하는&amp;nbsp;제도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; width: 20.5814%;&quot;&gt;&lt;b&gt; 계좌 판매 한도란&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 80.5815%;&quot;&gt;금융위원회는 혁신금융서비스로 지정된 신상품에 대해 테스트 목적으로 계좌 개설 수량에 제한을 둠&lt;br /&gt;이는 금융소비자 보호 및 시장안정성 확보를 위한 장치이며, 서비스가 검증되면 단계적으로 한도 증액 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; width: 20.5814%;&quot;&gt;&lt;b&gt;왜 한도가 필요할까?&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 80.5815%;&quot;&gt;혁신금융 지정 상품은 규제 유예를 받는 실험적 상품이므로, 초기에는 제한된 규모로 운영해 위험을 관리 &lt;br /&gt;지나치게 많은 고객에게 적용될 경우 시스템적 리스크나 소비자 피해로 이어질 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;나의 의견&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국내 금융 플랫폼의 경쟁이 이미 과부하 상태로 진입했다는 생각이 든다. 대다수의 고객이 본인들이 사용하는 은행 혹은 증권사와 같은 여러가지 금융 서비스가 존재하는데, 과도기에 빠진 고객을 다른 곳에서 유입시키기 위해 서로가 서로를 활용하는 형태로 보인다. 복잡한 절차 제거 (대출/투자/가입 과정의 간소화), 모바일 중심 접근성, 일상과 연결된 서비스 (예: 카카오톡&amp;middot;토스 내에서 바로 금융 거래), 기존 금융사에 없는 유연성(예: 소액 투자, 간편 대출, 높은 금리 파킹통장 등) 등 여러가지 요인들이 고객들의 마음을 움직이는 요인으로 추정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 금융시장에서 기존에 경험해 보지 못한 서비스로 사용자 경험을 해치지 않고, 자연스럽게 서비스를 확대하는 것이 주요한 전략으로 활용될 수 있음을 시사한다. 고객이 새로운 서비스를 거부감 없이 받아들일 수 있도록 일상 속에 스며드는 금융 서비스를 설계하는 것이 향후 금융 서비스 기획자의 주요 과제가 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모니모 KB 외에 다른 혁신금융서비스로 어떤 것이 있고, 왜 소비자들이 이를 선호하는지 추가적으로 찾아보자. 아래의 금융규제 샌드박스에서 관련 내용을 찾아볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1749114049052&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;금융규제 샌드박스 | Sandbox&quot; data-og-description=&quot;혁신금융서비스, 지정대리인, 위탁테스트, 규제신속확인 등 금융규제 샌드박스 안내&quot; data-og-host=&quot;sandbox.fintech.or.kr&quot; data-og-source-url=&quot;https://sandbox.fintech.or.kr/business/enterprise_intro.do?lang=ko&quot; data-og-url=&quot;https://sandbox.fintech.or.kr&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hG5c5/hyY36F9KZt/aRwPMWGZEAgdQ2p2DPSLN0/img.png?width=1280&amp;amp;height=720&amp;amp;face=760_156_916_326,https://scrap.kakaocdn.net/dn/cgPlep/hyY1f5Bzcd/T1Ayt90acaAn4haUABb0zK/img.png?width=1280&amp;amp;height=720&amp;amp;face=716_172_852_320&quot;&gt;&lt;a href=&quot;https://sandbox.fintech.or.kr/business/enterprise_intro.do?lang=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sandbox.fintech.or.kr/business/enterprise_intro.do?lang=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hG5c5/hyY36F9KZt/aRwPMWGZEAgdQ2p2DPSLN0/img.png?width=1280&amp;amp;height=720&amp;amp;face=760_156_916_326,https://scrap.kakaocdn.net/dn/cgPlep/hyY1f5Bzcd/T1Ayt90acaAn4haUABb0zK/img.png?width=1280&amp;amp;height=720&amp;amp;face=716_172_852_320');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;금융규제 샌드박스 | Sandbox&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;혁신금융서비스, 지정대리인, 위탁테스트, 규제신속확인 등 금융규제 샌드박스 안내&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sandbox.fintech.or.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>경제신문 스터디</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/109</guid>
      <comments>https://hr1588.tistory.com/109#entry109comment</comments>
      <pubDate>Thu, 5 Jun 2025 17:36:35 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 조건에 맞는 개발자 찾기</title>
      <link>https://hr1588.tistory.com/108</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DEVELOPERS 테이블에서 Python이나 C# 스킬을 가진 개발자의 정보를 조회하려 합니다. 조건에 맞는 개발자의 ID, 이메일, 이름, 성을 조회하는 SQL 문을 작성해 주세요.결과는 ID를 기준으로 오름차순 정렬해 주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 문제를 풀려면 비트 연산자의 개념을 알아야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;비트 연산자란?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의 : 비트 연산자는 정수를 이진수(0,1)의 자리 단위로 처리하는 연산자&lt;/li&gt;
&lt;li&gt;종류
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;논리 연산 : AND(&amp;amp;), OR(|), XOR(^), NOT(~)&lt;/li&gt;
&lt;li&gt;시프트 연산 : 좌측 시프트(&amp;lt;&amp;lt;), 우측 시프트(&amp;gt;&amp;gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 85px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;A&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;B&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;b&gt;A &amp;amp; B&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 비트가 모두 1일 때만 결과가 1이 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;6&amp;nbsp;&amp;nbsp;=&amp;nbsp;0000&amp;nbsp;0110₂&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;3&amp;nbsp;&amp;nbsp;=&amp;nbsp;0000&amp;nbsp;0011₂&amp;nbsp;&amp;nbsp; &lt;br /&gt;------------------------&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;6&amp;amp;3=&amp;nbsp;0000&amp;nbsp;0010₂&amp;nbsp;=&amp;nbsp;2&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SQL에서 비트 연산자 활용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CODE&amp;nbsp;=&amp;nbsp;2ⁿ&lt;br /&gt;&amp;nbsp;&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;rArr;&amp;nbsp;2⁰&amp;nbsp;&amp;rArr;&amp;nbsp;스킬&amp;nbsp;A&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;rArr;&amp;nbsp;2&amp;sup1;&amp;nbsp;&amp;rArr;&amp;nbsp;스킬&amp;nbsp;B&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;rArr;&amp;nbsp;2&amp;sup2;&amp;nbsp;&amp;rArr;&amp;nbsp;스킬&amp;nbsp;C&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;hellip;&amp;nbsp;&amp;nbsp;&lt;br /&gt;256&amp;nbsp;&amp;rArr;&amp;nbsp;2⁸&amp;nbsp;&amp;rArr;&amp;nbsp;Python&amp;nbsp;&amp;nbsp;&lt;br /&gt;128&amp;nbsp;&amp;rArr;&amp;nbsp;2⁷&amp;nbsp;&amp;rArr;&amp;nbsp;C#&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SKILLCODES 테이블의 CODE 컬럼이 2^N 형태의 비트이고, DEVELOPER 테이블의 SKILL_CODE 테이블에 여러 스킬 비트의 조합이 저장되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 특정 개발자의 SKILL CODE가 400(110 010 000)이면 256, 128, 16 스킬을 보유하고 있는 것 이다. Python은 256, C#은 1024이니까 JOIN 조건에 개발자가 해당 스킬 비트를 포함하는지를 검사하고, 그 스킬 중 이름에 Python 혹은 C#이 포함되었는지를 확인하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡해 보일 수 있지만, 여러 속성을 하나의 정수로 묶어서 관리할 수 있고, 조건 비교 시 산술 연산보다 연산 비용이 적기 때문에 비트 연산자를 알아두면 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;최종 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746602296302&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    DISTINCT
    D.ID,
    D.EMAIL,
    D.FIRST_NAME,
    D.LAST_NAME
FROM DEVELOPERS D
JOIN SKILLCODES S
ON (D.SKILL_CODE &amp;amp; S.CODE) = S.CODE AND S.NAME IN ('Python','C#')
ORDER BY D.ID&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;400&amp;nbsp; = 1 1001 0000₂&amp;nbsp;&amp;nbsp;&lt;br /&gt;256&amp;nbsp; = 1 0000 0000₂&amp;nbsp;&amp;nbsp;&lt;br /&gt;-------------------------------&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;400&amp;amp;256 = 1 0000 0000₂ = 256&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 자리에서 둘 다 1인 경우에만 1이 남는다. 즉, 연산 결과가 S.CODE와 같아야만 개발자가 해당 스킬을 가지고 있다고 판단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 S.CODE가 64라면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;110010000₂ (400) &amp;amp; 001000000₂ (64) = 000000000₂ (0) 0 &amp;ne; 64 이므로 FALSE(스킬 미보유)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&amp;amp;' 연산으로 두 수의 공통된 &amp;lsquo;1&amp;rsquo; 비트만 뽑아내고, 그 결과가 S.CODE(단일 비트)와 같으면 해당 비트(스킬)를 포함한 것이다. SQL에서는 이 조건만으로 개발자가 Python(CODE=256) 또는 C#(CODE=1024) 스킬을 가졌는지를 빠르게 검사할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/108</guid>
      <comments>https://hr1588.tistory.com/108#entry108comment</comments>
      <pubDate>Mon, 5 May 2025 17:00:46 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 대장균의 크기에 따라 분류하기 2</title>
      <link>https://hr1588.tistory.com/107</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대장균 개체의 크기를 내름차순으로 정렬했을 때 상위 0% ~ 25% 를 'CRITICAL', 26% ~ 50% 를 'HIGH', 51% ~ 75% 를 'MEDIUM', 76% ~ 100% 를 'LOW' 라고 분류합니다. 대장균 개체의 ID(ID) 와 분류된 이름(COLONY_NAME)을 출력하는 SQL 문을 작성해주세요. 이때 결과는 개체의 ID 에 대해 오름차순 정렬해주세요 . 단, 총 데이터의 수는 4의 배수이며 같은 사이즈의 대장균 개체가 서로 다른 이름으로 분류되는 경우는 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;내가 푼 쿼리&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1746012411752&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH PERCENT_COLONY AS
(
SELECT
    ID,
    PERCENT_RANK() OVER(ORDER BY SIZE_OF_COLONY DESC) AS PERCENT_OF_COLONY
FROM ECOLI_DATA
)

SELECT 
    ID,
    CASE
        WHEN PERCENT_OF_COLONY &amp;lt;= 0.25 THEN &quot;CRITICAL&quot;
        WHEN PERCENT_OF_COLONY &amp;lt;= 0.5 THEN &quot;HIGH&quot;
        WHEN PERCENT_OF_COLONY &amp;lt;= 0.75 THEN &quot;MEDIUM&quot;
        ELSE &quot;LOW&quot;
    END AS COLONY_NAME
FROM PERCENT_COLONY
ORDER BY ID;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECOLI_DATA&amp;nbsp;테이블에는&amp;nbsp;각&amp;nbsp;균주의&amp;nbsp;ID와&amp;nbsp;군집&amp;nbsp;크기(SIZE_OF_COLONY)&amp;nbsp;정보가&amp;nbsp;있다.&amp;nbsp;이번&amp;nbsp;문제를&amp;nbsp;해결하기&amp;nbsp;위해서는&amp;nbsp;PERCENT_RANK()&amp;nbsp;함수를&amp;nbsp;활용하여,&amp;nbsp;특정&amp;nbsp;값을&amp;nbsp;기준으로&amp;nbsp;각&amp;nbsp;행의&amp;nbsp;상대적인&amp;nbsp;순위를&amp;nbsp;계산한&amp;nbsp;뒤&amp;nbsp;구간별로&amp;nbsp;분류해야&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;PERCENT_RANK()는&amp;nbsp;전체&amp;nbsp;데이터&amp;nbsp;중&amp;nbsp;해당&amp;nbsp;행이&amp;nbsp;차지하는&amp;nbsp;상대적&amp;nbsp;백분위&amp;nbsp;순위(0~1)&amp;nbsp;를&amp;nbsp;반환한다.&amp;nbsp;ORDER&amp;nbsp;BY&amp;nbsp;SIZE_OF_COLONY&amp;nbsp;DESC를&amp;nbsp;지정했기&amp;nbsp;때문에,&amp;nbsp;군집&amp;nbsp;크기가&amp;nbsp;클수록&amp;nbsp;PERCENT_RANK()&amp;nbsp;값은&amp;nbsp;0에&amp;nbsp;가까워지고,&amp;nbsp;작을수록&amp;nbsp;1에&amp;nbsp;수렴한다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;함수는&amp;nbsp;구간별&amp;nbsp;분류나&amp;nbsp;등급화를&amp;nbsp;할&amp;nbsp;때&amp;nbsp;특히&amp;nbsp;유용하며,&amp;nbsp;데이터가&amp;nbsp;균등하지&amp;nbsp;않거나&amp;nbsp;분포가&amp;nbsp;왜곡된&amp;nbsp;경우에도&amp;nbsp;안정적으로&amp;nbsp;작동한다.&amp;nbsp;또한&amp;nbsp;CASE문과&amp;nbsp;함께&amp;nbsp;사용하면,&amp;nbsp;데이터를&amp;nbsp;자동으로&amp;nbsp;라벨링하거나&amp;nbsp;범주화할&amp;nbsp;수&amp;nbsp;있어&amp;nbsp;다양한&amp;nbsp;실무&amp;nbsp;상황에&amp;nbsp;적용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/107</guid>
      <comments>https://hr1588.tistory.com/107#entry107comment</comments>
      <pubDate>Tue, 29 Apr 2025 20:55:04 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 대장균들의 자식의 수 구하기</title>
      <link>https://hr1588.tistory.com/106</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대장균&amp;nbsp;개체의&amp;nbsp;ID(ID)와&amp;nbsp;자식의&amp;nbsp;수(CHILD_COUNT)를&amp;nbsp;출력하는&amp;nbsp;SQL&amp;nbsp;문을&amp;nbsp;작성해주세요.&amp;nbsp;자식이&amp;nbsp;없다면&amp;nbsp;자식의&amp;nbsp;수는&amp;nbsp;0으로&amp;nbsp;출력해주세요.&amp;nbsp;이때&amp;nbsp;결과는&amp;nbsp;개체의&amp;nbsp;ID&amp;nbsp;에&amp;nbsp;대해&amp;nbsp;오름차순&amp;nbsp;정렬해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;내가 푼 쿼리&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1746010511832&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
    E1.ID,
    COUNT(COALESCE(E2.PARENT_ID)) AS CHILD_COUNT
FROM ECOLI_DATA E1
LEFT JOIN ECOLI_DATA E2
ON E2.PARENT_ID = E1.ID
GROUP BY 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 테이블에 서로 다른 계층이 존재한다. 이런 경우, SELF JOIN을 활용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECOLI_DATA 테이블은 아래와 같은 계층적 구조를 가지고 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;ID&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;PARENT_ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 행은 하나의 개체를 나타내며, PARENT_ID는 상위 개체의 ID를 참조한다. 즉, 1번은 최상위 개체이며, 2번과 3번은 1번의 자식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SELF JOIN은 같은 테이블을 두 번 이상 조인하여 자신과 비교할 때 사용하는 방식이다. 이번 쿼리에서는 ECOLI_DATA 테이블을 E1, E2로 각각 참조하여 ID와 PARENT_ID를 비교했다. &lt;br /&gt;&lt;br /&gt;1. JOIN 기준과 매칭 방식&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;E1은 부모, E2는 자식 역할&lt;/li&gt;
&lt;li&gt;따라서 E2.PARENT_ID = E1.ID 로 매칭해야 부모-자식 관계를 정확히 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. LEFT JOIN을 사용하는 이유&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자식이 없는 부모도 결과에 포함되도록 하기 위함&lt;/li&gt;
&lt;li&gt;LEFT JOIN은 왼쪽(E1)의 모든 레코드를 유지하고, 매칭되는 자식(E2)이 없어도 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. COUNT 함수에서의 유의사항&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;COUNT는 기본적으로 NULL 값을 제외&lt;/li&gt;
&lt;li&gt;따라서 COUNT(E2.PARENT_ID) 또는 COUNT(COALESCE(E2.PARENT_ID))를 사용하면 자식이 있는 경우만 세어짐을 보장할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SELF&amp;nbsp;JOIN은&amp;nbsp;같은&amp;nbsp;테이블을&amp;nbsp;자기&amp;nbsp;자신과&amp;nbsp;조인해&amp;nbsp;관계를&amp;nbsp;분석하는&amp;nbsp;방식이며,&amp;nbsp;LEFT&amp;nbsp;JOIN을&amp;nbsp;활용하여&amp;nbsp;부모&amp;nbsp;기준으로&amp;nbsp;자식&amp;nbsp;개체를&amp;nbsp;연결하고,&amp;nbsp;PARENT_ID와&amp;nbsp;ID를&amp;nbsp;매칭하여&amp;nbsp;계층&amp;nbsp;구조를&amp;nbsp;분석할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;COUNT&amp;nbsp;함수는&amp;nbsp;NULL을&amp;nbsp;제외하므로,&amp;nbsp;자식이&amp;nbsp;있을&amp;nbsp;때만&amp;nbsp;정확한&amp;nbsp;개수로&amp;nbsp;계산된다.&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/106</guid>
      <comments>https://hr1588.tistory.com/106#entry106comment</comments>
      <pubDate>Sat, 26 Apr 2025 20:48:11 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기</title>
      <link>https://hr1588.tistory.com/105</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과&amp;nbsp; &amp;nbsp; CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '세단' 또는 'SUV' 인 자동차 중 2022년 11월 1일부터 2022년 11월 30일까지 대여 가능하고 30일간의 대여 금액이 50만원 이상 200만원 미만인 자동차에 대해서 자동차 ID, 자동차 종류, 대여 금액(컬럼명: FEE) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 자동차 종류를 기준으로 오름차순 정렬, 자동차 종류까지 같은 경우 자동차 ID를 기준으로 내림차순 정렬해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;내가 푼 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1744553261937&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH CHECK_CAR_STATUS AS(
SELECT
    CAR_ID,
    MAX(START_DATE &amp;lt; &quot;2022-11-01&quot; AND END_DATE &amp;gt; &quot;2022-11-30&quot;) AS STATUS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
GROUP BY CAR_ID)

SELECT
    *
FROM(
SELECT
    C1.CAR_ID,
    C1.CAR_TYPE,
    ROUND(DAILY_FEE * (1 - C3.DISCOUNT_RATE/100) * 30) AS FEE
FROM CAR_RENTAL_COMPANY_CAR C1
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN C3
ON C1.CAR_TYPE = C3.CAR_TYPE
WHERE
    C1.CAR_TYPE IN ('세단','SUV') AND 
    C1.CAR_ID IN (
        SELECT
            CAR_ID
        FROM CHECK_CAR_STATUS
        WHERE STATUS = 1) AND
    C3.DURATION_TYPE = &quot;30일 이상&quot;) SUB
WHERE FEE BETWEEN 500000 AND 2000000
ORDER BY FEE DESC, CAR_TYPE, CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 문제는 쿼리가 맞다고 생각했지만, 문제를 풀지 못했다. 어떤 점이 문제인지 확인해보고, 효율적인 방법을 생각해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1744553537234&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MAX(START_DATE &amp;lt; '2022-11-01' AND END_DATE &amp;gt; '2022-11-30') AS STATUS&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;2022년 11월 1일부터 2022년 11월 30일까지 대여 가능&quot; 이라는 조건이 이 문제의 핵심이다. 내가 푼 쿼리의 의도는 시작 날짜가11월 1일 이전이고, 반납 날짜가 11월 30일 이후인 상태 여부 COLUMN을 만든 것이다. 그러나, 이 조건은 대여가 전체 기간(즉, 11월 1일보다 이전에 시작하고 11월 30일 보다 이후에 끝나는 경우)만 판단하여, 부분적으로 겹치는 대여가 누락된다. 11월 1일부터 11월 30일까지 하루라도 대여 중인 차량을 조건으로 찾아야 문제를 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1744553764005&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MAX(START_DATE &amp;lt;= '2022-11-30' AND END_DATE &amp;gt;= '2022-11-01') AS STATUS&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 조건을 동시에 만족하면, 대여 기간이 11월 1일부터 11월 30일 사이의 어떤 시점과도 겹친다는 의미다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 대여가 10월 25일에 시작하여 11월 5일에 끝난다고 가정해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;10월 25일 &amp;lt; 11월 30일 (참)&lt;/li&gt;
&lt;li&gt;11월 5일 &amp;gt; 11월 1일 (참)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 11월 기간 중에 대여 중인 날이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 대여가 10월 20일에 시작하여 10월 29일에 끝난다고 가정해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;10월 20일 &amp;lt; 11월 30일 (참)&lt;/li&gt;
&lt;li&gt;10월 29일 &amp;lt; 11월 1일 (거짓)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 11월 기간 중에 대여 중인 날이 존재하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 어느 한쪽만 조건에 맞지 않더라도 대여 기간이 겹치지 않는다. 두 조건을 모두 만족하면 11월 기간 중에 대여 중인 날이 있다고 해석하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;최종 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1744554459374&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH CarFees AS (
  SELECT 
    C.CAR_ID, 
    C.CAR_TYPE, 
    ROUND(C.DAILY_FEE * (1 - D.DISCOUNT_RATE / 100) * 30) AS FEE
  FROM CAR_RENTAL_COMPANY_CAR C
  JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN D 
    ON C.CAR_TYPE = D.CAR_TYPE 
    AND D.DURATION_TYPE = '30일 이상'
  WHERE C.CAR_TYPE IN ('세단','SUV')
)
SELECT *
FROM CarFees CF
WHERE FEE BETWEEN 500000 AND 2000000
  -- 지정한 기간에 대여 중인 기록이 없는 자동차 선택
  AND NOT EXISTS (
      SELECT 1 
      FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H
      WHERE H.CAR_ID = CF.CAR_ID
        AND H.START_DATE &amp;lt; '2022-11-30'
        AND H.END_DATE &amp;gt; '2022-11-01'
  )
ORDER BY FEE DESC, CAR_TYPE, CAR_ID DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건을 수정하면서, 불필요한 집계(CTE 내 MAX 사용)을 피하고 HAVING 절에 조건을 넣으면 부분 집합을 바로 필터링하므로 불필요한 집계 연산을 피할 수 있다.&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/105</guid>
      <comments>https://hr1588.tistory.com/105#entry105comment</comments>
      <pubDate>Sun, 13 Apr 2025 23:15:36 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 물고기 종류 별 대어 찾기</title>
      <link>https://hr1588.tistory.com/104</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물고기 종류 별로 가장 큰 물고기의 ID, 물고기 이름, 길이를 출력하는 SQL 문을 작성해주세요. 물고기의 ID 컬럼명은 ID, 이름 컬럼명은 FISH_NAME, 길이 컬럼명은 LENGTH로 해주세요. 결과는 물고기의 ID에 대해 오름차순 정렬해주세요. 단, 물고기 종류별 가장 큰 물고기는 1마리만 있으며 10cm 이하의 물고기가 가장 큰 경우는 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 문제는 2가지 방법으로 문제를 풀었는데, 아래에 하나씩 리뷰 후 서로 비교해서 더 효율적인 방법을 제시했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;내가 푼 쿼리&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. RANK() + IN 서브쿼리&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1743258542901&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
    F1.ID,
    F2.FISH_NAME,
    F1.LENGTH
FROM FISH_INFO F1
LEFT JOIN FISH_NAME_INFO F2
ON F1.FISH_TYPE = F2.FISH_TYPE
WHERE F1.ID IN (
    SELECT ID
    FROM (
        SELECT
            ID,
            FISH_TYPE,
            RANK() OVER(PARTITION BY FISH_TYPE ORDER BY LENGTH DESC) AS FISH_RANK,
            LENGTH
        FROM FISH_INFO
    ) SUB_RANK
    WHERE FISH_RANK = 1
)
ORDER BY F1.ID;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RANK() 로 FISH_TYPE 별 가장 큰 물고기를 정확하게 추출&lt;/li&gt;
&lt;li&gt;만약 동점이 있을 경우에도 모두 가져올 수 있음 (단, 이번 문제는 물고기 종류별 가장 큰 물고기는 1마리만 있어서 해당 없음)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IN 서브쿼리를 다시 원본 테이블에 매칭하는 구조는 성능 저하 가능성이 있음&lt;/li&gt;
&lt;li&gt;서브쿼리 이후 JOIN을 별도로 다시 수행하므로 쿼리 복잡도 상승&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IN 서브쿼리는 내부적으로 결과 집합을 임시 테이블로 만들고, 바깥 쿼리의 조건과 매 건을 비교하는 방식이다. 만약 서브쿼리 내부가 윈도우 함수 등으로 복잡한 경우 DB를 이를 먼저 전체 계산 후 외부 쿼리에서 IN 절의 ID와 FISH_INFO의 일치 여부를 검사하므로 속도가 느리다. IN이 외부 테이블의 PK와 직접 연결되는 경우, JOIN 방식이 더 효율적일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. GROUP BY + (COL1, COL2) IN&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1743258877353&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH FISH_JOIN AS (
    SELECT 
        F.ID,
        N.FISH_NAME,
        F.LENGTH
    FROM FISH_INFO F
    LEFT JOIN FISH_NAME_INFO N
      ON F.FISH_TYPE = N.FISH_TYPE
)

SELECT *
FROM FISH_JOIN
WHERE (FISH_NAME, LENGTH) IN (
    SELECT 
        FISH_NAME,
        MAX(LENGTH)
    FROM FISH_JOIN
    GROUP BY FISH_NAME
)
ORDER BY ID;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;로직이 직관적이고 이해하기 쉬움&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;JOIN을 먼저 수행하고 재활용하므로 가독성 향상&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;(FISH_NAME,&amp;nbsp;LENGTH)로&amp;nbsp;비교하므로,&amp;nbsp;동일한&amp;nbsp;이름&amp;nbsp;+&amp;nbsp;동일한&amp;nbsp;길이인&amp;nbsp;여러&amp;nbsp;행이&amp;nbsp;존재하면&amp;nbsp;다수&amp;nbsp;반환&amp;nbsp;위험&amp;nbsp;(이&amp;nbsp;문제에선&amp;nbsp;괜찮지만&amp;nbsp;일반화는&amp;nbsp;어려움)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;CTE를 2번 실행하기 때문에 성능 면에서 효율이 다소 떨어질 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;튜플 비고는 일반적인 단일 컬럼 비교보다 더 많은 계산 비용이 든다. DB는 메인 쿼리와 IN 서브쿼리에서 CTE를 두 번 실행하는데, 이 때 FISH_NAME과 LENGTH를 비교하므로 인덱스를 제대로 활용하기 어렵다. 또한, MAX(LENGTH)가 FISH_NAME에 대해 그룹화한 값을 반환하지만, 같은 길이를 가진 물고기가 여러 마리 있는 경우 비교 대상이 늘어날 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;최종 쿼리&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1743259357193&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH MAX_FISH AS (
    SELECT 
    	   *,
           ROW_NUMBER() OVER(PARTITION BY FISH_TYPE ORDER BY LENGTH DESC) AS RN
    FROM FISH_INFO
)

SELECT
    F.ID,
    N.FISH_NAME,
    F.LENGTH
FROM MAX_FISH F
JOIN FISH_NAME_INFO N
	ON F.FISH_TYPE = N.FISH_TYPE
WHERE F.RN = 1
ORDER BY F.ID;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ROW_NUMBER()로 각 그룹 내에서 정확히 1개만 선택&lt;/li&gt;
&lt;li&gt;IN 없이 바로 원하는 조건 필터링 =&amp;gt; 별도의 임시 테이블이 없어 성능상 유리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 문제는 ROW_NUMBER()와 RANK() 중 어떤 함수를 써도 무방하지만, 다양한 풀이 방법을 쓰고 싶어서 다르게 구성해보았다. 임시 테이블이 없기 때문에, 동일한 결과를 반환하더라도 성능 측면에서 더 효율적인 쿼리를 구성할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;순위 함수 비교 (윈도우 함수)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;함수&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;동점 처리 방식&lt;/td&gt;
&lt;td style=&quot;width: 17.907%; text-align: center;&quot;&gt;다음 순위 처리&lt;/td&gt;
&lt;td style=&quot;width: 15.6976%; text-align: center;&quot;&gt;고유 번호 보장&lt;/td&gt;
&lt;td style=&quot;width: 26.3954%; text-align: center;&quot;&gt;대표 활용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;ROW_NUMBER()&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;동점도 다르게 부여&lt;/td&gt;
&lt;td style=&quot;width: 17.907%; text-align: center;&quot;&gt;1씩 증가&lt;/td&gt;
&lt;td style=&quot;width: 15.6976%; text-align: center;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 26.3954%; text-align: center;&quot;&gt;정확히 하나만 추출할 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;RANK()&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;동점은 같은 순위&lt;/td&gt;
&lt;td style=&quot;width: 17.907%; text-align: center;&quot;&gt;건너뜀&lt;/td&gt;
&lt;td style=&quot;width: 15.6976%; text-align: center;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 26.3954%; text-align: center;&quot;&gt;공동 순위 허용 시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;DENSE_RANK()&lt;/td&gt;
&lt;td style=&quot;width: 20%; text-align: center;&quot;&gt;동점은 같은 순위&lt;/td&gt;
&lt;td style=&quot;width: 17.907%; text-align: center;&quot;&gt;건너뛰지 않음&lt;/td&gt;
&lt;td style=&quot;width: 15.6976%; text-align: center;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 26.3954%; text-align: center;&quot;&gt;순위별 통계나 구간 나눌 때&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/104</guid>
      <comments>https://hr1588.tistory.com/104#entry104comment</comments>
      <pubDate>Sat, 29 Mar 2025 20:03:00 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 상품을 구매한 회원 비율 구하기</title>
      <link>https://hr1588.tistory.com/102</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;USER_INFO&amp;nbsp;테이블과&amp;nbsp;ONLINE_SALE&amp;nbsp;테이블에서&amp;nbsp;2021년에&amp;nbsp;가입한&amp;nbsp;전체&amp;nbsp;회원들&amp;nbsp;중&amp;nbsp;상품을&amp;nbsp;구매한&amp;nbsp;회원수와&amp;nbsp;상품을&amp;nbsp;구매한&amp;nbsp;회원의&amp;nbsp;비율(=2021년에&amp;nbsp;가입한&amp;nbsp;회원&amp;nbsp;중&amp;nbsp;상품을&amp;nbsp;구매한&amp;nbsp;회원수&amp;nbsp;/&amp;nbsp;2021년에&amp;nbsp;가입한&amp;nbsp;전체&amp;nbsp;회원&amp;nbsp;수)을&amp;nbsp;년,&amp;nbsp;월&amp;nbsp;별로&amp;nbsp;출력하는&amp;nbsp;SQL문을&amp;nbsp;작성해주세요.&amp;nbsp;상품을&amp;nbsp;구매한&amp;nbsp;회원의&amp;nbsp;비율은&amp;nbsp;소수점&amp;nbsp;두번째자리에서&amp;nbsp;반올림하고,&amp;nbsp;전체&amp;nbsp;결과는&amp;nbsp;년을&amp;nbsp;기준으로&amp;nbsp;오름차순&amp;nbsp;정렬해주시고&amp;nbsp;년이&amp;nbsp;같다면&amp;nbsp;월을&amp;nbsp;기준으로&amp;nbsp;오름차순&amp;nbsp;정렬해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;오답 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1740932427156&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 연/월별 집계 후 전체 집계 과정에서 동일 사용자가 여러 번 카운트되는 문제 발생

SELECT
    YEAR,
    MONTH,
    PURCHASED_USERS,
    ROUND(PURCHASED_USERS / TOTAL_USERS,1) AS PURCHASED_RATIO
FROM(
SELECT
    YEAR(SALES_DATE) AS YEAR,
    MONTH(SALES_DATE) AS MONTH,
    COUNT(DISTINCT U.USER_ID) AS PURCHASED_USERS,
    SUM(COUNT(DISTINCT U.USER_ID)) OVER() AS TOTAL_USERS
FROM USER_INFO U
LEFT JOIN ONLINE_SALE O
ON U.USER_ID = O.USER_ID
WHERE YEAR(JOINED) = 2021
GROUP BY 1,2
) SUB
WHERE YEAR IS NOT NULL
ORDER BY 1,2;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오답 쿼리는 겉보기에는 잘 구성된 것처럼 보이지만, 전체 집계 과정에서 중복 집계가 발생하는 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;COUNT(DISTINCT&amp;nbsp;U.USER_ID)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연/월별로 고유한 사용자 수를 집계할 때는 올바르게 작동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SUM(COUNT(DISTINCT U.USER_ID)) OVER()&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전체 집계 시 GROUP BY 절에 의해 연/월별로 분할된 결과를 다시 집계하는 과정에서 문제가 발생한다.&lt;/li&gt;
&lt;li&gt;예를 들어, USER_ID 1번이 2022년 1월과 2월에 각각 한 번씩 구매했다면, 전체 집계에서는 한 명으로 처리되어야 하지만, 이 쿼리는 두 번 집계되어 중복 계산되는 문제가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1740932961094&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 서브쿼리로 전체 집계 과정을 분리하여, USER_ID 기준의 고유 집계를 수행함

SELECT
    YEAR(SALES_DATE) AS YEAR,
    MONTH(SALES_DATE) AS MONTH,
    COUNT(DISTINCT U.USER_ID) AS PURCHASED_USERS,
    ROUND(COUNT(DISTINCT U.USER_ID) 
    / (SELECT COUNT(*) FROM USER_INFO WHERE YEAR(JOINED)=2021),1) AS PURCHASED_RATIO
FROM USER_INFO U
LEFT JOIN ONLINE_SALE O
ON U.USER_ID = O.USER_ID
WHERE YEAR(JOINED) = 2021 AND YEAR(SALES_DATE) IS NOT NULL
GROUP BY 1,2
ORDER BY 1,2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 집계 과정을 별도의 서브쿼리로 분리하여 처리하면 중복 집계 문제가 해결된다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;서브쿼리 활용&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 쿼리는 연/월별로 집계된 사용자 수를 다시 전체 집계하는 과정에서 중복이 발생했으나, 서브쿼리를 사용하면 USER_ID가 PK(Primary Key)인 테이블에서 직접 집계할 수 있다.&lt;/li&gt;
&lt;li&gt;그 결과, 예를 들어 2021년에 가입한 고유한 사용자의 수가 정확하게 출력된다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/102</guid>
      <comments>https://hr1588.tistory.com/102#entry102comment</comments>
      <pubDate>Thu, 27 Feb 2025 02:13:28 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 입양 시각 구하기(2)</title>
      <link>https://hr1588.tistory.com/100</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보호소에서는&amp;nbsp;몇&amp;nbsp;시에&amp;nbsp;입양이&amp;nbsp;가장&amp;nbsp;활발하게&amp;nbsp;일어나는지&amp;nbsp;알아보려&amp;nbsp;합니다.&amp;nbsp;0시부터&amp;nbsp;23시까지,&amp;nbsp;각&amp;nbsp;시간대별로&amp;nbsp;입양이&amp;nbsp;몇&amp;nbsp;건이나&amp;nbsp;발생했는지&amp;nbsp;조회하는&amp;nbsp;SQL문을&amp;nbsp;작성해주세요.&amp;nbsp;이때&amp;nbsp;결과는&amp;nbsp;시간대&amp;nbsp;순으로&amp;nbsp;정렬해야&amp;nbsp;합니다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;내가 푼 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순하게 생각하면, 아래와 같이 접근하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1740580942800&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
    HOUR(DATETIME) AS HOUR,
    COUNT(*) AS &quot;COUNT&quot;
FROM ANIMAL_OUTS
GROUP BY 1
ORDER BY 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이렇게 풀면, 집계 함수에 포함되지 않은 시간이 출력되지 않기 때문에 문제를 풀 수 없다. 즉, 입양이 0건인 시간대가 출력되지 않는 것이 문제이다.&lt;/p&gt;
&lt;pre id=&quot;code_1740581056860&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH HOUR_TABLE AS(
    SELECT
        0 AS HOUR
UNION
    SELECT
        1 AS HOUR
UNION
    SELECT
        2 AS HOUR
UNION
    SELECT
        3 AS HOUR
UNION
    SELECT
        4 AS HOUR
UNION
    SELECT
        5 AS HOUR
UNION
    SELECT
        6 AS HOUR
UNION
    SELECT
        20 AS HOUR
UNION
    SELECT
        21 AS HOUR
UNION
    SELECT
        22 AS HOUR
UNION
    SELECT
        23 AS HOUR
), ANIMAL_OUTS_DATE AS(
SELECT
    ANIMAL_ID,
    HOUR(DATETIME) AS HOUR
FROM ANIMAL_OUTS
)

SELECT
     SUB.HOUR,
     COUNT(ANIMAL_ID) AS &quot;COUNT&quot;
FROM(
SELECT
    HOUR(DATETIME) AS HOUR
FROM ANIMAL_OUTS
UNION
SELECT
    HOUR
FROM HOUR_TABLE) SUB
LEFT JOIN ANIMAL_OUTS_DATE
ON SUB.HOUR = ANIMAL_OUTS_DATE.HOUR
GROUP BY HOUR
ORDER BY HOUR;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 해결하기 위해 테이블에서 입양이 발생하지 않은 시간을 확인하고, 해당 시간을 별도의 테이블로 만들어 문제를 해결했다. 정답은 맞지만, 어떤 의미로는 하드 코딩으로 풀었고 굉장히 비효율적이라는 생각이 들었다. 더 효율적인 쿼리를 구성하기 위해 구글링을 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재귀 함수&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1740581366396&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 출처 : MySQL 공식문서

WITH RECURSIVE fibonacci (n, fib_n, next_fib_n) AS
(
  -- Anchor
  SELECT 1, 0, 1 
  UNION ALL
  -- 재귀 멤버 (재귀 부분)
  SELECT n + 1, next_fib_n, fib_n + next_fib_n
    FROM fibonacci WHERE n &amp;lt; 10
)
SELECT * FROM fibonacci;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링 결과, MySQL 공식문서에서 &lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;recursive common table expressions&lt;/span&gt; 라는 개념을 확인했다. 즉, 자기 자신을 참조하여 반복적으로 데이터를 생성하거나 계층적으로 데이터를 처리하는 기능이다. 작동 원리를 정리해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Anchor : 재귀 처리를 시작하기 위한 초기 값으로, 한 번 실행되어 기본 결과 집합을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재귀 멤버 : Anchor 또는 이전 재귀 단계에서 생성된 결과를 기반으로 새로운 행을 생성, 재귀 멤버 내부의 &lt;b&gt;WHERE 조건&lt;/b&gt;을 통해 더 이상 새로운 행이 생성되지 않을 때 재귀가 종료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Anchor 멤버가 실행되어 초기 집합(예: 1)이 생성&lt;/li&gt;
&lt;li&gt;재귀 멤버가 실행되어 이전 결과(예: 1)를 이용해 1을, 그 다음 2를, ... 식으로 결과 집합을 확장&lt;/li&gt;
&lt;li&gt;WHERE 조건(예: n&amp;lt; 10)이 더 이상 참이 아닐 때, 재귀가 중지되고 모든 결과가 UNION(혹은 UNION ALL)되어 최종 결과 집합을 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정된 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1740582154560&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH RECURSIVE HOUR_TABLE (HOUR) AS(
    SELECT 
        0 
    UNION ALL
    SELECT
        HOUR+1
    FROM HOUR_TABLE
    WHERE HOUR &amp;lt; 23
),
ANIMAL_OUTS_HOUR_TABLE AS(
    SELECT
        ANIMAL_ID,
        HOUR(DATETIME) AS HOUR
    FROM ANIMAL_OUTS
)

SELECT
    H.HOUR,
    COUNT(A.ANIMAL_ID) AS &quot;COUNT&quot;
FROM HOUR_TABLE H
LEFT JOIN ANIMAL_OUTS_HOUR_TABLE A
ON H.HOUR = A.HOUR
GROUP BY H.HOUR
ORDER BY H.HOUR;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 결과를 도출하지만, 재귀 CTE를 활용하여 가독성과 효율성이 크게 향상되었음을 확인할 수 있다. 추가적인 정보는 아래 첨부한 공식 문서를 참고해보시면 도움이 될 것이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1740581379988&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;MySQL :: MySQL 8.4 Reference Manual :: 15.2.20 WITH (Common Table Expressions)&quot; data-og-description=&quot;15.2.20&amp;nbsp;WITH (Common Table Expressions) A common table expression (CTE) is a named temporary result set that exists within the scope of a single statement and that can be referred to later within that statement, possibly multiple times. The following disc&quot; data-og-host=&quot;dev.mysql.com&quot; data-og-source-url=&quot;https://dev.mysql.com/doc/refman/8.4/en/with.html#common-table-expressions-recursive-examples&quot; data-og-url=&quot;https://dev.mysql.com/doc/refman/8.4/en/with.html#common-table-expressions-recursive-examples&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.4/en/with.html#common-table-expressions-recursive-examples&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dev.mysql.com/doc/refman/8.4/en/with.html#common-table-expressions-recursive-examples&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;MySQL :: MySQL 8.4 Reference Manual :: 15.2.20 WITH (Common Table Expressions)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;15.2.20&amp;nbsp;WITH (Common Table Expressions) A common table expression (CTE) is a named temporary result set that exists within the scope of a single statement and that can be referred to later within that statement, possibly multiple times. The following disc&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dev.mysql.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/100</guid>
      <comments>https://hr1588.tistory.com/100#entry100comment</comments>
      <pubDate>Wed, 19 Feb 2025 04:09:11 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기</title>
      <link>https://hr1588.tistory.com/98</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '세단' 또는 'SUV' 인 자동차 중 2022년 11월 1일부터 2022년 11월 30일까지 대여 가능하고 30일간의 대여 금액이 50만원 이상 200만원 미만인 자동차에 대해서 자동차 ID, 자동차 종류, 대여 금액(컬럼명: FEE) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 자동차 종류를 기준으로 오름차순 정렬, 자동차 종류까지 같은 경우 자동차 ID를 기준으로 내림차순 정렬해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;오답 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1739988290700&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH CHECK_CAR_STATUS AS(
SELECT
    CAR_ID,
    MAX(START_DATE &amp;lt; &quot;2022-11-01&quot; AND END_DATE &amp;gt; &quot;2022-11-30&quot;) AS STATUS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
GROUP BY CAR_ID)

SELECT
    *
FROM(
SELECT
    C1.CAR_ID,
    C1.CAR_TYPE,
    ROUND(DAILY_FEE * (1 - C3.DISCOUNT_RATE/100) * 30) AS FEE
FROM CAR_RENTAL_COMPANY_CAR C1
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN C3
ON C1.CAR_TYPE = C3.CAR_TYPE
WHERE
    C1.CAR_TYPE IN ('세단','SUV') AND 
    C1.CAR_ID IN (
        SELECT
            CAR_ID
        FROM CHECK_CAR_STATUS
        WHERE STATUS = 0) AND
    C3.DURATION_TYPE = &quot;30일 이상&quot;) SUB
WHERE FEE BETWEEN 500000 AND 2000000
ORDER BY FEE DESC, CAR_TYPE, CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 포스팅했던 자동차 대여 기록에서 MAX 함수를 활용해서 각 대여 기록마다 특정 날짜가 해당 기간에 속하는지 평가 했었다. 동일한 로직으로 생각했지만, 문제를 풀 수 없었다. 어떤 부분이 문제 일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;조건의 차이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 차량이 11월 중 어느 순간이라도 대여되고 있으면 대여 중으로 판단하고, 그렇지 않으면 대여 가능으로 판단해야한다. 11월 한달 간 빌릴 수 있는 차량을 선별하는 것이 문제의 조건이기 때문이다. SQL에서 특정 기간(11월 1일 ~ 11월 30일)과 대여 기록의 겹침 여부를 판단할 때, 두 가지 조건을 고려할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;조건 A :&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1739988468455&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MAX(START_DATE &amp;lt; '2022-11-01' AND END_DATE &amp;gt; '2022-11-30')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 조건은 대여 기록이 11월 전체를 완전히 커버할 때만 TRUE를 반환한다. 즉, 대여 시작일이 11월 1일 이전이어야 하고, 종료일이 11월 30일 이후여야 한다. 예를 들어 대여 기간이 11월 5일부터 11월 20일인 경우에는 조건이 FALSE로 평가되어 결과가 누락된다. 즉, 기존 쿼리는 &lt;b&gt;11월 전체 기간에서 대여가 포함된 것은 추출되지만, 부분적으로 대여되는 ID를 감지하지 못해&lt;/b&gt; 잘못된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;조건 B :&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1739988788531&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MAX(START_DATE &amp;lt; '2022-11-30' AND END_DATE &amp;gt; '2022-11-01')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대여 시작일이 11월 30일 이전이어야 한다. = 대여가 11월 말 이전에 시작하면 11월 중에 대여가 진행될 가능성이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대여 종료일이 11월 1일 이후여야 한다. = 대여가 11월 초 이후 에 끝나면 11월 중에 대여가 진행될 가능성이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 대여 기록의 시작일이 11월 30일 이전이고, 종료일이 11월 1일 이후라면 대여 기간과 11월이 어느부분이라도 겹친다는 것을 의미한다. 이전 포스팅은 &lt;b&gt;특정한 단일 날짜가 대여 기록에 포함되는지 확인&lt;/b&gt;했던 것이고, 이번 문제는 &lt;b&gt;특정한 기간과 대여 기록이 겹치는지를 확인&lt;/b&gt;하기 때문에 접근 방식이 다른 것 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1739989076988&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH CHECK_CAR_STATUS AS(
SELECT
    CAR_ID,
    MAX(START_DATE &amp;lt; &quot;2022-11-30&quot; AND END_DATE &amp;gt; &quot;2022-11-01&quot;) AS STATUS -- 날짜 수정
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
GROUP BY CAR_ID)

SELECT
    *
FROM(
SELECT
    C1.CAR_ID,
    C1.CAR_TYPE,
    ROUND(DAILY_FEE * (1 - C3.DISCOUNT_RATE/100) * 30) AS FEE
FROM CAR_RENTAL_COMPANY_CAR C1
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN C3
ON C1.CAR_TYPE = C3.CAR_TYPE
WHERE
    C1.CAR_TYPE IN ('세단','SUV') AND 
    C1.CAR_ID IN (
        SELECT
            CAR_ID
        FROM CHECK_CAR_STATUS
        WHERE STATUS = 0) AND
    C3.DURATION_TYPE = &quot;30일 이상&quot;) SUB
WHERE FEE BETWEEN 500000 AND 2000000
ORDER BY FEE DESC, CAR_TYPE, CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;날짜를 제외한 다른 부분은 문제가 없었다. 추가로, MySQL은 Boolean 값을 내부적으로 1(참)과 0(거짓)으로 처리하지만 일부 DBMS(PostgreSQL 등)에서는 명시적인 변환이 필요할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1739989232579&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MAX(
  CASE
    WHEN START_DATE &amp;lt; '2022-11-30' AND END_DATE &amp;gt; '2022-11-01' THEN 1
    ELSE 0
  END
) AS conflict&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그련 경우 CASE 문을 사용하여 1, 0으로 처리해주면 동일한 결과를 확인할 수 있다.&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/98</guid>
      <comments>https://hr1588.tistory.com/98#entry98comment</comments>
      <pubDate>Tue, 4 Feb 2025 23:08:32 +0900</pubDate>
    </item>
    <item>
      <title>[MYSQL] 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기</title>
      <link>https://hr1588.tistory.com/96</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CAR_RENTAL_COMPANY_RENTAL_HISTORY&amp;nbsp;테이블에서&amp;nbsp;2022년&amp;nbsp;10월&amp;nbsp;16일에&amp;nbsp;대여&amp;nbsp;중인&amp;nbsp;자동차인&amp;nbsp;경우&amp;nbsp;'대여중'&amp;nbsp;이라고&amp;nbsp;표시하고,&amp;nbsp;대여&amp;nbsp;중이지&amp;nbsp;않은&amp;nbsp;자동차인&amp;nbsp;경우&amp;nbsp;'대여&amp;nbsp;가능'을&amp;nbsp;표시하는&amp;nbsp;컬럼(컬럼명:&amp;nbsp;AVAILABILITY)을&amp;nbsp;추가하여&amp;nbsp;자동차&amp;nbsp;ID와&amp;nbsp;AVAILABILITY&amp;nbsp;리스트를&amp;nbsp;출력하는&amp;nbsp;SQL문을&amp;nbsp;작성해주세요.&amp;nbsp;이때&amp;nbsp;반납&amp;nbsp;날짜가&amp;nbsp;2022년&amp;nbsp;10월&amp;nbsp;16일인&amp;nbsp;경우에도&amp;nbsp;'대여중'으로&amp;nbsp;표시해주시고&amp;nbsp;결과는&amp;nbsp;자동차&amp;nbsp;ID를&amp;nbsp;기준으로&amp;nbsp;내림차순&amp;nbsp;정렬해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;오답 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1739905882664&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
    CAR_ID,
    CASE
        WHEN &quot;2022-10-16&quot; BETWEEN MAX(START_DATE) AND DATE_ADD(MAX(END_DATE), INTERVAL 1 DAY) THEN &quot;대여중&quot;
        ELSE &quot;대여 가능&quot;
    END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 쿼리는 오답을 반환하는데, 어떤 부분이 틀렸는지 이유를 생각해보고 정리해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAX(START_DATE)와 MAX(END_DATE)는 각 CAR_ID별 가장 최근의 대여 기록을 찾는다. 즉, 차량이 여러 번 대여되었더라도 &lt;b&gt;마지막 대여 기록&lt;/b&gt;만 확인하게 된다. 그 마지막 대여 기간이 2022-10-16을 포함하는지 확인하여 '대여중' 또는 '대여 가능'을 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CAR_ID가 A001인 차량의 대여기록이 있다고 가정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 번째 대여 기록 : 2022-10-10 ~ 2022-10-17&lt;/li&gt;
&lt;li&gt;두 번째 대여 기록 : 2022-10-20 ~ 2022-10-25&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오답 쿼리는 차량에 대해 MAX(START_DATE) = 2022년 10월 20일, MAX(END_DATE) = 2022년 10월 25일을 사용한다. 10월 16일에 대여 중임에도, MAX 값의 범위 사이에 없기 때문에 대여 가능으로 판단한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정한 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1739906376754&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CAR_ID,
CASE 
    WHEN MAX(START_DATE &amp;lt;= '2022-10-16' AND END_DATE &amp;gt;= '2022-10-16') THEN '대여중'
    ELSE '대여 가능'
END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정된 쿼리는 &lt;b&gt;각 대여 기록마다&lt;/b&gt; 2022년 10월 16일이 해당 기간에 속하는지 평가한 후, MAX 함수를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 기록의 경우 시작일이 10월 10일이고 종료일이 10월 17일이다. 10월 16일은 해당 기간 사이에 있으므로, 조건이 성립한다. 두 번째 기록의 경우 시작일이 10월 20일이고 종료일이 10월 25일이다. 10월 16일은 10월 20일보다 이전이므로, 조건은 거짓이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL에서 MAX 함수를 사용하면 각 기록의 조건 결과 중 최대값을 구한다. Boolean 값에서 TRUE는 1, FALSE는 0으로 간주되므로 MAX(TRUE, FALSE)는 TRUE가 된다. 따라서 하나라도 조건이 참인 기록이 존재하기 때문에 최종 결과는 대여중으로 반환된다.&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/96</guid>
      <comments>https://hr1588.tistory.com/96#entry96comment</comments>
      <pubDate>Mon, 4 Nov 2024 23:18:37 +0900</pubDate>
    </item>
    <item>
      <title>[웹크롤링] Tmax 채용공고 분석</title>
      <link>https://hr1588.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;KT 에이블스쿨 잡페어에서 TmaxBI라는 부스를 방문하게 되면서 Tmax라는 회사에 관심이 생겼다. 이 회사에서 에이블스쿨 수료생을 대상으로 어떤 직무를 채용할지 알 수 없기 때문에, 다양한 직무의 Job Description(JD)을 미리 파악해두면 차후 지원서를 효과적으로 작성할 수 있을 것이라 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1724002068712&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;티맥스 - 채용 홈페이지&quot; data-og-description=&quot;티맥스 채용 홈페이지입니다.&quot; data-og-host=&quot;tmaxcareers.ninehire.site&quot; data-og-source-url=&quot;https://tmaxcareers.ninehire.site/recruit&quot; data-og-url=&quot;https://tmaxcareers.ninehire.site/recruit&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://tmaxcareers.ninehire.site/recruit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://tmaxcareers.ninehire.site/recruit&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;티맥스 - 채용 홈페이지&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;티맥스 채용 홈페이지입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;tmaxcareers.ninehire.site&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상시 채용 페이지를 확인해보니, 예상보다 너무 많은 채용 공고가 올라와있어 내용을 하나씩 정리하는건 비효율적이라고 판단했다. 효율적 정보 수집을 위해 Python으로 웹크롤링을 시도했으나, 간단하게 끝날 것이라는 예상과 달리 생각보다 시간이 많이 소요되었다. 그 과정에서 사용한 코드를 하나씩 살펴보면서 원인과 결과를 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;채용공고 웹크롤링&lt;/h2&gt;
&lt;pre id=&quot;code_1724002593556&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import requests
from bs4 import BeautifulSoup

# 대상 URL
url = &quot;https://tmaxcareers.ninehire.site/recruit&quot;

# 페이지 요청
response = requests.get(url)

# 요청 성공 여부 확인
if response.status_code == 200:
    # HTML 파싱
    soup = BeautifulSoup(response.text, 'html.parser')
    
    # 모든 'a' 태그 찾기
    links = soup.find_all('a')

    for link in links:
        href = link.get('href')  # 'href' 속성을 가져옵니다
        if href:
            print(f&quot;Link: {href}&quot;)
else:
    print(f&quot;Failed to retrieve the page. Status code: {response.status_code}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 requests와 bs4로 페이지가 문제없이 출력되는지 확인했다. 만약 html 선택자로 파싱이 안된다면, 네트워크 정보를 하나씩 추가하면서 연결에 성공할 때까지 작업을 반복해야하기 때문이다. 다행히, response 200으로 연결 자체에는 문제가 없음을 확인했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRlLr0/btsI7U9BQ46/TuJsnckkrWD1DlFfMbi7w1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRlLr0/btsI7U9BQ46/TuJsnckkrWD1DlFfMbi7w1/img.png&quot; data-alt=&quot;채용 공고 사이트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRlLr0/btsI7U9BQ46/TuJsnckkrWD1DlFfMbi7w1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRlLr0%2FbtsI7U9BQ46%2FTuJsnckkrWD1DlFfMbi7w1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;709&quot; height=&quot;520&quot; data-origin-width=&quot;709&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;채용 공고 사이트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;215&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9WqHt/btsI6uq3I7b/Ah0m1enMTi7J4BHp5sVUL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9WqHt/btsI6uq3I7b/Ah0m1enMTi7J4BHp5sVUL0/img.png&quot; data-alt=&quot;개별 채용 공고&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9WqHt/btsI6uq3I7b/Ah0m1enMTi7J4BHp5sVUL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9WqHt%2FbtsI6uq3I7b%2FAh0m1enMTi7J4BHp5sVUL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;267&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;215&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;개별 채용 공고&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, 사이트의 구조를 확인했다. 계열사별로 다양한 채용공고가 기재되어있으며, 개별 공고를 누르면 직무별로 담당 업무 및 필요한 역량을 확인할 수 있다. 여기서 개별 채용 공고의 URL이 job_posting/고유ID 구조임을 확인했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724003050970&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
import re
import time

# 웹 드라이버 설정
driver = webdriver.Chrome(service=Service())

# 대상 URL
url = &quot;https://tmaxcareers.ninehire.site/recruit&quot;
driver.get(url)

# 페이지 로딩 대기
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.TAG_NAME, &quot;body&quot;))
)

# 스크롤을 통해 페이지의 모든 콘텐츠 로드
last_height = driver.execute_script(&quot;return document.body.scrollHeight&quot;)

while True:
    # 페이지 끝까지 스크롤
    driver.execute_script(&quot;window.scrollTo(0, document.body.scrollHeight);&quot;)
    # 스크롤 후 로딩 대기
    time.sleep(2)
    # 새로운 페이지 높이 계산
    new_height = driver.execute_script(&quot;return document.body.scrollHeight&quot;)
    if new_height == last_height:
        break
    last_height = new_height

# 페이지 소스 가져오기
page_content = driver.page_source

# 정규 표현식으로 'job_posting'이 포함된 링크 추출
pattern = r'&quot;(https://tmaxcareers\.ninehire\.site/job_posting/[^&quot;]+)&quot;'
matches = re.findall(pattern, page_content)

for match in matches:
    print(f&quot;Link: {match}&quot;)

# 브라우저 종료
driver.quit()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조를 확인했으니, 이제 개별 채용공고 링크를 가져와서 파싱을 진행하면 끝이라고 생각했다. Webdriver로 페이지를 끝까지 내려서 모든 페이지 소스를 가져오고, job_posting이 포함된 링크를 추출했다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CUy4y/btsI8gdAiMS/YPCvvEUhs6NODwL4cNruG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CUy4y/btsI8gdAiMS/YPCvvEUhs6NODwL4cNruG0/img.png&quot; data-alt=&quot;추출된 링크들(Invalid)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CUy4y/btsI8gdAiMS/YPCvvEUhs6NODwL4cNruG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCUy4y%2FbtsI8gdAiMS%2FYPCvvEUhs6NODwL4cNruG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;610&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;추출된 링크들(Invalid)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;361&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGkQou/btsI7Hio417/x9JjlHqx7Rr8JL4vuScQtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGkQou/btsI7Hio417/x9JjlHqx7Rr8JL4vuScQtK/img.png&quot; data-alt=&quot;중단된 채용 공고&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGkQou/btsI7Hio417/x9JjlHqx7Rr8JL4vuScQtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGkQou%2FbtsI7Hio417%2Fx9JjlHqx7Rr8JL4vuScQtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;361&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;361&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;중단된 채용 공고&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일부 링크는 정상적으로 현재 채용 공고를 출력했지만, 이미 접수가 중단된 채용공고들이 대다수였다. 단순히 URL 구조만으로는 현재 진행중인 채용 공고 정보를 가져올 수 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFOYtb/btsI8qfVbWP/kWTjPBGTXmferhr3C5sXJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFOYtb/btsI8qfVbWP/kWTjPBGTXmferhr3C5sXJ1/img.png&quot; data-alt=&quot;HTML 태그 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFOYtb/btsI8qfVbWP/kWTjPBGTXmferhr3C5sXJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFOYtb%2FbtsI8qfVbWP%2FkWTjPBGTXmferhr3C5sXJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;380&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HTML 태그 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 방법으로, 채용공고의 HTML 태그 구조를 확인했다. 그 결과, div 태그 중 &quot;fuGTMM&quot; 으로 끝나는 class 안에 해당 페이지의 a태그가 전부 들어있음을 확인했다. 해당 태그를 webdriver로 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724003614161&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 웹 드라이버 설정
driver = webdriver.Chrome(service=Service())

# 대상 URL
url = &quot;https://tmaxcareers.ninehire.site/recruit&quot;
driver.get(url)

# 페이지 로딩 대기
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CLASS_NAME, &quot;JobPostingsDropdownTypeLayoutJobPostings__Content-sc-b886b4af-0&quot;))
)

# 특정 클래스 이름을 가진 모든 div 요소 찾기
divs = driver.find_elements(By.CLASS_NAME, &quot;JobPostingsDropdownTypeLayoutJobPostings__Content-sc-b886b4af-0.fuGTMM&quot;)

# 각 div 요소 안의 a 태그 href 추출
for div in divs:
    links = div.find_elements(By.TAG_NAME, &quot;a&quot;)
    for link in links:
        href = link.get_attribute('href')
        print(f&quot;Link: {href}&quot;)

# 브라우저 종료
driver.quit()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctdnT2/btsI7hqMgeT/BafPorrh6zZ22Pj0hIq7O0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctdnT2/btsI7hqMgeT/BafPorrh6zZ22Pj0hIq7O0/img.png&quot; data-alt=&quot;추출된 링크들 (Valid)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctdnT2/btsI7hqMgeT/BafPorrh6zZ22Pj0hIq7O0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctdnT2%2FbtsI7hqMgeT%2FBafPorrh6zZ22Pj0hIq7O0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;495&quot; height=&quot;390&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;추출된 링크들 (Valid)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과, 현재 진행되고 있는 채용공고 링크들을 수집할 수 있었다. 사진에 있는 링크는 1페이지에 기재된 공고이고, 모든 페이지의 공고를 가져 오기 위해 try-except 문을 활용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724003755541&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 웹 드라이버 설정
driver = webdriver.Chrome(service=Service())

# 대상 URL
url = &quot;https://tmaxcareers.ninehire.site/recruit&quot;
driver.get(url)

# 페이지 로딩 대기
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CLASS_NAME, &quot;JobPostingsDropdownTypeLayoutJobPostings__Content-sc-b886b4af-0&quot;))
)

# 페이지 수를 설정
max_pages = 10

for page in range(1, max_pages + 1):
    # 페이지 번호 출력
    print(f&quot;Processing page {page}...&quot;)
    
    # 특정 클래스 이름을 가진 모든 div 요소 찾기
    divs = driver.find_elements(By.CLASS_NAME, &quot;JobPostingsDropdownTypeLayoutJobPostings__Content-sc-b886b4af-0.fuGTMM&quot;)
    
    # 각 div 요소 안의 a 태그 href 추출
    for div in divs:
        links = div.find_elements(By.TAG_NAME, &quot;a&quot;)
        for link in links:
            href = link.get_attribute('href')
            print(f&quot;Link: {href}&quot;)
    
    # 다음 페이지로 이동
    if page &amp;lt; max_pages:
        try:
            next_page = WebDriverWait(driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, f&quot;//li[@title='{page + 1}']/a&quot;))
            )
            next_page.click()
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.CLASS_NAME, &quot;JobPostingsDropdownTypeLayoutJobPostings__Content-sc-b886b4af-0&quot;))
            )
        except Exception as e:
            print(f&quot;Failed to navigate to page {page + 1}: {e}&quot;)
            break

# 브라우저 종료
driver.quit()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 페이지를 확인한 결과, 189개의 채용공고 링크를 확보했다. 이제 개별 링크에서 어떤 정보를 가져올지 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cA4u51/btsI6wCpqli/OrfObgKD7zk0kGjDOPvV01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cA4u51/btsI6wCpqli/OrfObgKD7zk0kGjDOPvV01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cA4u51/btsI6wCpqli/OrfObgKD7zk0kGjDOPvV01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcA4u51%2FbtsI6wCpqli%2FOrfObgKD7zk0kGjDOPvV01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;529&quot; height=&quot;101&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3eo27/btsI6PoaXUT/Mf1yHK783UvUCwIIMHIvEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3eo27/btsI6PoaXUT/Mf1yHK783UvUCwIIMHIvEK/img.png&quot; data-alt=&quot;Job Description&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3eo27/btsI6PoaXUT/Mf1yHK783UvUCwIIMHIvEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3eo27%2FbtsI6PoaXUT%2FMf1yHK783UvUCwIIMHIvEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;636&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Job Description&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;링크를 확인하고 기업명, 직무, 세부 직무, 경력 사항, 고용 형태, 근무지, 채용 방식, 담당 업무, 필수 요건, 우대 요건 이상 10개의 column으로 구성된 테이블을 제작했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724005629765&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 각 링크를 방문하여 채용 공고 내용 추출
job_data = []

for job_url in job_links:
    driver = webdriver.Chrome(service=Service())
    driver.get(job_url)
    
    # 페이지 로딩 대기
    try:
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, &quot;PostingLayout1Header__TitleWrapper-sc-128164c6-2&quot;))
        )
        
        try:
            # 기업명, 직무, 세부 직무, 경력, 고용 형태, 근무지, 채용 방식 추출
            label_container = driver.find_element(By.CLASS_NAME, &quot;LabelGroup__Container-sc-d40b1697-0.hLfIyn&quot;)
            labels = label_container.find_elements(By.TAG_NAME, &quot;span&quot;)
            
            label_texts = [label.text for label in labels]
            
            if len(label_texts) == 7:
                company, job_title, detailed_job, experience, employment_type, location, hiring_method = label_texts
            elif len(label_texts) == 6:
                company, job_title, experience, employment_type, location, hiring_method = label_texts
                detailed_job = &quot;&quot;
            else:
                continue

            # 담당 업무, 필수 요건, 우대 요건
            content_container = driver.find_element(By.CLASS_NAME, &quot;PostingHTMLContent__Content-sc-a46df660-0.dMdmJ&quot;)
            sections = content_container.find_elements(By.XPATH, &quot;.//h3&quot;)

            tasks = []
            requirements = []
            preferences = []

            for section in sections:
                title = section.text
                try:
                    ul_element = section.find_element(By.XPATH, &quot;following-sibling::ul&quot;)
                    li_elements = ul_element.find_elements(By.TAG_NAME, &quot;li&quot;)

                    items = [li.text for li in li_elements]

                    if title == &quot;✔ 담당 업무&quot;:
                        tasks.extend(items)
                    elif title == &quot;✔ 필수 요건&quot;:
                        requirements.extend(items)
                    elif title == &quot;✔ 우대 요건&quot;:
                        preferences.extend(items)
                except Exception as e:
                    print(f&quot;Failed to process section '{title}' at {job_url}: {e}&quot;)
                    continue

            # 데이터 저장
            job_data.append({
                'Company': company,
                'Job Title': job_title,
                'Detailed Job': detailed_job,
                'Experience': experience,
                'Employment Type': employment_type,
                'Location': location,
                'Hiring Method': hiring_method,
                'Tasks': '\n'.join(tasks),
                'Requirements': '\n'.join(requirements),
                'Preferences': '\n'.join(preferences),
            })

        except Exception as e:
            print(f&quot;Failed to process job post at {job_url}: {e}&quot;)
        
    except Exception as e:
        print(f&quot;Failed to load job post at {job_url}: {e}&quot;)
    
    finally:
        # 브라우저 종료
        driver.quit()

# 데이터프레임 생성
df = pd.DataFrame(job_data)

# 데이터프레임 파일로 저장
df.to_excel('job_postings.xlsx', index=False)

print(&quot;Data extraction complete and saved to job_postings.xlsx&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;1045&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRzoTD/btsI6S578X8/qLnFFWOCHt94kSqiHCYnFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRzoTD/btsI6S578X8/qLnFFWOCHt94kSqiHCYnFk/img.png&quot; data-alt=&quot;파싱 결과 데이터 프레임&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRzoTD/btsI6S578X8/qLnFFWOCHt94kSqiHCYnFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRzoTD%2FbtsI6S578X8%2FqLnFFWOCHt94kSqiHCYnFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;818&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;1045&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파싱 결과 데이터 프레임&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크롤링 결과, 전체 189개의 공고 중 30% 정도만 내용을 가져올 수 있었다. 70%의 공고를 살펴보니 계열사별로 공고 내부의 html 구조가 달랐고, 제목을 h3태그로 지정한 공고와 h1태그로 지정한 공고도 있어서 제대로 파싱이 되지 않았다. 세부적으로 발견한 사항은 다음과 같다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;li 태그 안에 텍스트가 직접 제시된 경우&lt;/li&gt;
&lt;li&gt;li &amp;gt; p &amp;gt; span 태그 구조&lt;/li&gt;
&lt;li&gt;기타 예외 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 사항을 반영해서 수정한 결과, 전체 공고 중 70%는 데이터 프레임으로 저장에 성공했다. 실패한 30%의 대부분은 R&amp;amp;D 직무이었는데, 해당 직무는 세부 직무가 비어있는 공고들이다. 다른 공고들과 달리 태그 구조가 달라서 파싱에 실패한 것으로 추측된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;TmaxBI 채용공고 분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터의 수가 많진 않지만, 어떤 역량을 강조하는지 궁금해서 TmaxBI의 공고 24가지로 TF-IDF 분석을 시도했다. 이 방법은 각 단어가 채용공고에서 얼마나 중요한지를 평가하는 방법이다. 여러 JD에서 자주 등장하는 단어를 다른 JD에서는 얼마나 자주 언급되지 않는지를 고려하여 어떤 역량이 두드러지는지를 분석할 수 있다. 일반적인 채용공고에 4년제 대학 졸업자, 해외여행 결격자와 같은 역량이 반복되기 때문에도 TF-IDF가 적합한 방법이라 판단했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724007413314&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# df는 TmaxBI의 채용공고들로 구성된 테이블
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer

df['combined'] = df['Requirements'].fillna('') + ' ' + df['Preferences'].fillna('')

# Text preprocessing function
def preprocess_text(text):
    # Remove special characters and digits
    text = re.sub(r'[^가-힣\s]', '', text)
    return text

# Apply preprocessing
df['cleaned_text'] = df['combined'].apply(preprocess_text)

# TF-IDF 벡터라이저 초기화
tfidf_vectorizer = TfidfVectorizer(max_features=100)  # 상위 100개의 중요 단어를 추출합니다.
tfidf_matrix = tfidf_vectorizer.fit_transform(combined_text)

# TF-IDF 결과를 DataFrame으로 변환
tfidf_df = pd.DataFrame(tfidf_matrix.toarray(), columns=tfidf_vectorizer.get_feature_names_out())

# 결과 출력 (단어와 각 문서에서의 TF-IDF 값)
print(tfidf_df)

# 각 문서에서 가장 중요한 단어들 추출
for i, row in tfidf_df.iterrows():
    print(f&quot;Document {i+1}:&quot;)
    print(row.sort_values(ascending=False).head(10))  # 상위 10개 단어 출력&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TF-IDF 분석 결과는 개별 채용 공고에서 특정 단어가 해당 문서 내에서 얼마나 중요한지를 나타낸다. 값이 높을수록 해당 단어가 그 문서에서 중요한 단어로 간주된다. 분석 결과는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서별로 높은 TF-IDF 값을 가진 단어들:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Document 2: '경력이', '기획', '업무', '서비스'&lt;/li&gt;
&lt;li&gt;Document 6: '테스트', '수행', '자동화'&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Document 14, 15, 16: '경험이', '프로젝트', 'pm', 'it'&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Document 18: '기획', '역량', '데이터분석'&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Document 19: '디자인', '협업', '경력'&lt;/li&gt;
&lt;li&gt;Document 23, 24: '클라우드', '운영', '커뮤니케이션', 'db', '개발'&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통된 역량으로 '있으신', '보유하신', '경험' 등과 같은 단어가 여러 문서에서 반복적으로 등장하고 있다. 이는 대부분의 채용 공고에서 관련 경험과 보유 역량을 중요하게 다루고 있음을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;몇몇 문서에서는 TF-IDF 값이 모두 0으로 나와 있다. 이는 해당 문서에서 의미 있는 단어들이 포함되지 않거나, 단어가 매우 일반적이어서 모든 문서에 걸쳐 균일하게 분포되기 때문에 TF-IDF 값이 낮게 나오게 되는 경우이다. 4년제 대학 졸업자, 해외여행 결격자와 같은 역량으로 추정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TmaxBI에서는 &lt;b&gt;기획, 프로젝트 관리, IT 및 클라우드 관련 역량, 데이터 분석, 테스트 자동화&lt;/b&gt; 등을 중점 역량으로 다루고 있으며, &lt;b&gt;경험 및 보유 역량에 대한 강조&lt;/b&gt;가 거의 모든 공고에서 나타나고 있음을 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data Science</category>
      <category>TMAX</category>
      <category>데이터분석</category>
      <category>에이블스쿨</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/94</guid>
      <comments>https://hr1588.tistory.com/94#entry94comment</comments>
      <pubDate>Mon, 5 Aug 2024 00:58:52 +0900</pubDate>
    </item>
    <item>
      <title>[빅프로젝트] Nginx 웹 배포</title>
      <link>https://hr1588.tistory.com/93</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 에이블스쿨 빅프로젝트 프로토타입 제작 과정에서 활용한 AWS EC2와 Nginx를 이용한 웹 배포 방법을 정리하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1913&quot; data-origin-height=&quot;998&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uerc9/btsIQ2An0cP/oCipoGpA0k4ZTbNEfyzuM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uerc9/btsIQ2An0cP/oCipoGpA0k4ZTbNEfyzuM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uerc9/btsIQ2An0cP/oCipoGpA0k4ZTbNEfyzuM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuerc9%2FbtsIQ2An0cP%2FoCipoGpA0k4ZTbNEfyzuM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1913&quot; height=&quot;998&quot; data-origin-width=&quot;1913&quot; data-origin-height=&quot;998&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, Local에 내가 만든 파일이 있어야한다. 상단의 주소를 보면, 현재 Local에 위치한 디렉토리로 출력됨을 확인할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;EC2&amp;nbsp;instance&amp;nbsp;제작&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bA939e/btsIQF6q9iy/U5eCl3U1cT3pBOjxwGE8Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bA939e/btsIQF6q9iy/U5eCl3U1cT3pBOjxwGE8Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bA939e/btsIQF6q9iy/U5eCl3U1cT3pBOjxwGE8Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbA939e%2FbtsIQF6q9iy%2FU5eCl3U1cT3pBOjxwGE8Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1904&quot; height=&quot;690&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 로그인 이후, EC2를 검색한다. 왼쪽 메뉴바의 인스턴스를 누르면, 현재 제작된 인스턴스를 보여주고 새롭게 인스턴스를 만들 수도 있다. 이미 배포에 활용한 인스턴스가 존재함을 확인할 수 있는데, 포스팅을 위해 새로운 인스턴스를 하나 제작했다. 우측 상단의 인스턴스 시작을 눌러보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/co9VFi/btsIP0i24Gq/UFIfhsOoRLZXi2KSjD2bVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/co9VFi/btsIP0i24Gq/UFIfhsOoRLZXi2KSjD2bVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/co9VFi/btsIP0i24Gq/UFIfhsOoRLZXi2KSjD2bVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fco9VFi%2FbtsIP0i24Gq%2FUFIfhsOoRLZXi2KSjD2bVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;698&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 이름을 지정해야한다. 블로그를 위해 인스턴스를 제작했기 때문에, blog-deploy로 이름을 지정했다. 바로 밑에 어떤 애플리케이션을 사용할지 정해야하는데, 다른 애플리케이션보다 간단한 Ubuntu를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;529&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bL3VYU/btsIR2Gpva8/pSrVHbV6Vc4g1AQmVSFjX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bL3VYU/btsIR2Gpva8/pSrVHbV6Vc4g1AQmVSFjX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bL3VYU/btsIR2Gpva8/pSrVHbV6Vc4g1AQmVSFjX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbL3VYU%2FbtsIR2Gpva8%2FpSrVHbV6Vc4g1AQmVSFjX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;529&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;529&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, 요금제 및 키 페어를 설정해야한다. AWS에는 프리 티어라는 무료 요금제가 존재한다. 하지만 사용 기간과 용량에 따라서 과금이 발생할 수 있으니, 항상 주의하자. 밑에서 과금 정책과 관련해서 확인할 수 있는 서비스도 소개할 예정이다. t2.micro 요금제를 사용하고, 키 페어를 지정하면 된다. 만약 키 페어가 없을 경우, 오른쪽에 새 키 페어를 생성해야한다. 단, 키 페어 파일은 반드시 보관해야한다. ssh 및 scp 파일 전송에 키 페어가 반드시 필요하기 때문이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;697&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ben3l1/btsIPL0MIYS/R5GkDS1E9KQ4ASrYJDJbN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ben3l1/btsIPL0MIYS/R5GkDS1E9KQ4ASrYJDJbN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ben3l1/btsIPL0MIYS/R5GkDS1E9KQ4ASrYJDJbN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fben3l1%2FbtsIPL0MIYS%2FR5GkDS1E9KQ4ASrYJDJbN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1201&quot; height=&quot;697&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;697&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 설정에서 기본값을 그대로 두고, 인터넷에서 HTTP 트래픽 허용을 체크 후 오른쪽에 인스턴스 시작을 누르면, EC2에서 설정할 것은 끝이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cA5953/btsIPUJ229J/40PgjHR7kBNChl4n3WbPtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cA5953/btsIPUJ229J/40PgjHR7kBNChl4n3WbPtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cA5953/btsIPUJ229J/40PgjHR7kBNChl4n3WbPtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcA5953%2FbtsIPUJ229J%2F40PgjHR7kBNChl4n3WbPtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;392&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 설정이 끝나면 실행 중 상태가 되는데, 여기서 우리는 퍼블릭 IPv4 주소를 확인하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;ssh 접속&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/laoRz/btsIQ3Tz6lS/AZM6kgKUhT5oBP6iynE1z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/laoRz/btsIQ3Tz6lS/AZM6kgKUhT5oBP6iynE1z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/laoRz/btsIQ3Tz6lS/AZM6kgKUhT5oBP6iynE1z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlaoRz%2FbtsIQ3Tz6lS%2FAZM6kgKUhT5oBP6iynE1z1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;116&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;본 포스팅은 windows 환경 기준으로 작성되었다. Windows 왼쪽 하단에 검색을 누르고, 명령 프롬프트(CMD)를 실행한다. 여기서 key 파일이 필요하다.&amp;nbsp;ssh -i &quot;key 디렉토리&quot; ubuntu@퍼블릭 IPv4 주소를 입력하고 yes를 누르면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZUpdO/btsIRe1KA0A/CtsSkdRWZlKCibx8x6L3KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZUpdO/btsIRe1KA0A/CtsSkdRWZlKCibx8x6L3KK/img.png&quot; data-alt=&quot;접속 성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZUpdO/btsIRe1KA0A/CtsSkdRWZlKCibx8x6L3KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZUpdO%2FbtsIRe1KA0A%2FCtsSkdRWZlKCibx8x6L3KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;729&quot; height=&quot;423&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;접속 성공&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적으로 실행했으면, 다음과 같은 창을 확인할 수 있다. 혹시 오류가 발생한다면 key 파일의 위치가 맞는지, 띄어쓰기 등 오탈자가 없는지 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Nginx 설치 및 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접속에 성공 했으면, ubuntu 시스템 업데이트 및 Nginx 설치를 진행해야한다. 명령어는 다음과 같다.&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;ubuntu&amp;nbsp;시스템&amp;nbsp;업데이트&amp;nbsp;(sudo&amp;nbsp;apt-get&amp;nbsp;update) &lt;br /&gt;-&amp;nbsp;nginx&amp;nbsp;설치&amp;nbsp;(sudo&amp;nbsp;apt&amp;nbsp;install&amp;nbsp;nginx)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwHyuH/btsIQIILHYx/bqwOn3sjCcuvIIAioOJWnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwHyuH/btsIQIILHYx/bqwOn3sjCcuvIIAioOJWnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwHyuH/btsIQIILHYx/bqwOn3sjCcuvIIAioOJWnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwHyuH%2FbtsIQIILHYx%2FbqwOn3sjCcuvIIAioOJWnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;778&quot; height=&quot;620&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;620&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어 실행 이후, nginx -v를 눌러서 버전이 출력되면 성공적으로 설치가 완료된 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wa56k/btsIQHJZqSm/wBtHObMfmSvTHY0XOhfqv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wa56k/btsIQHJZqSm/wBtHObMfmSvTHY0XOhfqv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wa56k/btsIQHJZqSm/wBtHObMfmSvTHY0XOhfqv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwa56k%2FbtsIQHJZqSm%2FwBtHObMfmSvTHY0XOhfqv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1168&quot; height=&quot;631&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd; text-align: start;&quot;&gt;설치&amp;nbsp;이후,&amp;nbsp;Nginx의&amp;nbsp;default&amp;nbsp;파일을&amp;nbsp;확인하여&amp;nbsp;루트&amp;nbsp;디렉토리가&amp;nbsp;올바르게&amp;nbsp;설정되어&amp;nbsp;있는지&amp;nbsp;확인해야한다.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #dddddd; text-align: start;&quot;&gt;sudo&amp;nbsp;nano&amp;nbsp;/etc/nginx/sites-available/default&amp;nbsp;명령어를&amp;nbsp;입력하면&amp;nbsp;nano&amp;nbsp;편집기가&amp;nbsp;실행된다.&amp;nbsp;이&amp;nbsp;때,&amp;nbsp;해당&amp;nbsp;파일의&amp;nbsp;내용에서&amp;nbsp;root의&amp;nbsp;값이&amp;nbsp;/var/www/html&amp;nbsp;;인지&amp;nbsp;확인한다.&amp;nbsp;nano&amp;nbsp;편집기는&amp;nbsp;ctrl+:(콜론)을&amp;nbsp;누르고&amp;nbsp;방향키를&amp;nbsp;밑으로&amp;nbsp;내려서&amp;nbsp;편집할&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;ctrl&amp;nbsp;+&amp;nbsp;x로&amp;nbsp;나올&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;거의&amp;nbsp;대부분&amp;nbsp;root의&amp;nbsp;값이&amp;nbsp;&amp;nbsp;/var/www/html&amp;nbsp;;&amp;nbsp;일&amp;nbsp;것&amp;nbsp;이지만,&amp;nbsp;혹시&amp;nbsp;값이&amp;nbsp;다르다면&amp;nbsp;바꿔줘야한다.&amp;nbsp;해당&amp;nbsp;디렉토리로&amp;nbsp;local의&amp;nbsp;파일이&amp;nbsp;올라가기&amp;nbsp;때문이다.&lt;/span&gt; &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ldf82/btsIRlsUHU2/DYpA9qujngVM5X9TYNU1A0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ldf82/btsIRlsUHU2/DYpA9qujngVM5X9TYNU1A0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ldf82/btsIRlsUHU2/DYpA9qujngVM5X9TYNU1A0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLdf82%2FbtsIRlsUHU2%2FDYpA9qujngVM5X9TYNU1A0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;836&quot; height=&quot;622&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #dddddd;&quot;&gt;nano&amp;nbsp;편집기를&amp;nbsp;확인했으면,&amp;nbsp;root&amp;nbsp;디렉토리의&amp;nbsp;권한을&amp;nbsp;변경한다.&amp;nbsp;이제&amp;nbsp;Local의&amp;nbsp;파일을&amp;nbsp;업로드&amp;nbsp;해야하는데,&amp;nbsp;간헐적으로&amp;nbsp;권한&amp;nbsp;문제로&amp;nbsp;업로드가&amp;nbsp;안되는&amp;nbsp;경우가&amp;nbsp;있기&amp;nbsp;때문이다.&amp;nbsp;sudo&amp;nbsp;chmod&amp;nbsp;777&amp;nbsp;/var/www/html을&amp;nbsp;입력하면,&amp;nbsp;Local&amp;nbsp;파일의&amp;nbsp;업로드&amp;nbsp;준비가&amp;nbsp;끝났다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Local 파일 업로드&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;713&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cz1trV/btsIQKzQTQQ/X0LKD18h5rnonBx2SEf3cK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cz1trV/btsIQKzQTQQ/X0LKD18h5rnonBx2SEf3cK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cz1trV/btsIQKzQTQQ/X0LKD18h5rnonBx2SEf3cK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcz1trV%2FbtsIQKzQTQQ%2FX0LKD18h5rnonBx2SEf3cK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1204&quot; height=&quot;713&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;713&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 로컬에서 만든 프로토타입을 업로드하면된다. 먼저, html, css, js 및 홈페이지 구성에 포함된 logo, img, video 등 모든 파일을 하나의 폴더에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBgMEP/btsIPMyEcVH/8xkkQbp7yOFdOrDlBxo1d0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBgMEP/btsIPMyEcVH/8xkkQbp7yOFdOrDlBxo1d0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBgMEP/btsIPMyEcVH/8xkkQbp7yOFdOrDlBxo1d0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBgMEP%2FbtsIPMyEcVH%2F8xkkQbp7yOFdOrDlBxo1d0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1183&quot; height=&quot;413&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일 처음으로 실행한 명령 프롬프트는 이미 SSH로 Ubuntu에 접속했기 때문에, 별도의 명령 프롬포트를 실행한다. 이후, 다음 명령어를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- scp -i &quot;key-pair 주소&quot;&amp;nbsp; -r &quot;파일 위치&quot; ubuntu@public ip:/var/www/html/&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, key 주소와 파일 위치 사이에 -r을 사용해야한다. 대용량 파일 전송시 not a regular file 오류가 발생하며, 특정 파일이 업로드 되지 않기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;445&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VAjd3/btsIQeanP2y/Ka3p280uQDwV0U05caeEv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VAjd3/btsIQeanP2y/Ka3p280uQDwV0U05caeEv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VAjd3/btsIQeanP2y/Ka3p280uQDwV0U05caeEv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVAjd3%2FbtsIQeanP2y%2FKa3p280uQDwV0U05caeEv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;445&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;445&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;업로드 이후, Ubuntu에서 ls -al /var/www/html/을 입력하면 정상적으로 데이터가 업로드 됐음을 확인할 수 있다. 업로드가 완료 됐으니, 디렉토리 권한을 원상 복구 하고 Nginx가 파일에 접근할 수 있도록 권한을 새롭게 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 권한&amp;nbsp;원상&amp;nbsp;복구&amp;nbsp;(sudo&amp;nbsp;chmod&amp;nbsp;755&amp;nbsp;/var/www/html)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Nginx 접근 권한 설정 (sudo chown -R www-data:www-data /var/www/html)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;여기서 의문을 가질 수 있다. 굳이 권한을 다시 복구하고, 또 Nginx에 별도의 접근 권한 설정을 해야할까? 디렉토리의 권한을 복구하는 이유는 권한과 접근 제어 때문인데, 구체적으로 관련 내용을 찾아보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 보안 강화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/var/www/html 디렉토리는 일반적으로 웹 서버의 루트 디렉토리이다. 이 디렉토리에 적절한 권한 설정을 하지 않으면 보안 취약점이 발생할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;권한 755&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;소유자(owner)&lt;/b&gt;: 읽기(r), 쓰기(w), 실행(x) 권한을 가짐 (7)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;그룹(group)&lt;/b&gt;: 읽기(r)와 실행(x) 권한을 가짐 (5)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기타 사용자(others)&lt;/b&gt;: 읽기(r)와 실행(x) 권한을 가짐 (5)&lt;/li&gt;
&lt;li&gt;즉, rwxr-xr-x 권한으로 설정되어 소유자는 모든 권한을 가지며, 그룹과 기타 사용자는 읽기와 실행 권한만 가진다. 이는 디렉토리 내 파일들을 웹 서버가 접근할 수 있도록 하고, 불필요한 쓰기 권한을 제한하여 보안을 강화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 웹 서버의 정상 작동 보장&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 서버가 정상적으로 작동하려면 웹 서버 프로세스(apache, nginx 등)가 /var/www/html 디렉토리와 그 안의 파일들에 접근할 수 있어야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;읽기 권한(r)&lt;/b&gt;: 웹 서버가 파일을 읽어 클라이언트에게 제공할 수 있게 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실행 권한(x)&lt;/b&gt;: 디렉토리를 탐색할 수 있게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 쓰기 권한 제한&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;쓰기 권한(w)&lt;/b&gt;: 일반적으로 /var/www/html 디렉토리 자체에는 쓰기 권한을 부여하지 않는다. 이렇게 하면 웹 서버 프로세스 또는 다른 사용자들이 이 디렉토리 내에 파일을 생성하거나 수정하지 못하게 하여, 악의적인 파일 업로드나 수정으로부터 보호할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 웹 서버 프로세스의 파일 접근 제어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 서버는 보통 특정 사용자(예: www-data, apache, nginx)로 실행됩니다. 이 사용자에게 적절한 권한을 부여함으로써, 웹 서버가 필요한 파일을 접근하고 서비스할 수 있게 하고, 다른 사용자나 프로세스가 불필요하게 파일을 수정하거나 삭제하지 못하게 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;실행&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;631&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXcT2S/btsIQv30Zy4/vETrXR1N9JYlHK2EN2T3I1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXcT2S/btsIQv30Zy4/vETrXR1N9JYlHK2EN2T3I1/img.png&quot; data-alt=&quot;최종 실행, 오탈자에 주의해야함&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXcT2S/btsIQv30Zy4/vETrXR1N9JYlHK2EN2T3I1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXcT2S%2FbtsIQv30Zy4%2FvETrXR1N9JYlHK2EN2T3I1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;802&quot; height=&quot;631&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;631&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종 실행, 오탈자에 주의해야함&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉토리 권한 원상 복구 및 Nginx 권한 설정을 끝냈으면, Nginx를 재시작한다. 사진을 보면 chwon으로 오탈자가 있는데, linux는 오탈자 뿐만 아니라 단순 띄어쓰기 하나라도 틀리면 오류가 발생하기 때문에 주의해야한다.&lt;br /&gt;&lt;br /&gt;- Nginx 재시작 (sudo systemctl restart nginx)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1911&quot; data-origin-height=&quot;1003&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b33RGu/btsIPJhBgUS/giREXhKjSLwLRtloB0p6l1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b33RGu/btsIPJhBgUS/giREXhKjSLwLRtloB0p6l1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b33RGu/btsIPJhBgUS/giREXhKjSLwLRtloB0p6l1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb33RGu%2FbtsIPJhBgUS%2FgiREXhKjSLwLRtloB0p6l1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1911&quot; height=&quot;1003&quot; data-origin-width=&quot;1911&quot; data-origin-height=&quot;1003&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;상단의 주소를 보면, 웹으로 배포됐음을 확인할 수 있다. 주소는 http://IPv4 public IP를 입력하거나, E2C 세부사항에 있는&amp;nbsp;퍼블릭&amp;nbsp;IPv4&amp;nbsp;DNS를&amp;nbsp;웹에&amp;nbsp;입력하면&amp;nbsp;된다.&amp;nbsp;로컬에&amp;nbsp;들고&amp;nbsp;있는&amp;nbsp;웹&amp;nbsp;파일이&amp;nbsp;있다면,&amp;nbsp;URL로&amp;nbsp;올려서&amp;nbsp;프로토타입을&amp;nbsp;공유해보도록&amp;nbsp;하자.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Aivle/Project</category>
      <category>AWS</category>
      <category>nginx</category>
      <category>빅프로젝트</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/93</guid>
      <comments>https://hr1588.tistory.com/93#entry93comment</comments>
      <pubDate>Sat, 27 Jul 2024 15:01:06 +0900</pubDate>
    </item>
    <item>
      <title>[빅프로젝트] 네이버 뉴스 웹크롤링</title>
      <link>https://hr1588.tistory.com/92</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 빅프로젝트 주제로 선정된 가짜뉴스 탐지와 관련해서, raw data를 수집하기 위해 네이버 뉴스 크롤링 코드를 정리했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;조회공시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 가짜뉴스를 탐지하는 것은 현실적으로 불가능하기 때문에, 우리 팀은 조회공시 이력이 있는 기업을 대상으로, 해당 기업이 조회공시를 요청받았을 때 해당 시점을 기사를 들고 오기로 결정했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-id=&quot;fc11877a-0639-43ee-b12f-017c48cde779&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회공시란, 한국의 자본시장에서 상장 기업에 대해 거래소나 기타 규제 기관이 특정 사항에 대해 설명을 요구하는 제도이다. 이는 투자자들이 해당 기업의 경영 상태나 재무 상황 등에 대해 명확히 이해할 수 있도록 하기 위한 목적으로 시행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회공시는 주로 다음과 같은 상황에서 이루어진다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;주가 급등락:&lt;/b&gt; 기업의 주가가 비정상적으로 급등하거나 급락하는 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;중요한 정보 유출:&lt;/b&gt; 기업과 관련된 중요한 정보가 유출된 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;거래량 급증:&lt;/b&gt; 특정 기업의 거래량이 급증하는 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소문이나 루머:&lt;/b&gt; 특정 기업에 대한 소문이나 루머가 퍼지는 경우&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회공시의 절차는 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;거래소의 조회공시 요구:&lt;/b&gt; 거래소는 특정 기업에 대해 조회공시를 요구할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기업의 회신:&lt;/b&gt; 기업은 조회공시 요구를 받은 후 일정 기간 내에 해당 사항에 대한 설명을 공시한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;공시내용 검토:&lt;/b&gt; 거래소는 기업의 공시 내용을 검토하여 추가적인 조치가 필요한 경우 이를 요구할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회공시는 투자자 보호와 시장의 투명성 제고를 위한 중요한 수단으로, 이를 통해 투자자들은 보다 정확하고 신뢰할 수 있는 정보를 바탕으로 투자 결정을 내릴 수 있다. 우리는 답변이 오는 시점이 아닌, 조회공시를 요구했을 때 기사를 확인하고, 해당 시점에서 다른 패턴을 보이는 기사를 확인하고자 했다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba5iwD/btsIScoIzST/AtVOmAz6hmBOC1pAMUldfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba5iwD/btsIScoIzST/AtVOmAz6hmBOC1pAMUldfK/img.png&quot; data-alt=&quot;조회공시 요청 시점 확보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba5iwD/btsIScoIzST/AtVOmAz6hmBOC1pAMUldfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba5iwD%2FbtsIScoIzST%2FAtVOmAz6hmBOC1pAMUldfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;871&quot; height=&quot;467&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;조회공시 요청 시점 확보&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1722267330784&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import requests
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime, timedelta
import re
from tqdm import tqdm

def generate_date_range(center_date, days=3):
    center_date = datetime.strptime(center_date, &quot;%Y-%m-%d&quot;)
    start_date = center_date - timedelta(days=days)
    end_date = center_date + timedelta(days=days)
    
    date_range = []
    while start_date &amp;lt;= end_date:
        date_range.append(start_date.strftime(&quot;%Y.%m.%d&quot;))
        start_date += timedelta(days=1)
    
    return date_range

def make_url(search, date, start_pg, end_pg):
    start_dt = date
    start_dt1 = date.replace(&quot;.&quot;, &quot;&quot;)
    urls = []
    for i in range(start_pg, end_pg + 1):
        page = 1 + (i-1) * 10
        url = f&quot;https://search.naver.com/search.naver?where=news&amp;amp;sm=tab_pge&amp;amp;query={search}&amp;amp;sort=0&amp;amp;photo=0&amp;amp;field=0&amp;amp;pd=3&amp;amp;ds={start_dt}&amp;amp;de={start_dt}&amp;amp;cluster_rank=27&amp;amp;mynews=0&amp;amp;office_type=0&amp;amp;office_section_code=0&amp;amp;news_office_checked=&amp;amp;nso=so:r,p:from{start_dt1}to{start_dt1},a:all&amp;amp;start={page}&quot;
        urls.append(url)
    return urls

def get_articles(url):
    headers = {&quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4758.102&quot;}
    res = requests.get(url, headers=headers)
    soup = BeautifulSoup(res.text, &quot;html.parser&quot;)
    articles = soup.select(&quot;div.group_news &amp;gt; ul.list_news &amp;gt; li div.news_area &amp;gt; div.news_info &amp;gt; div.info_group &amp;gt; a.info&quot;)
    return [article[&quot;href&quot;] for article in articles if &quot;news.naver.com&quot; in article[&quot;href&quot;]]

def get_article_data(url):
    headers = {&quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/98.0.4758.102&quot;}
    res = requests.get(url, headers=headers)
    soup = BeautifulSoup(res.text, &quot;html.parser&quot;)

    title = soup.select_one(&quot;#content &amp;gt; div &amp;gt; div.end_ct_area &amp;gt; h2&quot;)
    if title is None:
        title = soup.select_one(&quot;#ct &amp;gt; div.media_end_head.go_trans &amp;gt; div.media_end_head_title &amp;gt; h2&quot;)

    date = soup.select_one(&quot;div.media_end_head_info_datestamp &amp;gt; div &amp;gt; span&quot;)
    if date is None:
        date = soup.select_one(&quot;#content &amp;gt; div &amp;gt; div.article_info &amp;gt; span &amp;gt; em&quot;)

    content = soup.select_one(&quot;#dic_area&quot;)
    if content is None:
        content = soup.select_one(&quot;#articleBodyContents&quot;)

    title = re.sub('&amp;lt;[^&amp;gt;]*&amp;gt;', '', str(title)).strip()
    date = date[&quot;data-date-time&quot;] if date is not None else re.sub('&amp;lt;[^&amp;gt;]*&amp;gt;', '', str(date)).strip()
    content = re.sub('&amp;lt;[^&amp;gt;]*&amp;gt;', '', str(content)).replace('\n', ' ').strip()
    
    return title, date, content

def fetch_news_data_for_company(df):
    news_data = []
    for idx, row in df.iterrows():
        company = row['회사명']
        date = row['시간'].split(' ')[0]  # Extracting date only
        date_range = generate_date_range(date)

        for date in tqdm(date_range, desc=f&quot;Fetching news for {company} on {date}&quot;):
            urls = make_url(company, date, 1, 3)
            for url in urls:
                articles = get_articles(url)
                for article in articles:
                    title, date, content = get_article_data(article)
                    news_data.append((company, date, title, article, content))

    news_df = pd.DataFrame(news_data, columns=['company', 'date', 'title', 'link', 'content'])
    news_df = news_df.drop_duplicates(keep='first', ignore_index=True)
    return news_df

# Fetch news data for the dataframe
news_df = fetch_news_data_for_company(demand)
print(&quot;크롤링한 기사 개수:&quot;, len(news_df))

# Save to CSV
news_df.to_csv('news_data_0701.csv', encoding='utf-8-sig', index=False)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 정상적으로 작동하던 코드가 일정 시간이 경과한 후 크롤링이 막히는 문제가 발생했다. 원인을 조사한 결과, 네이버 측에서 일정 시간 이상 정보를 추출하면 디도스(DDoS) 공격으로 간주하여 연결을 차단하는 것으로 확인되었다. 또한, 데이터를 하나의 파일로 저장하는 방식 때문에 크롤링이 중간에 끊기면 처음부터 모든 기사를 다시 가져와야 하는 비효율적인 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근본적으로는 조회공시라는 프로세스 자체가 요청된 시점이면 이미 사실 여부를 판별하기 시작한 후이기 때문에, 가짜 뉴스를 탐지하는 것과는 본질적으로 거리가 멀다는 문제점도 발견했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;투자 위험/경고 기업&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;694&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tANQq/btsIP6wO5V7/celWDkczOdp0GZ3zZcK1k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tANQq/btsIP6wO5V7/celWDkczOdp0GZ3zZcK1k1/img.png&quot; data-alt=&quot;투자 위험/경고 기업 255개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tANQq/btsIP6wO5V7/celWDkczOdp0GZ3zZcK1k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtANQq%2FbtsIP6wO5V7%2FcelWDkczOdp0GZ3zZcK1k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;694&quot; height=&quot;554&quot; data-origin-width=&quot;694&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;투자 위험/경고 기업 255개&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가짜 뉴스를 탐지하기 위한 새로운 방법을 제안해보았다. 특정 시점의 기사에서 유사도를 활용하여 군집화하고, 이를 통해 유사한 시점에 작성된 기사 중 명확하게 다른 패턴을 보이는 기사를 식별하는 방식이다. 이를 실험하기 위해 투자 위험/경고 공시를 받은 시점의 기사를 분석 대상으로 선정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722267717493&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import os
import sys
import urllib.request
import datetime
import time
import json
import re

client_id = ''
client_secret = ''

title1 = []
pDate1 = []
description1 = []
org_link1 =[]
link1 = []
dt_now = datetime.datetime.now().strftime('%Y-%m-%d')

# [CODE 1]
def getRequestUrl(url):
    req = urllib.request.Request(url)
    req.add_header(&quot;X-Naver-Client-Id&quot;, client_id)
    req.add_header(&quot;X-Naver-Client-Secret&quot;, client_secret)
    
    try:
        response = urllib.request.urlopen(req)
        if response.getcode() == 200:
            return response.read().decode('utf-8')
    except Exception as e:
        print(e)
        print(&quot;[%s] Error for URL : %s&quot; % (datetime.datetime.now(), url))
        return None

# [CODE 2]
def getNaverSearch(node, srcText, start, display):
    base = &quot;https://openapi.naver.com/v1/search&quot;
    node = &quot;/%s.json&quot; % node
    parameters = &quot;?query=%s&amp;amp;start=%s&amp;amp;display=%s&quot; % (urllib.parse.quote(srcText), start, display)

    url = base + node + parameters
    responseDecode = getRequestUrl(url)  # [CODE 1]

    if responseDecode is None:
        return None
    else:
        return json.loads(responseDecode)

# [CODE 3]
def getPostData(post, jsonResult, cnt):
    cleanr = re.compile('&amp;lt;.*?&amp;gt;')
    
    title = post['title']
    titlec = re.sub(cleanr, '', title)
    description = post['description']
    descriptionc = re.sub(cleanr, '', description)
    org_link = post['originallink']
    link = post['link']

    pDate = datetime.datetime.strptime(post['pubDate'], '%a, %d %b %Y %H:%M:%S +0900')
    pDate = pDate.strftime('%Y-%m-%d %H:%M:%S')

    title1.append(titlec)
    description1.append(descriptionc)
    org_link1.append(org_link)
    link1.append(link)
    pDate1.append(pDate)

    jsonResult.append({'cnt': cnt, 'title': title, 'description': description,
                       'org_link': org_link, 'link': link, 'pDate': pDate})
    return

# [CODE 0]
def main(company_list):
    node = 'news'  # 크롤링한 대상
    stock_data = company_list
    
    for index, row in stock_data.iterrows():
        srcText = row['종목명']
        end_date = datetime.datetime.strptime(row['공시일'], '%Y/%m/%d')
        start_date = end_date - datetime.timedelta(days=9)
        cnt = 0
        jsonResult = []
        
        start = 1
        display = 100
        
        while True:
            jsonResponse = getNaverSearch(node, srcText, start, display)  # [CODE 2]
            if jsonResponse is None or jsonResponse['display'] == 0:
                break
            
            for post in jsonResponse['items']:
                cnt += 1
                getPostData(post, jsonResult, cnt)  # [CODE 3]
                
            start += display
            if start &amp;gt; 1000:
                break
        
        df = pd.DataFrame(jsonResult)
        df['pDate'] = pd.to_datetime(df['pDate'])
        df_filtered = df[(df['pDate'] &amp;gt;= start_date.strftime('%Y-%m-%d')) &amp;amp; (df['pDate'] &amp;lt;= end_date.strftime('%Y-%m-%d'))]
        
        if not df_filtered.empty:
            df_filtered.to_csv(f'article/{srcText}_news.csv', encoding='utf-8-sig', index=False)
            print(f&quot;{srcText} : {len(df_filtered)} 건&quot;)
    
    return&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div data-message-id=&quot;05cb0fa0-f3c7-494d-9ed5-034e781e5d01&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 문제를 해결하기 위해 네이버 OPEN API에서 키를 발급받아 파일을 가져왔다. 조회공시 기업 알고리즘에서는 네이버 뉴스에서 특정 포맷의 기사만 가져올 수 있었지만, API를 활용하면서 네이버 포털 사이트에 등록된 모든 기사를 가져올 수 있었다. 또한, API를 사용함으로써 중간에 끊기지 않고 안정적으로 정보를 수집할 수 있었으며, 종목별로 개별 파일로 기사를 수집하여 코드가 중간에 끊기더라도 다시 진행할 수 있도록 설계했다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmTFCA/btsIRmZMJ48/iwKZZ05akTFjPRNNjB53Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmTFCA/btsIRmZMJ48/iwKZZ05akTFjPRNNjB53Tk/img.png&quot; data-alt=&quot;수집 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmTFCA/btsIRmZMJ48/iwKZZ05akTFjPRNNjB53Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmTFCA%2FbtsIRmZMJ48%2FiwKZZ05akTFjPRNNjB53Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;663&quot; height=&quot;484&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;수집 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과, 255개의 투자 경고/위험 기업 중 172개 기업의 뉴스 기사를 확보할 수 있었다. 미추출된 83개 기업의 경우, 동전주와 같은 이유로 해당 시점에 기사가 없어 수집이 되지 않았다. 다음 포스팅에서는 172개 기업 중 특정 기업을 선택하고, 해당 기업의 기사 유사도를 분석한 후 군집화한 결과를 소개할 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Aivle/Project</category>
      <category>가짜뉴스</category>
      <category>빅프로젝트</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/92</guid>
      <comments>https://hr1588.tistory.com/92#entry92comment</comments>
      <pubDate>Thu, 11 Jul 2024 01:29:45 +0900</pubDate>
    </item>
    <item>
      <title>[MySQL] 프로그래머스 - 특정 조건을 만족하는 물고기별 수와 최대 길이 구하기</title>
      <link>https://hr1588.tistory.com/91</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;FISH_INFO 테이블에서 평균 길이가 33cm 이상인 물고기들을 종류별로 분류하여 잡은 수, 최대 길이, 물고기의 종류를 출력하는 SQL문을 작성해주세요. 결과는 물고기 종류에 대해 오름차순으로 정렬해주시고, 10cm이하의 물고기들은 10cm로 취급하여 평균 길이를 구해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;487&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xCklj/btsIdx9jfKx/KCiF4jR7tQbc6PO3K6EPQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xCklj/btsIdx9jfKx/KCiF4jR7tQbc6PO3K6EPQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xCklj/btsIdx9jfKx/KCiF4jR7tQbc6PO3K6EPQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxCklj%2FbtsIdx9jfKx%2FKCiF4jR7tQbc6PO3K6EPQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;487&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;487&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719417728616&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH FILL_TABLE AS(
SELECT ID, FISH_TYPE,
    CASE WHEN LENGTH IS NULL THEN 10 ELSE LENGTH END AS LENGTH,
    TIME
FROM FISH_INFO)

SELECT 
    COUNT(FISH_TYPE) AS FISH_COUNT,
    MAX(LENGTH) AS MAX_LENGTH,
    FISH_TYPE
FROM FILL_TABLE
GROUP BY FISH_TYPE
HAVING AVG(LENGTH) &amp;gt;= 33
ORDER BY FISH_TYPE&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물고기의 null 값을 처리하기 위해 CTE에서 CASE WHEN 문을 선언하고, 문제의 조건에 따라 10CM로 변경하였다. 이후, 집계 함수를 활용해 쿼리를 작성했다. 정답을 풀었지만, 보다 효율적으로 쿼리를 구상하기 위해 COALESCE 함수를 활용해 다르게 문제를 풀어보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719417950923&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    COUNT(FISH_TYPE) AS FISH_COUNT,
    MAX(COALESCE(LENGTH, 10)) AS MAX_LENGTH,
    FISH_TYPE
FROM FISH_INFO
GROUP BY FISH_TYPE
HAVING AVG(COALESCE(LENGTH, 10)) &amp;gt;= 33
ORDER BY FISH_TYPE;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;COALESCE는 LENGTH COLUMN의 값이 NULL인 경우 10으로 처리한다. 이는 CASE WHEN 구문을 대체하며, 동일한 결과여도 보다 효율적으로 결과를 제시한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건절 문제를 풀다보면, WHERE 절과 HAVING 절의 사용이 헷갈릴 때가 있다.&amp;nbsp; 이 두 절은 각각 SQL 쿼리의 다른 단계에서 작동한다. &lt;br /&gt;&lt;br /&gt;1. WHERE 절&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WHERE 절은 데이터베이스가 데이터를 가져오는 단계에서 조건을 적용&lt;/li&gt;
&lt;li&gt;즉, GROUP BY 절이 적용되기 전에 각 행을 필터링&lt;/li&gt;
&lt;li&gt;따라서 집계 함수(예: AVG, COUNT, MAX)와 함께 사용할 수 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. HAVING 절&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HAVING 절은 데이터를 그룹화하고 나서 각 그룹에 조건을 적용&lt;/li&gt;
&lt;li&gt;집계 함수와 함께 사용할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제에서는 평균 길이가 33cm 이상인 물고기 종류를 필터링하고 있다. 이 조건은 LENGTH 값의 평균을 계산한 후에 적용되므로 HAVING 절을 사용해야 한다. 만약 WHERE 절을 사용하면, 평균 길이를 계산하기 전에 조건을 적용하게 되어 원하는 결과를 얻을 수 없다. &lt;br /&gt;&lt;br /&gt;예를 들어, HAVING 절을 WHERE 절로 바꾸면 쿼리가 올바르게 작동하지 않는다. WHERE 절은 개별 행에 대해 조건을 적용하므로, 집계 함수가 계산되기 전에 조건을 충족하지 않는 행이 필터링되기 때문이다. 다시 말해, 이 쿼리에서 HAVING 절을 WHERE 절로 바꿀 수 없는 이유는 HAVING 절이 집계된 결과에 대해 조건을 적용하는데 사용되기 때문이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1719418199550&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/298519&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/LsA1L/hyWrUatXvV/up3eNwQ1Qm0xk61hu3dZM0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/7sWt7/hyWoHDPYpv/d031r16fPjbgtKbMKE50MK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/298519&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/298519&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/LsA1L/hyWrUatXvV/up3eNwQ1Qm0xk61hu3dZM0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/7sWt7/hyWoHDPYpv/d031r16fPjbgtKbMKE50MK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/91</guid>
      <comments>https://hr1588.tistory.com/91#entry91comment</comments>
      <pubDate>Tue, 25 Jun 2024 21:52:21 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] KT Aivle</title>
      <link>https://hr1588.tistory.com/90</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Aivle School 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zOGM0/btsH81a65Ha/BIWkUnFIohtlLrqpTRBYc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zOGM0/btsH81a65Ha/BIWkUnFIohtlLrqpTRBYc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zOGM0/btsH81a65Ha/BIWkUnFIohtlLrqpTRBYc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzOGM0%2FbtsH81a65Ha%2FBIWkUnFIohtlLrqpTRBYc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;779&quot; height=&quot;483&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KT Aivle School은 기업 실무형 AI/DX 인재를 양성하는 교육 프로그램으로, KT에서 직접 운영하는 K-Digital Training 과정입니다. AI 개발자와 DX 컨설턴트 두 가지 트랙이 있으며, 현재 DX 컨설턴트 트랙의 최종 프로젝트를 진행 중입니다. 4개월간의 경험을 바탕으로 과정 전 예비 에이블러들이 궁금해할 사항들을 정리했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;의문사항&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. KT에 갈 수 있나요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기수마다 다르지만, 본인의 역량에 따라 달려 있습니다. 4기까지는 에이블 전형이 별도로 존재해 에이블러를 대상으로 채용을 진행했으며, 6기부터는 25년 상반기 공채 서류를 면제시켜준다고 합니다. 채용 확약은 아니며, 일부 교육생에게만 KT 계열사 취업 연계가 제공됩니다. 5기의 경우, 확실하진 않지만 에이블전형이 유지된다고 알고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 국민취업제도?&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1718981554695&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;국민취업지원제도&quot; data-og-description=&quot;국민취업지원제도 정보시스템 회원은 2년을 주기로 재동의 절차를 거쳐 동의한 경우에만 회원자격을 유지할 수 있습니다. 개인정보 수집∙이용 동의일로부터 2년이 되는 까지 기간 내 재동의를&quot; data-og-host=&quot;www.kua.go.kr&quot; data-og-source-url=&quot;https://www.kua.go.kr/uaptm010/selectMain.do&quot; data-og-url=&quot;https://www.kua.go.kr&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/p9FTZ/hyWoJU4Gbe/uVQw6ZCZi2tdyvhiHuGqk1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/YYy4S/hyWoAYasVU/HKQSsRhqIQ0RtKmjxyKCh0/img.jpg?width=1167&amp;amp;height=1183&amp;amp;face=0_0_1167_1183,https://scrap.kakaocdn.net/dn/c3wR51/hyWozZfPhJ/WuDoBNcGEAwwEYqyo6vOQ1/img.jpg?width=1167&amp;amp;height=1183&amp;amp;face=0_0_1167_1183&quot;&gt;&lt;a href=&quot;https://www.kua.go.kr/uaptm010/selectMain.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.kua.go.kr/uaptm010/selectMain.do&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/p9FTZ/hyWoJU4Gbe/uVQw6ZCZi2tdyvhiHuGqk1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/YYy4S/hyWoAYasVU/HKQSsRhqIQ0RtKmjxyKCh0/img.jpg?width=1167&amp;amp;height=1183&amp;amp;face=0_0_1167_1183,https://scrap.kakaocdn.net/dn/c3wR51/hyWozZfPhJ/WuDoBNcGEAwwEYqyo6vOQ1/img.jpg?width=1167&amp;amp;height=1183&amp;amp;face=0_0_1167_1183');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;국민취업지원제도&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;국민취업지원제도 정보시스템 회원은 2년을 주기로 재동의 절차를 거쳐 동의한 경우에만 회원자격을 유지할 수 있습니다. 개인정보 수집∙이용 동의일로부터 2년이 되는 까지 기간 내 재동의를&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kua.go.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;K-Digital Training을 수강하면 매달 약 30만 원의 지원금을 받을 수 있습니다. 국민취업제도는 I유형과 II유형이 있으며, 소득분위에 따라 수령금액이 달라집니다. 교육 시작 전 최대한 빨리 신청하는 것이 좋으며, 자세한 사항은 고용센터 또는 국민취업지원제도 홈페이지를 참고하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 여기서 중요한 사항이 있습니다. 에이블스쿨은자기소개서 및 인적성 검사를 통과해야 교육을 수강할 수 있습니다. 만약 합격이 확실해진 경우, 교육 시작 전 최대한 빨리 국민취업제도 신청을 시작하는 것이 좋습니다. 저의 경우, 교육 시작 1주일 전 신청을 완료했고 결국 수당 한 달 분량을 받지 못했습니다. 내일배움카드 신청과도 연관있기 때문에, 무작정 신청을 하기보다 고용센터 혹은 거주지 근처의 위탁 기관에 먼저 문의드리는걸 추천드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 자기소개서 및 인적성 검사&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DX 트랙은 코딩 역량 및 관련 경험이 필수는 아닙니다. 비전공자도 많이 참여하고 있으며, DX에 대한 관심과 열정이 더 중요하다고 생각합니다. 자기소개서에는 본인의 경험도 좋지만, 만약 경험이 없다면 해당 분야에 지원한 이유를 담백하게 적는 것을 추천드립니다. 인적성 검사는 E-book으로 문제를 풀고 응시했으며, 한두 번 정도 연습하는 것을 추천합니다. 또한, 일부 대학에서는 특별 전형으로 서류를 통과시키는 전형이 존재하니, 참고하시기 바랍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 코딩을 몰라요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분 또한 많은 분들이 고민하실 것이라고 생각합니다. 먼저, AI 트랙의 경우 기본적인 코딩역량이 필요합니다. 하지만, DX 트랙의 경우 코딩 역량보다 어떻게 정보를 활용할지 생각하는 관점이 중요하다고 생각합니다. 단순히 코딩을 잘하는 것도 좋지만, 그것보다 고객의 관점에서 우리가 뭘 해결할 수 있고, 그 결과로 어떤 효과를 만들 수 있을지 생각하는 것이 DX의 출발점이라고 생각합니다. 또한, Step 1에서 기본적인 Python은 강사님과 튜터분들의 도움을 받을 수 있으니 걱정하지 않으셔도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 수업 진행방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수업은 비대면으로 진행되며, 프로젝트 기간에는 지역별 강의장이 개방됩니다. KT에서 프로그램이 설치된 노트북을 제공해 집에서도 부담 없이 수업을 들을 수 있습니다. 교육은 오전 9시부터 오후 6시까지 진행되며, 4년제 대학 졸업 또는 졸업 예정자만 수강 가능합니다. 풀타임 교육이기 때문에 학업과 병행하기는 어렵습니다. 자세한 조건은 아래의 링크를 확인해주세요 !&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;474&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bexr8w/btsH9tEYBkK/6bKnbDCDot6jmrNZSNHhf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bexr8w/btsH9tEYBkK/6bKnbDCDot6jmrNZSNHhf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bexr8w/btsH9tEYBkK/6bKnbDCDot6jmrNZSNHhf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbexr8w%2FbtsH9tEYBkK%2F6bKnbDCDot6jmrNZSNHhf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;471&quot; height=&quot;474&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;474&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 에이블스쿨 6기를 모집 중입니다. 대학을 졸업하고 취업을 준비하는 이들에게 에이블스쿨은 좋은 기회가 될 수 있습니다. 저도 개인의 역량만을 쌓기보다, 좋은 동료들을 만나 함께 스터디/공모전에 참여했습니다. 디지털 전환에 관심이 많고,&amp;nbsp;좋은 동료와 협업을 통해 함께 성장하고 싶은 분들은 에이블스쿨에 지원해 보시길 권합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1718989677064&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AIVLE&quot; data-og-description=&quot;실무에 강한 AI/DX 인재를 꿈꾸는 대한민국 청년이라면 KT AIVLE School 6기에 도전해보세요. 지원자격 학력 정규 4년제 대학(학사 이상) 졸업자 및 졸업 예정자 전공 무관하나, AI트랙은 기본적인 코딩&quot; data-og-host=&quot;aivle.kt.co.kr&quot; data-og-source-url=&quot;https://aivle.kt.co.kr/home/main/applyMain?mcd=MC00000051&quot; data-og-url=&quot;https://aivle.kt.co.kr/home/main/applyMain?mcd=MC00000051&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/S3Skk/hyWoLelxKC/s9MTF7RlRzZFdfDiF5jFtK/img.png?width=1598&amp;amp;height=600&amp;amp;face=0_0_1598_600,https://scrap.kakaocdn.net/dn/gQOtw/hyWoBvZ2H8/3BDWNsNt0SGW9NWDfdvVk1/img.png?width=1782&amp;amp;height=345&amp;amp;face=1275_0_1686_130&quot;&gt;&lt;a href=&quot;https://aivle.kt.co.kr/home/main/applyMain?mcd=MC00000051&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aivle.kt.co.kr/home/main/applyMain?mcd=MC00000051&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/S3Skk/hyWoLelxKC/s9MTF7RlRzZFdfDiF5jFtK/img.png?width=1598&amp;amp;height=600&amp;amp;face=0_0_1598_600,https://scrap.kakaocdn.net/dn/gQOtw/hyWoBvZ2H8/3BDWNsNt0SGW9NWDfdvVk1/img.png?width=1782&amp;amp;height=345&amp;amp;face=1275_0_1686_130');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AIVLE&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;실무에 강한 AI/DX 인재를 꿈꾸는 대한민국 청년이라면 KT AIVLE School 6기에 도전해보세요. 지원자격 학력 정규 4년제 대학(학사 이상) 졸업자 및 졸업 예정자 전공 무관하나, AI트랙은 기본적인 코딩&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aivle.kt.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Aivle</category>
      <category>aivle</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/90</guid>
      <comments>https://hr1588.tistory.com/90#entry90comment</comments>
      <pubDate>Fri, 21 Jun 2024 23:47:19 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 구글 플레이 스토어 리뷰 분석</title>
      <link>https://hr1588.tistory.com/89</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 에이블러들과 공모전을 준비하면서, 무슬림들이 먹는 할랄 음식 서비스 기획을 진행하고 있다. 이번 포스팅에서는 플레이 스토어에 등록된 할랄 관련 어플의 리뷰를 가져와서, 부정적인 리뷰를 요약해보았다. 코드 진행에 앞서, 분석이 필요한 이유를 먼저 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VOC(Voice Of Customer)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VOC(Voice Of Customer)는 고객의 목소리를 의미한다. 이는 고객이 직접적으로 혹은 간접적으로 제공하는 피드백, 의견, 제안, 불만 등을 포함하는 포괄적인 개념이다. 이는 기업이 고객의 니즈의 기대를 이해하고, 제품과 서비스를 개선하는 데 중요한 역할을 한다. 특히, VOC는 고객 경험을 최적화하고 고객 만족도를 높이기 위한 전략적 도구로 활용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;외국 할랄 어플 리뷰 분석의 필요성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KOSIS 외래방문객 통계에 따르면, 코로나19를 제외하고 2016년부터 2019년까지 한국을 방문하는 무슬림 관광객은 계속 증가하고 있다. 또한, 한국관광공사에서 발표한 2022년 외래관광객 조사에 따르면 관광객들이 한국을 찾는 요인 1순위가 먹거리 문화이다. 이 상황에서, 음식을 마음대로 먹을 수 없는 무슬림 관광객들이 편리하게 이용할 수 있는 할랄 푸드맵 서비스를 제공하려고 한다. 그래서, 이미 시장에 나와 있는 외국 할랄 어플의 리뷰를 분석해서 고객의 요구사항과 기대치를 파악해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Python Code&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, google_play_scraper를 설치해야한다. 자세한 사항은 아래의 문서를 참고하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1716824478009&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;google-play-scraper&quot; data-og-description=&quot;Google-Play-Scraper provides APIs to easily crawl the Google Play Store for Python without any external dependencies!&quot; data-og-host=&quot;pypi.org&quot; data-og-source-url=&quot;https://pypi.org/project/google-play-scraper/&quot; data-og-url=&quot;https://pypi.org/project/google-play-scraper/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Aletm/hyV9Ub6faL/YWhZmT4CNoIsvFGj62laCk/img.jpg?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300&quot;&gt;&lt;a href=&quot;https://pypi.org/project/google-play-scraper/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pypi.org/project/google-play-scraper/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Aletm/hyV9Ub6faL/YWhZmT4CNoIsvFGj62laCk/img.jpg?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;google-play-scraper&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Google-Play-Scraper provides APIs to easily crawl the Google Play Store for Python without any external dependencies!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pypi.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716824541368&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
import numpy as np
import json
import time
from tqdm import tqdm

from pprint import pprint
import urllib.parse
from transformers import pipeline
from google_play_scraper import app, Sort, reviews_all, reviews

result, continuation_token = reviews(
    'com.unated', # 어플 ID
    lang='en', # defaults to 'en'
    country='us', # defaults to 'us'
    sort=Sort.NEWEST, # defaults to Sort.NEWEST
    count=3, # defaults to 100
    filter_score_with=5 # defaults to None(means all score)
)

# If you pass `continuation_token` as an argument to the reviews function at this point,
# it will crawl the items after 3 review items.

result, _ = reviews(
    'com.unated',
    continuation_token=continuation_token # defaults to None(load from the beginning)
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lelYC/btsHCByAr6O/SL4CAODLl57bqIiAOZaIS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lelYC/btsHCByAr6O/SL4CAODLl57bqIiAOZaIS0/img.png&quot; data-alt=&quot;플레이 스토어&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lelYC/btsHCByAr6O/SL4CAODLl57bqIiAOZaIS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlelYC%2FbtsHCByAr6O%2FSL4CAODLl57bqIiAOZaIS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;241&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;플레이 스토어&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이 스토어의 어플은 모두 고유한 ID를 가지고 있다. input 파라미터로 어플 ID를 넣고, 국가와 언어, 정렬, 개수, 점수를 지정하면 결과와 토큰을 return 받는다. 단, 이 방법은 모든 리뷰를 가져오지는 못하고, 정해진 개수만큼을 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716827761349&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from google_play_scraper import reviews_all

result = reviews_all(
    'com.serunai.verifyhalal',
    sleep_milliseconds=100,  # sleep time between requests
    lang='en',
    country='us'
)

for review in result:
    print(review)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgj8Hb/btsHFpJvBUr/PFJkKxk14zlTqBIvLmKKF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgj8Hb/btsHFpJvBUr/PFJkKxk14zlTqBIvLmKKF1/img.png&quot; data-alt=&quot;result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgj8Hb/btsHFpJvBUr/PFJkKxk14zlTqBIvLmKKF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcgj8Hb%2FbtsHFpJvBUr%2FPFJkKxk14zlTqBIvLmKKF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;432&quot; height=&quot;609&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 리뷰를 가져오고 싶으면, review_all 메서드를 사용하면된다. ID를 입력하고, 동일한 조건을 제시하면 해당 어플의 모든 리뷰가 출력된다. sleep_milliseconds는 요청 사이에 약간의 틈을 줘서, 오류를 방지하는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716827954409&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from google_play_scraper import search, reviews_all
import pandas as pd

def get_app_ids(query, lang='en', country='us'):
    try:
        # Perform search on Google Play Store
        results = search(
            query,
            lang=lang,
            country=country
        )

        # Extract app IDs from the results
        app_ids = [app['appId'] for app in results]
        return app_ids

    except Exception as e:
        print(f&quot;An error occurred: {e}&quot;)
        return []

def crawl_review(app_id, lang='en', country='us'):
    try:
        result = reviews_all(
            app_id,
            sleep_milliseconds=100,  # sleep time between requests
            lang=lang,
            country=country
        )
        return pd.DataFrame(result)
    except Exception as e:
        print(f&quot;An error occurred while fetching reviews for {app_id}: {e}&quot;)
        return pd.DataFrame()

def get_all_reviews(query, lang='en', country='us'):
    app_ids = get_app_ids(query, lang=lang, country=country)
    all_reviews = pd.DataFrame()

    for app_id in app_ids:
        reviews_df = crawl_review(app_id, lang=lang, country=country)
        all_reviews = pd.concat([all_reviews, reviews_df], ignore_index=True)
    
    return all_reviews

# Example usage
query = 'halal'
all_reviews_df = get_all_reviews(query)
print(all_reviews_df)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/slHcp/btsHE0wqxc2/OXBeCXxLAJ4WBrSfzeUPVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/slHcp/btsHE0wqxc2/OXBeCXxLAJ4WBrSfzeUPVK/img.png&quot; data-alt=&quot;Review DataFrame&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/slHcp/btsHE0wqxc2/OXBeCXxLAJ4WBrSfzeUPVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FslHcp%2FbtsHE0wqxc2%2FOXBeCXxLAJ4WBrSfzeUPVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;959&quot; height=&quot;544&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Review DataFrame&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 어플이 아니라, 할랄과 관련된 모든 어플의 리뷰를 확인해보고 싶다는 생각이 들었다. 따라서, 특정 키워드를 입력하면 키워드 관련 어플 ID를 return 하는 함수를 추가적으로 작성했다. 그 결과, 2.387개의 다국어 리뷰를 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;감성 분석&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 서비스와 독창성을 주기위해, 사용자들의 부정적 감성을 분석했다. huggingface의 다국어 Bert 모델을 활용했으며, 코드는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716828595995&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
from transformers import pipeline

all_reviews_df = pd.read_csv('all_reviews_df.csv')

# Load pre-trained multilingual sentiment analysis model
sentiment_analysis = pipeline(&quot;sentiment-analysis&quot;, model=&quot;nlptown/bert-base-multilingual-uncased-sentiment&quot;)

def sentiment_analysis_for_dataframe(df):
    sentiments = []
    for content in df['content']:
        try:
            sentiment = sentiment_analysis(content)[0]
            sentiments.append(sentiment)
        except Exception as e:
            print(f&quot;An error occurred: {e}&quot;)
            sentiments.append({&quot;label&quot;: &quot;neutral&quot;, &quot;score&quot;: 0.0})
    
    df['sentiment'] = [s['label'] for s in sentiments]
    df['sentiment_score'] = [s['score'] for s in sentiments]
    return df

# Example usage
if __name__ == &quot;__main__&quot;:
    # Perform sentiment analysis
    analyzed_df = sentiment_analysis_for_dataframe(all_reviews_df)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 119px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;Level&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;Count&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;5 stars&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;985&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;4 stars&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;368&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;3 stars&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;201&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;2 stars&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;169&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;1 star&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;664&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;neutral&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 별점으로 return되며, 6종의 감성으로 분류된다. 또한, 해당 감성 분류의 신뢰도(confidence score)도 존재한다. 먼저, 다국적 언어를 처리하기 위해 영어로 번역을 진행했다. 이후, 부정적 감성을 이해하기 위해 별점 2점 이하인 데이터 중 신뢰도가 0.5 이상인 데이터를 추출했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716829272376&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
from googletrans import Translator
from nltk.corpus import stopwords
import nltk

# Download stopwords
nltk.download('stopwords')

def translate_to_english(texts):
    translator = Translator()
    translated_texts = []
    for text in texts:
        try:
            translated_text = translator.translate(text, dest='en').text
            translated_texts.append(translated_text)
        except Exception as e:
            print(f&quot;Translation error: {e}&quot;)
            translated_texts.append(text)  # In case of error, use original text
    return translated_texts

def extract_negative_reviews(df):
    # Filter negative reviews (1 star and 2 stars)
    negative_reviews = df[(df['sentiment'].isin(['1 star', '2 stars']))&amp;amp;(analyzed_df['sentiment_score']&amp;gt;=0.5)]
    return negative_reviews
    
# Example usage
if __name__ == &quot;__main__&quot;:
    
    # Extract negative reviews
    negative_reviews_df = extract_negative_reviews(analyzed_df)
    negative_reviews = negative_reviews_df['content'].tolist()

    # Translate reviews to English
    translated_reviews = translate_to_english(negative_reviews)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWr162/btsHFpJvQn8/Rn6ueMgfsyzlTanOGyL5yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWr162/btsHFpJvQn8/Rn6ueMgfsyzlTanOGyL5yk/img.png&quot; data-alt=&quot;번역된 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWr162/btsHFpJvQn8/Rn6ueMgfsyzlTanOGyL5yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWr162%2FbtsHFpJvQn8%2FRn6ueMgfsyzlTanOGyL5yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;960&quot; height=&quot;670&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;번역된 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과, 506개의 문장을 확인했다. 전체 결과가 너무 많아서 내용을 파악할 수가 없기 때문에, 요약을 진행했다. 또, 이모지, 특수문자도 일부 존재함을 확인했다. 불필요한 문자를 제거하고, facebook에서 발표한 bart-large-cnn 모델로 요약을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716829448607&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import re
from bs4 import BeautifulSoup
import emoji
from transformers import pipeline

# 리뷰 정리 함수
def clean_reviews_list(reviews):
    return [clean_text(review) for review in reviews]

# 리뷰 분할 함수
def split_reviews(reviews, chunk_size):
    for i in range(0, len(reviews), chunk_size):
        yield reviews[i:i + chunk_size]

# 요약 함수
def summarize_reviews(reviews, summarizer, chunk_size=50):
    summarized_sections = []
    for chunk in split_reviews(reviews, chunk_size):
        combined_text = &quot; &quot;.join(chunk)
        summary = summarizer(combined_text, max_length=130, min_length=30, do_sample=False)[0]['summary_text']
        summarized_sections.append(summary)
    return summarized_sections

# 예제 사용법
if __name__ == &quot;__main__&quot;:
    
    # 텍스트 정리
    cleaned_reviews = clean_reviews_list(reviews_list)
    
    # Summarization pipeline 초기화
    summarizer = pipeline(&quot;summarization&quot;, model=&quot;facebook/bart-large-cnn&quot;)
    
    # 리뷰 요약
    summarized_sections = summarize_reviews(cleaned_reviews, summarizer, chunk_size=50)
    
    final_review = summarize_reviews(summarized_sections, summarizer, chunk_size = 3)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 리뷰를 한 번에 요약하면 정보 손실이 너무 크다고 판단했다. 따라서, 임의의 chunk_size를 정해서 리뷰를 분할한 후, 요약된 결과를 다시 한 번 더 요약했다. 결과는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;리뷰 &lt;/span&gt;&lt;span&gt;주요 내용 및 공통된 문제점&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1. &lt;/span&gt;&lt;span&gt;앱 기능 문제&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2. &lt;/span&gt;&lt;span&gt;사용자 경험 문제&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;광고 동의 버튼이 작동하지 않으며, 해당 화면에서 진행되지 않는 문제가 있음&lt;/li&gt;
&lt;li&gt;UI&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;가 매우 느림&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;광고 없는 버전을 구매했음에도 불구하고&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;다시 연간 구독을 요구&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3. &lt;/span&gt;&lt;span&gt;정확성 문제&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일부 제품이 '할랄'로 표시되지만, 실제로는 돼지고기를 포함하고 있는 등 정확성에 문제가 있다는 불만&lt;/li&gt;
&lt;li&gt;각 나라별로 다른 기준을 반영하지 못하고 있다는 지적이 있음&amp;nbsp;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;예&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;말레이시아와 브루나이의 기준 차이&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;).&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;4. &lt;/span&gt;&lt;span&gt;로그인 및 계정 문제&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구글 계정으로만 로그인 가능하게 강제하는 점에 대한 불만&lt;/li&gt;
&lt;li&gt;비밀번호 재설정 이메일이 오지 않는 문제&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;게스트로 주문할 수 없는 문제 등 계정 관리 문제도 언급&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;5. &lt;/span&gt;&lt;span&gt;지역화 및 데이터베이스 문제&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;할랄 음식점 검색 기능이 제대로 작동하지 않아, 실제로 근처에 있는 음식점을 찾지 못하고 수백 마일 떨어진 곳의 결과를 보여줌&lt;/li&gt;
&lt;li&gt;제품 데이터베이스가 부족하여 많은 제품이 등록되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;6. &lt;/span&gt;&lt;span&gt;기타 기술적 문제&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OTP(일회용 비밀번호) 수신 문제 등 기술적 결함&lt;/li&gt;
&lt;li&gt;앱의 아이콘이 너무 작음&lt;/li&gt;
&lt;li&gt;이와 같은 리뷰들은 주로 앱의 기능적 결함&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;사용자 경험의 불편함&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;데이터의 정확성 문제&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;그리고 계정 및 로그인 문제 등을 공통적으로 지적&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[집계]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;앱 기능 문제: 5건&lt;/li&gt;
&lt;li&gt;사용자 경험 문제: 2건&lt;/li&gt;
&lt;li&gt;정확성 문제: 2건&lt;/li&gt;
&lt;li&gt;로그인 및 계정 문제: 2건&lt;/li&gt;
&lt;li&gt;지역화 및 데이터베이스 문제: 2건&lt;/li&gt;
&lt;li&gt;기타 기술적 문제: 1건&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Aivle/Project</category>
      <category>VOC</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/89</guid>
      <comments>https://hr1588.tistory.com/89#entry89comment</comments>
      <pubDate>Sun, 19 May 2024 17:45:26 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] GCP, Naver Cloud, 형태소 분석기 바른</title>
      <link>https://hr1588.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 게임 업데이트 반응 분석 프로젝트를 수행했다. 이번 포스팅에서는 프로젝트에서 사용했던 API를 소개하고, 향후 활용을 위해 정리한 내용을 공유하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GCP(Google Cloud Platform)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqRgZ6/btsHsKN31zk/DQmUFkK9z8ZAkyi6APWTEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqRgZ6/btsHsKN31zk/DQmUFkK9z8ZAkyi6APWTEk/img.png&quot; data-alt=&quot;YouTube Data API v3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqRgZ6/btsHsKN31zk/DQmUFkK9z8ZAkyi6APWTEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqRgZ6%2FbtsHsKN31zk%2FDQmUFkK9z8ZAkyi6APWTEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1058&quot; height=&quot;639&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;YouTube Data API v3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GCP는 구글이 제공하는 클라우드 컴퓨팅 서비스로, 다양한 클라우드 기반 솔루션을 제공한다. VM(가상 머신),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bigquery(SQL), VPC(네트워킹) 등 여러가지 API 서비스를 제공하여, 기업과 개발자가 더 빠르고 효율적으로 분석/운영 할 수 있도록 돕는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 기능들 중, 업데이트 관련 유튜브 댓글을 가져오기 위해 YouTube Data API v3 라는 API를 활용했다. 추가적인 기능이 궁금하신 분들은 아래의 공식 docs를 참고하시면 된다. 단, GCP는 기본적으로 유료 서비스이다. 신규 사용자에게는 3개월 간 무료 체험판을 제공하니, 혹시 기능이 궁금하신 분들은 체험판을 사용해보시는걸 추천드린다. 구글 계정만 있으면 누구나 사용할 수 있다는 편리함도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1715876375218&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;YouTube 개발자 문서
   &amp;nbsp;|&amp;nbsp; Google for Developers&quot; data-og-description=&quot;이 페이지는 Cloud Translation API를 통해 번역되었습니다. YouTube 개발자 문서 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. YouTube에는 YouTube 기능을 자체 웹사&quot; data-og-host=&quot;developers.google.com&quot; data-og-source-url=&quot;https://developers.google.com/youtube/documentation?hl=ko&quot; data-og-url=&quot;https://developers.google.com/youtube/documentation?hl=ko&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://developers.google.com/youtube/documentation?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developers.google.com/youtube/documentation?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;YouTube 개발자 문서 &amp;nbsp;|&amp;nbsp; Google for Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지는 Cloud Translation API를 통해 번역되었습니다. YouTube 개발자 문서 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. YouTube에는 YouTube 기능을 자체 웹사&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developers.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1715876436032&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from googleapiclient.discovery import build
import pandas as pd
import re
import unicodedata
from datetime import datetime
import requests
from bs4 import BeautifulSoup

search_query = &quot;검색어를 입력하세요.&quot;
base_url = f&quot;https://www.youtube.com/results?search_query={search_query}&amp;amp;sp=CAMSAggE&quot;
response = requests.get(base_url, headers={'User-Agent': 'Mozilla/5.0'})
response_text = response.text

# 정규표현식으로 해당 패턴 찾기
pattern = r'https://i.ytimg.com/vi/([^/]+)/'
matches = re.findall(pattern, response_text)

extract_ids = []

if matches:
    video_ids = matches
    for video_id in video_ids:
        extract_ids.append(video_id)
else:
    print(&quot;해당 패턴을 찾을 수 없습니다.&quot;)

extract_ids = set(extract_ids)
print(extract_ids)

class YouTubeCommentAnalyzer:
    def __init__(self, api_key):
        self.youtube = build('youtube', 'v3', developerKey=api_key)

    def get_comments(self, video_ids):
        comments = []
        for video_id in video_ids:
            response = self.youtube.commentThreads().list(
                part='snippet,replies',
                videoId=video_id,
                maxResults=100
            ).execute()
            while response:
                for item in response['items']:
                    comment = item['snippet']['topLevelComment']['snippet']
                    comments.append([comment['textDisplay'], comment['authorDisplayName'], comment['publishedAt'], comment['likeCount']])
                    if item['snippet']['totalReplyCount'] &amp;gt; 0:
                        for reply_item in item['replies']['comments']:
                            reply = reply_item['snippet']
                            comments.append([reply['textDisplay'], reply['authorDisplayName'], reply['publishedAt'], reply['likeCount']])
                if 'nextPageToken' in response:
                    response = self.youtube.commentThreads().list(
                        part='snippet,replies',
                        videoId=video_id,
                        pageToken=response['nextPageToken'],
                        maxResults=100
                    ).execute()
                else:
                    break
        df = pd.DataFrame(comments, columns=['text', 'author', 'date', 'likes'])
        return df

    def remove_emojis(self, text):
        return ''.join(c for c in text if not unicodedata.category(c).startswith('So'))

    def preprocess_comments(self, df):
        df['preprocessed_text'] = df['text'].apply(lambda x: re.sub(r'https?://[\w/:%#\$&amp;amp;\?\(\)~\.=\+\-]+', '', x))  # URL 제거
        df['preprocessed_text'] = df['preprocessed_text'].apply(lambda x: re.sub(r'[^가-힣\s]', '', x))  # 한글과 공백 이외의 모든 문자 제거
        df['preprocessed_text'] = df['preprocessed_text'].apply(lambda x: re.sub(r'@(\w+)', '', x))  # 멘션 제거
        df['preprocessed_text'] = df['preprocessed_text'].apply(lambda x: re.sub(r'\d+', '', x))  # 숫자 제거
        df['preprocessed_text'] = df['preprocessed_text'].apply(lambda x: re.sub(r'\r', '', x))  # 줄바꿈 태그 제거
        df['preprocessed_text'] = df['preprocessed_text'].apply(self.remove_emojis)  # 이모지 제거

        # date 열 형식 변경
        df['date'] = df['date'].apply(lambda x: datetime.strptime(x, '%Y-%m-%dT%H:%M:%SZ').strftime('%Y-%m-%d %H:00'))

        return df

api_key = ''
analyzer = YouTubeCommentAnalyzer(api_key)

df = analyzer.get_comments(video_id)
df = analyzer.preprocess_comments(df)
df = df.dropna()
df.head()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 Class는 Youtube에 특정 검색어를 입력하면, 그 검색어와 관련된 영상들에서 일괄적으로 댓글을 크롤링한 후 DataFrame으로 Return 하는 Code이다. &lt;b&gt;Youtube 영상은 모두 고유한 videoid를 가지고 있는데, API에 videoid를 input 시키면 output으로 일시, 작성자, 좋아요 수, 댓글이 출력된다.&lt;/b&gt; 간단한 전처리를 거친 후, 텍스트 마이닝 및 시각화를 진행했다. 프로젝트에 대한 내용은 별도로 자세히 포스팅 할 예정이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Naver Cloud Platform&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;1115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4jbSx/btsHr0qriH8/zVQ7TGG2SdFXrIRcdu5g4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4jbSx/btsHr0qriH8/zVQ7TGG2SdFXrIRcdu5g4k/img.png&quot; data-alt=&quot;CLOVA Sentiment&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4jbSx/btsHr0qriH8/zVQ7TGG2SdFXrIRcdu5g4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4jbSx%2FbtsHr0qriH8%2FzVQ7TGG2SdFXrIRcdu5g4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1051&quot; height=&quot;1115&quot; data-origin-width=&quot;1051&quot; data-origin-height=&quot;1115&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CLOVA Sentiment&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추출한 텍스트로 KNU 감성사전을 활용, 감성 분석을 진행했으나 결과가 좋지않았다. 방법을 탐색하던 중, 네이버 클라우드에서 감성 분석 API를 제공함을 확인했다. 네이버 블로그를 기반으로, 대량의 한국어 corpus를 학습시킨 CLOVA가 보다 정확한 결과를 출력할 것이라 예상하고, 해당 API로 감성분석을 진행했다. 네이버 클라우드도 GCP 못지않게 많은 API 서비스를 제공한다. 자세한 사항은 공식 Docs를 참고하길 바란다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1715877405622&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;NAVER CLOUD PLATFORM&quot; data-og-description=&quot;cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification&quot; data-og-host=&quot;www.ncloud.com&quot; data-og-source-url=&quot;https://www.ncloud.com/product/aiService/clovaSentiment&quot; data-og-url=&quot;https://www.ncloud.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oWM3x/hyV6c3R2Nv/deImF5lWdQI8c7pZtQ0Xr1/img.jpg?width=526&amp;amp;height=274&amp;amp;face=0_0_526_274,https://scrap.kakaocdn.net/dn/DZEu2/hyV6gZuEtL/MQoHvA2fqmNq1gJWuCbdJ0/img.jpg?width=1692&amp;amp;height=826&amp;amp;face=0_0_1692_826,https://scrap.kakaocdn.net/dn/xbbNU/hyV6fsLMBC/A4vraNMsOMoJP9KKKhdvR1/img.png?width=1600&amp;amp;height=720&amp;amp;face=0_0_1600_720&quot;&gt;&lt;a href=&quot;https://www.ncloud.com/product/aiService/clovaSentiment&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ncloud.com/product/aiService/clovaSentiment&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oWM3x/hyV6c3R2Nv/deImF5lWdQI8c7pZtQ0Xr1/img.jpg?width=526&amp;amp;height=274&amp;amp;face=0_0_526_274,https://scrap.kakaocdn.net/dn/DZEu2/hyV6gZuEtL/MQoHvA2fqmNq1gJWuCbdJ0/img.jpg?width=1692&amp;amp;height=826&amp;amp;face=0_0_1692_826,https://scrap.kakaocdn.net/dn/xbbNU/hyV6fsLMBC/A4vraNMsOMoJP9KKKhdvR1/img.png?width=1600&amp;amp;height=720&amp;amp;face=0_0_1600_720');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;NAVER CLOUD PLATFORM&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ncloud.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1715877499748&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def analyze_sentiment(text, client_id, client_secret):
    url = &quot;https://naveropenapi.apigw.ntruss.com/sentiment-analysis/v1/analyze&quot;
    headers = {
        &quot;X-NCP-APIGW-API-KEY-ID&quot;: client_id,
        &quot;X-NCP-APIGW-API-KEY&quot;: client_secret,
        &quot;Content-Type&quot;: &quot;application/json&quot;
    }
    data = {&quot;content&quot;: text, &quot;config&quot;: {&quot;negativeClassification&quot;: True} }
    response = requests.post(url, json=data, headers=headers)
    if response.status_code == 200:
        result = json.loads(response.text)
        sentiment_summary = {
            &quot;document_sentiment&quot;: result[&quot;document&quot;][&quot;sentiment&quot;],
            &quot;confidence&quot;: result[&quot;document&quot;][&quot;confidence&quot;],
            &quot;sentence_details&quot;: []
        }
        for sentence in result[&quot;sentences&quot;]:
            sentiment_summary[&quot;sentence_details&quot;].append({
                &quot;content&quot;: sentence[&quot;content&quot;],
                &quot;sentiment&quot;: sentence[&quot;sentiment&quot;],
                &quot;confidence&quot;: sentence[&quot;confidence&quot;]
            })
            if sentence[&quot;sentiment&quot;] == &quot;negative&quot;:
                sentiment_summary[&quot;sentence_details&quot;][-1][&quot;negativeSentiment&quot;] = sentence.get(&quot;negativeSentiment&quot;, {})
        return sentiment_summary
    else:
        return &quot;Error&quot;

# 데이터 프레임의 'preprocessed_text' 열에 대해 감성 분석 수행
sentiment_analysis = []  
for text in tqdm(merge_df['preprocessed_text'], desc=&quot;Analyzing sentiments&quot;):
    analysis_result = analyze_sentiment(text, client_id, client_secret)  # 변수 이름 변경
    sentiment_analysis.append(analysis_result)  

# 결과 확인
for analysis in sentiment_analysis:
    print(analysis)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, CLOVA Sentiment는 개별 문장의 감성이 부정적이라면, 세부 감정 정보를 함께 제공한다. 단순히 부정적이다만 판별하는 것이 아니라, 세부적으로 어떤 감정인지를 파악하고 이를 제품/서비스 개선에 반영할 수 있다는 장점도 존재한다. 또한, 월 1,000건의 문장까지는 무료로 서비스를 제공한다. 직접 감성 분석을 해보고, LLM의 감성 분석과의 결과를 비교해봐도 좋을듯하다. 1,000회를 초과하면 건당 1원의 요금이 발생하니, 이 점은 주의하기 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;바른(Bareun)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;519&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LnFQw/btsHqM00yPU/xUV5U3ST5OgkODx8mP1F70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LnFQw/btsHqM00yPU/xUV5U3ST5OgkODx8mP1F70/img.png&quot; data-alt=&quot;바른 형태소 분석기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LnFQw/btsHqM00yPU/xUV5U3ST5OgkODx8mP1F70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLnFQw%2FbtsHqM00yPU%2FxUV5U3ST5OgkODx8mP1F70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1036&quot; height=&quot;519&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;519&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;바른 형태소 분석기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 2가지 방법에 비해, 바른 형태소 분석기는 다소 생소할 수 있다. 바른 형태소 분석기를 사용하기 이전, 한국어 말뭉치를 분석할 때 konlpy의 mecab, okt를 주로 사용했다. 하지만, konlpy는 의미없는 결과 혹은 부정확한 결과가 출력되는 경우가 종종 있었고, 이를 해결하고자 방법을 찾던 중 바른 형태소 분석기를 발견했다. 무료로 다운받을 수 있고, Docs도 정리가 잘 되어있으니 한국어 말뭉치를 분석해야하면 해당 분석기를 사용해보는걸 추천드린다. 단점이 있다면, 로컬 서버에 API로 가져와서 웹으로 배포하는 데는 어려움이 존재한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1715877962870&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;바른&quot; data-og-description=&quot;최고 성능의 한국어 형태소 분석기「바른」을 무료로 사용해 보세요.&quot; data-og-host=&quot;bareun.ai&quot; data-og-source-url=&quot;https://bareun.ai/&quot; data-og-url=&quot;https://bareun.ai/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/T7OR8/hyV57VN6k1/kRWHLJNgpnYjAlQq3OkWG0/img.png?width=426&amp;amp;height=227&amp;amp;face=0_0_426_227&quot;&gt;&lt;a href=&quot;https://bareun.ai/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://bareun.ai/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/T7OR8/hyV57VN6k1/kRWHLJNgpnYjAlQq3OkWG0/img.png?width=426&amp;amp;height=227&amp;amp;face=0_0_426_227');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;바른&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;최고 성능의 한국어 형태소 분석기「바른」을 무료로 사용해 보세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;bareun.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1715878171394&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def tokenizer(data, api_key):
    # Tagger 인스턴스 생성 및 사용자 정의 사전 설정
    t = brn.Tagger(api_key, &quot;localhost&quot;, 5656)
    cust_dic = t.custom_dict(&quot;my_dict_01&quot;)
    # 고유명사 사전
    cust_dic.copy_np_set({'캐릭터', '비질란테', '박종민', '강정호', '윤명진', '네오플', '헌터'})
    cust_dic.update()
    t.set_domain(&quot;my_dict_01&quot;)
    
    # 불용어 로딩 (이 과정은 함수 외부에서 한 번만 수행되어야 합니다)
    stopwords = load_stopwords()

    tags = t.tags(data)
    nouns = tags.nouns()

    # 불용어 제거 및 단어 길이 필터링
    filtered_nouns = [word for word in nouns if word not in stopwords and len(word) &amp;gt;= 2]
    
    # 단어 빈도수 계산 및 DataFrame 변환
    count_tokens = Counter(filtered_nouns)
    df_tokens = pd.DataFrame(count_tokens.items(), columns=['word', 'count'])
    df_tokens = df_tokens[df_tokens['count'] &amp;gt;= 10].sort_values('count', ascending=False).reset_index(drop=True)
    
    return df_tokens&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가입 이후, Key만 있으면 Local에서 Python으로 분석하면 된다. 또한, OOV(Out-Of-Vocabulary)문제를 해결하기 위해 자체적으로 고유명사 사전을 제작할 수 있다. 이번 프로젝트에서는 디렉터 및 주요 직원분들의 성함과 직업명, 회사명을 간단하게 삽입했다. 이처럼 특정 도메인에 특화된 고유명사를 추가하면 해당 텍스트에 대한 분석을 더욱 정교하게 할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 가져와 불용어를 제거하고, tags 메소드로 POS(Part-Of-Speech)를 부착했다. 전체 데이터에서 명사가 고유한 의미를 가지고 있기 때문에 문서의 주제를 대표할 수 있다고 생각했다. 따라서, 명사만을 가져온 후 두 글자 이상의 데이터를 분석에 활용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 프로젝트에서 활용한 3가지 API를 간단하게 소개하고, 어떻게 Python으로 구현하였는지 정리하였다. 다음 포스팅에서는 프로젝트 전체를 리뷰해서 왜 분석을 진행했고, 어떻게 전체적인 흐름을 구성했는지 정리해보자.&lt;/p&gt;</description>
      <category>Aivle/Project</category>
      <category>bareun</category>
      <category>GCP</category>
      <category>Naver Cloud</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/85</guid>
      <comments>https://hr1588.tistory.com/85#entry85comment</comments>
      <pubDate>Sat, 20 Apr 2024 16:56:25 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] DNN과 활성화 함수</title>
      <link>https://hr1588.tistory.com/84</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝은 이미지 인식, 자연어 처리, 자율 주행 등 많은 분야에서 활용되고 있다. 현재는 다양한 아키텍처가 발전했지만, 이전에 가장 두드러진 아키텍처로 DNN, CNN, RNN이 있다. 각각 특정한 유형의 데이터와 작업을 처리하도록 설계되었는데, 이번 포스팅에서는 DNN을 python 예제와 함께 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DNN(Deep Neural Network)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DNN은 입력층과 출력층 사이에 여러 개의 은닉층을 가진 인공 신경망이다. &quot;Deep&quot; 이라는 용어는 층(Layer)의 수를 나타내며, 여러 개의 은닉층을 통해 입력 데이터를 처리하여 출력 결과를 생성한다. 이는 기본적인 인공 신경망(ANN)의 확장된 형태로, 더 많은 층과 뉴런을 포함하여 보다 복잡한 패턴과 구조를 학습할 수 있다. 기본적인 구조는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력층(Input Layer) : 입력 데이터를 받아들이는 층으로, 데이터의 특징(feature)을 입력으로 받는다.&lt;/li&gt;
&lt;li&gt;은닉층(Hidden Layer) : 입력층과 출력층 사이에 위치한 층으로, 여러 개의 층으로 구성될 수 있따. 이 층들은 입력 데이터를 처리하고 변환하여 다음 층으로 전달한다.&lt;/li&gt;
&lt;li&gt;출력층(Output Layer) : 최종 결과를 출력하는 층으로, 분류 문제에서는 클래스의 확률을 출력할 수 있고, 회귀 문제에서는 연속적인 값을 출력할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 여러 개의 층을 통화하면서 각 뉴런은 다음의 두 단계를 거친다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;선형 변환(Linear Transformation)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 데이터 x와 가중치 w를 선형 결합한다.&lt;/li&gt;
&lt;li&gt;수학적으로는 z = w * x + b로 표현된다. 여기서 b는 편향(bias)&lt;/li&gt;
&lt;li&gt;편향(bias) : 신경망에서 활성화 함수의 입력값에 더해지는 상수값으로, Neural Network가 더 유연하고 표현력 있는 모델을 만드는 데 활용된다.&lt;/li&gt;
&lt;li&gt;편향의 역할 : 활성화 함수의 이동(shift), 학습 능력 향상(유연한 결정 경계), 학습 과정 개선(활성화 함수)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;비선형 활성화 함수(Non-linear Activation Function)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;선형 변환의 결과에 비선형 활성화 함수를 적용하여 뉴런의 출력을 생성&lt;/li&gt;
&lt;li&gt;일반적인 활성화 함수로는 ReLU, Sigmoid, tanh 등이 있다.&lt;/li&gt;
&lt;li&gt;활성화 함수는 모델이 비선형성을 학습할 수 있게 하여 복잡한 데이터 패턴을 포착하도록 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선형 변환은 입력 데이터를 가중치와 편향을 통해 변환하는 수학적 과정이다. 이는 입력 데이터가 뉴런에 의해 처리되는 첫 번째 단계로, 입력 데이터의 가중 합을 계산한다. 이 선형 변환을 통해 입력 데이터가 다음 층의 뉴런으로 전달되기 전에 가중치와 편향에 의해 조정된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 입력 데이터 예를 들어, 입력 데이터 x = [x1,x2,x3]와 가중치 w = [w1,w2,w3]가 주어진다고 가정해보자. 각 입력은 해당 가중치와 곱해진 후, 모든 결과가 더해진다. 여기에 편향 b를 더하여 다음과 같은 선형 변환을 수행한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;z = w1 * x1 + w2 * x2 + w3 * x3 + b&lt;br /&gt;&lt;br /&gt;​이 z 값은 비선형 활성화 함수에 입력되어 최종 뉴런 출력을 생성한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;활성화 함수(Activation Function)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;python 예제를 살펴보기 전에, 활성화 함수의 종류에 대해 간단하게 정리해보자.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V9pxt/btsHsGY7jrH/r4z9gKTRMluzrYsYKCAmjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V9pxt/btsHsGY7jrH/r4z9gKTRMluzrYsYKCAmjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V9pxt/btsHsGY7jrH/r4z9gKTRMluzrYsYKCAmjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV9pxt%2FbtsHsGY7jrH%2Fr4z9gKTRMluzrYsYKCAmjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;371&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Sigmoid&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sigmoid 함수는 입력 값을 [0,1] 범위로 압축한다. 이는 출력 값이 확률을 나타내야 하는 이진 분류(Binary Classification) 문제에 자주 사용된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확률적 해석 : 출력 값이 0과 1 사이에 위치하므로 확률적 해석이 가능하다.&lt;/li&gt;
&lt;li&gt;연속적이고 미분 가능 : 모든 입력 값에 대해 연속적이고 미분 가능하여 역전파에 유리함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기울기 소실(Gradient Vanishing) : 입력 값이 매우 크거나 작은 경우, 기울기가 매우 작아져 학습이 어려워질 수 있음&lt;/li&gt;
&lt;li&gt;출력 범위 제한 : 출력이 [0,1]로 제한되어 있어, 매우 큰 양수나 음수 값을 효과적으로 처리하지 못함&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Tanh(Hyperbolic Tangent)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Tanh 함수는 입력 값을 [-1,1] 범위로 압축한다. Sigmoid 함수와 유사하지만 중심이 0이므로 음수 입력 값은 음수 출력을, 양수 입력 값은 양수 출력을 가진다.&lt;/p&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중심이 0 : 출력 값의 평균이 0에 가까워지므로, 다음 층의 입력이 더 잘 정규화된다.&lt;/li&gt;
&lt;li&gt;기울기 소실 문제 개선 : Sigmoid 함수에 비해 기울기 소실 문제가 덜 심각하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기울기 소실(Gradient Vanishing) : Sigmoid에 비해 덜 심각한 것이기, 여전히 기울기 소실 위험은 존재한다. -1과 1에 가까워질수록 기울기가 작아지기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. ReLU(Rectified Linear Unit)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ReLU는 가장 많이 사용되는 활성화 함수 중 하나로, 입력이 양수인 경우 입력 값을 그대로 출력하고, 음수인 경우에는 0을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단순함 : 계산이 매우 간단하여 학습 속도를 빠르게 한다.&lt;/li&gt;
&lt;li&gt;희소성 : 음수 값을 0으로 변환하여 일부 뉴런을 비활성화 시킴으로써 모델의 희소성을 증가시킨다.&lt;/li&gt;
&lt;li&gt;기울기 소실 문제 해결 : sigmoid나 tanh 함수에 비해 기울기 소실 문제를 크게 완화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Dead ReLU 문제 : ReLU 뉴런이 음수 입력 값만 계속 받게 되면, 해당 뉴런은 항상 0을 출력하게 되어 학습되지 않는 문제가 발생한다. 이를 해결하기 위해 Leaky ReLU, Parametric ReLU와 같은 변형된 ReLU 함수가 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면, ReLU는 어떻게 기울기 소실 문제를 완화할까?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출력 값의 분포 : ReLU 함수는 음수 입력 값을 0으로, 양수 입력 값을 그대로 출력한다. 이는 ReLU가 0 이상의 값을 출력할 때, 기울기가 항상 1이 되도록 한다. 따라서, 입력 값이 커지더라도 기울기가 0으로 수렴하지 않는다.&lt;/li&gt;
&lt;li&gt;비선형성 유지 : ReLU는 입력 값의 절반 이상을 0으로 만듦으로써 모델에 비선형성을 추가한다. 이는 신경망이 복잡한 패턴을 학습할 수 있도록 도와준다.&lt;/li&gt;
&lt;li&gt;희소성(Sparsity): ReLU의 특성으로 인해 뉴런의 절반이 0이 되어 희소성을 증가시킨다. 이는 모델의 일반화 성능을 향상시키고 과적합을 줄일 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. Leaky ReLU(LReLU)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Leaky ReLU는 ReLU의 변형으로, 입력 값이 음수일 때도 작은 기울기를 가지도록 만든 함수다. 이를 통해 ReLU에서 발생할 수 있는 '죽은 ReLU' 문제를 완화할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;음수 값에 작은 기울기를 부여하여 모든 뉴런이 학습에 기여할 수 있도록 함&lt;/li&gt;
&lt;li&gt;ReLU의 간단함과 계산 효율성을 유지하면서 죽은 뉴런 문제를 완화&lt;/li&gt;
&lt;li&gt;하지만, 음수 부분의 기울기 값을 적절히 선택하는게 어렵고 극단값에 민감하다는 단점도 존재&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. Maxout&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Maxout은 신경망의 각 층에서 여러 선형 함수 중 최대값을 선택하는 방식으로 작동하는 활성화 함수이다. 이는 비선형성을 더 잘 표현할 수 있도록 한다. 기존의 뉴런은 하나의 선형 함수에 활성화 함수를 적용하여 출력을 생성한다. 하지만, Maxout 뉴런은 개별 입력에 대해 여러 선형 함수를 계산하고, 계산된 값 중 최대값을 선택하여 최종 출력으로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 비선형성을 학습할 수 있어 더 강력한 표현력을 가짐&lt;/li&gt;
&lt;li&gt;다중 퍼셉트론(MLP)와 잘 통합되어 성능을 향상시킬 수 있음&lt;/li&gt;
&lt;li&gt;하지만, 파라미터의 수가 증가하여 모델의 복잡성과 계산 비용이 증가함&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;6. ELU&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ELU는 ReLU와 Leaky ReLU의 단점을 보완하기 위해 고안된 함수로, 입력이 음수일 때도 지수 함수 형태를 가지도록 설계되었다. 이를 통해 신경망이 일정한 기울기를 유지할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;음수 구간에서의 출력을 일정하게 유지하여 평균 출력을 0에 가깝게 만든다.&lt;/li&gt;
&lt;li&gt;기울기가 음수 구간에서도 0이 아니므로 Dead 문제를 방지한다.&lt;/li&gt;
&lt;li&gt;지수 함수 계산이 포함되어 있어 ReLU에 비해 계산 비용이 약간 더 높다는 단점도 존재한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;7. Softmax&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uNCG5/btsHsHKwuPd/vuA22q2JU612XYk7JXVFQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uNCG5/btsHsHKwuPd/vuA22q2JU612XYk7JXVFQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uNCG5/btsHsHKwuPd/vuA22q2JU612XYk7JXVFQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuNCG5%2FbtsHsHKwuPd%2FvuA22q2JU612XYk7JXVFQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;970&quot; height=&quot;524&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;softmax 함수는 다중 클래스 분류 문제에서 자주 사용된다. 개별 클래스에 대한 확률 분포를 출력하며, 모든 출력 값의 합이 1이 되도록 정규화한다. sigmoid가 [0,1]의 범위에서 threshold의 값에 따라 이진 분류를 한다면, softmax는 무한대의 범위를 가진 logit을 [0,1] 범위의 확률로 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확률적 해석 : 각 클래스에 대한 확률 값을 제공하여 다중 클래스 분류 문제에 적합함&lt;/li&gt;
&lt;li&gt;출력의 합이 1 : 모든 클래스의 확률 합이 1이 되도록 보장하여 확률 분포를 형성&lt;/li&gt;
&lt;li&gt;계산 복잡성 : 다른 활성화 함수에 비해 계산이 복잡하여 다중 클래스 분류 문제에서만 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Python 예제&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1715875517284&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Tensorflow 예제

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# 더미 데이터 생성
X = np.random.rand(1000, 20)  # 1000개의 샘플, 각 샘플당 20개의 특징
y = np.random.randint(2, size=(1000, 1))  # 이진 분류

# DNN 모델 정의
model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# 모델 훈련
model.fit(X, y, epochs=10, batch_size=10)

# 모델 평가
loss, accuracy = model.evaluate(X, y)
print(f'Loss: {loss}, Accuracy: {accuracy}')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1715875526341&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Pytorch 예제

import torch
import torch.nn as nn
import torch.optim as optim

# 더미 데이터 생성
X = torch.randn(1000, 20)  # 1000개의 샘플, 각 샘플당 20개의 특징
y = torch.randint(0, 2, (1000, 1)).float()  # 이진 분류

# DNN 모델 정의
class DNN(nn.Module):
    def __init__(self):
        super(DNN, self).__init__()
        self.layer1 = nn.Linear(20, 64)
        self.layer2 = nn.Linear(64, 64)
        self.output = nn.Linear(64, 1)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.relu(self.layer1(x))
        x = self.relu(self.layer2(x))
        x = self.sigmoid(self.output(x))
        return x

model = DNN()
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 모델 훈련
for epoch in range(10):
    optimizer.zero_grad()
    outputs = model(X)
    loss = criterion(outputs, y)
    loss.backward()
    optimizer.step()
    print(f'Epoch {epoch+1}, Loss: {loss.item()}')

# 모델 평가
with torch.no_grad():
    outputs = model(X)
    predicted = (outputs &amp;gt; 0.5).float()
    accuracy = (predicted == y).float().mean()
    print(f'Accuracy: {accuracy.item()}')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝에는 여러가지 프레임워크가 있는데, 대표적으로 텐서플로우(Tensorflow)와 파이토치(Pytorch)를 가장 널리 사용한다. Tensorflow는 Keras라는 라이브러리를 활용해 쉽게 모델을 구축할 수 있고, Pytorch는 Python과 매우 유사한 문법을 사용하여 디버깅과 모델 개발이 더 쉽다는 장점이 있다. 위의 두 가지 예제 모두 동일한 데이터와 아키텍처를 표현한 결과이다. 결과는 동일하지만, 어떤 프레임워크를 쓰냐에 따라 코드 구성이 달라진다고 해석하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진 출처 &lt;br /&gt;&lt;a href=&quot;https://medium.com/@kmkgabia/ml-sigmoid-%EB%8C%80%EC%8B%A0-relu-%EC%83%81%ED%99%A9%EC%97%90-%EB%A7%9E%EB%8A%94-%ED%99%9C%EC%84%B1%ED%99%94-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-c65f620ad6fd&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://medium.com/@kmkgabia/ml-sigmoid-%EB%8C%80%EC%8B%A0-relu-%EC%83%81%ED%99%A9%EC%97%90-%EB%A7%9E%EB%8A%94-%ED%99%9C%EC%84%B1%ED%99%94-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-c65f620ad6fd&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://velog.io/@chiroya/13-Softmax-Function&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@chiroya/13-Softmax-Function&lt;/a&gt;&lt;/p&gt;</description>
      <category>Data Science</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/84</guid>
      <comments>https://hr1588.tistory.com/84#entry84comment</comments>
      <pubDate>Wed, 10 Apr 2024 16:46:30 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 딥러닝이란?</title>
      <link>https://hr1588.tistory.com/83</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 딥러닝의 정의에 대해 살펴보고, 어떻게 학습을 진행하는지 간단하게 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;딥러닝이란?&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgvCjU/btsGPoLnknH/B9HAyEFktsTgzdVcAI8Kf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgvCjU/btsGPoLnknH/B9HAyEFktsTgzdVcAI8Kf0/img.png&quot; data-alt=&quot;인공지능의 발전 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgvCjU/btsGPoLnknH/B9HAyEFktsTgzdVcAI8Kf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgvCjU%2FbtsGPoLnknH%2FB9HAyEFktsTgzdVcAI8Kf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;740&quot; height=&quot;468&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인공지능의 발전 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인공지능(AI) 은 1950년대에 처음으로 개념화되었다. 초기의 인공지능 연구는 규칙 기반 시스템(rule-based systems)과 논리적 추론(logical reasoning)에 중점을 두었으며, 이를 통해 기계가 스스로 문제를 해결하도록 만드는 것이 목표였다. 1956년 다트머스 회의에서 이 분야는 공식적으로 &amp;lsquo;인공지능&amp;rsquo;이라는 용어를 사용하기 시작했다. &lt;br /&gt;&lt;br /&gt;머신러닝(ML) 은 1980년대에 인공지능의 한 분야로서 등장했다. 머신러닝은 데이터로부터 학습하여 결정을 내릴 수 있는 알고리즘을 개발하는 기술이다. 이는 인공지능을 실현하는 구체적인 방법으로서, 기계가 명시적인 프로그래밍 없이 학습할 수 있게 하는 것을 목표로 한다. 대표적인 머신러닝 알고리즘에는 의사결정 나무(decision tree), 서포트 벡터 머신(support vector machine), 랜덤 포레스트(random forest) 등이 있다. &lt;br /&gt;&lt;br /&gt;딥러닝(DL)은 2000년대 초반부터 주목받기 시작한 머신러닝의 한 분야이다. 이 기술은 인간의 뇌가 정보를 처리하는 방식을 모방하는 인공 신경망에 기반을 두고 있다. 딥러닝 신경망은 여러 계층(layer)으로 구성되며, 이 계층들은 데이터에서 점차 복잡하고 추상적인 특성들을 학습한다. 복잡한 문제를 해결하는 데 탁월한 능력을 보이는 딥러닝 모델은 이미지 인식, 음성 인식, 자연어 처리 등 다양한 분야에서 활용되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;딥러닝의&amp;nbsp;핵심&amp;nbsp;특징&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;계층적 표현 학습: 딥러닝 모델은 입력 데이터에서 다양한 추상적 수준의 특성을 자동으로 학습한다. 예를 들어, 이미지 처리에서는 낮은 계층에서는 가장자리나 질감 같은 기본적인 특성을, 높은 계층에서는 객체의 부분이나 전체 구조 같은 더 복잡한 특성을 학습한다.&lt;/li&gt;
&lt;li&gt;데이터에서의 학습: 딥러닝 모델은 데이터로부터 직접 학습하여 특정 작업을 수행한다. 이를 통해 모델은 수많은 데이터 예제를 통해 스스로를 개선하며, 사람이 직접 특성을 설계하지 않아도 된다.&lt;/li&gt;
&lt;li&gt;보편적 근사성: 딥러닝 모델은 복잡한 함수를 근사할 수 있는 능력이 매우 뛰어나며, 이를 통해 다양한 종류의 데이터와 작업에 유연하게 적용될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;딥러닝의 주요 구성 요소&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인공 신경망 : 여러 계층으로 구성된 네트워크로, 각 계층은 여러 뉴런으로 구성되며, 이 뉴런들은 활성화 함수를 통해 신호를 처리하고 전달한다.&lt;/li&gt;
&lt;li&gt;활성화 함수(Activation Function) : 비선형 문제를 해결하기 위해 각 뉴런에 적용되는 함수로, 신경망이 복잡한 패턴과 관계를 학습할 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;손실 함수(Loss Function) : 모델의 예측이 실제 값과 얼마나 잘 일치하는지 측정한다. 이는 모델의 학습을 지휘하는 지표로 작용한다.&lt;/li&gt;
&lt;li&gt;옵티마이저(Optimizer) : 모델의 가중치를 업데이트하는 방식을 결정한다. 대표적인 방법으로는 경사 하강법(Gradient Descent)이 있으며, 이를 통해 손실 함수를 최소화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면, 딥러닝은 어떻게 학습을 진행할까?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;가중치&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bca782/btsGNOD1fag/EzAmwtUAOHd5LTm3VbWPdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bca782/btsGNOD1fag/EzAmwtUAOHd5LTm3VbWPdK/img.png&quot; data-alt=&quot;딥러닝 학습 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bca782/btsGNOD1fag/EzAmwtUAOHd5LTm3VbWPdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbca782%2FbtsGNOD1fag%2FEzAmwtUAOHd5LTm3VbWPdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;738&quot; height=&quot;340&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;딥러닝 학습 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝에서 '가중치'는 매우 중요한 개념이다. 이를 이해하기 위해선, 딥러닝 모델이 어떻게 데이터로부터 학습하는지 먼저 알아야 한다. 딥러닝 모델은 입력 데이터를 받아들여, 그 데이터를 기반으로 예측이나 결정을 내리는 인공 신경망이다. 가중치는 이러한 인공 신경망에서 입력 데이터의 각 특성이 결과에 미치는 중요도를 결정하는 역할을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;가중치는 딥러닝에서 신경망의 핵심 요소 중 하나로, 각 입력 데이터 포인트에 곱해져 그 효과를 조절한다. 각 연결선에는 가중치가 할당되며, 이 가중치는 입력 신호가 다음 뉴런에 전달되는 영향력을 조절한다. 예를 들어, 어떤 가중치는 입력 신호를 강화시킬 수도 있고, 다른 가중치는 약화시킬 수도 있다. 즉, 모든 입력 정보가 동일한 중요도를 갖지 않는다. 가중치는 중요한 정보를 강조하고 덜 중요한 정보를 억제하는 필터 역할을 한다고 생각할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;가중치는 초기에 무작위로 설정되며, 학습이 진행됨에 따라 모델이 정확한 결과를 낼 수 있도록 조정된다. 이 조정 과정을 통해 모델은 특정 작업에 대해 최적화된다. 가중치의 조정은 손실 함수를 최소화하는 방향으로 진행되는데, 손실 함수는 모델의 예측이 실제 값과 얼마나 차이 나는지를 측정한다. 이 손실 값을 줄이기 위해, 학습 과정에서는 경사 하강법(Gradient Descent)과 같은 최적화 알고리즘을 통해 가중치가 업데이트된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; Gradient Descent&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cf61Bj/btsGMTe7MPz/0dloeqXVaiwr7mM4PtMuK1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cf61Bj/btsGMTe7MPz/0dloeqXVaiwr7mM4PtMuK1/img.jpg&quot; data-alt=&quot;경사 하강법 학습 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cf61Bj/btsGMTe7MPz/0dloeqXVaiwr7mM4PtMuK1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcf61Bj%2FbtsGMTe7MPz%2F0dloeqXVaiwr7mM4PtMuK1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;374&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;경사 하강법 학습 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경사 하강법(Gradient Descent)는 머신러닝과 딥러닝에서 매우 중요한 최적화 알고리즘으로, 모델의 가중치를 조정해가면서 손실 함수를 최소화하는 방법이다. 간단하게 말하자면, Gradient Descent는 모델의 오류(손실 함수)를 최소화하는 가장 좋은 매개변수(가중치)를 찾기 위한 과정이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;손실 함수: 모델이 얼마나 잘못되었는지를 측정하는 함수로, 이 함수의 값(손실 값)을 최소화하려는 것이 목표이다.&lt;/li&gt;
&lt;li&gt;기울기(Gradient): 손실 함수의 기울기를 계산한다. 이 기울기는 각 가중치에 대해 손실 함수가 얼마나 빠르게 변하는지를 나타낸다. 기울기가 양수면 함수는 증가하는 방향, 음수면 감소하는 방향이다.&lt;/li&gt;
&lt;li&gt;학습률(Learning Rate): 기울기에 따라 가중치를 얼마나 조정할지 결정하는 매개변수이다. 너무 크면 최소점을 지나쳐버리고, 너무 작으면 학습이 너무 느려질 수 있다.&lt;/li&gt;
&lt;li&gt;업데이트 규칙: 가중치를 기울기의 반대 방향으로 조정한다. 기울기가 양수면 가중치를 감소시키고, 음수면 가중치를 증가시킨다. 이렇게 함으로써 손실 함수의 값을 점차 줄여 나간다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 과정은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 초기화: 가중치를 무작위로 설정한다. &lt;br /&gt;2. 아래 단계를 손실 함수가 충분히 작아질 때까지 반복한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 가중치에서 손실 함수의 기울기(미분값)를 계산&lt;/li&gt;
&lt;li&gt;계산된 기울기에 학습률을 곱한 값을 현재 가중치에서 빼서 새로운 가중치를 계산&lt;/li&gt;
&lt;li&gt;새로운 가중치로 모델을 업데이트&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 경사 하강법의 목표는 손실 함수의 최소값을 찾는 것이다. 기울기가 0인점, 즉 미분값이 0인 점을 찾는 것이 중요하다. 기울기(손실 함수의 미분값)가 0인 점이 극값을 나타내기 때문이다. 이 극값은 최소값일 수도 있고, 최대값이나 안장점(saddle point)일 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기울기가 양수인 경우, 가중치를 줄여서 손실 함수의 값을 감소시키는 방향으로 이동한다. 반대로, 기울기가 음수인 경우 가중치를 늘려서 손실 함수의 값을 감소시키는 방향으로 이동한다. 이러한 방식으로 기울기가 0인 점을 찾아 나가며, 이 점이 손실 함수의 최소값을 나타내는지를 확인한다. 하지만, 모든 기울기가 0인 점이 Global minima(전체 최소값)인 것은 아니기 때문에, Gradient descent는 때때로 Local minima(지역 최소값)에 머무를 수도 있다. 최근에는 gradient descent를 변형한 SGD, adam과 같은 optimizer가 더 좋은 성능을 보여주고 있다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;가중치의&amp;nbsp;초기화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가중치의 초기 값 설정도 모델의 성능에 큰 영향을 미친다. 너무 크거나 작은 값으로 시작하면 학습 과정이 비효율적이거나 불안정해질 수 있다. 따라서, 적절한 초기화 방법을 선택하는 것이 중요하며, Xavier 초기화나 He 초기화 같은 기법이 자주 사용된다. 가중치 초기화에 대해 간단히 정리한 포스트가 있으니, 관심 있으신분들은 참고하시기 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1713635195502&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Pytorch] 가중치 초기화&quot; data-og-description=&quot;이번 포스팅에서는 pytorch에서 Tensor의 가중치를 초기화하는 방법을 정리했다. 신경망 모델의 성능은 가중치 초기 값에 민감할 수 있기 때문에, 가중치 초기화 과정은 모델 훈련에서 중요한 역할&quot; data-og-host=&quot;hr1588.tistory.com&quot; data-og-source-url=&quot;https://hr1588.tistory.com/43&quot; data-og-url=&quot;https://hr1588.tistory.com/43&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rTxiG/hyVS4ZgvMy/zp4pFtwpmtUZkOGHNMRdrk/img.png?width=800&amp;amp;height=240&amp;amp;face=0_0_800_240,https://scrap.kakaocdn.net/dn/uNAEd/hyVS4ydUV3/dTYsIRdW24zgLsB1nnGT5k/img.png?width=800&amp;amp;height=240&amp;amp;face=0_0_800_240,https://scrap.kakaocdn.net/dn/bkFxO2/hyVSZwS4Rk/eLcZxuKl3dP52od6hFGzGK/img.png?width=750&amp;amp;height=225&amp;amp;face=0_0_750_225&quot;&gt;&lt;a href=&quot;https://hr1588.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hr1588.tistory.com/43&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rTxiG/hyVS4ZgvMy/zp4pFtwpmtUZkOGHNMRdrk/img.png?width=800&amp;amp;height=240&amp;amp;face=0_0_800_240,https://scrap.kakaocdn.net/dn/uNAEd/hyVS4ydUV3/dTYsIRdW24zgLsB1nnGT5k/img.png?width=800&amp;amp;height=240&amp;amp;face=0_0_800_240,https://scrap.kakaocdn.net/dn/bkFxO2/hyVSZwS4Rk/eLcZxuKl3dP52od6hFGzGK/img.png?width=750&amp;amp;height=225&amp;amp;face=0_0_750_225');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Pytorch] 가중치 초기화&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 pytorch에서 Tensor의 가중치를 초기화하는 방법을 정리했다. 신경망 모델의 성능은 가중치 초기 값에 민감할 수 있기 때문에, 가중치 초기화 과정은 모델 훈련에서 중요한 역할&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hr1588.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 가중치는 딥러닝 모델의 성능을 좌우하는 결정적인 요소로, 모델이 어떻게 데이터를 해석하고 예측에 반영하는지 결정짓는 핵심 요소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, 딥러닝의 기본적인 학습 절차는 다음과 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 가중치 초기값 할당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 초기 모델을 활용한 예측&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 오차를 계산(loss function)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 오차를 줄이는 방향으로 가중치를 조절한다(optimizer). 이 때, learning_rate(학습률)로 얼마나 조절할지를 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 다시 처음으로 가서 반복(epoch)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blogs.nvidia.co.kr/blog/difference_ai_learning_machinelearning/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blogs.nvidia.co.kr/blog/difference_ai_learning_machinelearning/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.gopenai.com/understanding-of-gradient-descent-intuition-and-implementation-b1f98b3645ea&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.gopenai.com/understanding-of-gradient-descent-intuition-and-implementation-b1f98b3645ea&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KT 에이블스쿨 - 한기영 강사님 자료&lt;/p&gt;</description>
      <category>Data Science</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/83</guid>
      <comments>https://hr1588.tistory.com/83#entry83comment</comments>
      <pubDate>Sat, 6 Apr 2024 22:23:02 +0900</pubDate>
    </item>
    <item>
      <title>안녕하세요 ! 데이터로 새로운 세계를 탐색하는 데 관심이 많은 이동현입니다.</title>
      <link>https://hr1588.tistory.com/notice/82</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;SUMMARY &lt;br /&gt;-&amp;nbsp;도메인&amp;nbsp;지식과&amp;nbsp;문제해결&amp;nbsp;능력을&amp;nbsp;바탕으로&amp;nbsp;보이지&amp;nbsp;않던&amp;nbsp;세계를&amp;nbsp;탐색하는&amp;nbsp;데&amp;nbsp;관심이&amp;nbsp;많습니다.&amp;nbsp; &lt;br /&gt;-&amp;nbsp;혼자&amp;nbsp;고민하는&amp;nbsp;것보다는&amp;nbsp;동료들과&amp;nbsp;함께&amp;nbsp;문제를&amp;nbsp;논의하고,&amp;nbsp;해결하는&amp;nbsp;것을&amp;nbsp;선호합니다. &lt;br /&gt;-&amp;nbsp;꾸준히&amp;nbsp;공부한&amp;nbsp;것들을&amp;nbsp;블로그에&amp;nbsp;기록하며&amp;nbsp;성장해&amp;nbsp;나가려고&amp;nbsp;노력합니다.&amp;nbsp; &lt;br /&gt;-&amp;nbsp;하드&amp;nbsp;스킬,&amp;nbsp;소프트&amp;nbsp;스킬&amp;nbsp;모두에&amp;nbsp;관심이&amp;nbsp;많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이메일 : gaiqclass@gmail.com&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블로그 스킨 문제로 일부 글씨가 이상하게 출력되고 있습니다 ! 다크 모드로 봐주시면 감사하겠습니다 :)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;궁금하신점이 있으시면 언제든지 메일 주세요 !&lt;/p&gt;</description>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/notice/82</guid>
      <pubDate>Fri, 29 Mar 2024 16:15:38 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] SVM</title>
      <link>https://hr1588.tistory.com/81</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 지도학습(Supervised Learning)의 알고리즘 중 하나인 SVM(Support Vector Mechine)에 대해 정리했다. 우리는 SVM으로 복잡한 분류 문제를 해결하고, 회귀 및 이상치 탐지에도 SVM을 활용할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SVM&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bemAVW/btsGq8CCWAA/x0VpLXWQLl4UKHziGtOK5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bemAVW/btsGq8CCWAA/x0VpLXWQLl4UKHziGtOK5k/img.png&quot; data-alt=&quot;Iris Classification with SVM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bemAVW/btsGq8CCWAA/x0VpLXWQLl4UKHziGtOK5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbemAVW%2FbtsGq8CCWAA%2Fx0VpLXWQLl4UKHziGtOK5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;711&quot; height=&quot;484&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Iris Classification with SVM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SVM은 데이터를 분류하기 위해 결정 경계(Decision Boundary) 또는 분리 초평면(Separating Hyperplane)을 찾는 알고리즘이다. 이 경계는 서로 다른 클래스의 데이터를 가능한 가장 멀리 떨어지게 하는 선(혹은 초평면)으로 정의된다. 주요 구성요소는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-ke-style=&quot;style2&quot;&gt;초평면(hyperplane) : SVM의 목적은 데이터의 클래스를 구분하는 최적의 초평면(결정 경계)을 찾는 것이다. 초평면은 n차원의 공간에서 (n-1)차원의 평면으로, 2차원에서는 선, 3차원에서는 평면이 된다고 이해할 수 있다. 즉, 선형 혹은 비선형 결정경계를 만들 수 있다.&lt;/li&gt;
&lt;li data-ke-style=&quot;style2&quot;&gt;서포트 벡터(Support Vector) : Support vector는 초평면과 가장 가까운 훈련 데이터 포인트로, 초평면의 위치와 방향을 결정하는데 중요한 역할을 수행한다. 또한, margin의 결정에도 영향을 끼친다.&lt;/li&gt;
&lt;li data-ke-style=&quot;style2&quot;&gt;마진(Margin) : Margin은 Support Vector와 초평면 사이의 거리로, SVM은 margin을 최대화시켜 초평면의 안정성과 일반화 성능을 향상시킨다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 서포트 벡터는 결졍 경계에 가장 가까이 있는 각 클래스들의 데이터 포인트들이다. 이 포인트들은 결정 경계의 위치와 방향을 결정하는데 중요한 영향을 미친다. SVM은 이러한 서포트 벡터들을 사용하여 분리 초평면을 최적화하고, 클래스 간의 마진을 최대화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;커널 함수&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OZEj3/btsGqW3yZcn/3abGXDKiGuPCcrlPjASqa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OZEj3/btsGqW3yZcn/3abGXDKiGuPCcrlPjASqa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OZEj3/btsGqW3yZcn/3abGXDKiGuPCcrlPjASqa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOZEj3%2FbtsGqW3yZcn%2F3abGXDKiGuPCcrlPjASqa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;233&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 직선으로 데이터를 분류할 수 있으면 좋겠지만, 고차원 데이터의 경우 단순 직선으로 데이터를 분류하기에는 어려움이 존재한다. 이러한 상황에서 커널 트릭을 사용하면, 원본 데이터를 더 높은 차원의 특성 공간으로 매핑하여 데이터가 선형 분리 가능하도록 변환된다. 예를 들어, 2차원 공간에서 서로 얽혀 있는 두 클래스의 데이터를 직선으로 분류하는 것이 불가능할 수 있다. 하지만 커널 함수를 사용하여 데이터를 3차원 공간으로 매핑하면, 두 클래스를 분리하는 평면을 찾을 수 있게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Linear Kernel(선형 커널)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선형 커널은 가장 기본적인 커널로, 데이터를 변환하지 않고 원래의 특성 공간에서 직접 사용한다. 이 커널은 두 벡터의 내적으로 계산된다. 간단한 데이터 분류 문제에서 효과적이다. 포스팅 상단의 Iris classification의 결정 경계를 보면 선형으로 클래스가 분할됐음을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Polynomial Kernel(다항식 커널)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ah6gv/btsGpSH3558/S3I6SRuH6gHGqE1E1ruJNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ah6gv/btsGpSH3558/S3I6SRuH6gHGqE1E1ruJNK/img.png&quot; data-alt=&quot;Polynomial Kernel&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ah6gv/btsGpSH3558/S3I6SRuH6gHGqE1E1ruJNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAh6gv%2FbtsGpSH3558%2FS3I6SRuH6gHGqE1E1ruJNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;432&quot; height=&quot;231&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Polynomial Kernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다항식 커널은 데이터를 더 높은 차원으로 매핑하여 비선형 분류를 가능하게 한다. 이 커널은 원본 데이터의 특성을 결합하여 새로운 특성을 생성한다. 그림을 보면 왼쪽의 결정 경계는 직선이고, 오른쪽의 결정 경계는 2차원이상의 곡선으로 구성됨을 확인할 수 있다. 차수가 높아질수록 더 복잡한 특성 관계를 모델링할 수 있지만, 높은 차수는 overfitting을 초래할 수 있고, 계산 비용이 증가한다는 단점도 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. RBF Kernel(Gaussian Kernel)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pjyTF/btsGqyvlJqD/HWLa7gG9lNByFDIKtzBQZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pjyTF/btsGqyvlJqD/HWLa7gG9lNByFDIKtzBQZk/img.png&quot; data-alt=&quot;RBF(Gaussian) Kernel&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pjyTF/btsGqyvlJqD/HWLa7gG9lNByFDIKtzBQZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpjyTF%2FbtsGqyvlJqD%2FHWLa7gG9lNByFDIKtzBQZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;423&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RBF(Gaussian) Kernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RBF(Radial Basis Function Kernel) 커널은 방사 기저 함수 커널이라고도 하며, 가우시안 커널이라고도 불린다. 두 데이터 포인트 간의 거리(Euclidean Distance)를 기반으로 한 비선형 매핑을 사용하여, 데이터를 더 높은 차원의 공간으로 변환한다. 주로 유연한 결정 경계를 생성하는데, 이때 &amp;gamma;(Gamma)값에 따라 커널의 형태가 크게 변화한다. Gamma는 RBF 커널에서 사용되는 초매개변수로, 데이터 포인트가 결정 경계에 미치는 범위를 결정한다. 높은 Gamma 값은 각 데이터 포인트가 결정 경계 형성에 더 큰 영향을 미치게 하며, 이는 결정 경계를 더 복잡하게 만들 수 있다. 반면 낮은 Gamma 값은 데이터 포인트의 영향 범위를 넓혀 모델을 단순화시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 다항식 커널(Polynomial Kernel)과 RBF 커널(Radial Basis Function Kernel)은 모두 SVM에서 비선형 데이터를 처리하기 위해 사용되는 커널 함수이며, 데이터를 고차원 공간으로 매핑한다는 공통점을 가지고 있다. 그러나 이 두 커널은 데이터를 고차원으로 매핑하는 방식과 조정 가능한 매개변수에서 차이를 보인다. 두 가지 커널의 주요사항을 다시 정리하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Polynomial Kernel(다항식 커널)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매핑 방식: 다항식 커널은 데이터 포인트들의 특성들을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;고정된 차수 d&lt;/b&gt;의 다항식으로 조합하여 고차원 공간으로 매핑한다. 이 커널은 주어진 차수에 따라 특성들의 가능한 모든 조합을 고려한다.&lt;/li&gt;
&lt;li&gt;매개변수 : 다항식 커널의 주요 매개변수는 다항식의 차수 d&lt;/li&gt;
&lt;li&gt;특징: 다항식 커널은 고정된 차수를 사용하기 때문에, 모델이 학습할 수 있는 패턴의 복잡도가 차수에 의해 제한된다. 높은 차수는 더 복잡한 패턴을 학습할 수 있지만, 과적합의 위험과 계산 비용이 증가하는 단점이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RBF Kernel&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매핑 방식: RBF 커널은 데이터 포인트 간의 유클리디안 거리에 기반한 함수를 사용하여 무한한 차원으로 데이터를 매핑할 수 있다. 이 커널은 모든 차원의 특성 조합을 묵시적으로 고려하며, 데이터 포인트들이 결정 경계를 얼마나 민감하게 반영할지를 조정할 수 있다.&lt;/li&gt;
&lt;li&gt;매개변수: RBF 커널의 핵심 매개변수는 &amp;gamma;로, 가우시안 함수의 폭을 결정한다.&amp;nbsp;&amp;nbsp;&amp;gamma; 값이 클수록 개별 데이터 포인트가 미치는 영향이 작아져서 결정 경계가 더욱 복잡해질 수 있다.&lt;/li&gt;
&lt;li&gt;특징: RBF 커널은 &amp;gamma; 매개변수를 조절함으로써 모델의 복잡도를 매우 유연하게 조정할 수 있다. 이는 다양한 유형의 데이터와 복잡한 패턴에 적응할 수 있는 능력을 의미하며, RBF 커널을 매우 강력하고 유용하게 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;하이퍼 파라미터&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SVM의 성능은 하이퍼파라미터에 따라 크게 차이날 수 있다. 주요 하이퍼파라미터는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;C: 마진에서 사용되는 정규화 매개변수이다. C 값이 크면 마진 침범을 덜 허용하고, 작으면 더 많은 침범을 허용한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;커널 종류: 데이터를 고차원으로 매핑하는 함수이다. 주로 선형(linear), 다항식(polynomial), RBF(Radial Basis Function), 시그모이드(sigmoid) 등이 사용된다.&lt;/li&gt;
&lt;li&gt;&amp;gamma;(감마): RBF 커널에만 해당하는 파라미터로, 결정 경계의 곡률을 결정한다. &amp;gamma;가 크면 결정 경계가 더 유연해지고, 작으면 더 단순해진다. scikit-learn에서 gamma = 'scale' 옵션을 사용하면 범용적으로 사용할 수 있는 기본값을 제공받을 수 있다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;gamma&amp;nbsp;=&amp;nbsp;'scale'&amp;nbsp;:&amp;nbsp;gamma를&amp;nbsp;데이터의&amp;nbsp;특성들에&amp;nbsp;자동으로&amp;nbsp;맞추기&amp;nbsp;위한&amp;nbsp;방법으로,&amp;nbsp;각&amp;nbsp;특성의&amp;nbsp;분산에&amp;nbsp;기초하여&amp;nbsp;gamma&amp;nbsp;값을&amp;nbsp;결정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커널과 감마는 상단부에 정리했으니, C와 margin의 관계에 대해 알아보자. C는 결정 경계와 서포트 벡터 사이의 margin size를 조절하는 역할을 한다. 높은 C 값은 마진 오류를 적게 허용하며, 이는 모델이 훈련 데이터에 더 잘 맞추려고 하지만, 과적합의 위험이 커질 수 있다. 반면, 낮은 C 값은 마진 오류를 더 많이 허용하며, 이는 모델이 더 많은 오류를 수용하지만, 일반화 능력이 더 좋아질 수 있다. 이를 하드 마진(Hard Margin)과 소프트 마진(Soft Margin) 이라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하드&amp;nbsp;마진&amp;nbsp;SVM&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의: 하드 마진 SVM은 훈련 데이터를 완벽하게 분류하기 위해 최대 마진을 찾는 방식이다. 이 방식에서는 데이터 포인트가 마진 내부로 들어오거나 잘못 분류되는 것을 전혀 허용하지 않다.&lt;/li&gt;
&lt;li&gt;적용: 하드 마진 방식은 데이터가 완전히 &lt;b&gt;선형 분리&lt;/b&gt; 가능할 때 잘 작동한다. 그러나 실제 데이터는 종종 완벽하게 분리될 수 없으므로, 하드 마진 SVM은 과적합(overfitting)을 일으킬 수 있고, 실제 문제에 적용하기 어려울 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;소프트&amp;nbsp;마진&amp;nbsp;SVM&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의: 소프트 마진 SVM은 일부 마진 오류를 허용하는 방식으로, 데이터 포인트가 마진 내부에 위치하거나 잘못 분류되는 것을 어느 정도까지 수용한다. 이를 통해 모델의 일반화 능력이 향상될 수 있다.&lt;/li&gt;
&lt;li&gt;역할: C 매개변수는 이 마진 오류를 얼마나 허용할지를 결정한다. C가 높을수록 오류를 덜 허용하며(즉, 더 하드 마진에 가까워지며), C가 낮을수록 더 많은 오류를 허용한다.&lt;/li&gt;
&lt;li&gt;적용: 소프트 마진 방식은 데이터가 완벽히 선형 분리 가능하지 않거나 이상치가 포함된 경우에 유용하다. 이 방식은 모델이 새로운 데이터에 대해 더 잘 일반화되도록 돕는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, C의 값에 따라 SVM의 마진 오류 허용 정도가 달라지며, 이는 소프트 마진과 하드 마진 사이의 균형을 조절하는 데 사용된다. 따라서 C는 소프트 마진 SVM에서 중요한 하이퍼파라미터로 작용하며, 이 매개변수를 통해 모델의 오류 허용도와 복잡성을 조정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Python Example&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1712426457919&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### IRIS 분류 예제 ###

from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.metrics import *

# 데이터셋 로드
iris = load_iris()
X = iris.data
y = iris.target

# 데이터셋 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 다항식 커널 SVM 생성
svm_poly = SVC(kernel='poly', degree=3, C=1.0)
svm_poly.fit(X_train, y_train)

# 테스트 데이터셋으로 평가
y_pred_poly = svm_poly.predict(X_test)
print(f&quot;Accuracy with Polynomial Kernel: {classification_report(y_test, y_pred_poly)}&quot;)

# RBF 커널 SVM 생성
svm_rbf = SVC(kernel='rbf', gamma='scale', C=1.0)
svm_rbf.fit(X_train, y_train)

# 테스트 데이터셋으로 평가
y_pred_rbf = svm_rbf.predict(X_test)
print(f&quot;Accuracy with RBF Kernel: {accuracy_score(y_test, y_pred_rbf)}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ratsgo.github.io/machine%20learning/2017/05/30/SVM3/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ratsgo.github.io/machine%20learning/2017/05/30/SVM3/&lt;/a&gt;&lt;/p&gt;</description>
      <category>Data Science</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/81</guid>
      <comments>https://hr1588.tistory.com/81#entry81comment</comments>
      <pubDate>Sun, 24 Mar 2024 23:02:53 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 잡코리아 웹크롤링</title>
      <link>https://hr1588.tistory.com/80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 웹크롤링의 개념을 간단히 정리하고, 잡코리아의 데이터 분석가 채용공고로 실습을 진행했다. 먼저, 웹크롤링이란 무엇인지 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Web Crawling&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 크롤링(Web Crawling)은 웹봇 또는 크롤러라고 불리는 자동화된 스크립트나 프로그램을 사용하여 월드 와이드 웹(WWW)에서 데이터를 체계적으로 검색하고 수집하는 행위를 의미한다. 즉, 웹 페이지에서 데이터를 수집하는 방법이다.&amp;nbsp;크롤링을 위해서는 인터넷 프로토콜 HTTP에 요청을 보내야 하는데, 방법과 요청 코드는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Get
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;URL에 Query 포함&lt;/li&gt;
&lt;li&gt;Query(데이터) 노출, 전송 가능 데이터 작음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Post
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Body에 Query 포함&lt;/li&gt;
&lt;li&gt;Query(데이터) 비노출, 전송 가능 데이터 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Client와 Server가 데이터를 주고 받은 결과 정보
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;2XX - Success&lt;/li&gt;
&lt;li&gt;3XX - Redirect&lt;/li&gt;
&lt;li&gt;4XX - Request Error&lt;/li&gt;
&lt;li&gt;5XX - Server Error&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적으로 요청에 성공하면, 2XX를 return하고, 실패하면 보통 4XX를 return 한다. 간단하게 개념을 정리했으니, 잡코리아에서 데이터 분석가 채용공고를 검색하고 결과를 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WAT2q/btsF2EWGjHE/cFG1e6MnLb5IQU0EfBLF4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WAT2q/btsF2EWGjHE/cFG1e6MnLb5IQU0EfBLF4k/img.png&quot; data-alt=&quot;채용 플랫폼 잡코리아&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WAT2q/btsF2EWGjHE/cFG1e6MnLb5IQU0EfBLF4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWAT2q%2FbtsF2EWGjHE%2FcFG1e6MnLb5IQU0EfBLF4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1013&quot; height=&quot;792&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;채용 플랫폼 잡코리아&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;https://www.jobkorea.co.kr/Search/?stext=데이터 분석가&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;URL을 보면 다음과 같은 구성을 확인할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&lt;a href=&quot;https://www.jobkorea.co.kr/Search/&quot;&gt;https://www.jobkorea.co.kr/Search/&lt;/a&gt;는 잡코리아 사이트의 검색 페이지 URL의 기본 부분&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: left;&quot;&gt;?stext= 뒤에 오는 부분이 실제 검색어를 나타냄&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-align: left;&quot;&gt;데이터 분석가는 우리가 검색한 값으로, 실제는 공백 문자 인코딩으로 데이터%20분석가로 출력&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;따라서 주소 뒤 ?stext= 다음에 오는 부분이 사용자가 입력한 검색어를 URL 인코딩한 값임을 알 수 있다. 이를 통해 잡코리아에서 해당 검색어로 검색 요청을 진행함을 확인했다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;https://www.jobkorea.co.kr/Search/?stext=데이터 분석가&amp;amp;tabType=recruit&amp;amp;Page_No=2&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;사진의 왼쪽 위를 보면, 오늘을 기점으로 79건의 채용 공고가 등록되어있다. 스크롤을 내려서 다음 페이지로 가면, tabType과 Page number를 확인할 수 있다. 우리는 여기서 Page_No의 값을 조절하면 페이지가 넘어감을 확인했다. URL을 확인했으니, 이제 Python으로 채용공고를 가져와보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1711290638114&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import requests
import pandas as pd
from bs4 import BeautifulSoup

search = '데이터 분석가'
url = f'https://www.jobkorea.co.kr/Search/?stext={search}&amp;amp;tabType=recruit&amp;amp;Page_No=1'
response = requests.get(url)

dom = BeautifulSoup(response.text, &quot;html.parser&quot;)

elements = dom.select(&quot;li.list-post&quot;)
elements&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;f-string을 활용하고, 데이터 분석가 공고의 1페이지를 요청했다. 하지만, 저렇게 요청하면 response는 200이지만 결과는 빈 리스트가 출력된다. 이유가 뭘까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python은 코딩으로 user-agent 정보를 설정해서 서버로 보내고, 해당 서버에서 이를 처리하면 결과를 반환한다. 이런 오류가 발생하는 경우, requests 과정에서 headers 매개변수를 추가해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4ZHi9/btsF2ECoEqX/I5Zck4C1SPpfkifnRgD0hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4ZHi9/btsF2ECoEqX/I5Zck4C1SPpfkifnRgD0hk/img.png&quot; data-alt=&quot;크롬 개발자 도구(F12)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4ZHi9/btsF2ECoEqX/I5Zck4C1SPpfkifnRgD0hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4ZHi9%2FbtsF2ECoEqX%2FI5Zck4C1SPpfkifnRgD0hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1130&quot; height=&quot;497&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크롬 개발자 도구(F12)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0jrVy/btsF3b0UaXI/5kpIQWbibVPdinpiKl3hp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0jrVy/btsF3b0UaXI/5kpIQWbibVPdinpiKl3hp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0jrVy/btsF3b0UaXI/5kpIQWbibVPdinpiKl3hp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0jrVy%2FbtsF3b0UaXI%2F5kpIQWbibVPdinpiKl3hp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;233&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크롬 브라우저에서 F12를 눌러서, 개발자 도구를 실행한다. 상단 탭 - Network - Fetch/XHR - 새로고침(F5) 순으로 실행하면, 해당 브라우저가 어떤 방식으로 요청값을 받는지 확인할 수 있다. 왼쪽의 Name을 누르고, headers - requests headers - User-Agent의 값을 dict 형태로 headers에 넣으면 문제를 해결할 수 있다. 그래도 안된다면, Referer를 추가하고, 또 다른 요소를 추가하는 방식으로 해결해야한다. 웹 서버마다 어뷰징을 체크하는 기준이 다르기 때문이다. 여기서는 User-Agent의 값만으로 정상적으로 요청을 받아올 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MNJ1l/btsF4TyBtb7/cyEXrUopnjsf0JsMQyof2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MNJ1l/btsF4TyBtb7/cyEXrUopnjsf0JsMQyof2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MNJ1l/btsF4TyBtb7/cyEXrUopnjsf0JsMQyof2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMNJ1l%2FbtsF4TyBtb7%2FcyEXrUopnjsf0JsMQyof2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1066&quot; height=&quot;596&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbjUIw/btsF0ITBgFO/mLAKXOdZFe1y30mT4umN11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbjUIw/btsF0ITBgFO/mLAKXOdZFe1y30mT4umN11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbjUIw/btsF0ITBgFO/mLAKXOdZFe1y30mT4umN11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbjUIw%2FbtsF0ITBgFO%2FmLAKXOdZFe1y30mT4umN11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;885&quot; height=&quot;586&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;response에 성공했으면, 필요한 정보가 어떤 Tag에 있는지 찾아야한다. 우리가 필요한 정보는 회사명, 공고 제목, 채용 조건이다. 수많은 태그 중, li class list-post에 기업별 공고가 있음을 확인했다. 이 때, class의 개수가 여러 개 이기 때문에 select_one이 아닌 select 메서드를 사용해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;태그를 자세히보고 우리가 필요한 정보를 가지고 있는 태그와 class명을 찾아야한다. 내가 찾은 정보는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;data-gainfo : 공고 제목, 산업, 회사명&lt;/li&gt;
&lt;li&gt;p.option : 연차, 학력, 근무지, 채용 유형&lt;/li&gt;
&lt;li&gt;div.post-list-info a : 채용 공고 링크&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 필요한 정보만을 가져와서, DataFrame으로 묶어보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1711294490302&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data = []

for tag in elements: # tags는 bs4.element.Tag 객체들의 리스트
    gainfo = tag.get('data-gainfo')
    link_tag = tag.select_one('div.post-list-info a')
    p_tag = dom.find('p', class_ = 'option')
    if gainfo : 
        gainfo_dict = eval(gainfo)
        row = {
            'title' : gainfo_dict.get('dimension45'),
            'industry' : gainfo_dict.get('dimension43'),
            'company' : gainfo_dict.get('dimension48'),
            'link': link_tag.get('href') if link_tag else '',
            'exp' : '',
            'edu' : '',
            'location':'',
            'hiring_period' : ''
        }
        
        for span in p_tag.find_all('span'):
            if 'exp' in span.get('class', []):
                row['exp'] = span.text.strip()
            elif 'edu' in span.get('class', []):
                row['edu'] = span.text.strip()
            elif 'loc' in span.get('class', []):
                row['location'] = span.text.strip()
            elif 'date' in span.get('class', []):
                row['hiring_period'] = span.text.strip()
        
        data.append(row)

df = pd.DataFrame(data)
df['link'] = df['link'].str.replace('virtual/','') # link 가상 경로 제거
df.head()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 가지 주의해야할 점이 있다. div.post-list-info a 태그에서 가져온 링크는 가상 경로(Virtual path)를 나타내고 있다. 웹 서버에서는 실제 시스템의 경로와 다른 가상 경로를 매핑할 수 있다. 이렇게 하면 웹 사이트의 구조를 숨기고 보안을 강화할 수 있다. 실제 공고 링크와 맞추기 위해, link column에서 virtual/을 제거해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mw7zr/btsF3UdsEMH/A7Ppe2cVOucDlRbXnRFbok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mw7zr/btsF3UdsEMH/A7Ppe2cVOucDlRbXnRFbok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mw7zr/btsF3UdsEMH/A7Ppe2cVOucDlRbXnRFbok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMw7zr%2FbtsF3UdsEMH%2FA7Ppe2cVOucDlRbXnRFbok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;967&quot; height=&quot;311&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;311&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 결과를 확인할 수 있다. 1페이지의 데이터를 가져왔으니, 이제 데이터 분석가 공고 전체를 가져오는 함수를 선언해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사용자 정의 함수(잡코리아)&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1711294725100&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
from bs4 import BeautifulSoup
import requests
import re

def job_korea(search, page_no):
    data = []

    for page in range(1, page_no+1):
        url = f'https://www.jobkorea.co.kr/Search/?stext={search}&amp;amp;tabType=recruit&amp;amp;Page_No={page}'
        response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})
        dom = BeautifulSoup(response.text, &quot;html.parser&quot;)
        elements = dom.select(&quot;li.list-post&quot;)

        for tag in elements:
            gainfo = tag.get('data-gainfo')
            link_tag = tag.select_one('div.post-list-info a')
            p_tag = tag.select_one('p.option')

            if gainfo:
                gainfo_dict = eval(gainfo)
                row = {
                    'title': gainfo_dict.get('dimension45'),
                    'industry': gainfo_dict.get('dimension43'),
                    'company': gainfo_dict.get('dimension48'),
                    'link': '',
                    'exp': '',
                    'edu': '',
                    'location': '',
                    'hiring_period': ''
                }

                if link_tag:
                    link = link_tag.get('href')
                    if re.match(r'^/Recruit', link):
                        row['link'] = 'https://www.jobkorea.co.kr' + link
                    else:
                        row['link'] = link

                for child in p_tag.children:
                    if child.name == 'span':
                        if 'exp' in child.get('class', []):
                            row['exp'] = child.text.strip()
                        elif 'edu' in child.get('class', []):
                            row['edu'] = child.text.strip()
                        elif 'loc' in child.get('class', []):
                            row['location'] = child.text.strip()
                        elif 'date' in child.get('class', []):
                            row['hiring_period'] = child.text.strip()

                data.append(row)

    df = pd.DataFrame(data)
    df['link'] = df['link'].str.replace('virtual/', '')  # 가상 경로 제거
    return df
    
df = job_korea('데이터 분석가', 5)
df.head()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0G37N/btsF1cG1XTR/5rBw9mCiG1lLsfEYxWtMCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0G37N/btsF1cG1XTR/5rBw9mCiG1lLsfEYxWtMCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0G37N/btsF1cG1XTR/5rBw9mCiG1lLsfEYxWtMCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0G37N%2FbtsF1cG1XTR%2F5rBw9mCiG1lLsfEYxWtMCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;972&quot; height=&quot;448&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지를 합치면서 새로운 문제점을 몇 가지 발견했다. 마지막 페이지의 링크는 잡코리아의 링크가 아닌, &quot;게임잡&quot; 이라는 게임 구직 사이트와 연동되어 있다. 또한, 잡코리아의 모든 링크가 Https 프로토콜이 아닌 /Recruit로 시작하고 있다. 정규식으로 조건을 제시하고, 문자열을 결합해서 해결할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 실력이 많이 부족하지만, 지금보다 더 부족하던 시절 웹크롤링을 시도하며 다른분들의 코드를 많이 참고했었다. 나보다 더 뛰어나신 분들도 훨씬 많고, 더 고도화된 방법으로 크롤링을 하시는 분들도 분명히 계시지만 누군가에겐 나의 코드가 도움이 되기를 바라며 포스팅을 마무리하려고한다. 또한, 학습의 목적이라도 과도한 크롤링으로 서버에 과부하를 주는 경우 업무 방해 등으로 법적인 제재를 받을 수 있으니, 주의하기 바란다. 차후에는 다른 채용 사이트도 분석해서, 최종적으로 데이터 분석가를 시장에서 몇명이나 뽑는지, 어떤 역량을 요구하는지 시각화하는 것을 목표로 해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Aivle/Project</category>
      <category>aivle</category>
      <category>웹크롤링</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/80</guid>
      <comments>https://hr1588.tistory.com/80#entry80comment</comments>
      <pubDate>Thu, 21 Mar 2024 17:02:53 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 평균과 중심극한정리</title>
      <link>https://hr1588.tistory.com/79</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 평균과 중심극한정리에 대해 알아보자. 우리가 데이터로 특정 값을 추정할 때, 항상 모든 값을 조사할 수는 없다. 예를 들어, 전국민의 키를 조사한다고 가정해보자. 전수조사로 모든 사람의 키를 확인해서 평균값을 제작할 수 있지만, 엄청난 시간과 비용이 소모된다. 이럴 때 필요한 것이 표본이다. 표본에 대해 알아보기 전에, 먼저 기본적인 대푯값들을 정리해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;주요 개념&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 평균&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평균은 가장 기본적인 대푯값으로, 데이터의 중심 위치를 나타낸다. 전체 데이터 값의 합을 데이터 개수로 나눠서 구할 수 있으며, 다음과 같은 특징을 가진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 데이터 값을 사용해서 계산&lt;/li&gt;
&lt;li&gt;단순하고 직관적인 해석 가능&lt;/li&gt;
&lt;li&gt;데이터의 대칭성에 민감(이상치에 취약)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 흔히 사용하는 평균은 산술평균이지만, 데이터 사이언스에서는 다른 평균을 활용할 때도 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;산술평균 : 가장 일반적으로 사용되는 형태, 모든 데이터 값을 더한 후 데이터 개수로 나눈 값&lt;/li&gt;
&lt;li&gt;가중평균 : 데이터 값에 가중치를 부여하여 계산하는 평균, 가중치가 클수록 해당 값의 기여도가 커짐&lt;/li&gt;
&lt;li&gt;기하평균 : 데이터 값의 곱에 데이터 개수의 역수 거듭제곱을 취한값으로, 비율이나 백분율 데이터에 적합&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 분산과 표준편차&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분산과 표준편차는 데이터가 평균으로부터 퍼져있는 정도, 즉 데이터의 분포를 나타낸다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산 : 각 데이터값과 평균과의 차이 제곱의 평균&lt;/li&gt;
&lt;li&gt;표준편차 : 분산의 제곱근&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 모집단과 표본&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모집단(population) : 연구 대상이 되는 전체 집단&lt;/li&gt;
&lt;li&gt;표본(sample) : 모집단에서 추출한 부분 집단&lt;/li&gt;
&lt;li&gt;표본을 통해 모집단의 특성을 추정할 수 있음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 정규분포&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DAf8K/btsFP8RP7Xg/0rhayhwIoFnTGH93NeuSbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DAf8K/btsFP8RP7Xg/0rhayhwIoFnTGH93NeuSbk/img.png&quot; data-alt=&quot;정규 분포&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DAf8K/btsFP8RP7Xg/0rhayhwIoFnTGH93NeuSbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDAf8K%2FbtsFP8RP7Xg%2F0rhayhwIoFnTGH93NeuSbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;230&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정규 분포&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정규 분포는 종 모양의 곡선으로 나타나는 연속 확률 분포이다. 데이터 값이 평균 주변에 밀집되어 있고, 평균에서 멀어질수록 데이터 값의 빈도가 감소하는 특징을 갖는다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;중심극한정리(Central Limit Theorem)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중심극한정리란, 표본의 크기가 충분히 크다면 표본 평균의 분포가 정규 분포를 따른다는 개념이다. 즉, 모집단의 분포 형태와 무관하게 표본 평균의 분포는 정규 분포를 따르게 된다. 주요 조건은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표본의 크기가 충분히 크다 ( n &amp;gt;= 30)&lt;/li&gt;
&lt;li&gt;개별 데이터는 서로 독립적이다.&lt;/li&gt;
&lt;li&gt;모집단의 분포는 정규 분포를 따를 필요는 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 모집단의 분포가 정규 분포라면, 표본의 개수와 무방하게 표본평균의 분포는 정규분포이다. 모집단이 정규분포가 아니더라도 표본의 크기가 30이상이 되면 표본평균의 분포가 모집단의 분포와 상관없이 표본의 개수 n이 커짐에 따라 정규분포에 근사하는데, 이것이 바로 중심극한정리이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;모집단 평균 추정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중심극한정리에 따르면 표본 크기가 충분히 크면, 표본 평균의 분포는 정규 분포를 따르게 된다. 이를 통해 모집단의 평균을 추정할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&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;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;95% 신뢰구간&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신뢰구간은 모집단 모수(평균)가 있을 것으로 기대되는 범위를 뜻한다. &amp;nbsp;95% 신뢰구간은 만약 동일한 절차로 무한히 많은 표본을 추출한다면, 그 중 95%의 신뢰구간이 모집단 모수를 포함할 것이라는 의미이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;95% 신뢰구간은 다음과 같이 계산된다. 이 공식은 표분평균의 분포가 정규분포를 따른다는 중심극한정리에 기반한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;95% 신뢰구간 = (표본 평균 - 1.96 표준오차, 표본 평균 + 1.96 표준오차)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 표본평균이 50, 표준오차가 2라면 95% 신뢰구간은 (50 - 1.962, 50 + 1.962) = (46.08, 53.92)가 된다. 즉, 모집단 평균이 46.08에서 53.92 사이에 있을 것이라고 95% 확신할 수 있다. 신뢰구간의 범위는 표준오차에 따라 달라진다. 표준오차가 작을수록(표본 크기가 클수록) 신뢰구간이 좁아진다. &lt;br /&gt;&lt;br /&gt;요약하면, &lt;b&gt;표본평균과 표준오차를 이용하여 모집단 평균에 대한 점추정(표본평균)과 구간추정(신뢰구간)이 가능하다.&lt;/b&gt; 중심극한정리에 의해 표본 크기가 충분히 크다면 표본평균의 정규분포 가정이 성립하므로, 이를 기반으로 신뢰구간을 계산할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료 출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/68-95-99.7_%EA%B7%9C%EC%B9%99&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.wikipedia.org/wiki/68-95-99.7_%EA%B7%9C%EC%B9%99&lt;/a&gt;&lt;/p&gt;</description>
      <category>Data Science</category>
      <category>통계</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/79</guid>
      <comments>https://hr1588.tistory.com/79#entry79comment</comments>
      <pubDate>Mon, 18 Mar 2024 02:16:46 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 가설 검정 및 이변량 분석</title>
      <link>https://hr1588.tistory.com/78</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 포스팅에서는 수치, 범주형 데이터별 단변량 분석을 정리했다. 이번 포스팅에서는 단변량을 넘어, x / y 축간의 관계를 확인하는 이변량 분석에 대해 알아보자. 단변량 분석과 동일하게 시각화, 수치화를 활용하지만 이변량 분석은 가설검정 도구를 활용해 수치화를 진행한다. 먼저, 가설검정이란 무엇인지 정리해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;가설검정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이변량 분석에서 가설 감정은 두 변수 간의 관계를 분석하는데 중요한 역할을 수행한다. 가설검정은 귀무가설(H0)과 대립가설(H1)을 설정하고, 데이터가 귀무가설을 기각할 만큼 충분한 증거가 있는지를 평가한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;귀무가설&lt;/b&gt; : 연구자가 검증하고자 하는 기존 가정 또는 주장이다. 일반적으로 두 집단 간의 차이가 없다거나, 두 변수 간의 관계가 없다는 가정을 나타낸다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대립가설&lt;/b&gt; : 귀무가설과 반대되는 주장으로, 연구자가 입증하고자 하는 새로운 가정이다. 대립가설이 참인 경우, 귀무가설은 기각된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 두 집단의 평균 차이를 비교할 때 다음과 같은 가설을 설정할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;H0 : 두 집단의 평균은 동일하다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;H1 : 두 집단의 평균은 다르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가설검정에서는 먼저 유의수준(&amp;alpha;)을 설정한 후, 검정통계량을 계산한다. 검정통계량이 기각역(critical region)에 속하면 귀무가설을 기각하고, 그렇지 않으면 귀무가설을 채택한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;가설검정 절차&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8H2mH/btsFQh2k4j2/fTt3OxKkgLOaiKRRD4dfLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8H2mH/btsFQh2k4j2/fTt3OxKkgLOaiKRRD4dfLK/img.png&quot; data-alt=&quot;양측 검정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8H2mH/btsFQh2k4j2/fTt3OxKkgLOaiKRRD4dfLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8H2mH%2FbtsFQh2k4j2%2FfTt3OxKkgLOaiKRRD4dfLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;333&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;양측 검정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 연구 가설 설정&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연구 문제에 대한 귀무가설(H0)과 대립가설(H1)을 명확히 정의&lt;/li&gt;
&lt;li&gt;예: H0: 두 집단의 평균은 같다. H1: 두 집단의 평균은 다르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 유의수준(&amp;alpha;) 결정&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;귀무가설을 기각할 최대 오류 확률을 지정, 일반적으로 0.05 또는 0.01을 사용&lt;/li&gt;
&lt;li&gt;유의수준이 작을수록 귀무가설을 기각하기 어려워짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 검정통계량 계산&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표본 데이터를 바탕으로 검정통계량을 계산&lt;/li&gt;
&lt;li&gt;검정통계량의 종류는 가설검정 유형과 데이터 분포에 따라 다름 (t-검정, z-검정, F-검정, 카이제곱 검정 등).&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 기각역 결정 및 검정통계량 해석&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유의수준에 따라 기각역(critical region)을 결정&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 data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 결과 해석&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;p-value를 계산하여 유의성 여부를 판단한다. &lt;b&gt;만약 p-value가 유의수준보다 작은 경우, 귀무가설을 기각하고 대립가설을 채택한다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;p-value는 표본의 수에 영향을 많이 받는다. 예를 들어, 표본의 수가 엄청 많은 경우 비교 집단이 굉장히 유사하거나 아예 다르게 해석될 수 있다.&lt;/li&gt;
&lt;li&gt;따라서, 효과 크기(effect size)를 고려하여 실제 중요성을 평가해야 한다.&lt;/li&gt;
&lt;li&gt;효과 크기(effect size) : 가설검정에서 유의한 결과가 나왔을 때, 그 결과의 실제적인 중요성이나 의미 있는 정도를 나타내는 지표&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가설검정에서 귀무가설을 기각했다는 것은 두 집단 간에 차이가 있다는 통계적 증거가 있다는 의미이다. 하지만 이 차이가 실제로 중요한지, 얼마나 큰 차이인지는 확인할 수 없다. 효과 크기는 이러한 실제적인 중요성을 수치화한 값이다. 효과 크기가 클수록 두 집단 간 차이나 관계의 크기가 크다는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 지표는 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Cohen's d&lt;/b&gt; : 두 집단 평균 차이의 표준화된 값이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;r&lt;/b&gt; : 두 변수 간 상관계수의 절대값으로,&amp;nbsp; 0.1은 작은 효과, 0.3은 중간 효과, 0.5 이상은 큰 효과로 해석&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Odds Ratio &lt;/b&gt;: 두 집단 간 odds(발생 가능성 비율)의 비율이다. 1보다 크면 정적 관계, 1보다 작으면 부적 관계를 나타낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가설검정에서 유의한 결과가 나왔다면, 효과 크기를 함께 보고하는 것이 일반적이다. 이를 통해 결과의 실제적 중요성을 평가할 수 있다. 단순히 통계적 유의성만 보는 것이 아니라, 효과 크기를 함께 고려하여 연구 결과를 종합적으로 해석하는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;가설검정의&amp;nbsp;오류&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;귀무가설이 참&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;귀무가설이 거짓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;귀무가설 기각&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;제1종 오류&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;정확한 결정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;귀무가설 채택&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;정확한 결정&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;제2종 오류&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;제1종 오류&lt;/b&gt;: 귀무가설이 참인데 기각하는 오류&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제2종 오류&lt;/b&gt;: 귀무가설이 거짓인데 기각하지 못하는 오류&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가설검정에서는 이러한 오류를 최소화하는 것이 중요하다. 일반적으로 제1종 오류를 줄이기 위해 유의수준(&amp;alpha;)을 작게 설정한다. 그러나 유의수준을 너무 작게 하면 제2종 오류(&amp;beta;)가 커지게 된다. &lt;br /&gt;&lt;br /&gt;따라서 적절한 유의수준과 검정력을 설정하는 것이 필요합니다. 이를 위해서는 효과 크기와 표본 크기를 고려해야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;검정력(statistical power) : 귀무가설이 거짓일 때 이를 기각할 확률&lt;/li&gt;
&lt;li&gt;효과 크기가 클수록 검정력이 증가하여 제2종 오류(&amp;beta;)가 줄어든다.&lt;/li&gt;
&lt;li&gt;표본 크기가 클수록 검정력이 증가하여 제2종 오류(&amp;beta;)가 줄어든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가설검정에서는 이러한 오류를 최소화하는 동시에, 효과 크기와 표본 크기를 함께 고려하여 결과를 해석해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;이변량 분석(숫자-숫자)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가설검정에 대해 알아봤으니, 이제 이변량 분석을 어떻게 하면 되는지 알아보자. 먼저, 숫자-숫자간의 관계다. 위에서 언급했듯이, 시각화와 수치화라는 방법은 단변량 분석과 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;산점도(Scatter Plot)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;435&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b67LjZ/btsFPH8iYMP/8PwHpxEIJmgJBfRQy8zzy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b67LjZ/btsFPH8iYMP/8PwHpxEIJmgJBfRQy8zzy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b67LjZ/btsFPH8iYMP/8PwHpxEIJmgJBfRQy8zzy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb67LjZ%2FbtsFPH8iYMP%2F8PwHpxEIJmgJBfRQy8zzy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;435&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;435&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;산점도는 두 숫자형 변수 간의 관계를 시각화하는 가장 기본적인 방법이다. 각 관측값을 x-y 평면 상의 점으로 나타내면 두 변수 간의 패턴을 쉽게 파악할 수 있다. 점들의 패턴을 관찰하면 두 변수간의 관계 유형(선형, 비선형, 관계 없음)과 방향성(정비례, 반비례)을 대략적으로 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scatterplot 외에도 seaborn 패키지는 다양한 시각화 도구를 제공한다. regplot과 jointplot을 사용하면, 산점도에 추가로 추세선 / 히스토그램을 추가한 그림을 출력할 수 있다. 사용자 정의 함수를 활용해 여러가지 데이터를 살펴보는 것도 좋은 방법이다.&lt;/p&gt;
&lt;pre id=&quot;code_1710704835637&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def vis_corr(feature, target, data):
    
    plt.subplot(1,2,1)
    sns.scatterplot(x=feature, y=target, data=data)

    plt.subplot(1,2,2)
    sns.regplot(x=feature, y=target, data=data)

    sns.jointplot(x=feature, y=target, data=data)

    plt.tight_layout()
    plt.show()
    result = spst.pearsonr(data[feature], data[target])
    print(f'상관계수 : {result[0]}, p-value : {result[1]}')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;상관계수(Correlation Coefficient)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/laUC6/btsFRrW8Pr8/CSSPlbf1RpkTFC8VdY2HkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/laUC6/btsFRrW8Pr8/CSSPlbf1RpkTFC8VdY2HkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/laUC6/btsFRrW8Pr8/CSSPlbf1RpkTFC8VdY2HkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlaUC6%2FbtsFRrW8Pr8%2FCSSPlbf1RpkTFC8VdY2HkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1197&quot; height=&quot;347&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그림을 보면 여러 형태의 산점도가 있다. 두 숫자형 변수간의 선형 관계 강도를 수치로 나타낸 것이 상관계수이다. 보통, 피어슨 상관계수(Pearson Correlation)가 가장 널리 사용된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상관계수는 공분산을 표준화한 값으로, -1부터 1사이의 값을 가진다.&lt;/li&gt;
&lt;li&gt;공분산 : 두 개의 확률 변수 X와 Y의 선형적인 관계를 나타내는 값으로, 음의 무한대에서 양의 무한대까지의 범위를 가진다.&lt;/li&gt;
&lt;li&gt;1에 가까울수록 강한 정비례 선형관계, -1에 가까울수록 강한 반비례 선형관계를 의미한다.&lt;/li&gt;
&lt;li&gt;0에 가까우면 선형관계가 약하거나 없음을 뜻한다.&lt;/li&gt;
&lt;li&gt;두 변수간의 선형관계 정도를 쉽게 파악할 수 있지만, 비선형 관계에 대해서는 설명력이 약하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 유의해야할 점이 있다. 상관관계와 인과관계는 다른 개념이다. 예를 들어, 아이스크림 판매량과 범죄율 간에 높은 상관관계가 있다고 해서, 아이스크림 판매가 범죄를 유발한다고 볼 수는 없다. 이 경우 제3의 변수인 기온이 아이스크림 판매와 범죄율에 모두 영향을 미쳤기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 상관관계는 두 변수 간의 연관성을 보여줄 뿐, 그 관계의 원인과 결과에 대해서는 설명하지 못한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수치화 : 상관분석&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 python으로 직접 상관분석을 실행해보자. 상관분석의 가설은 다음과 같다. 단, 값에 NaN(결측치)가 있으면 계산되지 않으므로, 반드시 notnull()로 제외하고 검정을 수행해야한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;귀무가설 : 상관 관계가 없다.(상관계수가 0이다)&lt;/li&gt;
&lt;li&gt;대립가설 : 상관 관계가 있다.(상관계수가 0이 아니다)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710701488425&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import scipy.stats as spst

# 피어슨 상관계수 계산
corr = data[&quot;total_bill&quot;].corr(data[&quot;tip&quot;])
print(f&quot;Total Bill과 Tip 간의 상관계수: {corr}&quot;)

# 라이브러리 사용
spst.pearsonr(air['Temp'], air['Ozone'])

# PearsonRResult(statistic=0.6833717861490114, pvalue=2.197769800200284e-22)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;튜플의 첫 번쨰 값은 상관계수이고, 두 번쨰 값은 p-value를 뜻한다. 유의수준 0.05 기준, p-value가 유의수준 보다 낮기 때문에 귀무가설이 기각된다. 즉, 데이터에서 Temp와 Ozone은 상관관계가 있다고 해석하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;이변량 분석(범주-숫자)&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kTAoH/btsFSaHCcbN/kpegZauVJHu3DjFQiIbut1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kTAoH/btsFSaHCcbN/kpegZauVJHu3DjFQiIbut1/img.png&quot; data-alt=&quot;범주-숫자 비교&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kTAoH/btsFSaHCcbN/kpegZauVJHu3DjFQiIbut1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkTAoH%2FbtsFSaHCcbN%2FkpegZauVJHu3DjFQiIbut1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;432&quot; data-origin-width=&quot;563&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;범주-숫자 비교&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범주별 숫자를 비교할 때 사용되는 방식은 범주별 평균 비교이다. Data에서 x축에 범주를 주고, 수치를 Y로 두면된다. Seaborn 라이브러리를 사용하면, 별도의 집계없이 바로 평균을 비교할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1710702289755&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sns.barplot(x=&quot;Survived&quot;, y=&quot;Age&quot;, data=titanic)
plt.grid()
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;t-test(두 집단 평균 비교)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;t-test는 두 집단의 평균 차이가 통계적으로 유의한지 검정하는 방법이다. 상관분석과 동일하게 결측치가 없어야 분석이 가능하다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;귀무가설 : 두 집단간 평균에 차이가 없다.&lt;/li&gt;
&lt;li&gt;대립가설 : 두 집단간 평균에 차이가 있다.&lt;/li&gt;
&lt;li&gt;t-통계량 : 두 평균의 차이를 표준오차로 나눈 값으로, 두 평균의 차이로 이해해도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 두 집단의 관계에 따라서도 사용하는 방법이 달라진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;독립 표본 T-검정 : 두 독립된 집단의 평균 차이를 검정한다.&lt;/li&gt;
&lt;li&gt;대응 표본 T-검정(쌍체비교) : 같은 대상 혹은 두 집단이 대응되어 있을 때(치료 전/후 등) 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710702866536&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np
from scipy.stats import ttest_ind, ttest_rel

# 독립 두 집단 t-test 예시
group1 = [1, 2, 3, 4, 5]
group2 = [4, 5, 6, 7, 8]
t_stat, p_val = ttest_ind(group1, group2)
print(f&quot;t-statistic: {t_stat}, p-value: {p_val}&quot;)
# t-statistic: -3.0, p-value: 0.017071681233782634

# 대응 두 집단 t-test 예시
before = [5, 6, 7, 8, 9]
after = [6, 7, 8, 9, 10]
t_stat, p_val = ttest_rel(before, after)
print(f&quot;t-statistic: {t_stat}, p-value: {p_val}&quot;)
# t-statistic: -inf, p-value: 0.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독립 표본 T-검정의 경우, t 통계량이 -3으로 음수이므로, 두 집단의 평균 차이가 음의 방향임을 의미한다. 보통 t 값이 -2보다 작거나, 2보다 크면 차이가 있다고 본다. p-value 역시 0.05보다 작으므로, 두 집단 간 평균 차이가 통계적으로 유의한 것으로 해석된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대응표본 T-검정의 경우 before과 after의 차이값들이 모두 1로 동일하기 때문에 t 값의 절대값이 매우 커져서 -inf라는 결과가 출력됐다. 만약 일반적인 데이터로 진행했음에도 inf 값이 출력된다면 Levene의 등분산 검정을 실시하여 두 집단의 분산이 동일한지 확인해볼 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시에는 누락됐지만, T검정을 실시하면 t 통계량, p-value 외에도 자유도(degrees of freedom)도 출력된다. 자유도는 통계 분석에서 특정 확률 분포를 결정하는 데 사용된다. 추정해야 할 모수의 수에 따라 달라지는데, 일반적으로 자유도는 전체 관측치 수에서 추정해야 할 모수의 수를 뺀 값으로 계산된다. 예를 들어, 표본 평균을 계산할 때는 전체 관측치 수(n)에서 1(평균)을 뺀 n-1이 자유도가 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;t-검정에서 자유도는 다음과 같이 계산된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;독립표본 t-검정 : n1(첫 번째 집단의 표본 크기) + n2(두 번째 집단의 표본 크기) - 2&lt;/li&gt;
&lt;li&gt;대응표본 t-검정 : n(대응되는 쌍의 수)-1&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;t-분포에서 자유도가 클수록 정규분포에 가까워지므로, 표본의 크기가 클수록 t-검정의 정확도와 검정력이 높아진다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ANOVA(세 집단 이상 평균 비교)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ANOVA는 세 개 이상의 집단 간 평균 차이가 통계적으로 유의한지 검정하는 방법이다. 집단 간 변동과 집단 내 변동을 비교하여 집단 평균이 같다는 귀무가설을 검정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;귀무가설 : 범주별 평균은 차이가 없다.&lt;/li&gt;
&lt;li&gt;대립가설 : 범주별 평균은 차이가 있다.&lt;/li&gt;
&lt;li&gt;f-통계량 : 집단 간 분산 / 집단 내 분산&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ANOVA 분산 검정도 범주형 변수의 개수에 따라 방법이 달라진다,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일원 분산분석(One-way ANOVA): 하나의 범주형 변수에 따른 집단 비교&lt;/li&gt;
&lt;li&gt;이원&amp;nbsp;분산분석(Two-way&amp;nbsp;ANOVA):&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;범주형&amp;nbsp;변수에&amp;nbsp;따른&amp;nbsp;집단&amp;nbsp;비교&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710704183125&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
from scipy.stats import f_oneway

# 예제 데이터
data = pd.DataFrame({&quot;score&quot;: [80, 85, 90, 75, 82, 78, 92, 88, 95],
                     &quot;group&quot;: [&quot;A&quot;, &quot;A&quot;, &quot;A&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;C&quot;, &quot;C&quot;, &quot;C&quot;]})

# One-way ANOVA 예시
groups = data.groupby(&quot;group&quot;)[&quot;score&quot;].apply(list)
f_stat, p_val = f_oneway(*groups)
print(f&quot;F-statistic: {f_stat}, p-value: {p_val}&quot;)
# F-statistic: 8.053691275167786, p-value: 0.019991333852813854&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;f-통계량도 t-통계량처럼 값이 2~3 이상이면 차이가 있다고 판단한다. 예제의 경우 그룹별 성적 평균에 차이가 있다고 볼 수 있다. 단, 분산분석은 전체 평균 대비 각 그룹간 차이가 있는 지만 알려준다. 어느 그룹 간에 차이가 있는지는 알 수 없다. 그래서, 특정 집단간의 차이를 식별하려면 사후분석(post-hoc test)를 사용해 집단 간 차이를 개별적으로 비교해야한다. 예를 들어, A, B, C 세 집단에 대해 ANOVA 결과 유의한 차이가 있다고 하면, Tukey's HSD Test를 통해 A-B, A-C, B-C 각 쌍에 대한 평균 차이 검정을 수행할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1710704452771&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
from scipy.stats import f_oneway
import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.stats.multicomp import pairwise_tukeyhsd

# 예제 데이터
data = pd.DataFrame({&quot;score&quot;: [80, 85, 90, 75, 82, 78, 92, 88, 95], 
                     &quot;group&quot;: [&quot;A&quot;, &quot;A&quot;, &quot;A&quot;, &quot;B&quot;, &quot;B&quot;, &quot;B&quot;, &quot;C&quot;, &quot;C&quot;, &quot;C&quot;]})

# One-way ANOVA
groups = data.groupby(&quot;group&quot;)[&quot;score&quot;].apply(list)
f_stat, p_val = f_oneway(*groups)
print(f&quot;F-statistic: {f_stat}, p-value: {p_val}&quot;)

# Tukey's HSD Test
model = ols('score ~ C(group)', data=data).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
print(anova_table)

tukey = pairwise_tukeyhsd(endog=data['score'],
                          groups=data['group'],
                          alpha=0.05)
print(tukey)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;487&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kCgiM/btsFRDwBUu0/knn39JhWS9HbcfozZPbV9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kCgiM/btsFRDwBUu0/knn39JhWS9HbcfozZPbV9k/img.png&quot; data-alt=&quot;사후 검정 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kCgiM/btsFRDwBUu0/knn39JhWS9HbcfozZPbV9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkCgiM%2FbtsFRDwBUu0%2Fknn39JhWS9HbcfozZPbV9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;487&quot; height=&quot;234&quot; data-origin-width=&quot;487&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사후 검정 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, ANOVA 결과를 보면 f-통계량 8, p-value 0.019로 세 집단 간 유의한 차이가 있음을 확인할 수 있다. Tukey's HSD Test 결과에서는 각 집단 쌍에 대한 평균 차이(meandiff), 조정된 p-value(p-adj), 신뢰구간(lower, upper)를 보여준다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A-B 집단 쌍: 평균 차이 6.6667, 유의하지 않음(p-adj &amp;gt; 0.05)&lt;/li&gt;
&lt;li&gt;A-C 집단 쌍: 평균 차이 -5.6667, 유의하지 않음(p-adj &amp;gt; 0.05)&lt;/li&gt;
&lt;li&gt;B-C&amp;nbsp;집단&amp;nbsp;쌍:&amp;nbsp;평균&amp;nbsp;차이&amp;nbsp;-12.3333,&amp;nbsp;유의함(p-adj&amp;nbsp;&amp;lt;&amp;nbsp;0.05)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 B집단과 C집단 간에는 유의한 평균 차이가 있지만, A 집단과 B 집단, A 집단과 C 집단 간에는 유의한 차이가 없음을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;이변량 분석(범주-범주)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범주와 범주간의 관계를 비교 분석하기 위해서는 먼저 교차표를 만들어야한다. 교차표는 pandas의 crosstab(행,열) 메소드를 활용하면 만들 수 있다. 이 때, normalize 옵션으로 수치를 비율로 변환할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3246&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWKptW/btsFRjkQswr/yNJl0klk1Ub7yqSh8dwEK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWKptW/btsFRjkQswr/yNJl0klk1Ub7yqSh8dwEK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWKptW/btsFRjkQswr/yNJl0klk1Ub7yqSh8dwEK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWKptW%2FbtsFRjkQswr%2FyNJl0klk1Ub7yqSh8dwEK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3246&quot; height=&quot;736&quot; data-origin-width=&quot;3246&quot; data-origin-height=&quot;736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710704971877&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 교차표 제작
pd.crosstab(titanic['Survived'], titanic['Sex'], normalize = 'columns')&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;시각화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 모자이크 그림(Mosaic plot)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;모자이크 그림은 두 범주형 변수의 관계를 시각화하는 데 사용되는 그래프로, 각 범주 조합의 빈도를 나타내는 사각형을 나열하여 그린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd5x6G/btsFP2j59NY/S4YHP2LPCbhkGvsDtkoEz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd5x6G/btsFP2j59NY/S4YHP2LPCbhkGvsDtkoEz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd5x6G/btsFP2j59NY/S4YHP2LPCbhkGvsDtkoEz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd5x6G%2FbtsFP2j59NY%2FS4YHP2LPCbhkGvsDtkoEz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;555&quot; height=&quot;433&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;각 사각형은 객실 등급과 생존의 조합을 나타내며, 1등석 탑승객의 생존률이 가장 높고, .3등석 탑승객의 생존 비율이 가장 낮음을 확인할 수 있다.&lt;br /&gt;&lt;br /&gt;장점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 변수 간의 관계를 시각적으로 쉽게 파악 가능&lt;/li&gt;
&lt;li&gt;각 범주 조합의 빈도를 직관적으로 비교&lt;/li&gt;
&lt;li&gt;상호작용 효과를 확인하는 데 유용함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;범주 수가 많아지면 그림이 복잡해질 수 있음&lt;/li&gt;
&lt;li&gt;빈도가 낮은 범주 조합은 시각적으로 구분하기 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.&amp;nbsp;100%&amp;nbsp;stacked&amp;nbsp;bar&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;100% stacked bar는 각 범주 내에서 비율을 나타내는 막대 그래프이다. 각 범주 내의 비율을 100%로 표현하여 값을 비교한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CGkIe/btsFR0ykeIz/m7Mo0TvYpo3WeWFYl8mHX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CGkIe/btsFR0ykeIz/m7Mo0TvYpo3WeWFYl8mHX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CGkIe/btsFR0ykeIz/m7Mo0TvYpo3WeWFYl8mHX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCGkIe%2FbtsFR0ykeIz%2Fm7Mo0TvYpo3WeWFYl8mHX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;547&quot; height=&quot;427&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;장점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 범주 내의 비율을 쉽게 비교할 수 있음&lt;/li&gt;
&lt;li&gt;특정 범주 내에서 다른 범주들의 비율을 파악하는 데 유용함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;범주 수가 많아지면 그래프가 복잡해질 수 있음&lt;/li&gt;
&lt;li&gt;전체적인 빈도를 파악하기 어려울 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;카이제곱 검정(Chi-square Test)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카이제곱 검정은 범주형 변수들 사이에 어떤 관계가 있는지 수치화하는 바업ㅂ이다. 두 변수가 서로 독립인지, 변수 간에 연관성이 있는지를 검정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;귀무가설 : 두 변수는 서로 독립이다.(연관성이 없다.)&lt;/li&gt;
&lt;li&gt;대립가설 : 두 변수는 서로 독립이 아니다.(관련성이 있다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카이제곱 통계량은 관측된 빈도와 기대 빈도 간의 차이를 제곱하여 계산된다. &lt;b&gt;해당 통계량이 클수록 기대빈도와 실제 값과의 차이가 크다고 해석하면 된다&lt;/b&gt;. 단, 분할표를 생성할 때 normalize 옵션을 사용하면 각 셀의 기대 빈도가 행 또는 열의 합계에 비례하도록 조정되기 때문에 원래의 기대 빈도와 차이가 발생한다. 따라서, 카이제곱 검정에서 분할표를 생성할 때는 normalize 옵션을 사용하면 안된다.&lt;/p&gt;
&lt;pre id=&quot;code_1710706293408&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
from scipy.stats import chi2_contingency

# 예제 데이터
data = pd.DataFrame({&quot;성별&quot;: [&quot;남&quot;, &quot;남&quot;, &quot;여&quot;, &quot;여&quot;, &quot;남&quot;, &quot;여&quot;],
                     &quot;취미&quot;: [&quot;운동&quot;, &quot;독서&quot;, &quot;운동&quot;, &quot;음악&quot;, &quot;독서&quot;, &quot;음악&quot;]})

# 분할표 생성
contingency_table = pd.crosstab(data[&quot;성별&quot;], data[&quot;취미&quot;])
print(contingency_table)

# 카이제곱 검정
chi2_stat, p_val, dof, expected = chi2_contingency(contingency_table)
print(f&quot;카이제곱 통계량: {chi2_stat:.2f}, p-value: {p_val:.4f}&quot;)

카이제곱 통계량: 4.00, p-value: 0.1353&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로, 자유도의 2~3배 보다 카이제곱 통계량이 크면 차이가 있다고 본다. 범주형 변수의 자유도는 범주의 수 - 1 이므로, 여기서는 (2-1) * (3-1) = 2, 2의 2~3배인 4~6 보다 카이제곱 통계량이 크면 차이가 있다고 볼 수 있다. 그런데, p-value의 값이 0.13이다. 만약 p-value의 값만을 본다면 귀무가설을 기각할 충분한 근거가 없기 때문에 두 변수는 서로 독립이 아니라고 해석할 수 있다. 하지만, p-value만으로는 두 변수 간에 관련성이 있는지 확실하게 판단할 수 없다. 분할표의 크기, 모집단의 분포 등 다른 정보들을 고려하여 두 변수 간의 연관성을 판단해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료 출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dlearner.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dlearner.tistory.com/36&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/DA4BAM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/DA4BAM&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rfriend.tistory.com/418&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://rfriend.tistory.com/418&lt;/a&gt;&lt;/p&gt;</description>
      <category>Aivle/Python</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/78</guid>
      <comments>https://hr1588.tistory.com/78#entry78comment</comments>
      <pubDate>Sun, 17 Mar 2024 23:26:46 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 단변량 분석</title>
      <link>https://hr1588.tistory.com/77</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 Python에서 시각화 라이브러리를 활용한 단변량 분석을 정리했다. 대표적인 시각화 라이브러리로는 matplotlib와 seaborn이 있으며, 그림으로 변수에 대한 특성을 파악할 수 있다. 수치형 변수와 범주형 변수 모두 단변량 분석을 진행할 수 있는데, 먼저 수치형 변수에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;수치형 변수&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단변량 분석은 하나의 변수에 대한 특성을 파악하는 것이다. 수치형 변수의 경우 대푯값과 분포 특성을 파악하는 것이 중요하다. Python의 Pandas와 Seaborn을 활용해서, 특성을 알아보자.&lt;/p&gt;
&lt;pre id=&quot;code_1710685838035&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 예제 데이터 생성
data = pd.DataFrame({'age': [25, 30, 35, 40, 45, 50, 55, 60, 65, 70]})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대푯값 수치화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 산술평균(mean) : 데이터의 전체 값을 모두 더한 후 개수로 나눈 값&lt;/p&gt;
&lt;pre id=&quot;code_1710686994840&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mean_age = data['age'].mean()
print(f&quot;평균 연령: {mean_age}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 중앙값(median) : 데이터를 크기 순으로 정렬했을 때 가운데 위치하는 값&lt;/p&gt;
&lt;pre id=&quot;code_1710687019848&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;median_age = data['age'].median()
print(f&quot;중앙값 연령: {median_age}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.최빈값(mode) : 데이터에서 가장 많이 관측된 값&lt;/p&gt;
&lt;pre id=&quot;code_1710687060346&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mode_age = data['age'].mode()
print(f&quot;최빈값 연령: {mode_age.values}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 사분위수(quantile) : 데이터를 크기 순으로 정렬했을 때 일정 구간을 나누는 값&lt;/p&gt;
&lt;pre id=&quot;code_1710687541385&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;q1_age = data['age'].quantile(0.25)  # 제 1사분위수
q3_age = data['age'].quantile(0.75)  # 제 3사분위수
print(f&quot;제 1사분위수 연령: {q1_age}&quot;)
print(f&quot;제 3사분위수 연령: {q3_age}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기초통계량&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;describe() 메소드를 사용하면 한 번에 주요 기초통계량을 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1710687578318&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(data['age'].describe())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;시각화&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 히스토그램&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHrjyd/btsFQbgJne3/VQcafK42j9OldA5vkzK7k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHrjyd/btsFQbgJne3/VQcafK42j9OldA5vkzK7k1/img.png&quot; data-alt=&quot;Histogram&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHrjyd/btsFQbgJne3/VQcafK42j9OldA5vkzK7k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHrjyd%2FbtsFQbgJne3%2FVQcafK42j9OldA5vkzK7k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;432&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Histogram&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터의 분포를 막대 그래프로 시각화&lt;/li&gt;
&lt;li&gt;각 막대의 높이: 특정 범위에 속하는 데이터 개수&lt;/li&gt;
&lt;li&gt;x축: 데이터 값 범위&lt;/li&gt;
&lt;li&gt;y축: 데이터 개수&lt;/li&gt;
&lt;li&gt;Seaborn은 기본 옵션으로 색상 테마, 범례 설정 등 더 다양한 기능 제공&lt;/li&gt;
&lt;li&gt;kde = True 옵션을 사용하면 히스토그램과 KDE를 하나의 그림으로 확인할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710690768562&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt

plt.hist(data)
plt.xlabel(&quot;데이터 값&quot;)
plt.ylabel(&quot;데이터 개수&quot;)
plt.show()

import seaborn as sns

sns.histplot(data, bins = 20, kde = True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;장점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 분포 직관적으로 파악 가능&lt;/li&gt;
&lt;li&gt;간단하고 빠르게 시각화 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 값 범위에 따라 해상도가 달라짐&lt;/li&gt;
&lt;li&gt;이상치 영향을 크게 받음&lt;/li&gt;
&lt;li&gt;구간(bin)의 너비를 어떻게 잡는지에 따라 전혀 다른 모양이 될 수 있음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. kdeplot (Kernel Density Estimation)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9fSYQ/btsFQTGBJfz/sklSjdclnKIZ3PlBdtlXpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9fSYQ/btsFQTGBJfz/sklSjdclnKIZ3PlBdtlXpk/img.png&quot; data-alt=&quot;KDE&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9fSYQ/btsFQTGBJfz/sklSjdclnKIZ3PlBdtlXpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9fSYQ%2FbtsFQTGBJfz%2FsklSjdclnKIZ3PlBdtlXpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;594&quot; height=&quot;432&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;KDE&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;히스토그램의 연속적 표현&lt;/li&gt;
&lt;li&gt;데이터 밀도를 곡선으로 시각화&lt;/li&gt;
&lt;li&gt;밀도함수 그래프 아래의 면적은 1&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710693254630&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import seaborn as sns

sns.kdeplot(data)
plt.show()

sns.kdeplot(data, fill=True) # 면적 채우기 옵션
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;장점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 분포를 더 매끄럽게 표현&lt;/li&gt;
&lt;li&gt;이상치 영향 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;히스토그램보다 해석하기 어려울 수 있음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. boxplot&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbuGH0/btsFOZ8TKCs/JMlqIOC8itaRekQ3d3P5pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbuGH0/btsFOZ8TKCs/JMlqIOC8itaRekQ3d3P5pK/img.png&quot; data-alt=&quot;Boxplot&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbuGH0/btsFOZ8TKCs/JMlqIOC8itaRekQ3d3P5pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbuGH0%2FbtsFOZ8TKCs%2FJMlqIOC8itaRekQ3d3P5pK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;543&quot; height=&quot;413&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Boxplot&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터의 분포, 중앙값, 사분위수, 이상치 시각화&lt;/li&gt;
&lt;li&gt;상자: 25% ~ 75% 사분위수 범위&lt;/li&gt;
&lt;li&gt;중앙선: 중앙값&lt;/li&gt;
&lt;li&gt;수염: 최대값/최소값 (IQR 범위 밖의 값)&lt;/li&gt;
&lt;li&gt;Seaborn은&amp;nbsp;다양한&amp;nbsp;옵션&amp;nbsp;제공&amp;nbsp;(색상,&amp;nbsp;범례,&amp;nbsp;이상치&amp;nbsp;표시&amp;nbsp;등)&lt;/li&gt;
&lt;li&gt;값에 NaN이 있으면 그래프가 그려지지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710693485516&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt

plt.boxplot(data)
plt.xlabel(&quot;데이터&quot;)
plt.show()

import seaborn as sns

sns.boxplot(data)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 분포, 중앙값, 이상치 한눈에 파악 가능&lt;/li&gt;
&lt;li&gt;비교 분석 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 개수가 적으면 정확도가 떨어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히스토그램, kdeplot, boxplot은 각각 장단점이 존재하며, 상황에 따라 적절한 방법을 선택해야한다. 또한, Matplotlib와 Seaborn 중 어떤 라이브러리를 사용할지는 시각화의 목적과 복잡성을 고려해서 결정하면 된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;범주형 변수&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범주형 변수는 각 범주의 빈도와 비율을 파악하는 것이 중요하다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수치화&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1710695178650&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
import matplotlib.pyplot as plt

# 예제 데이터 생성
titanic = pd.read_csv(path)

print(titanic['Pclass'].value_counts())
print(titanic['Pclass'].value_counts(normalize=True))&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;value_counts() 메소드로 각 범주의 빈도수를 계산할 수 있음&lt;/li&gt;
&lt;li&gt;value_counts(normalize = True) 는 각 범주의 상대 빈도(비율)을 계산&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;시각화&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. bar chart&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p4l9F/btsFRjymrmT/Lfce7K1Ybr8UeRkKPkMEOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p4l9F/btsFRjymrmT/Lfce7K1Ybr8UeRkKPkMEOK/img.png&quot; data-alt=&quot;Bar Chart&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p4l9F/btsFRjymrmT/Lfce7K1Ybr8UeRkKPkMEOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp4l9F%2FbtsFRjymrmT%2FLfce7K1Ybr8UeRkKPkMEOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;432&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Bar Chart&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710695304835&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;titanic['Pclass'].value_counts().plot(kind='bar')
plt.title(&quot;성별 분포&quot;)
plt.xlabel(&quot;성별&quot;)
plt.ylabel(&quot;빈도&quot;)
plt.show()


sns.countplot(x='Pclass', data=titanic)
plt.grid()
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;plt.bar혹은 .plot(kind=bar)를 이용하려면 먼저 집계한 후 결과를 가지고 그래프를 그려야 한다,&lt;/li&gt;
&lt;li&gt;countplot은 집계 + bar plot을 한번에 실행한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. pie chart&lt;/b&gt; &lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LzSIT/btsFRa2nMCf/b1VOoCCKW3GZepb6AH5HDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LzSIT/btsFRa2nMCf/b1VOoCCKW3GZepb6AH5HDK/img.png&quot; data-alt=&quot;Pie Chart&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LzSIT/btsFRa2nMCf/b1VOoCCKW3GZepb6AH5HDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLzSIT%2FbtsFRa2nMCf%2Fb1VOoCCKW3GZepb6AH5HDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;389&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Pie Chart&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710695564999&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data['gender'].value_counts().plot(kind='pie', autopct='%.1f%%')
plt.title(&quot;성별 분포&quot;)
plt.show()

temp = titanic['Pclass'].value_counts()

plt.pie(temp.values, labels = temp.index, autopct = '%.2f%%',
        startangle=90, counterclock=False,
        explode = [0.05, 0.05, 0.05], shadow=True)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;bar chart와 동일하게 먼저 집계를 진행해야 시각화가 가능&lt;/li&gt;
&lt;li&gt;다양한 파라미터로 chart를 꾸밀 수 있음
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;autopct : 그래프에 표시할 값 비율 값에 대한 설정. ex) .2f% : 소수점 두 자리 퍼센트로 표기 한다는 의미&lt;/li&gt;
&lt;li&gt;startangle : 시작 각도&lt;/li&gt;
&lt;li&gt;counterclock : 시계 방향 여부&lt;/li&gt;
&lt;li&gt;explode : 중심으로부터 개별 요소를 얼마나 띄울지&lt;/li&gt;
&lt;li&gt;shadow : 그림자 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Aivle/Python</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/77</guid>
      <comments>https://hr1588.tistory.com/77#entry77comment</comments>
      <pubDate>Fri, 15 Mar 2024 15:47:31 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] RFM, Retention</title>
      <link>https://hr1588.tistory.com/76</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난&amp;nbsp;포스팅에서는&amp;nbsp;90일&amp;nbsp;이상&amp;nbsp;구매&amp;nbsp;이력이&amp;nbsp;없는&amp;nbsp;고객을&amp;nbsp;장기&amp;nbsp;미구매&amp;nbsp;고객이라&amp;nbsp;정의하고,&amp;nbsp;해당&amp;nbsp;고객군의&amp;nbsp;특성을&amp;nbsp;파악했다.&amp;nbsp;이번에는&amp;nbsp;RFM&amp;nbsp;분석으로&amp;nbsp;전체&amp;nbsp;판매&amp;nbsp;데이터를&amp;nbsp;활용해&amp;nbsp;고객&amp;nbsp;등급을&amp;nbsp;지정하고,&amp;nbsp;또&amp;nbsp;단순&amp;nbsp;90일이&amp;nbsp;아니라&amp;nbsp;Retention을&amp;nbsp;파악해서&amp;nbsp;첫&amp;nbsp;구매일&amp;nbsp;이후&amp;nbsp;고객의&amp;nbsp;잔존율도&amp;nbsp;확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, python으로 만든 csv 파일을 로드했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;538&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfQlwV/btsFPsbTQsQ/wDJIgxme6uUhHMTqvCVAQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfQlwV/btsFPsbTQsQ/wDJIgxme6uUhHMTqvCVAQ1/img.png&quot; data-alt=&quot;CSV LOAD&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfQlwV/btsFPsbTQsQ/wDJIgxme6uUhHMTqvCVAQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfQlwV%2FbtsFPsbTQsQ%2FwDJIgxme6uUhHMTqvCVAQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;538&quot; height=&quot;542&quot; data-origin-width=&quot;538&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CSV LOAD&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과가&amp;nbsp;문제없이&amp;nbsp;출력됨을&amp;nbsp;확인했으니,&amp;nbsp;RFM&amp;nbsp;분석을&amp;nbsp;시작해보자.&amp;nbsp;혹시&amp;nbsp;RFM&amp;nbsp;분석이&amp;nbsp;뭔지&amp;nbsp;모르신다면,&amp;nbsp;아래의&amp;nbsp;포스팅을&amp;nbsp;먼저&amp;nbsp;읽고&amp;nbsp;오시는걸&amp;nbsp;추천드린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1710679018926&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[RFM] 고객 세분화 분석이란?&quot; data-og-description=&quot;요즘 데이터리안의 SQL 부트캠프를 수강하며, 데이터 분석가에게 필수적인 SQL 역량을 쌓고 있다. 이번 포스팅에서는 데이터리안 데이터 분석가 이보민님의 RFM 분석에 관한 글을 공부하고, 이전&quot; data-og-host=&quot;hr1588.tistory.com&quot; data-og-source-url=&quot;https://hr1588.tistory.com/66&quot; data-og-url=&quot;https://hr1588.tistory.com/66&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gS7ZK/hyVyix2CXA/76xXu4zXIU4ZpfVSqIx8o1/img.png?width=800&amp;amp;height=452&amp;amp;face=0_0_800_452,https://scrap.kakaocdn.net/dn/35eyF/hyVAFeETl8/hHkK2dAcNGHIrDmwJYyVZ1/img.png?width=800&amp;amp;height=452&amp;amp;face=0_0_800_452,https://scrap.kakaocdn.net/dn/AZL3H/hyVAEUmoOL/L3J9G1LOT4lEKcZfPfTsvk/img.png?width=1280&amp;amp;height=724&amp;amp;face=0_0_1280_724&quot;&gt;&lt;a href=&quot;https://hr1588.tistory.com/66&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hr1588.tistory.com/66&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gS7ZK/hyVyix2CXA/76xXu4zXIU4ZpfVSqIx8o1/img.png?width=800&amp;amp;height=452&amp;amp;face=0_0_800_452,https://scrap.kakaocdn.net/dn/35eyF/hyVAFeETl8/hHkK2dAcNGHIrDmwJYyVZ1/img.png?width=800&amp;amp;height=452&amp;amp;face=0_0_800_452,https://scrap.kakaocdn.net/dn/AZL3H/hyVAEUmoOL/L3J9G1LOT4lEKcZfPfTsvk/img.png?width=1280&amp;amp;height=724&amp;amp;face=0_0_1280_724');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[RFM] 고객 세분화 분석이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;요즘 데이터리안의 SQL 부트캠프를 수강하며, 데이터 분석가에게 필수적인 SQL 역량을 쌓고 있다. 이번 포스팅에서는 데이터리안 데이터 분석가 이보민님의 RFM 분석에 관한 글을 공부하고, 이전&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hr1588.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RFM 분석&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;판매 데이터로 RFM을 구하기 위해서는 고객 ID, 고객 별 최신 구매일자, 구매 횟수, 구매 금액의 합이 필요하다. 또한, R/F/M의 기준도 세워야한다. 우리는 90일 이상 미구매 고객을 식별하므로, 90일을 기준으로 Recency를 분류하면된다. 그렇다면, Frequency와 Monetary는 어떻게 분류하는게 좋을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대규모 판매 데이터에는 분명 VIP가 있기 마련이고, 평균값은 극단값에 취약하다는 단점이 있다. 따라서, 판매 횟수와 구매금액의 합의 중앙값을 활용해서 F와 M을 2가지로 나눠보자. 편의상 RFM을 모두 2가지로 분할했지만, 고객/산업의 특성에 따라 더 세세하게 분류해도 무방하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710724331291&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 원본 테이블에서 필요한 정보 CTE로 추출

with records as(
	select CustomerID as ID, 
        Max(OrderDate) as last_order_date,
        count(CustomerID) as cnt_orders,
        sum(Amt) as sum_sales
    from long_cust
    group by CustomerID
)

-- F의 기준, M의 기준 설정(중앙값 활용)

select avg(cnt_orders)
from(
	select cnt_orders, percent_rank() over (order by cnt_orders) as percent
	from records) t
where percent between 0.49 and 0.51;

select avg(sum_sales)
from(
	select sum_sales, percent_rank() over (order by sum_sales) as percent
	from records) t
where percent between 0.49 and 0.51;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주문 횟수의 중앙값은 12, 구매 금액의 중앙값은 29,555인데 편의상 30,000으로 지정했다. MySQL은 median을 직접 구하는 함수가 없기 때문에, percent_rank() 함수를 사용해서 가운데 있는 값들의 평균으로 추출하면된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기준을 정했으니, RFM 그룹별로 몇 명의 고객이 있는지 확인해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1710724517577&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select 
	case 
		when last_order_date &amp;gt;= '2017-01-01'
		then 'recent'
        else 'past'
        end as recency,
	case 
		when cnt_orders &amp;gt;= 12
		then 'high'
        else 'low'
        end as frequency,
	case 
		when sum_sales &amp;gt;= 30000
        then 'high'
        else 'row'
        end as monetary,
		count(*) as customers
from records
group by recency, frequency, monetary
order by customers desc;&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;288&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;72&quot; height=&quot;22&quot;&gt;recency&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;72&quot;&gt;frequency&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;72&quot;&gt;monetary&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;72&quot;&gt;customers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;recent&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;954&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;past&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;low&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;row&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;717&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;recent&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;low&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;row&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;337&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;past&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;recent&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;low&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;recent&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;row&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;48&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;past&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;row&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;22&quot;&gt;past&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;low&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과를 다음과 같이 해석할 수 있다,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가장 가치 있는 충성 고객 : 954명&lt;/li&gt;
&lt;li&gt;떠나간 VIP : 95명&lt;/li&gt;
&lt;li&gt;구매 빈도와 금액이 낮은 과거 고객 : 717명&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 목적은 이탈 위험이 있는 고객군을 찾아 그들에게 프로모션을 제공, 고객의 이탈을 방지하는 것이다. 우리는 95명의 고객들의 특성을 파악해서 장기 미구매 요인을 탐색하고, 그들의 마음을 되돌릴 방안을 고민해볼 필요가 있다. 또한, 기존 충성 고객들을 위한 프로모션도 고민해야한다. 즉, VIP 고객들을 중점적으로 프로모션을 진행해보자. 먼저, VIP 고객들만을 추출하고, 그들의 비중을 확인해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710725130157&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select 
    recency,
    frequency,
    monetary,
    customers,
    round(customers / sum_cust,2) as cust_ratio
from(
select 
	case 
		when last_order_date &amp;gt;= '2017-01-01'
		then 'recent'
        else 'past'
        end as recency,
	case 
		when cnt_orders &amp;gt;= 12
		then 'high'
        else 'low'
        end as frequency,
	case 
		when sum_sales &amp;gt;= 30000
        then 'high'
        else 'row'
        end as monetary,
		count(*) as customers,
        sum(count(*)) over() as sum_cust
from records
group by recency, frequency, monetary) t
where
	recency in ('recent', 'past')
    and frequency = 'high'
    and monetary = 'high'
order by recency desc;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.2558%; text-align: center;&quot;&gt;recency&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; text-align: center;&quot;&gt;Frequency&lt;/td&gt;
&lt;td style=&quot;width: 18.9536%; text-align: center;&quot;&gt;Monetary&lt;/td&gt;
&lt;td style=&quot;width: 19.6511%; text-align: center;&quot;&gt;Customers&lt;/td&gt;
&lt;td style=&quot;width: 18.6047%; text-align: center;&quot;&gt;Ratio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.2558%; text-align: center;&quot;&gt;recent&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;width: 18.9536%; text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;width: 19.6511%; text-align: center;&quot;&gt;954&lt;/td&gt;
&lt;td style=&quot;width: 18.6047%; text-align: center;&quot;&gt;0.43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.2558%; text-align: center;&quot;&gt;past&lt;/td&gt;
&lt;td style=&quot;width: 19.4186%; text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;width: 18.9536%; text-align: center;&quot;&gt;high&lt;/td&gt;
&lt;td style=&quot;width: 19.6511%; text-align: center;&quot;&gt;95&lt;/td&gt;
&lt;td style=&quot;width: 18.6047%; text-align: center;&quot;&gt;0.04&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전체 고객 중 43%가 충성 고객이고, 4%가 떠나간 VIP이다.&lt;/b&gt; 47%가 높은 가치 고객층이므로, 이들에 대한 세분화된 분석을 통해 효과적인 리텐션 및 마케팅 전략을 수립할 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Retention(리텐션)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RFM 분석 결과, 고객들의 리텐션을 확인해볼 필요가 있다. 1년 3개월 동안 방문 횟수의 중앙값이 12회 이므로, 클래식 리텐션보다 롤링 리텐션을 사용하는게 좋다고 판단했다. 롤링 리텐션은 최초 활성화 시점부터 특정 시점까지 아직 이탈하지 않은 고객의 비율을 계산한다. 리텐션의 개념을 잘 모른다면, 아래의 포스팅을 참조하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1710730396667&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Retention] 리텐션&quot; data-og-description=&quot;예전 게임 사용자 분석을 하면서, KPI 포스팅을 진행했었다. 이번 포스팅에서는 Retention에 대해 다시 한 번 정리하고, 상황에 따라 어떤 방법을 사용해야할지 생각해보았다. AARRR 사용자가 특정 서&quot; data-og-host=&quot;hr1588.tistory.com&quot; data-og-source-url=&quot;https://hr1588.tistory.com/68&quot; data-og-url=&quot;https://hr1588.tistory.com/68&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ccskq2/hyVACoRHh6/RuZzwCh1uAb54Ak99I63Ak/img.png?width=800&amp;amp;height=388&amp;amp;face=0_0_800_388,https://scrap.kakaocdn.net/dn/1Oj4r/hyVAAdxb35/CDVgVBhW3hzVB1mDC3Xg00/img.png?width=800&amp;amp;height=388&amp;amp;face=0_0_800_388,https://scrap.kakaocdn.net/dn/cBfOXy/hyVANxbjTk/bVitmEkqcsRLKsKdbP3ro0/img.png?width=750&amp;amp;height=364&amp;amp;face=0_0_750_364&quot;&gt;&lt;a href=&quot;https://hr1588.tistory.com/68&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hr1588.tistory.com/68&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ccskq2/hyVACoRHh6/RuZzwCh1uAb54Ak99I63Ak/img.png?width=800&amp;amp;height=388&amp;amp;face=0_0_800_388,https://scrap.kakaocdn.net/dn/1Oj4r/hyVAAdxb35/CDVgVBhW3hzVB1mDC3Xg00/img.png?width=800&amp;amp;height=388&amp;amp;face=0_0_800_388,https://scrap.kakaocdn.net/dn/cBfOXy/hyVANxbjTk/bVitmEkqcsRLKsKdbP3ro0/img.png?width=750&amp;amp;height=364&amp;amp;face=0_0_750_364');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Retention] 리텐션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;예전 게임 사용자 분석을 하면서, KPI 포스팅을 진행했었다. 이번 포스팅에서는 Retention에 대해 다시 한 번 정리하고, 상황에 따라 어떤 방법을 사용해야할지 생각해보았다. AARRR 사용자가 특정 서&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hr1588.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 MySQL로 실습을 진행해보자.&amp;nbsp; 2016년 데이터로 1년간 리텐션 변화도를 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710730492931&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH ROLL_RT AS(
SELECT DISTINCT CustomerID, 
       DATE_FORMAT(MIN(OrderDate),'%Y-%m-01') AS first_order_month, 
       DATE_FORMAT(MAX(OrderDate),'%Y-%m-01') AS last_order_month
FROM long_cust
GROUP BY CustomerID)

SELECT first_order_month,
  COUNT(DISTINCT CustomerID) as month0,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 1 month) &amp;lt;= last_order_month then CustomerID end) as month1,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 2 month) &amp;lt;= last_order_month then CustomerID end) as month2,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 3 month) &amp;lt;= last_order_month then CustomerID end) as month3,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 4 month) &amp;lt;= last_order_month then CustomerID end) as month4,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 5 month) &amp;lt;= last_order_month then CustomerID end) as month5,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 6 month) &amp;lt;= last_order_month then CustomerID end) as month6,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 7 month) &amp;lt;= last_order_month then CustomerID end) as month7,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 8 month) &amp;lt;= last_order_month then CustomerID end) as month8,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 9 month) &amp;lt;= last_order_month then CustomerID end) as month9,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 10 month) &amp;lt;= last_order_month then CustomerID end) as month10,
  COUNT(DISTINCT CASE WHEN DATE_ADD(first_order_month, INTERVAL 11 month) &amp;lt;= last_order_month then CustomerID end) as month11
FROM ROLL_RT
WHERE first_order_month &amp;lt; '2017-01-01'
GROUP BY first_order_month
ORDER BY first_order_month&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lbZ1c/btsFP58LqNV/A7e5Hwpn6v6VhJKPAMoWV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lbZ1c/btsFP58LqNV/A7e5Hwpn6v6VhJKPAMoWV0/img.png&quot; data-alt=&quot;Rolling Retention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lbZ1c/btsFP58LqNV/A7e5Hwpn6v6VhJKPAMoWV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlbZ1c%2FbtsFP58LqNV%2FA7e5Hwpn6v6VhJKPAMoWV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1003&quot; height=&quot;290&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Rolling Retention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 표를 보면, 몇 가지 주요 포인트를 발견할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 달(month0) 사용자 기준으로 시간이 지날수록 리텐션율이 급격히 감소하는 추세를 보인다. 예를 들어 1월의 경우 1개월 후 92.65%, 3개월 후 90.35%로 떨어졌지만 11개월 후에는 61.28%까지 하락했다.&lt;/li&gt;
&lt;li&gt;초기 1~3개월의 리텐션율은 상대적으로 높은 편이지만, 그 이후에는 가파르게 감소하는 모습을 보인다. 이는 신규 유입 사용자 대비 장기 지속 사용자 비중이 낮다는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;가장 최근인 2016-11-01의 경우 1개월 리텐션율이 24%에 불과하다. 이는 새로 가입한 사용자 4명 중 1명만이 한 달 후에도 제품/서비스를 사용한다는 뜻이다.&lt;/li&gt;
&lt;li&gt;전체적으로 초기에는 높았다가 시간이 지날수록 리텐션율이 급격히 하락하는 형태를 보이고 있다. 이는 신규 사용자 유입에 비해 기존 사용자 유지가 잘 이뤄지지 않고 있음을 시사한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤링 리텐션의 특성상 리텐션이 개선되고 있는지에 대한 해석은 어렵다. 다만, 연말에 비해 연초 첫 구매자들의 리텐션이 좋음을 확인할 수 있다. 특히, 1월 첫 구매자들의 리텐션이 좋은데 당시 어떤 프로모션을 진행했는지 확인해볼 필요가 있다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사용자 지표&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 다른 방법으로, 리텐션이 가장 좋았던 2016년 1월의 구매자들의 2월 DAU, MAU, Stickness를 계산해보자. DAU(Daily Active Users)는 매일 실제로 제품/서비스를 사용하는 활성 사용자 수를 의미하므로, 1월에 가입한 신규 사용자들이 2월부터 본격적으로 이용을 시작할 것으로 가정할 수 있기 때문이다. 1월에는 신규 가입자들이 제품을 익히고 활용하는 기간이었다면, 2월부터는 안정적으로 일상 사용이 이루어졌을 것으로 예상된다. &lt;br /&gt;&lt;br /&gt;따라서 2016년 1월 신규 고객의 리텐션이 좋다면, 그들의 실제 활성 사용 추이를 파악하기 위해서는 2월 DAU 데이터를 활용하는 것이 가장 적절하다. 1월 DAU는 아직 대다수가 신규 가입 단계에 있었기 때문에 실제 활성 사용량을 제대로 반영하지 못할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710738286430&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with MAU as(
SELECT d.OrderDate as dt,
       count(DISTINCT d.CustomerID) as dau,
       count(distinct m.CustomerID) as mau,
       round(count(DISTINCT d.CustomerID) / count(DISTINCT m.CustomerID),2) as stickiness
from long_cust as d
left join long_cust as m on m.OrderDate BETWEEN DATE_SUB(d.OrderDate, INTERVAL 30 DAY) and d.OrderDate
where d.OrderDate between '2016-02-01' and '2016-02-29'
group by d.OrderDate
order by d.OrderDate)

select *, dayofweek(dt) as weekday
from MAU
order by stickiness desc;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A6MYa/btsFQgXigWS/QNpPGyORNf8crg6CcEULh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A6MYa/btsFQgXigWS/QNpPGyORNf8crg6CcEULh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A6MYa/btsFQgXigWS/QNpPGyORNf8crg6CcEULh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA6MYa%2FbtsFQgXigWS%2FQNpPGyORNf8crg6CcEULh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;244&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stickiness가 높은순으로 정렬한 결과, 2016년 2월 초와 금요일에 비교적 사용자가 많음을 확인할 수 있다. 당시 진행했던 프로모션 혹은 인기 상품을 확인해서 판매 전략에 활용할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;E-커머스 데이터로 간단한 분석을 수행해보았다. 이탈 위험 고객군을 90일로 지정하고, EDA / RFM / 리텐션 / 사용자 지표를 분석해보았다. 알아낸 사항은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이탈 위험 예상 고객은 30~50대의 경기도 거주 여성이 다수&lt;/li&gt;
&lt;li&gt;채소, 반찬류의 구매 빈도가 많은 것으로 보아 가정 주부로 추정&lt;/li&gt;
&lt;li&gt;2016년 1월 ~ 2017년 3월 사이의 충성고객은 약 43%, 떠나간 VIP는 4%&lt;/li&gt;
&lt;li&gt;2016년 리텐션을 롤링 리텐션으로 확인한 결과, 2016년 1월 가입자의 리텐션이 제일 좋음&lt;/li&gt;
&lt;li&gt;2016년 1월 가입자의 특성을 파악하고자 2016년 2월 데이터로 사용자 지표 추출 =&amp;gt; 2월초와 금요일에 비교적 일일 사용자가 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2월 초와 금요일에 활성화되는 패턴으로 미루어볼 때, 주말 식재료 구매를 위해 가입했던 주부 고객들이 점차 이탈한 것으로 판단된다. 결과적으로 주부 고객 확보와 초기 리텐션은 성공적이었지만, 장기 고객 유지에는 실패한 것으로 보인다. 이는 주부 고객의 니즈 변화를 제대로 반영하지 못했기 때문인 것으로 분석된다. &lt;br /&gt;&lt;br /&gt;따라서 앞으로는 주부 고객의 라이프스타일과 식품 소비 패턴 변화를 지속적으로 모니터링하고, 그에 맞는 차별화된 마케팅과 서비스 전략을 수립할 필요가 있다. 아울러 초기 유치 못지않게 장기 리텐션 제고를 위한 프로그램과 이벤트도 강화된다면 매출을 제고할 수 있을 것으로 예상된다.&lt;/p&gt;</description>
      <category>Aivle/Project</category>
      <category>retention</category>
      <category>RFM</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/76</guid>
      <comments>https://hr1588.tistory.com/76#entry76comment</comments>
      <pubDate>Tue, 12 Mar 2024 23:07:05 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] Python에서 WorkBench 연결</title>
      <link>https://hr1588.tistory.com/75</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;전자상거래 데이터를 활용하여 장기 미구매 고객을 식별하고, 데이터리안 SQL 캠프에서 배운 RFM(Recency, Frequency, Monetary) 분석과 고객 유지율(Retention) 분석을 수행하려고 한다.&amp;nbsp; 지금은 데이터가 작지만, 향후 빅데이터를 다루면 MySQL Workbench에 데이터를 직접 업로드하는건 시간이 오래 걸린다고 판단했다. 이참에 Python을 활용하여 데이터베이스에 데이터를 바로 적재하는 방법을 찾아보고 그 과정을 기록했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL Workbench를 실행해서 DB를 생성한다. 아래의 코드를 활용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mWPFq/btsFJJxr8tE/v17X4n0FheSEqfWuwCWzGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mWPFq/btsFJJxr8tE/v17X4n0FheSEqfWuwCWzGk/img.png&quot; data-alt=&quot;Create DB&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mWPFq/btsFJJxr8tE/v17X4n0FheSEqfWuwCWzGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmWPFq%2FbtsFJJxr8tE%2Fv17X4n0FheSEqfWuwCWzGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;371&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Create DB&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB가 만들어졌으면, Python으로 이동한다. 이제 패키지를 사용하는데, pymysql 패키지가 설치되어 있지 않으면 설치를 진행한다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mln43/btsFJspeAFX/ylxxN4qpw49DnSr1SNG3ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mln43/btsFJspeAFX/ylxxN4qpw49DnSr1SNG3ik/img.png&quot; data-alt=&quot;pymysql 설치(Anaconda 3)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mln43/btsFJspeAFX/ylxxN4qpw49DnSr1SNG3ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmln43%2FbtsFJspeAFX%2FylxxN4qpw49DnSr1SNG3ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;483&quot; height=&quot;256&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pymysql 설치(Anaconda 3)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가 끝났으면, 아래의 코드를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710252993251&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import csv
import pymysql

# local DB 정보
conn = pymysql.connect(host='*****', user='*****', password='*****', db='aivle', charset='utf8')
cursor = conn.cursor()

# csv load
with open('cust_rfm.csv', 'r', encoding='utf-8') as csv_file:
    csv_data = csv.reader(csv_file)
    next(csv_data)

    # 기존 테이블 드롭
    drop_table_query = &quot;DROP TABLE IF EXISTS LONG_CUST&quot;
    cursor.execute(drop_table_query)
	
    # Table 생성
    create_table_query = '''
    CREATE TABLE LONG_CUST (
        CustomerID VARCHAR(10),
        OrderDate DATE,
        Amt INT(6),
        ProductID VARCHAR(9)
    )
    '''
    cursor.execute(create_table_query)
	
    # csv data 삽입
    insert_query = '''INSERT INTO LONG_CUST (CustomerID, OrderDate, Amt, ProductID)
                      VALUES (%s, %s, %s, %s)'''

    for row in csv_data:
        cursor.execute(insert_query, row)

conn.commit()

cursor.close()
conn.close()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 구문이지만, 몇 가지 주의점이 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;인코딩 : 만약 csv에 한글이 포함된 경우, charset과 encoding을 모두 utf-8로 맞춰야한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;header : csv_reader에는 별도의 header 옵션이 없다. 만약 csv에 header가 있으면, next()를 사용해 헤더를 테이블에서 지워버리면 된다. create_table에 이미 header를 전부 명시했기 때문이다.&lt;/li&gt;
&lt;li&gt;줄바꿈 : SQL Query문은 길이 및 가독성으로 줄을 바꿔야하는 경우가 다반사다. 이런 경우, 단순히 싱글 코테이션 ''이 아니라, ''' ''' 3개를 써줘야 error가 발생하지 않는다.&lt;/li&gt;
&lt;li&gt;Table 생성 : Table 이름, Column 이름(Key)은 본인의 자유지만, Value의 속성은 반드시 맞춰야한다. Varchar는 가변형 문자열, Date는 날짜, Int는 정수형 데이터를 뜻한다. 괄호 안의 숫자는 max_length를 의미한다.&lt;/li&gt;
&lt;li&gt;Data 삽입 : Insert into와 For문으로 CSV 파일의 각 행을 LONG_CUST 테이블에 삽입한다. cursor.execute()에서 row는 csv 파일의 한 행을 나타내는 데이터이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;%s : 문자열에서 특정 부분을 다른 값으로 대체하고 싶을 때 사용하는 format 지정자이다. 여기서는 row 값이 쿼리문의 %s 자리에 차례로 대체되는데, 이를 통해 SQL의 injection 및 이상치 삽입을 방지할 수 있다.&lt;/li&gt;
&lt;li&gt;SQL Injection : 악의적인 SQL문을 주입하고 실행되게 하여 DB가 비정상적인 동작을 하도록 조작하는 행위&lt;/li&gt;
&lt;li&gt;conn.commit() : 변경 사항을 데이터에 영구적으로 저장한다.&lt;/li&gt;
&lt;li&gt;close() : 커서(Cursor)와 DB 연결을 종료한다.&lt;/li&gt;
&lt;li&gt;Cursor : Python에서 DB와 상호작용할 때 필수적인 객체로, 실제 쿼리를 실행하고, 결과를 가져오며, 트랜잭션을 제어하는 역할을 수행한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Error로 pymysql.err.DataError: (1406, &quot;Data too long for column 'CustomerID' at row 1&quot;) 오류가 발생할 수 있다. 아마 사용한 데이터의 첫 번쨰 column에서 오류가 발생할텐데, 아래의 코드를 MySQL CLI에서 실행하면 해결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710254857697&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysql &amp;gt; SET @@global.sql_mode = '';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 모드는 MySQL 서버의 글로벌 SQL Mode를 기본 동작으로 설정하는 것이다. 즉, 모든 SQL 모드가 해제되어 MySQL이 가장 느슨한 기본 동작 방식으로 실행된다. 이렇게 하면 SQL 문법 검사가 느슨해져서 일부 비표준 구문도 실행될 수 있다. 하지만, SQL 모드를 비우는 것은 보안과 안정성 측면에서 좋지 않기 때문에, Local이 아닌 다른 환경에서는 지양하는 편이 좋겠다.&lt;/p&gt;</description>
      <category>Aivle/Project</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/75</guid>
      <comments>https://hr1588.tistory.com/75#entry75comment</comments>
      <pubDate>Sun, 10 Mar 2024 16:47:07 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] E-커머스 장기 미구매 고객 탐색</title>
      <link>https://hr1588.tistory.com/74</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 1차 미니프로젝트 이후, 동일한 데이터로 나만의 실습을 진행했다. 데이터는 2016년 1월 ~ 2017년 3월간의 E-커머스 판매 Data를 활용했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 문제 정의&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차 미니프로젝트에서는 이탈 고객을 탐색했다. 여기서 단순히 이탈한 고객을 탐색하는 것이 아니라, 이탈 위험이 있는 고객군을 찾아 해당 고객에게 프로모션을 제공하면 이탈 방지가 가능하다고 판단했다. &lt;b&gt;전체 고객 중 3개월 이상 장기 미구매 이력이 있는 고객을 찾고, 어떤 특징을 가지고 있는지 확인해보자.&lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #e8e6e3; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-darkreader-inline-color=&quot;&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 코드 리뷰&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1710132259698&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

%config InlineBackend.figure_format = 'retina'

# 한글 폰트설정
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False

customers = pd.read_csv('customers.csv')
sales = pd.read_csv('sales.csv')
product = pd.read_csv('products.csv')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터는 2016년 1월 ~ 2017년 3월 사이의 판매 데이터, 고객 정보 데이터, 상품 데이터를 활용했다. 먼저, 고객 중 해당 기간에 구매를 하지않은 고객이 있는지 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710132642658&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cnt_orders = pd.merge(customers, sales, how='left', on ='CustomerID') # 고객 정보와 판매 정보 join
cnt_orders['OrderDate'] = pd.to_datetime(cnt_orders['OrderDate'])     # data type 변경

cnt_orders.sort_values(['CustomerID','OrderDate'], inplace=True)      # 데이터 정렬
cnt_orders = cnt_orders.reset_index(drop=True)

print(cnt_order.isnull().sum())
print(cnt_orders)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;merge 이후 NA 값을 확인해보면 아무것도 없다. 즉, 고객 DB에 있는 모든 고객이 판매 기간에 1회 이상 구매를 진행했다. 고객 정보와 판매 데이터는 1:M의 관계이다. 즉, 한 명의 고객이 여러 번의 주문을 할 수 있기 때문에, 고객 데이터를 기준으로 left join을 진행해야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710132841353&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;seq_orders = cnt_orders[['CustomerID','OrderDate']]

seq_orders = seq_orders.drop_duplicates(subset=['CustomerID','OrderDate']).reset_index(drop=True)
seq_orders['DaysDiff'] = seq_orders.groupby('CustomerID')['OrderDate'].diff().dt.days # 이전 구매와 현재 구매일 차이 추출

seq_orders['DaysDiff'].fillna(0, inplace=True)              # 결측치가 있는 경우, 고객ID가 바뀐 경우임으로 0으로 처리
more_month_order = seq_orders[seq_orders['DaysDiff'] &amp;gt;= 90] # 90일 이상 주문 이력이 없는 고객 확인
more_month_order = more_month_order.drop_duplicates(['CustomerID'])[['CustomerID']].reset_index(drop=True) # 중복ID 제거
more_month_order&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 주문 내역에서 고객별로 고유한 주문 날짜를 추출하고, 90일 이상 구매이력이 없는 고객정보를 필터링하는데 활용한다. 전체 고객 중, 36.33%의 고객이 90일 이상 구매하지 않은 이력이 존재함을 확인했다. 이제 해당 고객의 정보를 탐색해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710133268592&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df = pd.merge(customers, more_month_order, how='inner', on = 'CustomerID')
df['Age'] = 2016 - df['BirthYear']
df['Age_Group'] = df['Age'] // 10 * 10 # 연령대

# 등록 기간
df['RegisterDate'] = pd.to_datetime(df['RegisterDate'])
df['Registration_Year'] = 2016 - df['RegisterDate'].dt.year
df.head()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2979&quot; data-origin-height=&quot;2111&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWw007/btsFI50FzRB/NidJCbhV1TrhVPjqbTDQJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWw007/btsFI50FzRB/NidJCbhV1TrhVPjqbTDQJ1/img.png&quot; data-alt=&quot;장기 미구매 고객 정보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWw007/btsFI50FzRB/NidJCbhV1TrhVPjqbTDQJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWw007%2FbtsFI50FzRB%2FNidJCbhV1TrhVPjqbTDQJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2979&quot; height=&quot;2111&quot; data-origin-width=&quot;2979&quot; data-origin-height=&quot;2111&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;장기 미구매 고객 정보&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연령대 파생변수를 만들고, 장기 미구매 고객의 성별 / 연령대 / 등록연수 / 주소별 고객 정보를 확인했다. 비교적 최근에 가입한 고객의 비중이 높으며, 주로 30~50대 수도권 거주 여성 고객의 비중이 높음을 알 수 있다. 그럼 이 사람들은 어떤 상품을 주문할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710133398361&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;long_cust = df[['CustomerID']]
sales = pd.read_csv('sales.csv')

long_cust_product = pd.merge(pd.merge(sales, long_cust, how='inner', on = 'CustomerID'),product, how = 'left', on = 'ProductID')
long_cust_product.head()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1979&quot; data-origin-height=&quot;1582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OTb4I/btsFI32Rk9O/GFAQOACeRpG5qSNX5xdyGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OTb4I/btsFI32Rk9O/GFAQOACeRpG5qSNX5xdyGk/img.png&quot; data-alt=&quot;장기 미구매 고객 상품&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OTb4I/btsFI32Rk9O/GFAQOACeRpG5qSNX5xdyGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOTb4I%2FbtsFI32Rk9O%2FGFAQOACeRpG5qSNX5xdyGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1979&quot; height=&quot;1582&quot; data-origin-width=&quot;1979&quot; data-origin-height=&quot;1582&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;장기 미구매 고객 상품&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채소, 반찬류가 많은 것으로 보아 &lt;b&gt;가정 주부의 구매 비율이 높다고 추측&lt;/b&gt;할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #e8e6e3; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;3. 결과 해석&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장기&amp;nbsp;미구매&amp;nbsp;고객을&amp;nbsp;식별했으므로,&amp;nbsp;그룹에&amp;nbsp;대한&amp;nbsp;세분화를&amp;nbsp;더&amp;nbsp;심화시켜서&amp;nbsp;어떤&amp;nbsp;세부적인&amp;nbsp;특성을&amp;nbsp;가진&amp;nbsp;고객들이&amp;nbsp;있는지&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;30~50대&amp;nbsp;수도권&amp;nbsp;거주&amp;nbsp;여성&amp;nbsp;중에서&amp;nbsp;주부인지,&amp;nbsp;직장인인지,&amp;nbsp;혼자&amp;nbsp;사는지&amp;nbsp;등을&amp;nbsp;파악해서&amp;nbsp;보다&amp;nbsp;정밀한&amp;nbsp;결과를&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;아쉽게도&amp;nbsp;해당&amp;nbsp;데이터엔&amp;nbsp;가족&amp;nbsp;구성원&amp;nbsp;관련&amp;nbsp;정보가&amp;nbsp;없어,&amp;nbsp;세분화가&amp;nbsp;불가능하다.&amp;nbsp;혹은,&amp;nbsp;해당&amp;nbsp;고객층이&amp;nbsp;어떤&amp;nbsp;마케팅&amp;nbsp;채널을&amp;nbsp;언제&amp;nbsp;이용하는지&amp;nbsp;파악하여&amp;nbsp;접근하는&amp;nbsp;방법도&amp;nbsp;활용할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;가정&amp;nbsp;주부의&amp;nbsp;경우&amp;nbsp;주중에&amp;nbsp;쇼핑을&amp;nbsp;하거나,&amp;nbsp;오전/오후에&amp;nbsp;홈쇼핑을&amp;nbsp;시청하는&amp;nbsp;경우가&amp;nbsp;있으므로&amp;nbsp;주중에&amp;nbsp;특별한&amp;nbsp;할인&amp;nbsp;혹은&amp;nbsp;무료&amp;nbsp;배송&amp;nbsp;혜택을&amp;nbsp;제공할&amp;nbsp;수도&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;간단한&amp;nbsp;분석임에도,&amp;nbsp;장기&amp;nbsp;미구매&amp;nbsp;고객&amp;nbsp;중&amp;nbsp;가정&amp;nbsp;주부가&amp;nbsp;많다고&amp;nbsp;추측할&amp;nbsp;수&amp;nbsp;있었다.&amp;nbsp;다음&amp;nbsp;포스팅에서는&amp;nbsp;오늘&amp;nbsp;만든&amp;nbsp;cnt_orders&amp;nbsp;테이블에서&amp;nbsp;고객&amp;nbsp;ID,&amp;nbsp;구매&amp;nbsp;날짜,&amp;nbsp;구매&amp;nbsp;금액,&amp;nbsp;구매&amp;nbsp;상품&amp;nbsp;column을&amp;nbsp;활용해&amp;nbsp;전체&amp;nbsp;고객을&amp;nbsp;대상으로&amp;nbsp;RFM&amp;nbsp;분석&amp;nbsp;및&amp;nbsp;Retention&amp;nbsp;실습을&amp;nbsp;진행해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Aivle/Project</category>
      <category>aivle</category>
      <category>에이블스쿨</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/74</guid>
      <comments>https://hr1588.tistory.com/74#entry74comment</comments>
      <pubDate>Sat, 9 Mar 2024 19:59:02 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] Pandas</title>
      <link>https://hr1588.tistory.com/73</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 Python의 핵심 library인 Pandas를 알아보자. Pandas의 핵심은 '&lt;b&gt;DataFrame&lt;/b&gt;' 이라는 데이터 구조에 있다. Dataframe은 행과 열로 이루어진 테이블 형태의 데이터 구조로, 각 열은 서로 다른 데이터 타입(정수, 실수, 문자열 등)을 가질 수 있다. 이를 통해 우리가 실제 데이터 분석 과정에서 자주 등장하는 복잡한 형태의 데이터를 쉽게 다룰 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pandas는 여러가지 기능을 제공하지만, 대표적으로 다음과 같은 기능을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터의 로딩, 저장 : 다양한 파일 형식(csv, excel, DB 등)과의 데이터 입출력을 지원한다.&lt;/li&gt;
&lt;li&gt;데이터 정제 및 준비 : 결측치 처리, 데이터 형 변환, 필터링 등 데이터를 분석하기 전에 필요한 다양한 전처리를 수행&lt;/li&gt;
&lt;li&gt;데이터 조작 : 데이터 합치기, 그룹화, 정렬, 재구성 등 복잡한 데이터 조작을 원활하게 진행&lt;/li&gt;
&lt;li&gt;데이터 분석 및 모델링 : 통계 분석, 집계 및 요약 등의 기능 제공&lt;/li&gt;
&lt;li&gt;시각화 : Matplotlib, Seaborn 등의 시각화 library와 연동하여 데이터 분석 결과를 시각적으로 표현&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에는 기능별로 어떤 함수를 사용하는지 정리하고, 간단한 예제를 첨부했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터프레임 만들기&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pd.DataFrame() 함수 사용&lt;/li&gt;
&lt;li&gt;list, dict, numpy 배열 등을 사용해서 데이터프레임 제작 가능&lt;/li&gt;
&lt;li&gt;단, 데이터 / 열 이름(column), 인덱스 이름을 포함하는 데이터가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710058416039&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df = pd.read_csv(&quot;data.csv&quot;, index_col=&quot;ID&quot;, encoding = &quot;UTF-8&quot;)

# index_col = 인덱스 열 지정
# set_index를 사용해도 동일한 결과 제작 가능

df = df.set_index(&quot;ID&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 우리가 불러온 파일에 한글이 포함되어 있다면, &quot;UTF-8&quot;을 사용한 경우 한글 문자가 깨져보일 수 있다. 이런 경우에는 encoding 인자의 값을 &quot;CP949&quot;로 바꾸면된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #e8e6e3; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;b&gt;데이터프레임 탐색&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 데이터 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;head(): 상위 데이터 확인&lt;/li&gt;
&lt;li&gt;tail(): 하위 데이터 확인&lt;/li&gt;
&lt;li&gt;shape: 데이터프레임 크기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 정보 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;index: 인덱스 정보&lt;/li&gt;
&lt;li&gt;values: 값 정보&lt;/li&gt;
&lt;li&gt;columns: 열 정보&lt;/li&gt;
&lt;li&gt;dtypes: 열 자료형&lt;/li&gt;
&lt;li&gt;info(): 열 상세 정보&lt;/li&gt;
&lt;li&gt;describe(): 기술 통계 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 정렬&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;sort_values(): 특정 열 기준 정렬&lt;/li&gt;
&lt;li&gt;ascending:&amp;nbsp;오름차순/내림차순&amp;nbsp;설정&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710058789817&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df = df.sort_values(&quot;age&quot;, ascending=False)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 조회&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;loc:&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;행 라벨 기반 데이터 접근 (편리함)&lt;/li&gt;
&lt;li&gt;조건 조회 가능 (조건 df.loc[조건])&lt;/li&gt;
&lt;li&gt;범위 조회 가능 (범위 df.loc[:, '열 이름1':'열 이름2'])&lt;/li&gt;
&lt;li&gt;속도 느림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;iloc:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;행/열 위치 기반 데이터 접근 (속도 빠름)&lt;/li&gt;
&lt;li&gt;정수 인덱스 기반 접근에 유용 (정수 인덱스 df.iloc[0, 0])&lt;/li&gt;
&lt;li&gt;조건/범위 조회 불편&lt;/li&gt;
&lt;li&gt;라벨 기반 접근 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기타 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;df.sample(n) : 데이터 프레임에서 무작위로 n개의 행 출력&lt;/li&gt;
&lt;li&gt;df.drop_duplicates(subset=) : subset 인자에 포함된 column들로 중복된 값 제거&lt;/li&gt;
&lt;li&gt;isin() : 특정 값들에 해당하는 데이터만 선택&lt;/li&gt;
&lt;li&gt;between() : 특정 범위에 속하는 데이터만 선택, inclusive 옵션으로 both, neither, left, right 사용해서 이상/이하 조절&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710067207859&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 데이터 불러오기
df = pd.read_csv('data.csv')

# 기본 조회
df['열 이름']
df[['열 이름1', '열 이름2']]

# 조건 조회
df.loc[df['열 이름'] &amp;gt; 10]

# 범위 조회
df.loc[:, '열 이름1':'열 이름2']

# 여러 조건 조회
df.loc[(df['열 이름1'] &amp;gt; 10) &amp;amp; (df['열 이름2'] &amp;lt; 5)]

# 편리한 메서드
df.loc[df['열 이름'].isin(['값1', '값2'])]
df.loc[df['열 이름'].between(10, 20, inclusive = 'both')]

# iloc vs loc
df.iloc[0, 0]  # 행 위치 기반 접근
df.loc[0, '열 이름']  # 행 라벨 기반 접근

# 추가 기능

df.sample(5)
df.drop_duplicates(subset=)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 그룹화 및 집계&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;groupby() : 특정 열 기준 그룹화, as_index = False 인자로 groupby의 기준열을 index가 아닌 첫 번째 column으로 분리할 수 있음. 또한, 기준열에 list를 사용하면 여러개의 열로 집계 가능&lt;/li&gt;
&lt;li&gt;sum(), mean(), min(), max(), median() 등의 집계 함수 적용, avg()는 Pandas에서 사용하지 않음(SQL문에서 사용)&lt;/li&gt;
&lt;li&gt;집계 이후, matplotlib로 시각화 =&amp;gt; 값의 변화 및 비교에 유용함&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710058878268&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt
import pandas as pd

# plt 선명화, 한글 폰트 설정
%config InlineBackend.figure_format = 'retina'
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False

# 데이터 읽어오기
tip = pd.read_csv(path)

# 확인
tip.head()
grouped_df = tip.groupby('day')['tip'].mean()

# 그래프 설정
plt.title(&quot;요일별 Tip 비교&quot;)
plt.xlabel(&quot;요일&quot;)
plt.ylabel(&quot;Tip&quot;)

# 선형 그래프 그리기
plt.plot(grouped_df.index, grouped_df.values)

# 그래프 표시
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;913&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wf9gZ/btsFF2jiYqd/IrHZECyKuQOKQOrikeqmQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wf9gZ/btsFF2jiYqd/IrHZECyKuQOKQOrikeqmQ0/img.png&quot; data-alt=&quot;Agg Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wf9gZ/btsFF2jiYqd/IrHZECyKuQOKQOrikeqmQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwf9gZ%2FbtsFF2jiYqd%2FIrHZECyKuQOKQOrikeqmQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1128&quot; height=&quot;913&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;913&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Agg Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tips 데이터로 간단한 집계 후, 결과를 시각화했다. 평일에 비해, 주말에 Tip이 높음을 바로 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pandas DataFrame은 여러 열(Column)으로 구성된 테이블 형태의 데이터 구조이다. 각 열은 서로 다른 속성을 나타내며, 위의 예제와 같이 집계 함수를 사용하여 다양한 분석을 수행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 집계 함수를 사용할 때는 데이터의 종류를 고려해야 정확한 결과를 도출할 수 있다. 특히, 연속형과 범주형 데이터는 서로 다른 특성을 가지고 있으며, 아래와 같은 사항을 유의해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;연속형 데이터&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의 : 범위 내에서 어떤 값이든 취할 수 있는 데이터&lt;/li&gt;
&lt;li&gt;특징 :&lt;br /&gt;&amp;nbsp;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&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;/li&gt;
&lt;li&gt;세부 종류 :&lt;br /&gt;&amp;nbsp;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;이산형(Discrete Data) : 셀 수 있는 뚜렷한 값으로 구성된 데이터 (예 : 주사위 숫자, 결혼 횟수)&lt;/li&gt;
&lt;li&gt;연속형(Continuous Data) : 범위 내에서 어떤 값이든 취할 수 있는 데이터 (예 : 키, 몸무게, 온도, 시간)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;분석 방법 :&lt;br /&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&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;히스토그램: 데이터 값들의 분포를 시각화하는 방법 (plt.hist)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;범주형 데이터&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의 : &lt;span style=&quot;background-color: #181a1b; color: #d3cfc9; text-align: left;&quot; data-darkreader-inline-bgcolor=&quot;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;숫자로 측정하고 표시하는 것이 불가능한 데이터&lt;/li&gt;
&lt;li&gt;특징 :&lt;br /&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;값 사이에 명확한 경계 존재&lt;/li&gt;
&lt;li&gt;측정 오차 영향 미미&lt;/li&gt;
&lt;li&gt;일반적으로 빈도, 비율 등 집계 함수 활용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;세부 종류 :&lt;br /&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;명목형: 순서 없는 범주형 데이터 (예: 성별, 혈액형)&lt;/li&gt;
&lt;li&gt;순서형: 순서가 있는 범주형 데이터 (예: Likert 척도, 학년)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;분석 방법 :&lt;br /&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;빈도: 특정 카테고리에 속하는 데이터의 개수&lt;/li&gt;
&lt;li&gt;비율: 특정 카테고리에 속하는 데이터의 비율&lt;/li&gt;
&lt;li&gt;분포 그래프: 범주별 데이터 분포를 시각화하는 방법&lt;/li&gt;
&lt;li&gt;파이&amp;nbsp;차트:&amp;nbsp;범주별&amp;nbsp;비율을&amp;nbsp;시각화하는&amp;nbsp;방법&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #e8e6e3; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터프레임 변경&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;1. 일부 열 이름 변경&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;rename()메서드 사용&lt;/li&gt;
&lt;li&gt;변경 전후 열 이름 딕셔너리 형태로 나열&lt;/li&gt;
&lt;li&gt;inplace=True옵션으로 변경 사항 실제 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710070684573&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df.rename(columns={'total_bill_amount': 'total_bill',
                   'male_female': 'sex',
                   'smoke_yes_no': 'smoker',
                   'week_name': 'day',
                   'dinner_lunch': 'time'}, inplace=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;2. 모든 열 이름 변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;columns 속성 변경&lt;/li&gt;
&lt;li&gt;변경 필요 없는 열은 기존 이름 부여&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710070787008&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df.columns = ['고객ID', '상품명', '구매수량', '구매금액', '구매날짜']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3.&amp;nbsp;열&amp;nbsp;추가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로운 열 추가하여 계산된 결과값 저장&lt;/li&gt;
&lt;li&gt;insert() 메서드 사용하여 원하는 위치에 열 추가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710070828131&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df['final_amt'] = df['total_bill'] + df['tip']
df.insert(1, '주문시간', df['구매날짜'])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;4.&amp;nbsp;열&amp;nbsp;삭제&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;drop() 메서드 사용&lt;/li&gt;
&lt;li&gt;axis=0: 행 삭제 (기본값)&lt;/li&gt;
&lt;li&gt;axis=1: 열 삭제&lt;/li&gt;
&lt;li&gt;inplace=True 옵션으로 실제 반영&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710070857140&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df.drop('구매날짜', axis=1, inplace=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;5.&amp;nbsp;범주값&amp;nbsp;변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;map() 메서드 사용&lt;/li&gt;
&lt;li&gt;replace() 메서드도 유사&lt;/li&gt;
&lt;li&gt;&lt;b&gt;map()은 매칭하지 못한 값을 결측치로 변환하고, replace는 기존의 값을 그대로 사용&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710071003027&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df['성별'] = df['성별'].map({'남성': 'M', '여성': 'F'})
df['성별'] = df['성별'].replace({'남성': 'M', '여성': 'F'})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6.&amp;nbsp;범주값&amp;nbsp;만들기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;연속값을 구간 나누어 범주값 표현 (이산화)&lt;/li&gt;
&lt;li&gt;cut(), qcut() 함수 사용&lt;/li&gt;
&lt;li&gt;cut() : 크기를 기준으로 구간을 나누고 싶을 때 사용&lt;/li&gt;
&lt;li&gt;qcut() : 개수를 기준으로 구간을 나누고 싶을 때 사용&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710071134071&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
import numpy as np

df = pd.DataFrame({
    &quot;나이&quot;: [20, 25, 30, 35, 40, 45, 50, 55, 60],
    &quot;성별&quot;: [&quot;남성&quot;, &quot;여성&quot;, &quot;남성&quot;, &quot;여성&quot;, &quot;남성&quot;, &quot;여성&quot;, &quot;남성&quot;, &quot;여성&quot;, &quot;남성&quot;],
    &quot;소득&quot;: [1000, 2000, 3000, 5000, 5000, 6000, 7000, 8000, 9000]
})

df['연령구간_qcut'] = pd.qcut(df['나이'], 4, labels=['20대', '30대', '40대', '50대'])
df['연령구간_cut'] = pd.cut(df['나이'], bins=[-np.inf, 20, 30, 40, np.inf], 
						   labels=['20대', '30대', '40대', '50대'])

print(df)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 152px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 16px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 16px; text-align: center;&quot;&gt;qcut&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 16px; text-align: center;&quot;&gt;cut&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;기준&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;데이터 개수&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px; text-align: center;&quot;&gt;데이터 크기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 76px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 76px; text-align: center;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 76px; text-align: center;&quot;&gt;각 구간에 동일한 개수의 데이터가 들어가므로 비교 분석에 유리&lt;br /&gt;&lt;br /&gt;특정 값 이상/이하 구간 설정 가능&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 76px; text-align: center;&quot;&gt;특정 범위를 쉽게 설정 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px; text-align: center;&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px; text-align: center;&quot;&gt;구간 크기가 불균일할 수 있음&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px; text-align: center;&quot;&gt;데이터 개수가 적으면 구간이 왜곡될 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 함수를 사용할지는 데이터의 특성과 분석 목적에 따라 결정해야 한다. 데이터 개수가 많고 비교 분석을 하고 싶을 때는 qcut을 사용하는 것이 좋다. 혹은, 특정 범위를 설정하고 싶거나 데이터 개수가 적을 때는 cut을 사용하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;7. 결측치 확인/처리&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;isnull(), notnull() 메서드로 결측치 확인&lt;/li&gt;
&lt;li&gt;dropna()로 결측치 제거&lt;br /&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;axis=0: 행 제거 (기본값)&lt;/li&gt;
&lt;li&gt;axis=1: 열 제거&lt;/li&gt;
&lt;li&gt;inplace=True 옵션으로 실제 반영&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #c8c3bc; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot;&gt;fillna()로 결측치 값 대체&lt;/span&gt;&lt;span style=&quot;color: #c8c3bc; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #c1bcb4;&quot; data-darkreader-inline-color=&quot;&quot;&gt;method = 'ffill' 혹은 method = 'bfill'로 바로 앞의 값 혹은 다음 값으로 변경 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710071350927&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 결측치 개수 확인
df.isnull().sum()
df.notnull().sum()

# 결측치 삭제
df.dropna(axis=0, inplace=True)

# 결측치 대체
df['나이'].fillna(df['나이'].mean(), inplace=True)
df['성별'].fillna('미상', method = 'bfill', inplace=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 다른 방법으로, interpolate() 메서드가 있다. interpolate() 메서드는 결측치를 선형 보간법으로 채우는 데 사용할 수 있다. 선형 보간법은 두 개의 알려진 값을 이용하여 그 사이의 값을 추정하는 방법이다. 단, 주변 값이 정확하지 않거나 결측치의 개수가 많은 경우에는 선형 보간법이 데이터의 정확도를 저하시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710123780949&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df = pd.DataFrame({
    &quot;A&quot;: [1, 2, np.nan, 4, 5],
    &quot;B&quot;: [5, np.nan, np.nan, 8, 9],
    &quot;C&quot;: [9, 10, 11, 12, 13]
})

df = df.interpolate()

print(df)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8.&amp;nbsp;가변수&amp;nbsp;만들기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;범주형 데이터를 숫자로 변환&lt;/li&gt;
&lt;li&gt;get_dummies() 함수 사용&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #c8c3bc; text-align: left;&quot; data-darkreader-inline-color=&quot;&quot;&gt;다중공선성 문제 방지 위해 drop_first=True 옵션 사용&lt;/span&gt;&lt;span style=&quot;color: #c8c3bc; text-align: left;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #c8c3bc; text-align: left;&quot; data-darkreader-inline-color=&quot;&quot;&gt;one-hot-encoding으로 column 생성&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710071462581&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df = pd.get_dummies(df, columns=['성별', '결혼여부'], drop_first=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;One-Hot Encoding은 &lt;b&gt;범주형 변수를 숫자로 변환하는 방법&lt;/b&gt;이다. 각 범주에 대해 새로운 열을 만들고, 해당 범주에 속하는 경우 1, 그렇지 않으면 0으로 표현한다. 즉, 새로운 열이 많아진다. 범주가 늘어날수록 열들은 상관관계를 가지게 되는데, 이러한 상황을 다중공선성(Multicollinearity) 문제라고 한다.&lt;br /&gt;&lt;br /&gt;다중공선성 문제는 다음과 같은 문제를 야기한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;모델의 정확도 감소&lt;/li&gt;
&lt;li&gt;모델 계산 과정에서 불안정성 발생&lt;/li&gt;
&lt;li&gt;모델 해석의 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다중공선성 문제를 해결하기 위해 drop_first로 One-Hot Encoding 과정에서 만들어진 새로운 열 중 하나를 제거하거나, Ridge 혹은 Lasso와 같은 선형회귀 모델을 사용하여 다중공선성을 완화할 수 있다. 혹은 VIF(&lt;span style=&quot;background-color: #181a1b; color: #c8c3bc; text-align: left;&quot; data-darkreader-inline-bgcolor=&quot;&quot; data-darkreader-inline-color=&quot;&quot;&gt;Variance Inflation Factor)를 확인해서 변수를 제거해도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c54F3M/btsFF8KJdi0/iB7GeuRoqN8pE7qDMStBY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c54F3M/btsFF8KJdi0/iB7GeuRoqN8pE7qDMStBY1/img.png&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;399&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;45.9&quot; width=&quot;665&quot; height=&quot;441&quot; style=&quot;width: 45.3672%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c54F3M/btsFF8KJdi0/iB7GeuRoqN8pE7qDMStBY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc54F3M%2FbtsFF8KJdi0%2FiB7GeuRoqN8pE7qDMStBY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7uWAo/btsFHtgn36A/2tejkLBS7z1pHMDcpf93vK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7uWAo/btsFHtgn36A/2tejkLBS7z1pHMDcpf93vK/img.png&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;478&quot; data-is-animation=&quot;false&quot; style=&quot;width: 53.47%;&quot; data-widthpercent=&quot;54.1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7uWAo/btsFHtgn36A/2tejkLBS7z1pHMDcpf93vK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7uWAo%2FbtsFHtgn36A%2F2tejkLBS7z1pHMDcpf93vK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;850&quot; height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;L1 norm(왼쪽), L2 norm(오른쪽)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ridge : L2 정규화를 사용하여 모델 계수의 제곱합을 페널티 항으로 추가(모델 계수를 작게 만듦)&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Lasso : L1 정규화를 사용하여 모델 계수의 절댓값 합을 페널티 항으로 추가(일부 모델 개수를 0으로 만듦)&lt;/li&gt;
&lt;li&gt;Elastic Net : L1 정규화와 L2 정규화를 함께 사용하여 모델 계수 조절&lt;/li&gt;
&lt;li&gt;VIF : 회귀 계수의 분산(불확실성)이 다중공선성으로 인해 얼마나 증가했는지 나타내는 척도로, 일반적으로 VIF가 10보다 크면 문제가 있다고 판단&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백터 공간은 벡터의 집합과 벡터 간의 연산(덧셈, 곱셈)으로 구성된다. 여기서 벡터는 크기와 방향을 가진 대상이고, 벡터 공간에서 벡터의 크기를 나타내는 방법 중 하나가 Norm이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;L1 Norm : 벡터의 각 성분의 절댓값을 더한 값으로, outlier에 큰 영향을 받는다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;L2 Norm : 벡터의 각 성분을 제곱하여 더한 뒤, 제곱근을 취한 값으로, euclidean distance와 일치한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터프레임 병합&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. concat()&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;concat() 함수는 데이터프레임을 이어붙이는 데 사용된다. 기본적으로 index를 기준으로 이어붙이기 때문에, 동일한 열 이름을 가진 데이터프레임을 수직 또는 수평으로 연결할 때 사용된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;axis : 결합할 축을 지정한다. 기본값은 0이며, 0 또는 1을 선택할 수 있다. 0은 열 방향, 1은 행 방향을 의미한다.&lt;/li&gt;
&lt;li&gt;join : 결합 방식을 지정한다. 기본값은 'outer' 이며, outer, inner, left, right 중 하나를 선택할 수 있다,&lt;/li&gt;
&lt;li&gt;ignore_index : 결합 후 인덱스를 유지할지 여부를 지정한다. default는 False이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710125852736&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df1 = pd.DataFrame({&quot;A&quot;: [1, 2], &quot;B&quot;: [3, 4]})
df2 = pd.DataFrame({&quot;C&quot;: [5, 6], &quot;D&quot;: [7, 8]})

# 열 방향 결합
df = pd.concat([df1, df2], axis=1)

print(df)

# 결과
#   A  B  C  D
# 0  1  3  5  7
# 1  2  4  6  8

# 행 방향 결합
df = pd.concat([df1, df2], axis=0)

print(df)

# 결과
#   A  B
# 0  1  3
# 1  2  4
# 2  5  7
# 3  6  8&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. merge()&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;merge는 2개의 DataFrame을 공통된 Key를 기준으로 결합하는 방법이다,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;on : 결합 기준이 되는 열 이름을 지정&lt;/li&gt;
&lt;li&gt;how : 결합 방식을 지정한다. default는 inner이며, outer / inner / left / right 중 하나를 선택&lt;/li&gt;
&lt;li&gt;left_on : 왼쪽 &lt;span style=&quot;color: #c8c3bc; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot;&gt;DataFrame의 결합 기준 열 이름을 지정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #c8c3bc; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot;&gt;right_on : 오른쪽 &lt;span style=&quot;color: #c8c3bc; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot;&gt;DataFrame의 결합 기준 열 이름을 지정&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #c8c3bc; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span style=&quot;color: #c8c3bc; text-align: start;&quot; data-darkreader-inline-color=&quot;&quot;&gt;suffixes : 결합 후 열 이름 충돌 시 접미사를 지정&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1710126396059&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 왼쪽 데이터 프레임과 오른쪽 데이터 프레임의 모든 데이터를 포함
df = pd.merge(df1, df2, how=&quot;outer&quot;)

# 왼쪽 데이터 프레임과 오른쪽 데이터 프레임의 일치하는 데이터만 포함
df = pd.merge(df1, df2, how=&quot;inner&quot;)

# 왼쪽 데이터 프레임의 모든 데이터와 오른쪽 데이터 프레임에서 일치하는 데이터만 포함
df = pd.merge(df1, df2, how=&quot;left&quot;)

# 오른쪽 데이터 프레임의 모든 데이터와 왼쪽 데이터 프레임에서 일치하는 데이터만 포함
df = pd.merge(df1, df2, how=&quot;right&quot;)

# 왼쪽 데이터 프레임의 &quot;id&quot; 열과 오른쪽 데이터 프레임의 &quot;code&quot; 열을 기준으로 결합
df = pd.merge(df1, df2, left_on=&quot;id&quot;, right_on=&quot;code&quot;)

# 결합 후 열 이름 충돌 시 &quot;_x&quot; 및 &quot;_y&quot; 접미사를 지정
df = pd.merge(df1, df2, on=&quot;id&quot;, suffixes=[&quot;_x&quot;, &quot;_y&quot;])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. join()&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;merge와 join은 병합하는 기능에서 동일한 기능을 제공하지만, 어떤 데이터를 기준으로 병합할지에 대한 주의가 필요하다. 특히, 고객 정보와 상품 정보 테이블을 결합하는 경우, 상품 정보를 기준으로 결합하면 구매 이력이 없는 고객은 사라지게 된다. 이는 분석 목적에 따라 데이터를 올바르게 결합해야 함을 의미한다. 따라서, 어떤 데이터를 기준으로 결합할지를 결정할 때에는 분석 목적과 원하는 결과에 대해 신중히 고려해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0gvyB/btsFGDwZ4sJ/QosWOhO5vzmekyhCyVQSuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0gvyB/btsFGDwZ4sJ/QosWOhO5vzmekyhCyVQSuK/img.png&quot; data-alt=&quot;Join CheetSheet&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0gvyB/btsFGDwZ4sJ/QosWOhO5vzmekyhCyVQSuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0gvyB%2FbtsFGDwZ4sJ%2FQosWOhO5vzmekyhCyVQSuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;991&quot; height=&quot;689&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Join CheetSheet&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;left: 왼쪽 데이터 프레임의 모든 데이터를 포함하고, 오른쪽 데이터 프레임에서 일치하는 데이터만 포함&lt;/li&gt;
&lt;li&gt;right: 오른쪽 데이터 프레임의 모든 데이터를 포함하고, 왼쪽 데이터 프레임에서 일치하는 데이터만 포함&lt;/li&gt;
&lt;li&gt;outer: 왼쪽 데이터 프레임과 오른쪽 데이터 프레임의 모든 데이터를 포함하고, 일치하지 않는 데이터는 NaN으로 채움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사진 출처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stats.stackexchange.com/questions/347257/geometrical-interpretation-of-l1-regression&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stats.stackexchange.com/questions/347257/geometrical-interpretation-of-l1-regression&amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.researchgate.net/figure/Illustration-for-geometric-interpretation-L-VS-L2-norm_fig1_328588491&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.researchgate.net/figure/Illustration-for-geometric-interpretation-L-VS-L2-norm_fig1_328588491&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://opentutorials.org/course/195/1409&quot;&gt;https://opentutorials.org/course/195/1409&lt;/a&gt;&lt;/p&gt;</description>
      <category>Aivle/Python</category>
      <category>aivle</category>
      <category>pandas</category>
      <category>python</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/73</guid>
      <comments>https://hr1588.tistory.com/73#entry73comment</comments>
      <pubDate>Fri, 8 Mar 2024 16:00:09 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 제어문과 함수</title>
      <link>https://hr1588.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자료형을 정리했으니, 이제 자료형을 활용하는 방안을 정리해보자. 여러가지 방법이 있지만, 이번 포스팅에서는 제어문과 함수를 사용해 원하는 결과를 출력해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python에서는 코드의 실행 흐름을 제어하기 위해 '제어문'을 사용한다. 주로 조건 및 반복 처리를 위한 logic 작성에 필요하며, 들여쓰기를 통해 블럭을 지정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;if문&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;if문은 특정 조건이 만족될 때 코드를 실행하는 제어문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;단순 if문 : 조건이 참일 경우에만 처리하고, 조건이 거짓인 경우에는 아무런 처리도 하지 않는다.&lt;/li&gt;
&lt;li&gt;if ~ else문 : 조건이 참인 경우와 거짓인 경우를 각각 처리한다.&lt;/li&gt;
&lt;li&gt;if ~ elif ~ else문 : 여러 조건 중 참인 경우를 각각 처리하며, 모든 조건이 거짓인 경우에 대한 처리도 가능하다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1709516812065&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 단순 if문
x = 10
if x &amp;gt; 0:
    print(&quot;x는 양수입니다.&quot;)

# if ~ else문
if x &amp;gt; 0:
    print(&quot;x는 양수입니다.&quot;)
else:
    print(&quot;x는 0 또는 음수입니다.&quot;)

# if ~ elif ~ else문
if x &amp;gt; 0:
    print(&quot;x는 양수입니다.&quot;)
elif x == 0:
    print(&quot;x는 0입니다.&quot;)
else:
    print(&quot;x는 음수입니다.&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;For문&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문은 첫 번째 값부터 마지막 값까지 하나씩 가져가며 코드를 반복 처리하는 제어문이다. if문, range() 함수와 함께 사용할 수도 있다. 또한, 리스트와 딕셔너리의 요소를 대상으로 반복 처리도 되는데, 예제로 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;기본 반복문 : range() 함수로 지정된 범위, 리스트의 첫 번째 요소부터 마지막 요소까지 등 정해진 대상안에서 코드를 반복 처리한다.&lt;/li&gt;
&lt;li&gt;enumerate() : 문자열이나 컨테이너 자료형을 입력받아, 순번과 요소를 포함하는 object를 반환한다.&lt;/li&gt;
&lt;li&gt;List Comprehension(반복문 확장) : Python에서 리스트를 생성하는 간결하고 효율적인 방법으로, 기본 for-loop 문법을 사용하여 표현하는 것보다 간단하게 표현할 수 있어 가독성이 높아진다. 또한, 실행 속도 면에서도 보통의 for문보다 빠르다는 장점이 있다. [표현식 for 아이템 in 반복가능객체 if 조건문] 형식을 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;딕셔너리를 반복문에 사용할 때는 key와 value를 반환하는 items() 메서드를 많이 사용한다. 리스트와 동일하게 반복문 확장을 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;집합도 리스트, 딕셔너리와 동일하게 for문을 이용하여 반복 작업을 수행할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1709516947132&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 단순 for문
for i in range(5):
    print(i)       # 출력 : 0,1,2,3,4

# 기본 반복문
my_list = [1, 2, 3, 4, 5]
for i in my_list:
    print(i)

# enumerate() 함수 사용
for i, value in enumerate(my_list):
    print(f&quot;인덱스 {i}의 값은 {value}입니다.&quot;) # 출력 : 인덱스 0의 값은 1입니다.

# List Comprehension(반복문 확장)

for i in my_list:
	if i % 2 == 0 :
    	print(i**2)

squared = [i**2 for i in my_list if i%2==0]
print(squared) # 출력 : [4, 16]

# 딕셔너리와 for문
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key, value in my_dict.items():
    print(f&quot;키 {key}의 값은 {value}입니다.&quot;)
    
# 집합과 for문
my_set = {1, 2, 3, 4, 5}
for i in my_set:
    print(i)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;While문&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while문은 조건문이 참인 동안 코드를 계속해서 반복 실행하는 제어문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;일반 while문 : 문자열 길이를 반환하는 len() 함수를 활용하는 등 연산자를 사용해 특정 조건으로 반복문이 실행된다.&lt;/li&gt;
&lt;li&gt;무한루프 : While문은 조건문이 참이고, 특정 조건을 지정하지 않으면 무제한으로 실행된다. 만약 반복문 안에서 특정 조건이 되어 반복문을 빠져나오게 하려면 break 문을 사용해야하고, 반복문을 중단시키지 않고 특정 조건에서 다음 반복으로 넘어갈 때는 continue 문을 사용한다. 또한, input() 함수를 사용해 사용자의 입력을 받을 수도 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제와 함께 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709518074930&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 일반 while문
i = 0
while i &amp;lt; 5:
    print(i)
    i += 1

# 무한루프 다루기
while True:
    user_input = input(&quot;숫자를 입력하세요: &quot;)
    if user_input.isnumeric():
        print(&quot;입력하신 숫자는&quot;, user_input, &quot;입니다.&quot;)
        break
    else:
        print(&quot;숫자가 아닙니다. 다시 입력해주세요.&quot;)
        continue&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;isnumeric() 함수는 user_input에 입력받은 변수가 숫자인지를 판별한다. 만약 input() 함수에 숫자를 입력하면 break로 반복문을 빠져나오고, 숫자가 아닌 다른 값을 입력하면 print()문을 출력하고 continue문으로 숫자를 입력할 때까지 반복이 계속된다고 해석하면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;함수&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python의 함수는 입력을 받아 처리한 후 그 결과를 반환하는 역할을 한다. 내장 함수와 사용자 지정 함수가 있으며, 함수를 사용하면 같은 로직을 반복적으로 코딩하는 것을 피할 수 있다. 먼저, 사용자 정의 함수에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용자 정의 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 정의 함수는 def 키워드로 정의하며, 기본적으로 다음 세 가지로 구성된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력(Input) : 매개변수로 표현하며, 생략 가능&lt;/li&gt;
&lt;li&gt;처리 : 함수 내부에서 실행&lt;/li&gt;
&lt;li&gt;출력(Output) : 처리 결과로, return 키워드를 사용하여 반환(생략 가능). 만약 return 문이 없다면, 함수는 None을 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 함수의 매개변수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709519143182&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def greet(name):
    &quot;&quot;&quot;이름을 인자로 받아 인사말을 출력하는 함수&quot;&quot;&quot;
    print(f&quot;Hello, {name}!&quot;)

greet(&quot;Alice&quot;)  # 출력: Hello, Alice!

def hello(name='여러분'):
    print(f'{name}님 안녕하세요? 반갑습니다!')
    
hello() # 출력 : 여러분님 안녕하세요? 반갑습니다!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 name을 매개변수라고 한다. 매개변수는 함수의 입력으로 사용되며, 함수를 호출할 때 값을 전달받는다. 여기서 name의 default 값을 지정할 수도 있는데, default를 가진 매개변수를 기본 인수(Default Argument)라고 한다. 아래의 함수는 매개변수 name에 값을 전달하지 않아도, '여러분' 이라는 기본값을 사용하여 결과를 출력한다. 하지만, default 값과 매개변수를 입력한 경우의 고정된 출력값이 같아서, 출력된 값의 문맥이 이상한 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 매개변수의 순서&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709520540968&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def hello(name = '여러분', loud=0):
    if loud == 1:
        print(f'우~~와~~ {name}님 안녕하세요? 반갑습니다!!!')
    else:
        print(f'{name} 안녕하세요? 반가워요.')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 문제를 해결하기 위해 매개변수의 순서에 따라 값을 전달할 수 있으며, 이를 &lt;b&gt;위치 인수&lt;/b&gt;라고 한다. 또한, 매개변수 이름을 직접 지정하여 값을 전달하는 방식을 키워드 인수(keyword Argument)라고 한다.&amp;nbsp; 함수에서는 name 매개변수에 이름을, loud 매개변수에 1 또는 0을 전달할 수 있다. if문으로 loud default를 지정한 결과, name의 default 값과 매개변수를 입력한 경우가 다르게 출력되어 문제를 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 가변인수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709520653509&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def hello(*args):
    for who in args:
        print(f'{who}님 안녕하세요? 반갑습니다!')

hello('홍길동', '일지매', '강우동')

# 홍길동님 안녕하세요? 반갑습니다!
# 일지매님 안녕하세요? 반갑습니다!
# 강우동님 안녕하세요? 반갑습니다!

# for문을 안쓰면?

def hello(*args):
    print(args)

hello('홍길동', '일지매', '강우동')

# ('홍길동', '일지매', '강우동')
# for문을 안쓰면, 여러 개의 값이 하나의 Tuple로 출력됨

# list

def hello(*args):
    for who in args:
        print(f'{who}님 안녕하세요? 반갑습니다!')

# 함수 사용
member = ['김밍밍', '김아드', '장우동']
hello(member) # list를 사용하면, for문으로 돌아가는게 아니라 list가 하나로 출력됨
hello(member[0],member[1],member[2])
hello(*member) # * 인수를 사용하면, 인덱싱 없이 편리하게 처리가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가변 인수는 함수에 임의 개수의 값이 매개변수로 전달되는 것을 말한다. **args 형태로 표현되며, 함수 내부에서는 리스트나 튜플처럼 처리된다. 위의 함수는 임의 개수의 이름을 전달받아 각각에 대해 인사말을 출력한다. 반복문의 사용여부, 인수에 따라 결과값이 달라지기 때문에 개별 문법에 주의해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 가변 인수와 위치 인수의 활용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python에서는 가변 인수와 위치 인수를 함께 사용할 수 있다. 단, 위치 인수는 가변 인수 앞에 위치해야 한다. 아래 함수에서는 '선생님' 이라는 위치 인수와 3명의 사람 이름을 가변 인수로 사용했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709527023981&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def hello(title, *args):
    for who in args:
        print(f'{who}{title} 안녕하세요? 반갑습니다!')

hello('선생님', '김밍밍', '김아드', '최윤')  

# 출력
# 김밍밍선생님 안녕하세요? 반갑습니다!
# 김아드선생님 안녕하세요? 반갑습니다!
# 최윤선생님 안녕하세요? 반갑습니다!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, 위치와 키워드에 따라 오류가 발생할 수 있는데, 오류가 발생하는 경우는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위치 인수가 가변 인수 앞에 있는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #3b3f4e; color: #ffffff; text-align: left;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;python&quot; style=&quot;background-color: #1e1e1e; color: #dcdcdc; text-align: left;&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;def hello(title, *args):
    for who in args:
        print(f'{who}{title} 안녕하세요? 반갑습니다!')
 
# 함수 호출 시 keyword 오류 발생
hello(title='선생님', '홍길동', '일지매', '강우동')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가변 인수 뒤에 위치 인수를 두는 경우, 반드시 뒤에 있는 인수는 키워드 인수로 사용해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709527382867&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 함수 정의 시 오류 발생
def hello(*args, title):
    for who in args:
        print(f'{who}{title} 안녕하세요? 반갑습니다!')

# 오류 해결
def hello(*args, title):
    for who in args:
        print(f'{who}{title} 안녕하세요? 반갑습니다!')

hello('김밍밍', '김아드', '최윤', title='선생님')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;내장 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python은 사용자를 위한 많은 내장 함수를 제공한다. 수많은 함수 중, 중요하다고 생각하는 함수를 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;abs(x) : x의 절대값 반환&lt;/li&gt;
&lt;li&gt;all(x) : x의 요소 모두가 참이면 True 반환&lt;/li&gt;
&lt;li&gt;any(x) : x의 요소 중 하나라도 참이면 True 반환&lt;/li&gt;
&lt;li&gt;chr(x) : 아스키 코드값 x에 대응하는 문자 반환&lt;/li&gt;
&lt;li&gt;dir(x) : 객체 x가 가지고 있는 변수가 메서드 목록을 반환&lt;/li&gt;
&lt;li&gt;divmod(x,y) : x를 y로 나눈 몫과 나머지를 튜플 형태로 반환&lt;/li&gt;
&lt;li&gt;enumerate(x) : 리스트, 튜플, 문자열을 받아 인덱스와 값 반환&lt;/li&gt;
&lt;li&gt;eval(x) : 실행 가능한 문자열 x를 받아 그 문자열을 실행한 결과를 반환&lt;/li&gt;
&lt;li&gt;id(x) : 객체 x의 고유 주소값을 반환&lt;/li&gt;
&lt;li&gt;input() : 사용자로부터 입력을 받는다.(입력 받은 값은 언제나 문자열)&lt;/li&gt;
&lt;li&gt;isinstance(x,y) : x가 y의 인스턴스인지 여부를 True, False로 구분&lt;/li&gt;
&lt;li&gt;len(x) : x 요소들의 개수를 반환&lt;/li&gt;
&lt;li&gt;map(f,x) : 함수 f에 x 요소를 하나씩 전달해 얻은 결과를 반환&lt;/li&gt;
&lt;li&gt;min(x) : x 요소들 중 최솟값을 반환&lt;/li&gt;
&lt;li&gt;ord(x) : 문자 x의 아스키 코드값을 반환&lt;/li&gt;
&lt;li&gt;pow(x,y) : x를 y번 제곱한 결과를 반환&lt;/li&gt;
&lt;li&gt;range(x,y,z) : x부터 y-1까지 z씩 증가하는 객체를 반환&lt;/li&gt;
&lt;li&gt;sorted(x) : x 요소를 정렬하여 반환&lt;/li&gt;
&lt;li&gt;str(x) : x를 문자열로 변환하여 반환&lt;/li&gt;
&lt;li&gt;sum(x) : x의 요소를 모두 더한 결과를 반환&lt;/li&gt;
&lt;li&gt;tuple(x) : x를 튜플로 변환하여 반환&lt;/li&gt;
&lt;li&gt;zip(x,y) : x와 y 요소를 쌍으로 묶어서 반환&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Aivle/Python</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/72</guid>
      <comments>https://hr1588.tistory.com/72#entry72comment</comments>
      <pubDate>Mon, 4 Mar 2024 05:27:49 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 컨테이너 자료형</title>
      <link>https://hr1588.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 포스팅에서 Python의 기초가 되는 변수 선언부터, 함수와 메서드의 차이까지 알아보았다. 이번 포스팅에서는 우리가 가장 많이 사용할 컨테이너 자료형에 대해 알아보자. 컨테이너 자료형이란 여러 값을 묶어서 갖는 자료형으로, list, tuple, set, Dictionary가 여기에 해당한다. 먼저, 가장 많이 사용되는 list에 대해 정리해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;list(리스트)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;리스트는 여러 값을 묶어서 갖는 컨테이너 자료형으로, 대괄호([ ]) 안에 콤마로 구분한 값을 나열하여 생성한다. 리스트의 요소로는 어떤 데이터도 올 수 있으며, 리스트 자체도 요소가 될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;1. 리스트 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;비어있는 리스트를 만들 수도 있고, 같은 자료형이나 여러 자료형의 데이터를 요소로 갖는 리스트를 만들 수 있다. 또한, 리스트를 요소로 갖는 리스트를 만들 수도 있다. 연속된 정수로 리스트를 만들 때는 range() 함수를 사용하면된다. range() 함수의 문법은 다음과 같으며, 이후 포스팅할 반복문에서도 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;range(n) : 0부터 n-1까지의 정수 범위&lt;/li&gt;
&lt;li&gt;range(m,n) : m부터 n-1까지의 정수 범위가 된다.&lt;/li&gt;
&lt;li&gt;range(m,n,x) : m부터 n-1까지 x만큼의 증가하는 정수가 된다. x를 음수로 설정하면, 점점 값이 작아진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709498048776&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 비어있는 리스트 생성
empty_list = []
print(empty_list)  # 출력: []

# 여러 자료형을 갖는 리스트 생성
varied_list = [1, &quot;two&quot;, 3.0, True]
print(varied_list)  # 출력: [1, 'two', 3.0, True]

# 리스트를 요소로 갖는 리스트 생성
nested_list = [1, 2, [3, 4, 5]]
print(nested_list)  # 출력: [1,2, [3, 4, 5]]

# range() 함수를 사용한 리스트 생성
range_list = list(range(10))
range_list2 = list(range(1,10,2))

print(range_list)  # 출력: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(range_list2)  # 출력: [1, 3, 5, 7, 9]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;2. 리스트 인덱싱&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;특정 요소를 찾기 위해 인덱스를 사용하는 과정을 인덱싱이라고 한다. 인덱스는 대괄호([ ]) 안에 지정하며, 순방향 인덱스는 0부터 시작하고, 역방향 인덱스는 -1부터 시작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709498213768&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 리스트 인덱싱
print(varied_list[0])  # 출력: 1
print(varied_list[-1])  # 출력: True&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;3. 리스트 슬라이싱&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;인덱스를 사용하여 특정 범위의 요소를 찾는 과정을 슬라이싱이라고 한다. 대괄호 안에 [m:n] 형태로 범위를 지정하여 요소를 확인할 수 있다. 인덱스 m부터 n-1까지의 결과가 포함되며, 인덱스 n의 요소는 결과에 포함되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709498282880&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 리스트 슬라이싱
print(varied_list[1:3])  # 출력 ['two', 3.0]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;4. 리스트 연산&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;더하기는 리스트의 결합을, 곱하기는 문자열과 동일하게 리스트의 반복을 의미한다. 단, 빼기와 나누기 연산은 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709498299521&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 리스트 더하기
added_list = varied_list + [False, &quot;end&quot;]
print(added_list)  # 출력: [1, 'two', 3.0, True, False, 'end']

# 리스트 곱하기
multiplied_list = varied_list * 2
print(multiplied_list)  # 출력: [1, 'two', 3.0, True, 1, 'two', 3.0, True]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;5. 요소 변경, 추가, 삭제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;인덱싱 또는 슬라이싱 결과에 대해 요소를 변경하거나 삭제할 수 있다. 이 때, append(), remove() 메서드를 사용하여 요소를 추가 또는 삭제할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709498359643&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 요소 변경
varied_list[0] = &quot;one&quot;
print(varied_list)  # 출력: ['one', 'two', 3.0, True]

# 요소 추가
varied_list.append(&quot;end&quot;)
print(varied_list)  # 출력: ['one', 'two', 3.0, True, 'end']

# 요소 삭제
varied_list.remove(&quot;end&quot;)
print(varied_list)  # 출력: ['one', 'two', 3.0, True]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;6. 리스트 관련 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;count() : 특정 요소의 개수 반환&lt;/li&gt;
&lt;li&gt;index() : 특정 요소의 인덱스 반환&lt;/li&gt;
&lt;li&gt;append() : 리스트의 마지막에 요소를 추가&lt;/li&gt;
&lt;li&gt;extend() : 리스트 뒤에 리스트를 붙일 수 있음. 이 때, 2차원 리스트가 아닌 1차원 리스트로 결합&lt;/li&gt;
&lt;li&gt;reverse() : 리스트의 요소 순서를 역순으로 변경&lt;/li&gt;
&lt;li&gt;sort(reverse=False) : 리스트의 요소를 오름차순으로 정렬, 내림차순은 reverse = True 사용. 단, 리스트 요소들의 자료형이 다른 경우 정렬 불가&lt;/li&gt;
&lt;li&gt;insert() : 리스트의 특정 인덱스에 요소 추가&lt;/li&gt;
&lt;li&gt;remove() : 리스트에서 특정 요소 삭제&lt;/li&gt;
&lt;li&gt;pop() : 리스트의 마지막 요소를 제거하고, 그 요소를 반환&lt;/li&gt;
&lt;li&gt;clear() : 리스트의 모든 요소 제거&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Tuple(튜플)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;튜플은 리스트와 매우 비슷한 자료형으로, 소괄호(( ))를 사용하여 표현한다. 튜플의 가장 큰 특징은 한 번 생성하면 요소의 값을 바꿀 수 없다는 것이다. 또한, 튜플의 인덱싱, 슬라이싱, 연산 방법은 리스트와 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;1. 튜플 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;리스트와 마찬가지로 여러 자료형의 데이터를 요소로 갖는 튜플을 만들 수 있다. &lt;b&gt;단, 요소가 하나인 튜플을 만들 때는 콤마를 추가하여 만들어야 한다.&lt;/b&gt; 소괄호를 생략할 수 있으므로, 여러 변수에 동시에 값을 대입하거나, 두 변수의 값을 교환하거나, 함수 리턴값을 두 변수에 대입하는 등의 활용이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709498848325&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 튜플 생성
my_tuple = (1, 2, 3)

# 여러 자료형을 갖는 튜플
mixed_tuple = (1, &quot;Hello&quot;, True)

# 요소가 하나인 튜플 생성
single_tuple = (1,)  # 괄호와 콤마를 함께 사용
not_tuple = (90)     # 콤마가 빠지면, 정수형 변수가 선언

# 소괄호 생략
multiple_assignment = 1, 2, 3
print(multiple_assignment)  # 출력: (1, 2, 3)

# range() 함수 사용
nums = tuple(range(5))
print(nums) # (0,1,2,3,4)

# 두 변수의 값 교환
a = 1
b = 2
a, b = b, a
print(a, b)  # 출력: 2 1

# 튜플 인덱싱
print(my_tuple[0])  # 출력: 1

# 튜플 슬라이싱
print(my_tuple[1:3])  # 출력: (2, 3)

# 튜플 연산
print(my_tuple + (4, 5))  # 출력: (1, 2, 3, 4, 5)
print(my_tuple * 2)  # 출력: (1, 2, 3, 1, 2, 3)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Set(집합)&lt;/b&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;집합은 중복을 허용하지 않고, 순서가 없는 자료형이다. 이로 인해 인덱싱과 슬라이싱으로 값을 얻을 수 없다. 주로 교집합, 합집합, 차집합, 대칭 차집합 등의 집합 연산을 위해 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;1. 집합 생성 및 변환&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;set() 함수를 사용하여 다른 자료형을 집합으로 변환할 수 있다. 또한, 집합을 리스트나 튜플로 변환할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709499222781&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 집합 생성
my_set = set([1, 2, 3, 4, 5])

# 리스트를 집합으로 변환
my_list = [1, 2, 2, 3, 3, 3]
list_to_set = set(my_list)
print(list_to_set)  # 출력: {1, 2, 3}

# 집합을 리스트로 변환
set_to_list = list(list_to_set)
print(set_to_list)  # 출력: [1, 2, 3]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;2. 집합 활용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이전 포스팅에서 소개한 함수와 연산자로 집합의 정보를 확인할 수 있다. len() 함수로 집합에 포함된 원소 개수를 확인할 수 있고, in 연산자로 특정 요소가 집합에 속해 있는지 확인할 수 있다. 또한, 집합의 특성을 활용하여 리스트나 튜플에서 중복된 요소를 제거할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709499274420&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 집합의 요소 개수 확인
print(len(my_set))  # 출력: 5

# 특정 요소가 집합에 포함되어 있는지 확인
print(1 in my_set)  # 출력: True

# 리스트에서 중복된 요소 제거
unique_list = list(set(my_list))
print(unique_list)  # 출력: [1, 2, 3]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 집합 연산&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;합집합(| 또는 union()), 교집합(&amp;amp; 또는 intersection()), 차집합(- 또는 difference()), 대칭 차집합(^ 또는 symmetric_difference()) 등의 연산이 가능하다. 대칭 차집합이란, 합집합에서 교집합을 제외한 나머지를 뜻한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1709499434794&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;set1 = set([1, 2, 3])
set2 = set([2, 3, 4])

# 합집합
print(set1 | set2)  # 출력: {1, 2, 3, 4}
print(set1.union(set2))

# 교집합
print(set1 &amp;amp; set2)  # 출력: {2, 3}
print(set1.intersection(set2))

# 차집합
print(set1 - set2)  # 출력: {1}
print(set1.difference(set2))

# 대칭 차집합
print(set1 ^ set2)  # 출력: {1, 4}
print(set1.symmetric_difference(set2))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;4. 집합 관련 메서드&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;add() : 집합에 요소 추가&lt;/li&gt;
&lt;li&gt;update() : 집합에 여러 요소를 추가, 리스트 사용&lt;/li&gt;
&lt;li&gt;pop() : 집합에서 임의의 요소를 제거하고, 그 요소를 반환&lt;/li&gt;
&lt;li&gt;remove() : 집합에서 특정 요소 제거. 단, 요소가 없는 경우 error 발생&lt;/li&gt;
&lt;li&gt;discard() : 집합에서 특정 요소 제거. 단, 요소가 없어도 작동&lt;/li&gt;
&lt;li&gt;clear() : 모든 요소 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709499622875&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;my_set = {1, 2, 3}
my_set.add(4)
print(my_set)  # 출력: {1, 2, 3, 4}

my_set = {1, 2, 3}
my_set.update([4, 5, 6])
print(my_set)  # 출력: {1, 2, 3, 4, 5, 6}

my_set = {1, 2, 3}
my_set.remove(4)
print(my_set)  # 출력: Keyerror

my_set = {1, 2, 3}
my_set.discard(4)
print(my_set)  # 출력: {1, 2, 3}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Dictionary(딕셔너리)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딕셔너리는 키(Key)와 값(Value)의 쌍을 요소로 가지는 자료형이다. 중괄호({ })를 사용하여 선언하며, 키를 통해 값을 확인할 수 있다. 단, 딕셔너리는 집합과 동일하게 순서의 의미가 없어 인덱싱과 슬라이싱은 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;1. 딕셔너리 생성 및 변환&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;다양한 자료형을 키와 값으로 가질 수 있으며, dict() 함수를 사용하여 다른 자료형을 딕셔너리로 변환할 수 있다. 단, 키는 변경 가능한 자료형은 사용할 수 없으므로 리스트는 키로 사용할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709499742732&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 딕셔너리 생성
my_dict = {&quot;name&quot;: &quot;John&quot;, &quot;age&quot;: 30, &quot;city&quot;: &quot;New York&quot;}

# 다양한 자료형을 가진 딕셔너리
mixed_dict = {1: &quot;one&quot;, &quot;two&quot;: 2, 3.0: &quot;three&quot;}

# 리스트를 딕셔너리로 변환
list_to_dict = dict([(1, &quot;one&quot;), (2, &quot;two&quot;)])
print(list_to_dict)  # 출력: {1: 'one', 2: 'two'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;2. 딕셔너리 조회 및 변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;키를 사용하여 값을 찾을 수 있으며, in 연산자를 사용하여 해당 키의 존재 여부를 확인할 수 있다. 또한, 키를 이용하여 값을 변경하거나 추가할 수 있고, del 문이나 pop(), popitem() 메서드를 사용하여 요소를 삭제할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709499782913&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 키를 사용하여 값 조회
print(my_dict[&quot;name&quot;])  # 출력: 'John'

# in 연산자를 사용하여 키 존재 여부 확인
print(&quot;name&quot; in my_dict)  # 출력: True

# 값 변경
my_dict[&quot;name&quot;] = &quot;Jane&quot;
print(my_dict)  # 출력: {'name': 'Jane', 'age': 30, 'city': 'New York'}

# 값 추가
my_dict[&quot;country&quot;] = &quot;USA&quot;
print(my_dict)  # 출력: {'name': 'Jane', 'age': 30, 'city': 'New York', 'country': 'USA'}

# 요소 삭제
del my_dict[&quot;country&quot;]
print(my_dict)  # 출력: {'name': 'Jane', 'age': 30, 'city': 'New York'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;3. 딕셔너리 관련 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;keys() : 딕셔너리의 모든 키를 반환&lt;/li&gt;
&lt;li&gt;values() : 딕셔너리의 모든 값을 반환&lt;/li&gt;
&lt;li&gt;items() : 딕셔너리의 모든 key-value 쌍을 반환&lt;/li&gt;
&lt;li&gt;clear() : 딕셔너리의 모든 요소 제거&lt;/li&gt;
&lt;li&gt;get() : 딕셔너리에서 특정 키에 대한 값을 반환, 키가 없는 경우 None을 return&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709499913802&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}

print(my_dict.keys())  # 출력: dict_keys(['name', 'age', 'city'])
print(my_dict.values())  # 출력: dict_values(['John', 30, 'New York'])
print(my_dict.items())  # 출력: dict_items([('name', 'John'), ('age', 30), ('city', 'New York')])
my_dict.clear()
print(my_dict)  # 출력: {}

my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}
print(my_dict.get('name'))  # 출력: 'John'
print(my_dict.get('country'))  # 출력: None&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Aivle/Python</category>
      <category>python</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/71</guid>
      <comments>https://hr1588.tistory.com/71#entry71comment</comments>
      <pubDate>Sat, 2 Mar 2024 17:00:24 +0900</pubDate>
    </item>
    <item>
      <title>[에이블스쿨] 자료형</title>
      <link>https://hr1588.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Python에는 여러가지 자료형이 있다. 이번 포스팅에서는 기초적인 변수 선언부터, 중간에 의문을 가졌던 함수와 메소드의 차이를 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;변수&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변수는 값을 담는 그릇으로, 재사용을 위한 목적으로 사용된다.&lt;/li&gt;
&lt;li&gt;변수 선언은 &quot;변수 = 값&quot; 형태로 이뤄진다.&lt;/li&gt;
&lt;li&gt;변수의 이름은 다른 사람이 봐도 해당 변수의 의미를 알 수 있도록, 적절한 단어를 사용하는 것이 좋다.&lt;/li&gt;
&lt;li&gt;변수에 대입된 값에 의해 변수의 자료형이 결정된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709492102706&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
# 변수 선언
my_var = 10
print(my_var) # 출력 : 10
type(my_var) # int&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;키워드&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python&amp;nbsp;키워드는&amp;nbsp;자체&amp;nbsp;사용&amp;nbsp;목적으로&amp;nbsp;이미&amp;nbsp;예약된&amp;nbsp;문자열로,&amp;nbsp;변수나&amp;nbsp;함수&amp;nbsp;이름&amp;nbsp;등의&amp;nbsp;식별자로&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;없다.&lt;/p&gt;
&lt;pre id=&quot;code_1709492132958&quot; class=&quot;python&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# Python 키워드 확인
import keyword
print(keyword.kwlist)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;식별자&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;식별자는 변수나 함수 등의 이름을 위해 사용하는 단어&lt;/li&gt;
&lt;li&gt;식별자는 특정 규칙을 가지며, 대/소문자를 구분하므로 주로 소문자 사용이 권장된다. 가독성을 위해 언더바(_)와 영어 단어를 적절히 섞어 사용하는 것이 좋다.&lt;/li&gt;
&lt;li&gt;키워드, 특수 문자(언더바 제외), 공백 포함, 숫자 시작 금지&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;연산자&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python은&amp;nbsp;일반적으로&amp;nbsp;알고&amp;nbsp;있는&amp;nbsp;연산&amp;nbsp;방법과,&amp;nbsp;값을&amp;nbsp;비교하거나&amp;nbsp;대입하는&amp;nbsp;등&amp;nbsp;다양한&amp;nbsp;연산자를&amp;nbsp;가지고&amp;nbsp;있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;산술 연산자 : 사칙연산(+, - ,* , /), 몫(//), 나머지(%), 제곱(**) 연산자&lt;/li&gt;
&lt;li&gt;비교 연산자 : 같음(=), 같지 않음(!=)으로 True or False를 반환&lt;/li&gt;
&lt;li&gt;복합 대입 연산자 : 연산과 대입을 동시에 수행&lt;/li&gt;
&lt;li&gt;논리 연산자 : and, or, not으로 두 개 이상의 조건을 연결&lt;/li&gt;
&lt;li&gt;멤버 연산자 : in, not in으로 어떤 값이 특정 객체의 요소인지 확인&lt;/li&gt;
&lt;li&gt;식별 연산자 : is, is not으로 두 객체가 동일한 객체인지 확인, 값의 같음을 비교하는 비교 연산자와는 조금 다른 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709492698272&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 산술 연산자

a//b # 몫
a % b # 나머지
a ** 2 # 제곱

# 비교 연산자
a == b # &quot;같다&quot; 비교

# 문자열 비교
s1 = 'A'
s2 = 'a'

print(s1 == s2) # False
print(s1 &amp;lt; s2)  # True

# ASCII 값 비교
print(ord('A'), ord('a'))

# 복합 대입 연산자
val = 7

val += 7
val -= 2
val *= 2
val /= 5

print(val) # 4.8

# 논리 연산자
a = 10
print(a &amp;gt;= 7 and a &amp;lt;= 12) # True

b = 15
print(3 &amp;lt;= b &amp;lt;= 12) # False

# 멤버 연산자
d = [13,52,647,2]

print(13 in d) # True
print(41 not in d) # True

# 식별 연산자
x = [1,3,5]
y = [1,3,5]
z = x

print(x == y) # True
print(x == z) # True

print(x is y) # False
print(x is z) # True&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;P&lt;/span&gt;ython은 ASCII Code에 따라 문자의 대문자와 소문자를 비교하는 경우 소문자의 값이 더 크다고 출력한다. &lt;/span&gt;ASCII 코드는 컴퓨터에서 문자를 표현하는 표준적인 방법이다. 각 문자는 고유의 숫자값을 가지며, 이 숫자값은 컴퓨터가 문자를 인식하고 처리하는 데 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영문 대문자와 소문자의 ASCII 값은 다르게 설정되어 있다. 대문자 'A'의 ASCII 값은 65이고, 소문자 'a'의 ASCII 값은 97이다. 따라서 Python은 문자의 대소 비교에서 알파벳 순서가 아닌, ASCII 값에 따라 소문자를 대문자보다 큰 값으로 판단한다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기본 자료형&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정수형: 음의 정수, 0, 양의 정수를 포함하며, 정수 끼리의 연산 결과가 실수가 될 수 있다.&lt;/li&gt;
&lt;li&gt;실수형: 소수점을 표시할 수 있는 숫자를 포함&lt;/li&gt;
&lt;li&gt;부울형: 논리 자료형으로, 참(True)과 거짓(False)을 나타내는 자료형이다. 주로 조건문이나 반복문에 사용된다.&lt;/li&gt;
&lt;li&gt;자료형 변환: float(), int(), str(), bool() 함수를 사용해 자료형을 변환&lt;/li&gt;
&lt;li&gt;날짜 시간 자료형: Python은 기본적으로 날짜와 시간 관련 자료형을 제공하지 않으므로, 필요할 경우 datetime 라이브러리를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709493567579&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 정수형
integer = 10
print(type(integer))  # 출력: &amp;lt;class 'int'&amp;gt;

# 실수형
floating_point = 10.5
print(type(floating_point))  # 출력: &amp;lt;class 'float'&amp;gt;

# 부울형
boolean = True
print(type(boolean))  # 출력: &amp;lt;class 'bool'&amp;gt;

# 자료형 변환
string = &quot;100&quot;
print(type(string))  # 출력: &amp;lt;class 'str'&amp;gt;
converted = int(string)
print(type(converted))  # 출력: &amp;lt;class 'int'&amp;gt;

# 날짜 시간 자료형
from datetime import datetime

current_datetime = datetime.datetime.now()
print(current_datetime)  # 출력: 현재 날짜와 시간

date_only = current_datetime.date()
print(date_only)  # 출력: 현재 날짜

time_only = current_datetime.time()
print(time_only)  # 출력: 현재 시간

# 날짜 시간 정보 표시
print('날짜와 시간:', dt)
print('년:', dt.year)
print('월:', dt.month)
print('일:', dt.day)
print('시:', dt.hour)
print('분:', dt.minute)
print('초:', dt.second)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문자열 자료형&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 문자열 자료형&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Python에서 문자열은 큰 따옴표나 작은 따옴표를 사용해 표현&lt;/li&gt;
&lt;li&gt;문자열 길이는 len() 함수를 이용해 확인&lt;/li&gt;
&lt;li&gt;문자열 나열은 콤마 없이 나열하여 합치거나, 콤마로 구분하여 튜플 형태로 제작&lt;/li&gt;
&lt;li&gt;여러 줄 문자열은 따옴표 세 개나 \n을 사용해 표현할 수 있으며, print() 함수를 통해 출력&lt;/li&gt;
&lt;li&gt;문자열에 따옴표를 넣을 때는 큰 따옴표 안에 작은 따옴표를, 작은 따옴표 안에 큰 따옴표를 사용하거나, \' 또는 \&quot;를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709494344320&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 문자열 선언
my_str = &quot;Hello, World!&quot;

# 문자열 길이 확인
print(len(my_str))  # 출력: 13

# 여러 줄 문자열
multi_str = &quot;&quot;&quot;Hello,
World!&quot;&quot;&quot;
print(multi_str)

# 따옴표를 포함한 문자열
quote_str = 'He said, &quot;Hello, World!&quot;'
print(quote_str)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. format 메서드&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자열 일부분을 변경하며 재사용할 때는 문자열 포맷팅을 사용하며, 이는 문자열.format() 형태로 사용&lt;/li&gt;
&lt;li&gt;format 메서드는 대부분 print() 함수 안에서 사용됨&lt;/li&gt;
&lt;li&gt;format 메서드로 출력되는 값 순서, 자리수 등을 제어할 수 있으며, 최근에는 f-string이 많이 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709494595844&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import math

# format 메서드 사용
formatted_str = &quot;Hello, {}!&quot;.format(&quot;Python&quot;)
print(formatted_str)  # 출력: Hello, Python!

# f-string 사용
name = &quot;Python&quot;
f_str = f&quot;Hello, {name}!&quot;
print(f_str)  # 출력: Hello, Python!

# 세밀한 출력
print('{:.5f}'.format(math.pi)) # 소수점 자리수 제한(3.14159)

print('[{0}] [{1}]'.format('빵빵이', 150)) # 위치 지정
print('[{0:10}] [{1:6}]'.format('빵빵이', 120)) # 기본 정렬
print('[{0:&amp;gt;10}] [{1:&amp;lt;6}]'.format('빵빵이', 1700)) # 오른쪽, 왼쪽 정렬
print('[{0:^10}] [{1:^6}]'.format('빵빵이', 3200)) # 가운데 정렬

print('[{0:-^10}] [{1:_^6}]'.format('빵빵이', 200)) # 공백 다른 문자로 채우기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 문자열 인덱싱 및 슬라이싱&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자열은 문자 요소가 모여 만들어진 자료형이며, 인덱싱과 슬라이싱으로 특정 요소나 범위의 요소를 조회&lt;/li&gt;
&lt;li&gt;인덱스는 0부터 시작하며, 문자열 인덱싱과 슬라이싱은 리스트와 비슷한 특성을 가짐&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709494611921&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 문자열 인덱싱
print(my_str[0])  # 출력: H

# 문자열 슬라이싱
print(my_str[0:5])  # 출력: Hello
print(my_str[-1])   # 출력: !&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 문자열 관련 주요 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대/소문자 변환: capitalize(), title(), upper(), lower() 사용&lt;/li&gt;
&lt;li&gt;자릿수 지정과 정렬: rjust(x), ljust(x), center(x) 사용&lt;/li&gt;
&lt;li&gt;일부 변경 및 제거: replace(x, y), strip(x) 사용&lt;/li&gt;
&lt;li&gt;분리와&amp;nbsp;연결:&amp;nbsp;split(x),&amp;nbsp;x.join(s)&amp;nbsp;사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709494634135&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 대/소문자 변환
print(my_str.upper())  # 출력: HELLO, WORLD!
print(my_str.lower())  # 출력: hello, world!

# 정렬
print(my_str.center(20))  # 출력:   Hello, World!   

# 일부 변경 및 제거
print(my_str.replace(&quot;World&quot;, &quot;Python&quot;))  # 출력: Hello, Python!

# 분리와 연결
split_str = my_str.split(&quot;, &quot;)
print(split_str)  # 출력: ['Hello', 'World!']
joined_str = &quot;, &quot;.join(split_str)
print(joined_str)  # 출력: Hello, World!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료형에서 메서드와 함수라는 용어가 계속 반복되고 있다. 두 개 모두 특정 작업을 수행하는 코드의 집합이지만, 분명한 차이가 존재한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수(Function)&lt;/b&gt; : 함수는 특정 작업을 수행하는 독립적인 코드의 묶음이다. 함수는 입력값을 받아 처리하고, 결과를 반환하는 역할을 수행한다. Python은 기본적으로 print()와 같은 내장 함수(built-in-function)를 제공하며, 필요한 경우 def 구문을 활용해 사용자 정의 함수(user-defined-function)으로 함수를 정의할 수 있다. &lt;b&gt;함수는 독립적으로 존재하므로, 객체의 상태에 직접 접근할 수 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메서드(Method)&amp;nbsp;&lt;/b&gt;: 메서드는 클래스(Class)에 속한 함수를 말하며, 해당 클래스의 instance(객체)에서만 호출할 수 있다. 메서드는 self라는 특별한 인자를 통해 객체의 속성이나 다른 메서드에 접근할 수 있다. &lt;b&gt;즉, 객체의 상태를 변경하거나 객체의 행동을 조절하는 역할을 수행한다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1709495893394&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 함수 정의: 리스트를 받아 새로운 리스트를 반환하는 함수
def append_number_func(lst):
    new_lst = lst.copy()
    new_lst.append(10)
    return new_lst

# 함수 호출
original_list = [1, 2, 3]
result_function = append_number_func(original_list)
print(&quot;Original list after function: &quot;, original_list)
print(&quot;Function result: &quot;, result_function)


# 클래스 정의: 리스트를 속성으로 가지고, 메서드를 통해 리스트 속성을 변경하는 클래스
class MyClass:
    def __init__(self, lst):
        self.lst = lst

    def append_number_method(self):
        self.lst.append(10)
        return self.lst

# 클래스의 인스턴스 생성
my_class = MyClass([1, 2, 3])

# 메서드 호출
result_method = my_class.append_number_method()
print(&quot;Original list after method: &quot;, my_class.lst)
print(&quot;Method result: &quot;, result_method)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Original&amp;nbsp;list&amp;nbsp;after&amp;nbsp;function:&amp;nbsp;&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3] &lt;br /&gt;Function&amp;nbsp;result:&amp;nbsp;&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3,&amp;nbsp;10] &lt;br /&gt;Original&amp;nbsp;list&amp;nbsp;after&amp;nbsp;method:&amp;nbsp;&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3,&amp;nbsp;10] &lt;br /&gt;Method&amp;nbsp;result:&amp;nbsp;&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3,&amp;nbsp;10]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드를 실행하면, append_number_func() 함수는 원본 list에 변화를 주지 않고 새로운 리스트를 반환한다. 반면, MyClass Class의 append_number_method() 메서드는 객체의 list 속성 자체를 변경하는 것을 확인할 수 있다.&lt;/p&gt;</description>
      <category>Aivle/Python</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/70</guid>
      <comments>https://hr1588.tistory.com/70#entry70comment</comments>
      <pubDate>Thu, 29 Feb 2024 22:17:50 +0900</pubDate>
    </item>
    <item>
      <title>[Retention] 리텐션</title>
      <link>https://hr1588.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;예전 게임 사용자 분석을 하면서, KPI 포스팅을 진행했었다. 이번 포스팅에서는 Retention에 대해 다시 한 번 정리하고, 상황에 따라 어떤 방법을 사용해야할지 생각해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AARRR&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/32N4G/btsEXvleNck/DnIE4pb832XONdcftrtdc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/32N4G/btsEXvleNck/DnIE4pb832XONdcftrtdc0/img.png&quot; data-alt=&quot;AARRR&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/32N4G/btsEXvleNck/DnIE4pb832XONdcftrtdc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F32N4G%2FbtsEXvleNck%2FDnIE4pb832XONdcftrtdc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;363&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AARRR&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 특정 서비스를 사용하기 시작하면, 우리는 사용자의 이용 현황을 파악하고 그에 맞는 전략을 세워야한다. 이 때, AARRR을 사용할 수 있다. AARRR은 사용자 획득부터 전파까지 5단계의 유저 여정을 체계화한 프레임워크이다. 깔대기 모양으로 표현되며, 상단(사용자 획득)에서 아래 단계(전파)로 갈수록 유저 수가 감소하는 구조를 가지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Acquisition (사용자 획득): 광고, 홍보 등을 통해 새로운 사용자를 유치&lt;/li&gt;
&lt;li&gt;Activation (사용자 활성화): 획득된 사용자가 서비스의 핵심 가치를 경험하도록 유도&lt;/li&gt;
&lt;li&gt;Retention (사용자 유지): 활성화된 사용자가 서비스를 지속적으로 사용하도록 유지&lt;/li&gt;
&lt;li&gt;Revenue (매출): 사용자에게 서비스 이용 가치를 제공하고 대가를 받음&lt;/li&gt;
&lt;li&gt;Referral (전파): 만족한 사용자가 다른 사람들에게 서비스를 추천&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 쇼핑몰 서비스에 AARRR을 적용하면 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Acquisition: 검색 광고, SNS 광고 등을 통해 잠재 고객 유치&lt;/li&gt;
&lt;li&gt;Activation: 첫 구매 할인 쿠폰 제공, 제품 추천 기능 활용&lt;/li&gt;
&lt;li&gt;Retention: 개인화된 상품 추천, 멤버십 프로그램 운영&lt;/li&gt;
&lt;li&gt;Revenue: 상품 판매, 배송비 부과&lt;/li&gt;
&lt;li&gt;Referral:&amp;nbsp;친구&amp;nbsp;추천&amp;nbsp;프로그램&amp;nbsp;운영,&amp;nbsp;고객&amp;nbsp;후기&amp;nbsp;공유&amp;nbsp;기능&amp;nbsp;제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AARRR의 과정은 모두 중요하지만, 오늘은 Retention에 주목해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;리텐션(Retention)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리텐션은 사용자들이 서비스를 지속적으로 사용하는지 측정하는 지표이다. '방문', '특정 페이지 방문', '특정 기능 사용' 등 상황에 맞춰 다양한 로그를 활용하여 측정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 클래식 리텐션(Classic Retention)&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래식 리텐션은 일정 기간(일, 주, 월등) 동안 서비스를 이용한 사용자의 비율을 계산하는 방법이다. 이 방법은 주로 &lt;b&gt;매일 접속해서 사용할 것으로 기대되는 서비스(SNS 등)&lt;/b&gt;에 활용된다. 클래식 리텐션은 일정 기간 동안의 사용자 이용 패턴을 측정하므로, 매일 활용되는 서비스에서는 상당히 유용한 방법이다. 하지만, 사용 주기가 긴 서비스에서 사용자 유지 여부를 판단할 때 실제보다 훨씬 과소 계산될 수 있다는 단점도 존재한다. 즉, 주기적으로 사용되지 않는 서비스에서는 다른 방법을 사용해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.&amp;nbsp;롤링&amp;nbsp;리텐션(Rolling&amp;nbsp;Retention)&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤링 리텐션은 기준일을 포함하여 그 이후에 한 번이라도 재방문한 사용자의 비율을 나타내는 방법이다. 이 방법은 &lt;b&gt;사용 빈도가 높지 않은 서비스(여행 서비스, 쇼핑몰 등)&lt;/b&gt;에서 유용하게 활용된다. 특히, 사용자들의 이후 접속에 따라 기존 리텐션 값이 얼마든지 달라질 수 있다는 점에 주의해야한다. 이 방법은 사용자의 재방문 여부에 초점을 맞추므로, 사용 빈도가 낮은 서비스에서는 이 방법을 사용하면 더 정확한 값을 측정할 수 있다. 하지만, 롤링 리텐션의 특성상 리텐션이 개선되고 있는지에 대한 해석은 어려울 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 범위 리텐션(Range Retention)&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;범위&amp;nbsp;리텐션은&amp;nbsp;클래식&amp;nbsp;리텐션을&amp;nbsp;유연하게&amp;nbsp;확장한&amp;nbsp;개념으로,&amp;nbsp;구간을&amp;nbsp;나누어&amp;nbsp;계산하는&amp;nbsp;방법이다.&amp;nbsp;이&amp;nbsp;방법은&amp;nbsp;노이즈에&amp;nbsp;강하며,&amp;nbsp;서비스&amp;nbsp;사용주기가&amp;nbsp;길거나&amp;nbsp;주기적인&amp;nbsp;서비스에서&amp;nbsp;많이&amp;nbsp;사용된다.&amp;nbsp;범위&amp;nbsp;리텐션은&amp;nbsp;클래식&amp;nbsp;리텐션의&amp;nbsp;한계를&amp;nbsp;보완하여,&amp;nbsp;사용자의&amp;nbsp;이용&amp;nbsp;패턴에&amp;nbsp;따라&amp;nbsp;유연하게&amp;nbsp;리텐션을&amp;nbsp;측정할&amp;nbsp;수&amp;nbsp;있다.기간을&amp;nbsp;나눴기&amp;nbsp;때문에&amp;nbsp;우연히&amp;nbsp;하루정도&amp;nbsp;접속을&amp;nbsp;안&amp;nbsp;했다&amp;nbsp;하더라도,&amp;nbsp;리텐션에&amp;nbsp;영향을&amp;nbsp;주지&amp;nbsp;않는다. &lt;br /&gt;&lt;br /&gt;클래식&amp;nbsp;리텐션과&amp;nbsp;롤링&amp;nbsp;리텐션은&amp;nbsp;바로&amp;nbsp;이해했는데,&amp;nbsp;범위&amp;nbsp;리텐션은&amp;nbsp;정확히&amp;nbsp;이해가&amp;nbsp;되지&amp;nbsp;않아서&amp;nbsp;데이터리안&amp;nbsp;블로그의&amp;nbsp;글을&amp;nbsp;보고&amp;nbsp;직접&amp;nbsp;예시를&amp;nbsp;만들어보았다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;2월&amp;nbsp;8일에&amp;nbsp;사용자&amp;nbsp;A,B,C,D,E,F,G가&amp;nbsp;우리&amp;nbsp;서비스에&amp;nbsp;가입했다고&amp;nbsp;가정해보자.&amp;nbsp;데이터를&amp;nbsp;3일씩&amp;nbsp;묶어서&amp;nbsp;범위&amp;nbsp;리텐션을&amp;nbsp;계산하면,&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;결과를&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 139px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;사용자&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;DAY 0&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;DAY 1&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;DAY 2&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;DAY 3&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;DAY 4&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;DAY 5&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 20px; text-align: center;&quot;&gt;DAY 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;A&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;B&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;C&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;D&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;E&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;F&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;G&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;방문&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 12.5%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;DAY 0&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;DAY 1 ~ 3&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;DAY 4 ~ 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;기간 내 방문유저수&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;범위 리텐션(%)&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;100%&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;43%&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;43%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Day 1~3 구간에 사용자 B,D,E가 방문했고 Day 4~6 구간에는 사용자 B,C,F가 방문했다. 2개의 구간 중 Day 4~6 구간에 더 많은 방문이 발생했지만 데이터를 요약하면서 두 구간 모두 범위 리텐션은 60%로 계산된다. 예시를 확인하고, 노이즈에 강한 이유를 이해할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사용자 지표&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리텐션도 중요하지만, 사용자 지표 역시 중요하다. 여러가지 지표 중, &lt;b&gt;DAU/WAU/MAU/Stickiness&lt;/b&gt;를 간단히 정리해보자. KPI 포스팅에서도 해당 주제를 다뤘지만, 서비스 내에서 사용자의 행태 분석은 이용자 수를 늘리고, 이탈 요인을 파악하는 데 필수적인 요소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DAU: 일간 활성 사용자 수&lt;/li&gt;
&lt;li&gt;WAU: 주간 활성 사용자 수&lt;/li&gt;
&lt;li&gt;MAU: 월간 활성 사용자 수&lt;/li&gt;
&lt;li&gt;Stickiness:&amp;nbsp;사용자&amp;nbsp;고착도,&amp;nbsp;DAU를&amp;nbsp;MAU&amp;nbsp;또는&amp;nbsp;WAU로&amp;nbsp;나누어&amp;nbsp;계산&lt;/li&gt;
&lt;li&gt;DAU/WAU 비율: 일간 활성 사용자가 주간 활성 사용자 대비 얼마나 일관적으로 서비스를 이용하는지 보여줌&lt;/li&gt;
&lt;li&gt;DAU/MAU&amp;nbsp;비율:&amp;nbsp;일간&amp;nbsp;활성&amp;nbsp;사용자가&amp;nbsp;월간&amp;nbsp;활성&amp;nbsp;사용자&amp;nbsp;대비&amp;nbsp;얼마나&amp;nbsp;자주&amp;nbsp;서비스를&amp;nbsp;이용하는지&amp;nbsp;보여줌&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어, 100명의 사용자가 매일 서비스를 이용하고 150명의 사용자가 1주일에 한 번 이상 서비스를 이용하고, 200명의 사용자가 한 달에 한 번 이상 서비스를 이용한다고 가정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DAU/WAU 비율이 0.66 (66%)으로, 일주일에 한 번 이상 서비스를 이용하는 사용자 중 66%가 매일 서비스를 이용하고 있다. DAU/MAU 비율은 0.5 (50%)으로, 한 달에 한 번 이상 서비스를 이용하는 사용자 중 50%가 매일 서비스를 이용한다고 해석할 수 있다. Stickness를 분석하면, 다양한 이벤트 혹은 UX 개선을 통해 신규 사용자를 늘리고 기존 사용자의 이탈을 막을 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번&amp;nbsp;포스팅을&amp;nbsp;통해&amp;nbsp;리텐션과&amp;nbsp;사용자&amp;nbsp;지표에&amp;nbsp;대해&amp;nbsp;알아보았다.&amp;nbsp;데이터리안&amp;nbsp;선미님의&amp;nbsp;글&amp;nbsp;추천으로&amp;nbsp;리텐션을&amp;nbsp;높이는&amp;nbsp;두&amp;nbsp;가지&amp;nbsp;방법,&amp;nbsp;즉&amp;nbsp;초기&amp;nbsp;이탈&amp;nbsp;사용자&amp;nbsp;감소와&amp;nbsp;사용자와의&amp;nbsp;장기&amp;nbsp;관계&amp;nbsp;유지에&amp;nbsp;대해&amp;nbsp;배울&amp;nbsp;수&amp;nbsp;있었다.&amp;nbsp;데이터&amp;nbsp;분석에&amp;nbsp;있어서는&amp;nbsp;단순히&amp;nbsp;숫자를&amp;nbsp;해석하는&amp;nbsp;것보다&amp;nbsp;서비스를&amp;nbsp;직접&amp;nbsp;이용하며&amp;nbsp;사용자의&amp;nbsp;시각을&amp;nbsp;이해하는&amp;nbsp;것이&amp;nbsp;중요하다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;사용자가&amp;nbsp;어떤&amp;nbsp;요소를&amp;nbsp;선호하고,&amp;nbsp;어떤&amp;nbsp;부분이&amp;nbsp;불편한지&amp;nbsp;파악할&amp;nbsp;수&amp;nbsp;있는데,&amp;nbsp;해당&amp;nbsp;방법이&amp;nbsp;리텐션을&amp;nbsp;파악하는&amp;nbsp;가장&amp;nbsp;효과적인&amp;nbsp;방법이라고&amp;nbsp;생각한다.&amp;nbsp;또한,&amp;nbsp;데이터&amp;nbsp;분석가로서의&amp;nbsp;입장에서는&amp;nbsp;리텐션의&amp;nbsp;수치뿐만&amp;nbsp;아니라,&amp;nbsp;그&amp;nbsp;결과를&amp;nbsp;어떻게&amp;nbsp;비즈니스에&amp;nbsp;적용하고,&amp;nbsp;데이터에&amp;nbsp;익숙하지&amp;nbsp;않은&amp;nbsp;동료나&amp;nbsp;고객에게&amp;nbsp;어떻게&amp;nbsp;전달할지에&amp;nbsp;대한&amp;nbsp;고민이&amp;nbsp;필요함을&amp;nbsp;느꼈다.&amp;nbsp;혹시&amp;nbsp;데이터&amp;nbsp;분석이나&amp;nbsp;마케팅에&amp;nbsp;관심이&amp;nbsp;있지만&amp;nbsp;리텐션에&amp;nbsp;대해&amp;nbsp;잘&amp;nbsp;알지&amp;nbsp;못하는&amp;nbsp;분들에게는&amp;nbsp;데이터리안&amp;nbsp;블로그의&amp;nbsp;글을&amp;nbsp;추천드리고&amp;nbsp;싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1708010580513&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;리텐션 (1) Classic Retention&quot; data-og-description=&quot;AARRR 프레임워크에서 가장 중요한 Retention, 사용자 유지와 관련한 지표 계산에 대해서 알아봅시다.&quot; data-og-host=&quot;datarian.io&quot; data-og-source-url=&quot;https://datarian.io/blog/classic-retention?utm_source=sql-camp&amp;amp;utm_medium=camp&amp;amp;utm_campaign=referral&amp;amp;utm_content=sql-advanced&quot; data-og-url=&quot;https://datarian.io/blog/classic-retention?utm_campaign=referral&amp;amp;utm_content=sql-advanced&amp;amp;utm_medium=camp&amp;amp;utm_source=sql-camp&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cmeULz/hyVjgUnpVI/K7U5Ry82n2YG5b0R5cwMm1/img.gif?width=1080&amp;amp;height=608&amp;amp;face=0_0_1080_608,https://scrap.kakaocdn.net/dn/nUJ06/hyVmU9US3A/Brkn0rkyjjDHInZiCe0rdK/img.jpg?width=2000&amp;amp;height=1357&amp;amp;face=0_0_2000_1357,https://scrap.kakaocdn.net/dn/KKFTW/hyVjb6BMUi/rZ1jCjCvp9hDUvJ8AYcGZK/img.png?width=450&amp;amp;height=641&amp;amp;face=0_0_450_641&quot;&gt;&lt;a href=&quot;https://datarian.io/blog/classic-retention?utm_source=sql-camp&amp;amp;utm_medium=camp&amp;amp;utm_campaign=referral&amp;amp;utm_content=sql-advanced&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://datarian.io/blog/classic-retention?utm_source=sql-camp&amp;amp;utm_medium=camp&amp;amp;utm_campaign=referral&amp;amp;utm_content=sql-advanced&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cmeULz/hyVjgUnpVI/K7U5Ry82n2YG5b0R5cwMm1/img.gif?width=1080&amp;amp;height=608&amp;amp;face=0_0_1080_608,https://scrap.kakaocdn.net/dn/nUJ06/hyVmU9US3A/Brkn0rkyjjDHInZiCe0rdK/img.jpg?width=2000&amp;amp;height=1357&amp;amp;face=0_0_2000_1357,https://scrap.kakaocdn.net/dn/KKFTW/hyVjb6BMUi/rZ1jCjCvp9hDUvJ8AYcGZK/img.png?width=450&amp;amp;height=641&amp;amp;face=0_0_450_641');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;리텐션 (1) Classic Retention&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AARRR 프레임워크에서 가장 중요한 Retention, 사용자 유지와 관련한 지표 계산에 대해서 알아봅시다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;datarian.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진 출처 -&amp;nbsp;&lt;a href=&quot;https://boomboomba.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://boomboomba.tistory.com/41&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data Science</category>
      <category>retention</category>
      <category>데이터리안</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/68</guid>
      <comments>https://hr1588.tistory.com/68#entry68comment</comments>
      <pubDate>Thu, 15 Feb 2024 23:34:17 +0900</pubDate>
    </item>
    <item>
      <title>[MySQL] - Placements</title>
      <link>https://hr1588.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;가장 친한 친구들이 자신보다 더 많은 월급을 제안 받은 학생들의 이름을 출력하시오. (단, 이름은 친한 친구들의 월급 순서로 오름차순 정렬하고, 두 학생 중 어떤 학생도 같은 월급을 제안 받지 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707400044647&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with my_salary as(
select s.id, s.name, p.salary
    from students s, packages p
    where s.id = p.id),
friends_salary as(
select f.id, f.friend_id, p.salary
    from friends f, packages p
    where f.friend_id = p.id
)

select name
	from my_salary s, friends_salary f
	where s.id = f.id and s.salary &amp;lt; f.salary
	order by f.salary&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CTE를 사용해 나의 정보 테이블을 하나 만들고, 친구의 정보 테이블을 하나 만들어 2개를 결합했다. 데이터가 적으면 이렇게 해결해도 되지만, 실무에서 데이터 많은 경우 이런 쿼리는 상당히 비효율적이다. 시간이 오래걸리고, 서버에 과부하를 주기 때문이다. 따라서 다른 사람들이 어떤 방법으로 문제를 풀었는지 찾아보고, 직접 실행해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707400671748&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select s.name
	from students s, friends f, packages p
	where s.id = f.id and s.id = p.id and
	p.salary &amp;lt; (select p2.salary from packages p2 where p2.id = f.friend_id)
order by (select p2.salary from packages p2 where p2.id = f.friend_id)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 CTE와 달리, 서브쿼리를 사용해 조건을 명시했다. 결과가 동일하더라도, 아래의 방식을 사용하면 훨씬 효율적으로 쿼리를 구성하고 보다 빨리 데이터를 추출할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서브쿼리(Subquery)&lt;/b&gt; : 서브쿼리는 쿼리 내부에 포함된 또 다른 쿼리이다. 메인 쿼리의 where이나 from 절에서 데이터를 필터링하거나 조작하는 데 사용할 수 있다. 2번째 예시의 경우도 where절과 order by에 subquery를 사용했다고 해석할 수 있다. 서브쿼리는 메인 쿼리가 실행되기 전에 먼저 실행되며, 그 결과는 메인 쿼리에 사용된다. 단일 행 또는 다중 행 결과를 반환하기 때문에, 상황에 맞게 활용하면된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CTE(Common Table Expressions)&lt;/b&gt; : 복잡한 쿼리를 단순하게 만들기 위한 &lt;b&gt;임시 테이블&lt;/b&gt;로 서브쿼리를 사용하는 것과 비슷하지만, CTE는 쿼리 내에서 여러 번 재사용할 수 있다는 점에서 차이가 있다. 또한, CTE는 가독성을 높이고, 재귀 쿼리(Recursive)를 사용할 수도 있다.&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <category>hackerrank</category>
      <category>mysql</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/67</guid>
      <comments>https://hr1588.tistory.com/67#entry67comment</comments>
      <pubDate>Thu, 8 Feb 2024 23:04:28 +0900</pubDate>
    </item>
    <item>
      <title>[RFM] 고객 세분화 분석이란?</title>
      <link>https://hr1588.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 데이터리안의 SQL 부트캠프를 수강하며, 데이터 분석가에게 필수적인 SQL 역량을 쌓고 있다. 이번 포스팅에서는 데이터리안 데이터 분석가 이보민님의 RFM 분석에 관한 글을 공부하고, 이전에 진행했던 톤쇼유 리뷰 실습을 떠올리며 관련 내용을 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RFM 분석?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l2Lsn/btsDJFiIUFT/Uvgy3v1ZmGZGUo9NnTkoZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l2Lsn/btsDJFiIUFT/Uvgy3v1ZmGZGUo9NnTkoZK/img.png&quot; data-alt=&quot;RFM 분석(출처 : 하단 URL)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l2Lsn/btsDJFiIUFT/Uvgy3v1ZmGZGUo9NnTkoZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl2Lsn%2FbtsDJFiIUFT%2FUvgy3v1ZmGZGUo9NnTkoZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;724&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RFM 분석(출처 : 하단 URL)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 비즈니스에는 수많은 고객들이 존재한다. RFM 분석이란 이러한 고객의 가치를 평가하기 위해 사용되는 마케팅 분석 도구이다. RFM은 Recency(최근성), Frequency(빈도), Monetary Value(구매금액)의 약자로, 고객의 구매 행동을 3가지 요소를 통해 분석한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Recency (최근성)&lt;/b&gt; : 고객이 마지막으로 구매한 날짜를 기준으로 측정한다. 최근에 구매한 고객일수록 높은 점수를 받는다. 이는 최근에 구매한 고객이 더 활동적이며, 향후 구매 확률이 높다고 가정한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Frequency (구매 빈도)&lt;/b&gt; : 고객이 얼마나 자주 구매하는지를 측정한다. 더 많이 구매한 고객은 더 높은 점수를 받는다. 이는 자주 구매하는 고객이 더 충성도가 높고, 앞으로도 지속적으로 구매할 가능성이 높다고 예측할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Monetary Value (구매 금액)&lt;/b&gt; : 고객이 얼마나 많은 돈을 소비하는지를 측정한다. 더 많은 돈을 소비한 고객은 더 높은 점수를 받는다. 이는 많은 돈을 소비하는 고객이 더 가치가 있다고 가정한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RFM 분석은 3가지 요소를 각각 점수화하여 고객을 여러 그룹으로 분류한다. 이렇게 분류한 후, 각 그룹에 대한 특정 마케팅 전략을 수립하거나, 더 높은 가치의 고객을 Targeting하는 방법을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcJhA2/btsDJfrhUqo/EEEfF0tajRrkVRVwoNpLRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcJhA2/btsDJfrhUqo/EEEfF0tajRrkVRVwoNpLRk/img.png&quot; data-alt=&quot;예시 Data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcJhA2/btsDJfrhUqo/EEEfF0tajRrkVRVwoNpLRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcJhA2%2FbtsDJfrhUqo%2FEEEfF0tajRrkVRVwoNpLRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;782&quot; height=&quot;241&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예시 Data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 사진은 톤쇼우 리뷰 분석에서 활용했던 데이터이다. 숫자가 높을수록 해당 영역에서 좋은 점수를 받은 것 이며, 최근에 구매를 진행한 고객들도 구매 빈도와 금액에 따라 세부적으로 분류할 수 있음을 확인할 수 있다. 그렇다면, R이 동일한 상황에서 우리는 F와 M 중 어떤 것에 더 주목해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RFM 분석 유의점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정답은 &quot;사용하는 데이터에 따라 상이하다&quot; 이다. 실제 분석 대상인 데이터는 우리의 생각보다 복잡하므로, 산업군이나 플랫폼에 따라 기준을 조절해야 한다. RFM 분석을 실제 환경에 적용하려면 다음 요소를 고려할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Recency, Frequency, Monetary의 분할 단계 설정 :&lt;/b&gt; RFM 각 요소를 몇 단계로 나눌지 결정해야 한다. 개별 요소를 3~5 단계로 나누는 것이 일반적이지만, 데이터의 특성과 기업 비즈니스 목표에 따라 달라진다. 너무 많은 단계로 나누면 분석이 복잡해질 수 있으므로, 적절한 균형을 찾는 것이 중요하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Frequency, Monetary 집계 기간 설정 :&lt;/b&gt; 기간 설정은 비즈니스의 특성, 제품의 생애 주기, 고객의 구매 패턴 등을 고려해야한다. 예를 들어, 패션 산업에서는 계절성을 고려할 수 있고, 자동차 산업은 자사 제품별 평균 수명을 고려해 기간을 설정할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;점수 부여 방식 :&lt;/b&gt; 일반적으로는 모든 요소에 동일한 가중치를 부여하지만, 비즈니스의 특성에 따라 각 요소의 중요도를 다르게 설정할 수도 있다. 예를 들어, 식품 및 음료 산업에서는 신제품 출시와 계절별 선호도 변화가 빈번하게 일어난다. 이러한 사업은 고객이 최신 제품이나 서비스를 구매하는 경향이 있기 때문에, Recency의 가중치를 높여서 분석할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;고객 세분화 방법 :&lt;/b&gt; RFM 분석 결과를 바탕으로 고객을 어떻게 세분화할지 결정해야 한다. 이는 고객 그룹의 수, 개별 그룹의 크기, 그룹 간의 차이 등을 고려할 수 있다. 숫자에 비해 그룹이 너무 많으면 관리가 어렵고, 고객 만족도가 떨어질 위험이 존재한다. 따라서 적절한 수의 그룹을 설정하는 것이 중요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RFM 분석은 단순히 구매 이력을 우리의 기준으로 분류하는 기법이다. 그렇다면, 우리는 분류한 결과를 어떻게 활용할 수 있을까? 많은 방법이 있지만, 그 중 STP 분석에 대해 소개하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;STP 분석&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpuetS/btsDGL5AXQY/LtkaRGcckXWlzYqghaRquk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpuetS/btsDGL5AXQY/LtkaRGcckXWlzYqghaRquk/img.png&quot; data-alt=&quot;STP 분석&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpuetS/btsDGL5AXQY/LtkaRGcckXWlzYqghaRquk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpuetS%2FbtsDGL5AXQY%2FLtkaRGcckXWlzYqghaRquk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;739&quot; height=&quot;317&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;STP 분석&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진은 &quot;제1회 KRX 금융 빅데이터 활용 아이디어 경진대회&quot;에서 활용했던 STP 분석의 예시이다. STP 분석은 Segmentation(세분화), Targeting(타겟팅), Positioning(포지셔닝)의 약자로, 고객의 다양한 특성에 따라 시장을 여러 부분으로 나누고, 특정 고객 그룹에 초점을 맞춰 그들의 요구와 선호에 맞는 전략을 세우는 방법이다. 대회에서는 RFM 분석을 직접적으로 사용하지는 않았지만, RFM 분석으로도 고객 층을 세분화하고, 고객의 행동과 가치를 이해하는데 활용될 수 있다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Segmentation(세분화)&lt;/b&gt; : 시장을 명확하게 정의된 부분으로 세분화하는 것 이다. 고객의 요구 사항, 선호도, 구매 패턴, 인구 특성 등으로 수행되며, RFM 점수를 기반으로 고객의 가치를 평가하고 그룹화할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Targeting(타겟팅)&lt;/b&gt; : 세분화된 시장 중에서 자사의 제품 혹은 서비스를 판매할 대상을 선택한다. 대표적으로 RFM 분석을 통해 얻은 그룹에서 가장 가치가 높은 그룹, 혹은 F,M은 높지만 R은 낮은 떠나간 충성 고객 등을 Target으로 선택할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Positioning(포지셔닝)&lt;/b&gt; : 선택한 Target 시장에서 어떻게 경쟁 우위를 차지할지 결정한다. 이는 고객에게 제품이나 서비스의 가치를 명확히 제안하고, 고객이 경쟁사의 상품이 아닌 우리의 상품을 써야할 이유를 만드는 과정이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 STP 분석과 RFM 분석은 각각 독립적으로 사용할 수 있지만, 두 분석을 결합하면 고객의 행동 패턴과 선호를 더욱 정확하게 파악하고, 이를 바탕으로 더 효과적인 마케팅 전략을 수립할 수 있다. 이렇게 RFM 분석을 활용하면, 고객의 가치를 효과적으로 평가하고, 고객 그룹에 따른 맞춤형 마케팅 전략을 수립하는 데 도움이 된다. 이를 통해 데이터 분석가는 고객의 만족도를 높이고, 기업의 매출을 증가시키는 데 기여할 수 있다. &lt;b&gt;단순히 분석에서 끝나는 것이 아니라, 실제 비즈니스에서 이를 어떻게 활용할 수 있는지에 대한 아이디어를 생각해보는 습관을 가지도록 하자.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;본 내용은 데이터리안 'SQL 데이터 분석 캠프 입문반' 을 수강하며 작성한 내용입니다. 좋은 글을 소개해주셔서 감사합니다 !&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출처 - 데이터 분석가 보민님&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705667272392&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;RFM 고객 세분화 분석이란 무엇일까요&quot; data-og-description=&quot;CRM 타겟팅을 하는 방식 중 가장 범용적으로 사용할 수 있는 RFM 고객 세분화 분석에 대해 알아보겠습니다&quot; data-og-host=&quot;datarian.io&quot; data-og-source-url=&quot;https://datarian.io/blog/what-is-rfm?utm_source=sql-camp&amp;amp;utm_medium=camp&amp;amp;utm_campaign=referral&amp;amp;utm_content=sql-basic&quot; data-og-url=&quot;https://datarian.io/blog/what-is-rfm?utm_campaign=referral&amp;amp;utm_content=sql-basic&amp;amp;utm_medium=camp&amp;amp;utm_source=sql-camp&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ZgvFB/hyU5UKXTU9/J3H18DgcrvaIdKt2TVqaRk/img.png?width=2000&amp;amp;height=1500&amp;amp;face=0_0_2000_1500,https://scrap.kakaocdn.net/dn/efzmgw/hyU5UKXTPD/ogKPyp81ZCdPfMcx86WDH1/img.png?width=849&amp;amp;height=850&amp;amp;face=232_132_597_530,https://scrap.kakaocdn.net/dn/71jXo/hyU5ROeeXO/QkGjVwdKdvF1nRxtOH3WjK/img.png?width=450&amp;amp;height=641&amp;amp;face=0_0_450_641&quot;&gt;&lt;a href=&quot;https://datarian.io/blog/what-is-rfm?utm_source=sql-camp&amp;amp;utm_medium=camp&amp;amp;utm_campaign=referral&amp;amp;utm_content=sql-basic&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://datarian.io/blog/what-is-rfm?utm_source=sql-camp&amp;amp;utm_medium=camp&amp;amp;utm_campaign=referral&amp;amp;utm_content=sql-basic&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ZgvFB/hyU5UKXTU9/J3H18DgcrvaIdKt2TVqaRk/img.png?width=2000&amp;amp;height=1500&amp;amp;face=0_0_2000_1500,https://scrap.kakaocdn.net/dn/efzmgw/hyU5UKXTPD/ogKPyp81ZCdPfMcx86WDH1/img.png?width=849&amp;amp;height=850&amp;amp;face=232_132_597_530,https://scrap.kakaocdn.net/dn/71jXo/hyU5ROeeXO/QkGjVwdKdvF1nRxtOH3WjK/img.png?width=450&amp;amp;height=641&amp;amp;face=0_0_450_641');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RFM 고객 세분화 분석이란 무엇일까요&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CRM 타겟팅을 하는 방식 중 가장 범용적으로 사용할 수 있는 RFM 고객 세분화 분석에 대해 알아보겠습니다&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;datarian.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사진 출처&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705667319903&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;RFM analysis for Customer Segmentation - CleverTap&quot; data-og-description=&quot;RFM analysis segments customers on recency, frequency, and monetary value can indicate customer engagement, retention, and customer lifetime value.&quot; data-og-host=&quot;clevertap.com&quot; data-og-source-url=&quot;https://clevertap.com/blog/rfm-analysis/&quot; data-og-url=&quot;https://clevertap.com/blog/rfm-analysis/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bc1LLr/hyU83TNZcj/bSG4hUrmRR6fdCC9ejK2qk/img.png?width=900&amp;amp;height=378&amp;amp;face=0_0_900_378,https://scrap.kakaocdn.net/dn/bo2jd0/hyU5SzCPyi/oiLEJktiRqBdIRWXkwdKPk/img.png?width=900&amp;amp;height=378&amp;amp;face=0_0_900_378,https://scrap.kakaocdn.net/dn/boaApR/hyU5F1jW0P/jkZOQszQ1Px12ksL6sHcf0/img.png?width=1431&amp;amp;height=1412&amp;amp;face=0_0_1431_1412&quot;&gt;&lt;a href=&quot;https://clevertap.com/blog/rfm-analysis/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://clevertap.com/blog/rfm-analysis/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bc1LLr/hyU83TNZcj/bSG4hUrmRR6fdCC9ejK2qk/img.png?width=900&amp;amp;height=378&amp;amp;face=0_0_900_378,https://scrap.kakaocdn.net/dn/bo2jd0/hyU5SzCPyi/oiLEJktiRqBdIRWXkwdKPk/img.png?width=900&amp;amp;height=378&amp;amp;face=0_0_900_378,https://scrap.kakaocdn.net/dn/boaApR/hyU5F1jW0P/jkZOQszQ1Px12ksL6sHcf0/img.png?width=1431&amp;amp;height=1412&amp;amp;face=0_0_1431_1412');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RFM analysis for Customer Segmentation - CleverTap&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;RFM analysis segments customers on recency, frequency, and monetary value can indicate customer engagement, retention, and customer lifetime value.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;clevertap.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data Science</category>
      <category>RFM</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/66</guid>
      <comments>https://hr1588.tistory.com/66#entry66comment</comments>
      <pubDate>Fri, 19 Jan 2024 17:38:11 +0900</pubDate>
    </item>
    <item>
      <title>[MySQL] HackerRank - Weather Observation Station 20</title>
      <link>https://hr1588.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;다음 테이블에서 북위(LAT_N)의 중앙값(Median)을 찾고, 정답을 소수점 4자리 이하로 반올림하시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1705338117104&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select round(avg(lat_n),4)
from(
    select lat_n, count(*) over() as total_rows, row_number() over (order by lat_n) as row_num
    from station
) as sub_table
where row_num in ((total_rows+1)/2, (total_rows+2)/2)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DBMS는 종류에 따라 지원하는 함수와 문법이 조금씩 다르다.&lt;/b&gt; 문제를 풀기위해 PERCENTILE_CONT 함수를 사용해봤으나, MySQL은 해당 함수를 지원하지 않았다. 따라서 LAT_N으로 테이블을 정렬하고, 행의 수에 따라 중앙값을 추출하는 쿼리를 작성했다. 과정은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Inline View&lt;/b&gt; : station에서 LAT_N column을 선택하고, 전체 행의 개수와 각 행의 순서를 계산한다. 이 때, window function을 활용해서 모든 행에 대해 계산을 실시한다. 정렬된 값에 따라 row_number가 행 번호를 부여하기 때문에 우리는 행의 개수에 따라 중앙값을 추측할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;where절&lt;/b&gt; : 중앙값을 계산하기 위해 조건을 추가한다. 전체 행 수가 홀수인 경우와 짝수인 경우에 따라 중앙값은 달라진다. 행의 개수가 홀수인 경우 중앙값은 하나이고, 짝수이면 2개이기 때문이다. select 절에서 avg 함수를 사용하면, 홀/짝 여부와 관계 없이 모든 경우의 중앙값을 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1705338724804&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Weather Observation Station 20 | HackerRank&quot; data-og-description=&quot;Query the median of Northern Latitudes in STATION and round to 4 decimal places.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-20/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-20/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lL4F5/hyU5JIpnK9/Qtqw8c2qvXKreHfhfohwZ0/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-20/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-20/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lL4F5/hyU5JIpnK9/Qtqw8c2qvXKreHfhfohwZ0/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Weather Observation Station 20 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query the median of Northern Latitudes in STATION and round to 4 decimal places.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트/SQL</category>
      <author>머동</author>
      <guid isPermaLink="true">https://hr1588.tistory.com/65</guid>
      <comments>https://hr1588.tistory.com/65#entry65comment</comments>
      <pubDate>Tue, 16 Jan 2024 02:12:18 +0900</pubDate>
    </item>
  </channel>
</rss>