<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>cysk 님의 블로그</title>
    <link>https://cysk.tistory.com/</link>
    <description>cysk 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Tue, 14 Jul 2026 15:30:33 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>cysk</managingEditor>
    <item>
      <title>입찰제안서용 AI 솔루션 구축기 (1)</title>
      <link>https://cysk.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;인턴 생활을 하면서 개인적으로 가장 인상 깊었던 건 제안서 작업의 규모였다. 백 페이지에 달하는 제안요청서(RFP)를 처음부터 끝까지 읽고, 요구사항과 배점표를 수동으로 뽑아내는 작업이 입찰마다 반복됐다. 보면서 자연스럽게 드는 생각이 있었다. 이거 AI로 자동화할 수 있지 않을까?&lt;/span&gt;&lt;/p&gt;
&lt;div data-test-render-count=&quot;1&quot;&gt;
&lt;div&gt;
&lt;div data-is-streaming=&quot;false&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. 문제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;처음엔 단순하게 접근했다. 스크립트로 텍스트를 뽑아서 Gemini API에 통째로 던지면 되지 않을까 싶었는데, 두 가지 문제가 바로 터졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;첫째는 노이즈였다. 한글 문서(HWP, HWPX) 특성상 폰트 메타데이터나 표 레이아웃 같은 쓸모없는 데이터가 텍스트 안에 잔뜩 섞여 들어왔다. 둘째는 토큰이었다. RFP 텍스트가 10만 자를 넘어가는 경우가 많은데, 행정 절차나 서론 같은 불필요한 내용까지 전부 넘기다 보니 AI가 문맥을 잃거나 중요한 내용을 스킵하고 '정답일 것 같은 텍스트'를 생성하는 문제가 생겼다.&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;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2. 구축&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;핵심 방향은 하나였다. AI에게 넘기기 전에 문서를 잘라내자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;문서의 위계 구조(I, 1, 가, 1) 등을 정규식으로 분석해 단락을 분해하는 파서를 만들었다. 해체된 수십 개의 섹션 중 헤더에 '요구사항', '과업내용', '배점표', '평가항목' 같은 키워드가 포함된 블록만 골라내는 방식이다. 결과적으로 11만 자짜리 RFP가 3~4만 자로 압축됐다. AI가 소화하기 훨씬 쾌적한 크기가 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;배포는 LangChain과 Streamlit을 조합해 기획자들이 브라우저에서 파일을 올리고 결과를 바로 다운로드할 수 있는 GUI 앱 형태로 만들었다. 여러 파일을 한꺼번에 처리해야 하는 상황을 고려해 asyncio 비동기 병렬 처리도 붙였다. 10개의 문서를 동시에 구글 서버로 던져서 1~2분 안에 일괄 처리하는 구조다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이후 오버스펙과 유지보수 비용 문제를 고려해 LangChain 의존성을 완전히 제거하고, 구글 순정 API만으로 동작하는 Lite 버전도 따로 분리했다.&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;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;3. 테스트&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;샘플(대구도시정비 등)를 돌려보니 원본 텍스트가 약 10만 자였는데, 핵심 압축 파서를 거치자 약 3만 자로 줄었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4개의 파일을 따로 추출하여 txt파일로 확인하였는데 핵심 요구사항만 남기고 나머지를 성공적으로 제거했다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4개의 서로 다른 RFP 문서를 드래그 앤 드롭으로 다중 업로드한 뒤 비동기 일괄 생성을 돌렸을 때, 약 3분여 만에 4개 문서 각각의 PPT 구조도(Blueprint.md)와 어필 포인트(Appeal.md)가 다운로드 버튼 형태로 화면에 떴다.&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9U7Gm/dJMcajnJPGE/HKISOgGIkYGkw3YN5eG2L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9U7Gm/dJMcajnJPGE/HKISOgGIkYGkw3YN5eG2L0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9U7Gm/dJMcajnJPGE/HKISOgGIkYGkw3YN5eG2L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9U7Gm%2FdJMcajnJPGE%2FHKISOgGIkYGkw3YN5eG2L0%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;761&quot; height=&quot;374&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;374&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;764&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dTiya9/dJMcafsaiPS/04cjy5bmeATScgY6iOxw70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dTiya9/dJMcafsaiPS/04cjy5bmeATScgY6iOxw70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dTiya9/dJMcafsaiPS/04cjy5bmeATScgY6iOxw70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdTiya9%2FdJMcafsaiPS%2F04cjy5bmeATScgY6iOxw70%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;764&quot; height=&quot;460&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이정도로 구조화하고, 슬라이드 생성 지침을 제공해준다면 따로 수정할 필요 없이 젠스파크에 던져볼만 하다는 생각이 들었다. 아마 초기 제작본 제작시간(3인 2일~3일)을 1일이나 2일정도 단축시킬 수 있지 않을까? 물론 수정은 우리몫이겠지만&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp;&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;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;4. 503 에러, 스트림릿 오류&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;스트림릿으로 배포하기 위해 Gemini 3.1pro, 2.5pro, 2.5 flash 등 다양한 모델로 테스트를 돌려봤는데 스트림릿에서는 503 에러가 간헐적으로 발생했다. &lt;s&gt;내 PC에서는 문제가 없었는데.&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;대응방안을 찾기위해 공부하고 있지만 정말 모르겠다. 왜 그러지... &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;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;결과적으로 잘 되면 3인 1주 분량의 작업을 2일 정도 단축할 수 있을 것으로 기대하고 있다. 실전 투입 후기는 나중에 올리도록 하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-state=&quot;closed&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div data-state=&quot;closed&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div data-state=&quot;closed&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>공부 기록/회고</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/31</guid>
      <comments>https://cysk.tistory.com/31#entry31comment</comments>
      <pubDate>Mon, 2 Mar 2026 14:18:22 +0900</pubDate>
    </item>
    <item>
      <title>2월 인턴 생활 회고 &amp;amp; AI를 활용한 제작안 구축기</title>
      <link>https://cysk.tistory.com/30</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;내배캠의 1달 인턴에 지원하여 그로스 마케터로 들어갔으나, 공공입찰 기획 파트에 흥미를 느껴 해당 파트에 지원하겠다고 말했다. 개인적으로 다양한 경험을 할수록 더 넓은 인사이트와 좋은 결과물이 나온다고 믿는 편인데, 대시보드나 기능 개발을 원하는 기업과 핏을 맞춰볼 수 있는 좋은 기회라고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2월 동안 총 2개의 프로젝트를 진행했다. 제안요청서를 읽으면서 &quot;이 기능을 어떻게 풀어낼 것인가, 어떻게 어필할 것인가, 우리가 추가로 제안할 수 있는 포인트는 무엇인가&quot;를 계속 고민했다. 단순히 요구사항을 받아 구현하는 것이 아니라 제안의 맥락을 이해하고 설득력 있게 구성하는 작업이었는데, 생각보다 훨씬 재밌었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대시보드도 정말 많이 만들었다. 구상한 것만 10가지, A4에 직접 그려가며 구체화한 것도 5개는 되는 것 같다. 아래는 제안서에 수록된 대시보드로, 허락을 받고 올린다.&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;대시보드1.png&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZerpm/dJMcaf6Ld65/oF2ztWLdC7lkxEIKTtu8a0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZerpm/dJMcaf6Ld65/oF2ztWLdC7lkxEIKTtu8a0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZerpm/dJMcaf6Ld65/oF2ztWLdC7lkxEIKTtu8a0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZerpm%2FdJMcaf6Ld65%2FoF2ztWLdC7lkxEIKTtu8a0%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;684&quot; height=&quot;378&quot; data-filename=&quot;대시보드1.png&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제안서 마감 전날과 당일에 각각 새벽 3시, 4시까지 야근하며 다듬었던 제안서라 애착이 깊다. 결과는 아직 나오지 않았지만 되면 좋겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;819&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH9Ftg/dJMcaa5sNZM/6Zl57oUVSf7eBWNpD6N511/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH9Ftg/dJMcaa5sNZM/6Zl57oUVSf7eBWNpD6N511/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH9Ftg/dJMcaa5sNZM/6Zl57oUVSf7eBWNpD6N511/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH9Ftg%2FdJMcaa5sNZM%2F6Zl57oUVSf7eBWNpD6N511%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;923&quot; height=&quot;819&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;819&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제안요청서를 넣으면 자동으로 파싱해 텍스트를 AI에게 넘기고, 사전에 정의된 규격과 내용에 맞춰 제안서 초안을 뽑아주는 도구다. 아직 실전 투입 전이지만 잘 되면 3인 1주(기능 요구사항 15개 기준)의 작업을 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;마지막으로 감사하게도 1달 연장 제안을 받았다. 서울 생활이 한 달 더 늘어난 셈인데, 그것보다 내가 보여준 가치와 성장 가능성을 인정받은 것 같아서 더 기뻤다.&lt;/p&gt;</description>
      <category>공부 기록/회고</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/30</guid>
      <comments>https://cysk.tistory.com/30#entry30comment</comments>
      <pubDate>Sat, 28 Feb 2026 19:05:47 +0900</pubDate>
    </item>
    <item>
      <title>네번째 프로젝트 [AI기반 카드 추천 모델]</title>
      <link>https://cysk.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 최신기술에 대한 이해가 가장 늘어난 프로젝트가 아닐까싶다.&amp;nbsp;&lt;br&gt;크롤링, 데이터 정제, RAG, LLM API, 마케팅 퍼널 설계까지 다 진행했던 프로젝트라 좀 뜻깊다.&lt;br&gt;&amp;nbsp;&lt;br&gt;0. 문제 설정&lt;br&gt;새로운 프로젝트를 시작하면서 어떤 문제를 풀어볼까 고민이 많았다. 그러던 중 최근 카드를 바꾸려다 복잡한 로직때문에 그냥 기존에 쓰던 카드에 좋아보이는 카드를 하나 더 발급받은 경험이 생각나서 이 문제를 해결해보고 싶었다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;0-1. 기존 카드추천 모델 점검&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciD1TC/dJMcadHHY4x/nFSvVKWnHc8W9fsr4Ocpp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciD1TC/dJMcadHHY4x/nFSvVKWnHc8W9fsr4Ocpp0/img.png&quot; data-alt=&quot;카드고릴라&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciD1TC/dJMcadHHY4x/nFSvVKWnHc8W9fsr4Ocpp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciD1TC%2FdJMcadHHY4x%2FnFSvVKWnHc8W9fsr4Ocpp0%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;768&quot; height=&quot;368&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;368&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;카드고릴라&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;1115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xjKCG/dJMb99SSJaw/3QJIi9XGynLd5nColWr550/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xjKCG/dJMb99SSJaw/3QJIi9XGynLd5nColWr550/img.png&quot; data-alt=&quot;카드고릴라&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xjKCG/dJMb99SSJaw/3QJIi9XGynLd5nColWr550/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxjKCG%2FdJMb99SSJaw%2F3QJIi9XGynLd5nColWr550%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;344&quot; height=&quot;645&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;1115&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;카드고릴라&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1011&quot; data-origin-height=&quot;521&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bA8nIp/dJMcacoxmc3/BWBEZcLvKUELM19Aev6k71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bA8nIp/dJMcacoxmc3/BWBEZcLvKUELM19Aev6k71/img.png&quot; data-alt=&quot;뱅크샐러드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bA8nIp/dJMcacoxmc3/BWBEZcLvKUELM19Aev6k71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbA8nIp%2FdJMcacoxmc3%2FBWBEZcLvKUELM19Aev6k71%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;1011&quot; height=&quot;521&quot; data-origin-width=&quot;1011&quot; data-origin-height=&quot;521&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;뱅크샐러드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보시다싶이 대부분의 카드추천 모델들은 데이터를 통한 랭킹이나 마케팅적인 인기순위를 기반으로 한다. 커뮤니티의 카드 추천 역시 이런이런 카드가 더 좋더라~ 의 틀을 크게 벗어나지 못한다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;이는 카드의 혜택 로직이 고도화됨에 따라 하나의 카드에 하나의 계산 로직이 필요한 수준이기에 그렇다. 하나의 카드가 추가될 때 혜택의 컬럼을 추가하고, 해당 카드에 적합한 계산 로직을 만들어 추가하는것은 리소스가 매우 많이 드는 작업이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;기존 시장에 풀린 카드의 수가 수천종이라는 것을 감안한다면 수천개의 혜택별 컬럼(쇼핑, 밤, 낮, 몇시부터 몇시까지 5% 추가 혜택 등)과 조건부 계산로직이 필요하다. 이런 문제를 AI를 통해 해결할 수 있지 않을까 하는 생각으로 진행하였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;1. 데이터셋&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;AIHUB 금융 합성 데이터셋&lt;br&gt;1200컬럼, 60GB&lt;br&gt;네이버 카드 데이터 346개&lt;br&gt;&amp;nbsp;&lt;br&gt;2. 데이터 수집&lt;br&gt;네이버 카드의 카드를 크롤링해서 사용하였다&lt;br&gt;금융 데이터셋의 경우 aihub의 금융합성 데이터셋을 사용하였는데 캐글이나 여러 경로로 구할 수 있는 데이터셋 중에 가장 품질이 좋다고 판단하여 사용하였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;3. 데이터 정제&lt;br&gt;&amp;nbsp;&lt;br&gt;3-1.. AIHUB 데이터 정제&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;1차적으로 AIHUB의 데이터를 DuckDB로 변환하여 DBeaver로 연결하여 SQL을 통해 조회하였다. 데이터 카탈로그와 SQL을 통해 조회한 데이터를 통해 추출할 데이터를 선별하였고 추출 후 파케로 변환하여 용량부터 줄였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;3-2. 네이버 카드 데이터 정제&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;861&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diDd31/dJMcaaxuZ8x/Z9NBceknHLFwfOVSnXbjv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diDd31/dJMcaaxuZ8x/Z9NBceknHLFwfOVSnXbjv1/img.png&quot; data-alt=&quot;수집된 데이터의 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diDd31/dJMcaaxuZ8x/Z9NBceknHLFwfOVSnXbjv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiDd31%2FdJMcaaxuZ8x%2FZ9NBceknHLFwfOVSnXbjv1%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;615&quot; height=&quot;430&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;861&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;수집된 데이터의 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 말하였듯 하나의 카드에 포함되는 계산 로직이 이렇게 많다. 또한 반정형 형태로 이루어져 있기에 이것을 정형 데이터로 변환하는 과정을 먼저 진행하여야 하였다. 변환에는 제미나이 2.5 flash 모델을 사용하였고 System Instruction에 추출할 데이터의 구조와 예시를 주고 json형태로 받았다.(아마 다시한다면 pydantic 라이브러리를 사용할 것이다... pydantic 라이브러리를 나중에 알게되어 적용하였다. )&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;358&quot; data-origin-height=&quot;491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pTjM8/dJMcaf6DsG8/9KUIKGkaos2XXfoxvN7D91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pTjM8/dJMcaf6DsG8/9KUIKGkaos2XXfoxvN7D91/img.png&quot; data-alt=&quot;정제한 데이터의 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pTjM8/dJMcaf6DsG8/9KUIKGkaos2XXfoxvN7D91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpTjM8%2FdJMcaf6DsG8%2F9KUIKGkaos2XXfoxvN7D91%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;358&quot; height=&quot;491&quot; data-origin-width=&quot;358&quot; data-origin-height=&quot;491&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정제한 데이터의 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기초적인 계산을 위한 데이터셋이 완성되었다.&lt;br&gt;&amp;nbsp;&lt;br&gt;4. 모델 설계 및 서비스 전략&amp;nbsp;&lt;br&gt;신용카드 교체나 신규 발급은 보통 수년 단위로 일어나는 단발성 이벤트이다. 따라서 일반적인 금융 앱이 겪는 낮은 MAU(월간 활성 사용자) 문제를 해결하기 위해 사용자의 일상적인 소비 접점을 선점하여 DAU( 일간 활성 사용자)를 확보하는 마케팅 퍼널을 설계하였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;일상에서 전자제품을 사거나, 어떤 음식을 사기 전에 서비스에 들어와서 어느 카드로 사는게 더 효율적인지 검색하는 습관을 형성하고, 지속적으로 더 효율적인 카드에 노출되면서 자신이 쓰는 카드가 소비패턴과 알맞는지 확인하고자 하는 욕구를 형성하게끔 설계하였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;서비스 로직은 다음과 같다.&amp;nbsp;&lt;br&gt;간편 쇼핑 계산기(모델1) : 일상적 쇼핑 시 즉각적인 혜택 계산을 제공하여 플랫폼 접속 습관 형성.&lt;br&gt;소비 패턴 분석(모델2): 누적된 소비 이력을 분석하여 놓치고 있는 혜택(더 혜택이 좋은 카드)를 수치로 제시&lt;br&gt;프롬프트형 카드 추천 (모델 3): LLM 기반의 프롬프트 분석을 통해 카드 분리 및 사용자의 필요(배달, 교통 등)에 해당하는 카드 추천&lt;br&gt;&amp;nbsp;&lt;br&gt;모델 2번과 모델3번은 비슷한것 아닌가? 하는 의문이 있겠지만 용도가 다르다. 모델 2번은 사용자의 소비 데이터(최소 1개월)가 필요하고, 해당 소비패턴을 모두 분석하여 카드를 추천하는 모델이고, 모델 3번은 사용자 욕구에 의한 분리가 가능해진다.&lt;br&gt;즉, 모델 2와 모델 3은 모두 추천을 목적으로 하지만, 데이터를 다루는 관점과 사용자 경험 (UX)에서 차이가 있다.&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: 15.8914%; text-align: center;&quot;&gt;구분&lt;/td&gt;&lt;td style=&quot;width: 50.7752%; text-align: center;&quot;&gt;모델 2: 소비 이력 기반 추천&lt;/td&gt;&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;모델 3: 프롬프트형 카드 추천&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;width: 15.8914%; text-align: center;&quot;&gt;핵심 키워드&lt;/td&gt;&lt;td style=&quot;width: 50.7752%; 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: 15.8914%; text-align: center;&quot;&gt;데이터 소스&lt;/td&gt;&lt;td style=&quot;width: 50.7752%; 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: 15.8914%; text-align: center;&quot;&gt;분석 목적&lt;/td&gt;&lt;td style=&quot;width: 50.7752%; 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: 15.8914%; text-align: center;&quot;&gt;사용자 가치&lt;/td&gt;&lt;td style=&quot;width: 50.7752%; text-align: center;&quot;&gt;&quot;나는 내 소비에 맞는 카드를 쓰고 있는가?&quot;에 대한 객관적 검증&lt;/td&gt;&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&quot;내가 원하는 이 혜택을 가장 잘 주는 카드는 무엇인가?&quot;에 대한 맞춤형 컨설팅&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;4-1. 간편 쇼핑 계산기(모델 1)&lt;br&gt;사용자가 쿠팡, 네이버 쇼핑 등에서 고가의 물건을 구매하기 직전, &quot;지금 내 카드 중 무엇을 써야 가장 이득일까?&quot;라는 질문을 가질 때 우리 플랫폼을 먼저 찾도록 습관을 형성하는 데 목적이 있다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
   &lt;li&gt;&amp;nbsp;복잡한 개인화 로직 대신 사용자의 질문 (예: &quot;쿠팡에서 100만원 결제시 최적 카드는?&quot;에 대한 즉각적인 혜택 시뮬레이션)&lt;/li&gt; 
   &lt;li&gt;Python 계산 로직을 통한 LLM비용 절감&lt;/li&gt; 
   &lt;li&gt;설계 의도 : 구매 전 검색 단계를 선점함으로써 서비스 체류 시간을 늘리고, 자연스럽게 다음 단계인 소비 패턴 분석(모델 2)이나 프롬프트 분석(모델3)으로 유입시키는 트래픽 게이트 역할&amp;nbsp;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;4-2. 소비 이력 기반 추천(모델 2)&lt;br&gt;모델 2의 목적은 사용자가 인지하지 못하는 실제 소비 패턴을 정밀하게 분석하여 서비스에 대한 신뢰를 형성하고, 내가 가진 카드로 받는 혜택과 카드 추천을 통해 얻을 수 있는 혜택을 대비적으로 보여줌으로써 혜택의 차이를 기회비용의 손실로 인식하게 함에 있다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;예를 들어 한달에 100만원을 사용하고 월간 혜택 금액이 3만원인 사용자가 있다고 가정하겠다. 피킹률(혜택금액 / 사용금액)이 3%라면 준수하나 카드의 조합이나 사용 패턴에 맞는 카드로 전환한다면 피킹률 4%~4.5%까지는 쉽게 올릴 수 있다. 이때 3%의 기존카드의 피킹률과 추천받는 카드의 피킹률 4%(가정)의 차이는 월 1만원이지만 연으로 환산하면 12만원의 손해를 보고 있다고 할 수 있다. 이를 현재 카드로 놓치고 있는 혜택을 제시함으로써 사용자가 기존 카드를 유지하는 행위를 안전한 선택이 아닌 매년 12만원을 버리는 행위로 치환한다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&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;설계 의도 : 사용자가 자신의 카드에서 이탈하여 새로운 카드를 발급 받을 동인을 만든다. 이를 통해 모델 2, 모델 3을 통한 카드 추천으로 전환률을 올린다.&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;사용자의 월간 소비 데이터 (최소 1개월, 가능한 3개월 필요)&lt;/li&gt; 
   &lt;li&gt;LLM을 통한 카드의 복잡한 로직 대응(파이썬을 통한 계산 로직을 만들기 위해서는 하나의 카드에 하나의 계산 로직 필요, 현재 346개의 카드이므로 346개의 대응 로직을 만들어야 한다)&lt;/li&gt; 
   &lt;li&gt;LLM비용 감소를 위한 RAG와 데이터 압축 및 전송 데이터 선별&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;4-3 프롬프트형 카드 추천(모델 3)&lt;br&gt;모델 3번은 사용자의 최적화 욕구를 위한 서비스이다. 사용자가 직접 사용할 금액과 구체적인 소비 목적을 자연어로 입력하면 이를 기반으로 가장 적합한 카드 후보군을 선별하고 시뮬레이션을 통해 카드를 추천하는 모델이다. 기존의 단순 필터링 검색을 넘어 사용자의 페르소나를 해석하고, 스스로 최적화하여 카드 전환율을 극대화하는 것을 목적으로 한다.&amp;nbsp;&lt;br&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;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;또한 정형화된 데이터(모델2)가 담지 못하는 사용자의 미세한 라이프스타일(특정 가맹점 선호, 특수 고정 지출 등)을 LLM이 해석하여 추천 적합성을 확보한다&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;RAG 기반 선별 : 346개의 카드 데이터 중 사용자의 질의와 가장 연관성이 높은 후보군을 DB에서 선별적으로 추출하여 답변의 신뢰도를 높이고 불필요한 연산을 줄인다. 또한 소모되는 자연( 돈, 시간)을 줄여야 한다.&amp;nbsp;&lt;/li&gt; 
   &lt;li&gt;LLM 기반 계산 및 해석 : 선별된 카드를 LLM을 통해 해석, 계산하고 최종 산출물인 리포트의 품질을 일정 수준으로 유지해야 한다.(환각 제거)&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;5. 모델 구축&lt;br&gt;&amp;nbsp;&lt;br&gt;설계가 끝났으니 이제 실제로 만들어야 할 차례였다. 머릿속에 그린 구조가 실제로 작동하는지 확인하는 단계인데 늘 그렇듯 설계할 때는 깔끔해 보였던 것들이 구현하다 보면 생각치 못했던 지점에서 막혔다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;5-1. 간편 쇼핑 계산기(모델1)&lt;br&gt;모델 1은 세 모델 중 구조가 가장 단순하다. 그래서 가장 먼저 만들기 시작하였는데 생각보다 오래 붙잡고 있었다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;처음 설계는 직관적으로 사용자의 질문 -&amp;gt; 의도파악 후 카테고리 뽑기 -&amp;gt; RAG-&amp;gt;Python 계산 -&amp;gt; llm이 출력하는 로직이였다.&lt;br&gt;쿠팡에서 100만원을 결제한다고 하면 쿠팡과 쇼핑 카테고리의 카드를 먼저 뽑고, 그 카드들을 python으로 계산하는 로직이였는데 오답률이 40%에서 60%로 품질관리가 전혀되지 않았다. 로직 설계의 오류문제인가 싶어서 데이터를 재구조화 하거나, 계산 로직을 좀 더 고도화했지만 오답률은 여전했다. 천천히 로직을 따라 분석해보니 문제는 RAG의 방식에 있었다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;RAG는 키워드 기반 검색이다. 문제는 카드는 중복 로직이 많다는 것이였다. 예를들어 346개의 카드 중 [주유]혜택이 있는 카드는 106개이다. RAG를 통해 1차적으로 거르는 카드가 15개였으니 106개의 카드 중 랜덤으로 15개가 들어오는 것이였다.&lt;br&gt;즉 아무리 계산 로직이 정확해도 후보군 자체가 매번 달라지니 정답이 후보에 포함되지 않는 경우가 생기는 구조적인 문제였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;결국 순서를 뒤집었다. Python으로 전체 카드 혜택을 먼저 계산하고, 그 계산 결과를 기준으로 랭킹을 매기는 방식으로 바꿨다. RAG로 후보를 좁히는게 아니라, 계산이 끝난 결과물 중 키워드를 기반으로 선별해 상위 카드를 추려서 llm에 넘기는 구조다. LLM은 이미 계산이 완료된 결과를 자연어 리포트로 포장하는 역할만 한다. 이렇게 바꾸니 오답률이 2%까지 떨어졌다. 2%의 오답률은 카드 데이터 자체의 오류여서 수정하였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;돌이켜보면 당연한 이야기지만 처음에는 RAG로 카드 수를 먼저 줄이는게 더 효율적일 것이라 생각했다. 정작 문제는 후보군이 많을 때 일정 갯수만 랜덤하게 선별하는 후보군이였다. 계산은 Python이 하면 틀리지 않는다 그러면 전체를 다 계산하고 상위만 추리는게 맞다. 이걸 직접 부딪혀서 알게되니 언제 RAG를 쓰고, 언제 쓰지 말아야 하는지에 대한 감이 생겼다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;5-2 이력 기반 추천 모델 및 프롬프트 기반 추천 모델(모델2, 모델3)&lt;br&gt;모델 2와 모델3은 구조적으로 많은 부분을 공유한다. 둘 다 RAG로 카드를 선별하고, LLM이 혜택을 계산해 추천 리포트를 생성하는 흐름이다. 입력되는 데이터가 사용자의 소비 데이터냐, 사용자의 자연어 질문이냐가 다를뿐이다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;모델1을 만들때는 RAG를 계산 이후에 적용하였으나 모델 2, 3은 선별 후 계산으로 바꿨다. 모델 1의 경우 346개의 카드 전체를 Python으로 계산하는 것은 입력 후 출력되는 데이터가 쇼핑, 쿠팡 처럼 단일 가맹점이나 단일 컬럼이였으니 계산을 먼저하는 것이 효율적이였으나 모델 2, 3은 다양한 컬럼(혜택)에 대응해야 했다. 그렇기에 위에서 말했듯 python을 통해 계산하려면 한개의 카드당 한개의 계산 로직을 만들어야 한다. 그렇기에 카드 혜택의 계산은 LLM에게 맡기되, RAG로 후보군을 충분히 좁혀서 환각과 비용을 동시에 잡는 방향으로 설계하였다.&lt;br&gt;&amp;nbsp;&lt;br&gt;문제는 비용이였다. 전체 카드 데이터를 그대로 LLM에게 던지면 입력 토큰이 387,911개, 건당 비용이 286원이였다. 서비스로 만든다고 가정하면 1만회당 286만원이 나오게 되며 감당할 수 없는 구조였다. 또한 소요되는 시간이 제미나이 3.0 FLASH기준으로 60초가량이 걸렸다. 아무리 인내심이 많은 이용자라도&amp;nbsp; 60초는 서비스에서 이탈하기에 충분한 시간이였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;그렇기에 최우선 과제는 토큰의 소모를 줄이고 소요되는 시간을 줄이는 것이였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;최우선적으로 적용한 건 payload 최적화였다. json형태기에 중복되어 사용되는 컬럼들의 컬럼명을 압축하고 System Instruction에 해석 범례를 제공하여 해석하여 계산할 수 있게 하고,&amp;nbsp;&lt;br&gt;카드의 혜택을 계산할때 필요하지 않은 url이나 카드명을 제거하여 LLM에게 보내고 이를 후처리 로직에서 복구하는 방식으로 바꿨다.&amp;nbsp;&lt;br&gt;또한 json에서 줄바꿈, 공백, 들여쓰기 등은 인간이 데이터를 볼 때 필요하지만 LLM이 데이터를 파악할 때는 불필요한 정보이고, 토큰을 소모하기에 해당 부분도 삭제하였다.&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: 50%;&quot;&gt;최적화 전&lt;/td&gt;&lt;td style=&quot;width: 50%;&quot;&gt;최적화 후&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;width: 50%;&quot;&gt;&quot;title &quot;: &quot;신한카드 Mr.Life Deep Dream&quot;,&lt;/td&gt;&lt;td style=&quot;width: 50%;&quot;&gt;&quot;t&quot;: &quot;new1&quot;,&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;width: 50%;&quot;&gt;&quot;benefit_detail&quot;: &quot;편의점 10% 할인...&quot;&lt;/td&gt;&lt;td style=&quot;width: 50%;&quot;&gt;&quot;b&quot;: &quot;편의점 10%...&quot;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;width: 50%;&quot;&gt;&quot;url&quot;: &quot;https://www.shinhancard ...&quot;}&lt;/td&gt;&lt;td style=&quot;width: 50%;&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;br&gt;이것만으로 입력 토큰이 387,911개에서 243,367개로 줄었다. 비용은 286원에서 181원으로 약 37% 감소하였다.&lt;br&gt;두번째로 RAG를 붙였다. BM25와 RRF를 조합해 사용자의 질의와 연관성이 높은 카드만 추려 LLM에 전달하는 방식이다. payload 최적화와 RAG를 함께 적용하니 입력 토큰이 24,116개까지 떨어졌다. 최초 387,911개 대비 93.78%감소, 비용은 22.37원이였다. 응답 시간도 35초 수준으로 내려왔다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;마지막으로 출력 규격화 문제가 남아 있었다. LLM이 출력할 구조를 미리 System Instruction에 입력한다고 하여도 내부의 글자 수에 따라 규격이 매번 달라지는 문제가 있었다. LLM이 아무리 추천을 잘해도 출력 형식이 매번 달라지면 서비스로 쓸 수 없다. 그렇기에 Pydantic으로 출력 스키마를 고정해서 리포트가 항상 같은 구조로 나오게 했다. 데이터 정제 단계에서도 썼으면 좋았을 도구인데 뒤늦게 알게 되어 여기에 적용하였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;모델 2,3을 만들면서 모델 1때와 반대의 결론에 도달했다는게 흥미로웠다. 모델 1에서는 RAG가 문제였고, 여기서는 RAG가 해결책이였다. 같은 도구도 문제의 성격에 따라 다르게 써야한다는 걸 다시끔 배웠다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;6. 스트림릿 제작&lt;br&gt;&amp;nbsp;&lt;br&gt;모델을 만들었으면 혼자만 쓰는 것으로 끝내기엔 아쉬웠다. 약간의 인정욕구와 처음으로 만든 서비스에 대한 애착, 그리고 실사용자의 피드백을 직접 들어보고 싶다는 마음이 컸다. 내가 카드 상담사처럼 항상 옆에서 사용자의 소비패턴을 듣고 대신 입력해주는 방식은 윤리적인 문제도 있고 사용자 입장에서도 불편한 일이다. 서비스가 스스로 굴러가야 진짜 테스트가 되는 것이기도 했다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;모델 1. 간편 쇼핑 계산기&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;893&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnq5BS/dJMcacWmJTS/f4xnu2uUlVWKruXgu6YgE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnq5BS/dJMcacWmJTS/f4xnu2uUlVWKruXgu6YgE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnq5BS/dJMcacWmJTS/f4xnu2uUlVWKruXgu6YgE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbnq5BS%2FdJMcacWmJTS%2Ff4xnu2uUlVWKruXgu6YgE1%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;1224&quot; height=&quot;893&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;893&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 2. 소비 이력 기반 추천 모델&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;703&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYPb0c/dJMcaa5kUTY/pgsXkwo9OlIOxD6oi2BTYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYPb0c/dJMcaa5kUTY/pgsXkwo9OlIOxD6oi2BTYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYPb0c/dJMcaa5kUTY/pgsXkwo9OlIOxD6oi2BTYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYPb0c%2FdJMcaa5kUTY%2FpgsXkwo9OlIOxD6oi2BTYK%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;918&quot; height=&quot;703&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;703&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 3. 프롬프트형 카드 추천 모델&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BJNmr/dJMcabDbvRD/Fu7KVXlMcOCoB8PaFgt8Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BJNmr/dJMcabDbvRD/Fu7KVXlMcOCoB8PaFgt8Mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BJNmr/dJMcabDbvRD/Fu7KVXlMcOCoB8PaFgt8Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBJNmr%2FdJMcabDbvRD%2FFu7KVXlMcOCoB8PaFgt8Mk%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;894&quot; height=&quot;692&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;692&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 3의 프롬프트는 친구에게 블라인드 테스트를 부탁해서 프롬프트를 받아와 테스트에 이용하였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;7. 회고&lt;br&gt;개인적으로 최신 기술에 대한 이해가 가장 많이 늘어난 프로젝트였다. 크롤링부터 시작해서 데이터 정제, RAG, LLM, 마케팅 퍼널 설계까지 혼자 전 과정을 다 짚어본 경험은 처음이였고, 그만큼 배운것도 많았다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;배포 후 총 15건의 피드백을 받았다. 실용적이다. 추천이 자세하다는 긍정적인 반응도 있었지만 개선 요청이 더 눈에 들어왔다. 체크카드가 없다는 점, 속도 개선, UX와 온보딩이 불친절하다는 의견이 주를 이뤘다. 만들면서 기능 구현에 집중하느라 미처 챙기지 못했던 부분들이었다. 특히 UX와 온보딩 피드백이 4건으로 가장 많았는데, 기능이 아무리 좋아도 처음 진입하는 사용자가 사용법을 모르면 의미가 없다는 것을 새삼 느꼈다. 서비스를 만드는 것과 사용자가 쓸 수 있게 만드는 것은 다른 문제였다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;기술적으로 아쉬운 점도 있다. Pydantic을 처음부터 알았더라면 데이터 정제 단계에서 훨씬 깔끔하게 작업했을 것이고, RAG의 작동 방식을 제대로 이해하고 시작했다면 모델 1에서 해맸던 시간을 줄일 수 있었을 것이다. 다만 직접 부딪혀서 틀리고 고치면서 익힌 것들이라 머릿속에 더 오래 남아있을 것 같다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;응답 속도는 여전히 숙제다. 최적화를 거쳐 35초까지 줄였지만 서비스로서 만족스러운 수준은 아니다. 서비스의 이용 대기 시간이 길어질수록 신뢰도가 상승한다는 연구결과도 있지만 나는 서비스의 대기 시간을 의도적으로 늘린게 아니기에 해당 사항은 아닌 것 같다.&amp;nbsp; 피드백에서도 속도 개선 요청이 나온 만큼 다음 과제로 남겨뒀다.&lt;br&gt;&amp;nbsp;&lt;br&gt;5주짜리 1인 프로젝트치고는 꽤 많은 걸 담았다고 생각한다. 동시에 실제 서비스로 키우려면 아직 손봐야 할 게 많다는 것도 안다. 피드백 기반 개선은 현 시점에선 인턴 생활로 바쁘기에 조금씩 만지고 있다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;마지막으로 혹시라도 이용해보고 싶은 사람들을 위해 링크를 남겨두겠습니다. 이용하고 나면 후기를 댓글로 작성해주시길 부탁드립니다. 입력되는 모든 데이터는 제 컴퓨터와 로직상에 저장되지 않습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;a href=&quot;https://cardprojecttest-f8uyjzt5q35pievlgc4vwa.streamlit.app/%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8_%EC%B9%B4%EB%93%9C_%EC%B6%94%EC%B2%9C&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;AI 프롬프트형 카드 추천&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>공부 기록/회고</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/29</guid>
      <comments>https://cysk.tistory.com/29#entry29comment</comments>
      <pubDate>Wed, 18 Feb 2026 17:23:36 +0900</pubDate>
    </item>
    <item>
      <title>세번째 프로젝트 [낙농업 관리 최적화 프로젝트]</title>
      <link>https://cysk.tistory.com/28</link>
      <description>&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;2025.10.30&amp;nbsp;~&amp;nbsp;2025.11.12&amp;nbsp;(2주)&amp;nbsp;|&amp;nbsp;4인&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. 데이터 소개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스마트팜 코리아의 2021 「낙농_로봇착유기_데이터_2021」 및 「낙농_유성분검사성적서_데이터_2021」&lt;br /&gt;&lt;br /&gt;&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;중복 제거 및 결측치 제거&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 컬럼 [305일 유성분, 유단백 등]이 모두 결측치인 행이 약 40%가까이 되어 결측치 데이터를 어떻게 처리할 것인지가 1차적인 고민이였다. 생각했던 처리방법은 두가지로&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;였다. 첫번째 방법은 각 개체의 특성(유지방, 유량, 유단백, 체세포수)을 살리면서 데이터를 살릴 수 있다는 장점이 있으나 데이터가 중앙으로 군집한다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 데이터의 군집이 생성된것은 실제 우유 생산 패턴의 분산을 과도하게 축소시켜 통계적 유의성을 왜곡 시킬 수 있는 위험이 있다는 생각과 함께 &quot;분석가의 의도에 따라 데이터가 오염된것이 아닌가?&quot; 하는 의문이 들었고, 실제 데이터가 아닌 생성된 데이터이기에 신뢰도도 낮다고 판단하였다. 따라서 데이터의 양적 확보보다 데이터의 품질을 우선시하여 해당 행을 삭제하는 방향으로 확정하였다.&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;3. 문제 정의&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;체세포수는 원유의 위생 등급을 결정하는 지표로 20만 cells/mL 초과시 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. 어떻게 하면 건강과 품질을 해치지 않으면서 생산량을 최대화할 수 있을까?&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. 어떻게 하면 설비 효율을 확인 할 수 있을까?&lt;/p&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. 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;4-1 : &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;어떻게 하면 건강과 품질을 해치지 않으면서 생산량을 최대화할 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 낙농 데이터의 핵심 변수인 [일일 총 착유 횟수]는 1회, 2회 등과 같이 끊어지는 정수 형태로 나타나는 이산형 데이터이다. 그렇기에 포아송 회귀를 통해 산포와 분포 특성을 먼저 진행하였다.&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;포아송 회귀 분석 결과 0.1939의 과소산포를 확인하였고 이는 착유 횟수가 완전히 무작위적이지 않고, 로봇 착유 시스템 내에서 통제되고 있음을 의미한다. 통제되고 있다는 것은 해당 데이터가 농장주나 로봇 착유기 시스템의 의도에 의하여 데이터가 편향되어 있음을 의미하며 이러한 선택 편향이 존재하는 상황에서 일반적인 평균 비교를 수행할 경우, 착유 횟수가 유량을 늘린 것인지, 원래 유량이 많은 소를 많이 짠 것인지 구분할 수 없게 된다. 즉 개체별 특성을 유지하고, 개체마다 분리하여 진행 할 수 있는 방법론이 필요하였다.&lt;/p&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;그렇기에 다양한 회귀 방법론을 찾던 중 Panel OLS를 찾게 되었다.&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;Panel OLS는 개체별 인덱스를 직접 변수로 추가하지 않고도 수학적인 내부 편차 변환을 통해 개체 고유의 특성을 모델 내에서 상쇄시켜 제거한다. 이를 통해 자유도를 보존하면서도 &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;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ld0jr/dJMcaivkpcN/jMUY6vNH4bE5l53rGgxLNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ld0jr/dJMcaivkpcN/jMUY6vNH4bE5l53rGgxLNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ld0jr/dJMcaivkpcN/jMUY6vNH4bE5l53rGgxLNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fld0jr%2FdJMcaivkpcN%2FjMUY6vNH4bE5l53rGgxLNK%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;702&quot; height=&quot;151&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;255&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;또한 어떤 편향이 존재하는지 알아내기 위해 비교분석을 위한 ANOVA도 진행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ANOVA는 집단 간 평균 차이가 통계적으로 유의한지 검증하는 방법으로 t 검정의 확장판이다. 집단 간 분산을 집단 내 분산으로 나눈 F값을 통해 모든 그룹의 평균이 동일한지, 아니면 최소 하나가 다른지 판별한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 평균을 통해 구한다는 단점이 있어 위에서 말한 집단 내 개체의 고유 특성을 반영하지 못한다. 이러한 한계점을 이용하여 ANOVA와 Panel OLS를 비교하면 착유 2회라는 집단이 있을 때의 평균(ANOVA)과 1&amp;gt;2회로 이동하였을때 개체별 증가량 평균(Panel OLS)를 비교하여 어떤 편향이 있는지 밝혀낼 수 있다.&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;쉽게 말해서 착유당 고정적으로 6, 7을 착유하는 소 A, B가 있다고 가정해보겠다.(A=6, B=7)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 ANOVA 결과를 통해 2회 착유 집단의 평균이 6.4라면 우리는 A, B가 동일한 횟수로 착유했을때의 평균(6.5)보다 낮기에 음의 편향이 일어났다고 확인 할 수 있다.&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;1543&quot; data-origin-height=&quot;799&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n9kMO/dJMcahwtIwY/mudI09lAuJ5ad2VRFBUQoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n9kMO/dJMcahwtIwY/mudI09lAuJ5ad2VRFBUQoK/img.png&quot; data-alt=&quot;ANOVA와 Panel OLS의 결과를 비교한 표이다,&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n9kMO/dJMcahwtIwY/mudI09lAuJ5ad2VRFBUQoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn9kMO%2FdJMcahwtIwY%2FmudI09lAuJ5ad2VRFBUQoK%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;1543&quot; height=&quot;799&quot; data-origin-width=&quot;1543&quot; data-origin-height=&quot;799&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ANOVA와 Panel OLS의 결과를 비교한 표이다,&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간 박스를 보면 ANOVA는 8.8658,&amp;nbsp; Panel OLS는 10.082로 Panel OLS가 더 높게 나타난다. 이는 개체별로 3회 착유했을 경우의 평균은 10.082kg인 반면 3회착유라는 이벤트에서는 8.8658kg이 늘어났다는 것으로 착유량이 더 적은 소를 더 많이 착유한다는 의미이다. 즉 농장주의 편향은 생산량이 적은 소를 더 많이 착유한다.&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;결론 및 인사이트&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1795&quot; data-origin-height=&quot;1016&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckodPt/dJMb99SJKpG/gACDFNSInsOs6YvWjhdrsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckodPt/dJMb99SJKpG/gACDFNSInsOs6YvWjhdrsk/img.png&quot; data-alt=&quot;발표하기 위해 만든 PPT 중 일부 발췌&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckodPt/dJMb99SJKpG/gACDFNSInsOs6YvWjhdrsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckodPt%2FdJMb99SJKpG%2FgACDFNSInsOs6YvWjhdrsk%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;546&quot; height=&quot;309&quot; data-origin-width=&quot;1795&quot; data-origin-height=&quot;1016&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;발표하기 위해 만든 PPT 중 일부 발췌&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;착유 횟수가 늘어날수록 유성분 품질은 지속적으로 하락하는 트레이드오프 관계가 확인되었고 특히 1일 4회 이상 착유시 유지방 함량이 감소하여 유품질 저하에 따른 품질 비용이 커지는 비효율 구간에 진입한다.&amp;nbsp; 따라서 생산성과 유품질의 균형이 우수한 1일 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;4-2 어떻게 하면 개체 관리를 쉽게 할 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 소의 상태를 매일 개별적으로 확인하는 것은 불가능에 가깝다. 이를 해결하기 위해 영양 및 건강 지표를 기준으로 유사한 특성을 가진 개체들을 그룹화하는 K-means를 실행하였다.&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;1)전처리&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다중공선성 확인 : VIF지수를 확인 한 후 유지방율을 변수에서 제거하였다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;데이터 스케일링 : 각 변수의 단위 차이가 군집 결과에 왜곡을 주지 않도록 StandardScaler를 적용하여 표준화 하였다.&lt;/li&gt;
&lt;li&gt;로그 변환 : 체세포수의 왜도를 해결하기 위해 로그 변환된 값을 사용하여 군집의 응집도를 높였다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;Elbow Method를 통해 K = 6~8구간에서 기울기가 완만해지는 지점을 확인하였다. 실루엣 점수 분석 결과, K= 6(0.163), K=8(0.153)으로 둘 다 절대적 수치는 낮으나 K=6일 경우 미세하게 높음을 확인하였다&lt;/li&gt;
&lt;li&gt;비즈니스 및 UX/UI적 판단 : 국내 낙농가 농장주의 평균 연령대(50대 이상 76.8%)를 고려했을 때, 군집이 너무 세분화되면 오히려 관리에 혼선을 줄 수 있다고 판단하였다.&lt;/li&gt;
&lt;li&gt;군집별 개체 해석 결과 K=6일경우 케토시스, 유방염 등의 병증 개체군과 클러스터링 군집이 1:1로 매칭됨을 확인하였다. K=8일경우 고생산, 저생산과 같은 생산량 관련 지표에 의해 추가 분화가 일어남을 확인하였다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;결론 : 군집 해석 결과와 사용자 편의등을 종합하여 최종적으로 K=6를 선택하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 결론&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 분석 결과를 시각화한 의사결정 지원 대시보드를 구축하였다. 이를 통해 농장주는 격리가 필요한 개체와 설비 점검이 필요한 부분을 즉각적으로 파악할 수 있다. 아래의 접은글은 해당 대시보드의 시연 영상이다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/16ptDDlqwe7BlXrHuarqs1P6pjT5RcMo_/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://drive.google.com/file/d/16ptDDlqwe7BlXrHuarqs1P6pjT5RcMo_/view?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 한계점&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;착유 횟수 데이터의 불균형(2~3회에 90% 집중)으로 인한 극단 국간 분석 신뢰도 제한&lt;/li&gt;
&lt;li&gt;인건비, 전력료 등 실제 운영 비용 변수 누락으로 ROI산출 미비&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;ROI 분석 기반 마련 : 정확한 경제성 분석을 위해 누락된 비용 데이터를 확보
&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;최종 목표 : 착유량 증가와 품질, 운영, 건강 비용을 종합적으로 비교하는 ROI기반 의사결정 모델을 구축&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A/B 테스트를 통한 가설 검증
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 불균형 문제 해결 : 4-5회 착유 구간의 검증을 위해 통제된 환경에서의 A/B 테스트를 설계하여 데이터를 확보해야 함.&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;농장 전체의 평균 최적화이며, 개별 효율을 고려하지 못한 한계가 존재함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;개발&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;7. 회고&lt;/p&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;09~21시까지 진행되는데 보통 17시, 18시가 되면 머리가 안돌아가는 현상이 지속적으로 발생했다. 간단하게 말하면 낮의 지능과 밤의 지능 간의 차이가 극심했다. 이유를 찾아보기위해 현직 상담사로 일하는 친구에게 문의하였을 때 번아웃과 주요 증상이 일치한다고 진단 받았고, 센터로와서 검사를 한번 돌려보라는 권유를 받았다.&lt;/p&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;진단 이후 체력적 배분이나 쉴땐 쉬는 행위를 하며 체력이나 멘탈의 리소스 관리를 배웠고, 점심시간에도 밥먹으면서 분석하고, 쉬는 시간에 분석하는 행위를 그만두니 약 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;결론적으로는 1. 지식의 편향 인식 2. 자원 관리 방법 학습 3. 자만에 대한 인식을 학습할 수 있었던 프로젝트였고, 내적인 성장을 이룬 프로젝트같다.&amp;nbsp;&lt;/p&gt;</description>
      <category>공부 기록/회고</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/28</guid>
      <comments>https://cysk.tistory.com/28#entry28comment</comments>
      <pubDate>Tue, 27 Jan 2026 08:12:49 +0900</pubDate>
    </item>
    <item>
      <title>1.5 프로젝트 [서울시 부동산 예측 프로젝트]</title>
      <link>https://cysk.tistory.com/27</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째 프로젝트인 서울시 부동산 프로젝트의 아쉬운점과 당시 배우고 있던 ML관련학습을 위해 진행한 프로젝트다.&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;진행기간 : 09/17~10/12(4주)/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;1. 데이터셋&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서울시 부동산의 2010~2024까지의 데이터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행정동-법정동 매핑 데이터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2010~2024 주담대 금리 데이터&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;2.시기 구분&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2586&quot; data-origin-height=&quot;2486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I35a3/dJMcad1ONT9/IjSBwvk1tzhgZgGSi4pS70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I35a3/dJMcad1ONT9/IjSBwvk1tzhgZgGSi4pS70/img.png&quot; data-alt=&quot;주황-신축, 초록-준신축, 파랑-구축&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I35a3/dJMcad1ONT9/IjSBwvk1tzhgZgGSi4pS70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI35a3%2FdJMcad1ONT9%2FIjSBwvk1tzhgZgGSi4pS70%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;393&quot; height=&quot;2486&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2586&quot; data-origin-height=&quot;2486&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;2008년은 다들 기억할지 모르겠지만 리먼브라더스의 파산 이후 전세계적인 금융공황이 있었던 시기이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국은 이것을 극복하는 시기가 2010년으로 금융공황 이후 부동산 시장 역시 회복하던 시기다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 알수 있는 지표로는 2010년 3/4분기에 금리인상을 볼 수 있는데 데이터를 확인한 결과 해당 시기부터 부동산 시장이 성장하고 있음을 알 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 2010~ 2014는 회복기, 2015~2021는 성장기/ 2022~는 조정기라고 정의하고 진행하였다.&lt;/p&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;- 전처리 및 행정동 매핑&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;자치구코드와 법정동 코드를 결합해서 10자리 법정동코드 생성&lt;/li&gt;
&lt;li&gt;10자리 코드를 기준으로 법정동-행정동 매핑, 행정동명 부여&lt;/li&gt;
&lt;li&gt;준공년-계약년 기준으로 5&amp;gt;신축&lt;/li&gt;
&lt;li&gt;신구축 구분과 건물 유형을 조합해서 type1(오피스텔, 연립다가구, 아파트, 신축단독다가구), type2(구축 단독 다가구)&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;가장 고민을 많이 한 부분이다. 단순히 가격이 높다는 것을 기준으로 한다면 특수시장(고가,신축) 관련 데이터가 모두 빠져 나간다. 그렇기에 두가지 방법을 사용해서 각각 진행하였다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Isolation&amp;nbsp;Forest&lt;/li&gt;
&lt;li&gt;ML기반 잔차 평균 이상치 판별&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1769078467560&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 앙상블 세팅

class EnsembleRegressor(BaseEstimator, RegressorMixin):
    def __init__(self, xgb_params=None, cat_params=None):
        self.xgb_params = xgb_params
        self.cat_params = cat_params

    def fit(self, X, y):
        xgb_p = self.xgb_params or {}
        cat_p = self.cat_params or {}
        cat_p_final = {'verbose': False, 'loss_function': 'RMSE', **cat_p}

        self.xgb_model = XGBRegressor(**xgb_p)
        self.cat_model = CatBoostRegressor(**cat_p_final)

        self.xgb_model.fit(X, y)
        self.cat_model.fit(X, y)
        return self

    def predict(self, X):
        pred_xgb = self.xgb_model.predict(X)
        pred_cat = self.cat_model.predict(X)
        return (pred_xgb + pred_cat) / 2

    def get_params(self, deep=True):
        return {&quot;xgb_params&quot;: self.xgb_params, &quot;cat_params&quot;: self.cat_params}

    def set_params(self, **params):
        if &quot;xgb_params&quot; in params:
            self.xgb_params = params.pop(&quot;xgb_params&quot;)
        if &quot;cat_params&quot; in params:
            self.cat_params = params.pop(&quot;cat_params&quot;)
        super().set_params(**params)
        return self

# 메인 함수

def pipeline(input_path: str,
             main_output_path: str,
             specialty_output_path: str,
             quantile_clip: tuple = (0.01, 0.99)):

    #데이터 로드
    df = pd.read_csv(input_path, low_memory=False)
    
    df['contract_date'] = pd.to_datetime(df['contract_date']) 
    df = df.sort_values(by='contract_date').reset_index(drop=True)

        
    print(f&quot;데이터: {len(df):,}건&quot;)

    # 시장 국면 정의
    conditions = [
        df['contract_year'].between(2010, 2014),
        df['contract_year'].between(2015, 2021),
        df['contract_year'] &amp;gt;= 2022
    ]
    df['market_regime'] = np.select(conditions, ['회복기', '상승기', '조정기'], default='기타')

    # 로그 변환
    df['log_price_per_pyeong'] = np.log1p(df['price_per_pyeong'])

    #피처 분리
    categorical_features = ['market_regime', '행정동명', 'property_use', 'age_type']
    numeric_features = ['contract_year']

    X = df[categorical_features + numeric_features]
    y = df['log_price_per_pyeong']

    # 파이프라인 구성
    pipeline = Pipeline([
        ('encoder', TargetEncoder(cols=categorical_features, smoothing=0.3)),
        ('ensemble', EnsembleRegressor())
    ])

    #
    base_xgb_params = {
        'subsample': 0.8,
        'colsample_bytree': 0.8,
        'random_state': 42,
        'tree_method': 'gpu_hist',
        'eval_metric': 'rmse'
    }
    
    base_cat_params = {
        'random_state': 42,
        'task_type': 'GPU'
    }

    # Grid 1: XGB
    grid_1 = [
        {
            'ensemble__xgb_params': [{
                **base_xgb_params,
                'n_estimators': n,
                'max_depth': md,
                'learning_rate': lr
            }],
            'ensemble__cat_params': [base_cat_params]
        }
        for n in [100, 200]
        for md in [3, 5, 7]
        for lr in [0.1, 0.2]
    ]
    
    # Grid 2: CatBoost
    grid_2 = [
        {
            'ensemble__xgb_params': [base_xgb_params],
            'ensemble__cat_params': [{
                **base_cat_params,
                'iterations': i,
                'depth': d,
                'learning_rate': lr
            }]
        }
        for i in [200, 300]
        for d in [3, 5, 7]
        for lr in [0.1, 0.2]
    ]

    param_grid = grid_1 + grid_2

    # GridSearchCV 설정
    cv = TimeSeriesSplit(n_splits=3)
    grid_search = GridSearchCV(
        pipeline,
        param_grid=param_grid,
        scoring=make_scorer(r2_score),
        cv=cv,
        n_jobs=1
    )

    grid_search.fit(X, y)
    display(f&quot; 최적 파라미터: {grid_search.best_params_}&quot;)
    display(f&quot; 최고 교차검증 R&amp;sup2;: {grid_search.best_score_:.3f}&quot;)

    # Out-of-Fold
    best_xgb_params = grid_search.best_params_['ensemble__xgb_params']
    best_cat_params = grid_search.best_params_['ensemble__cat_params']

    final_pipeline = Pipeline([
        ('encoder', TargetEncoder(cols=categorical_features, smoothing=0.3)),
        ('ensemble', EnsembleRegressor(xgb_params=best_xgb_params,
                                        cat_params=best_cat_params))
    ])

    pred_cv = np.full(len(y), np.nan)
    
    for fold, (train_idx, test_idx) in enumerate(cv.split(X, y)):
        display(f&quot;--- Fold {fold+1}/{cv.get_n_splits()} ---&quot;)
        
        X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
        y_train = y.iloc[train_idx]
        
        model = clone(final_pipeline)
        model.fit(X_train, y_train)
        fold_preds = model.predict(X_test)
        
        pred_cv[test_idx] = fold_preds

    # 잔차 계산
    df['pred_ensemble'] = pred_cv
    
    # NaN 값을 원본 값으로 채워 잔차를 0으로 만듦
    df['pred_ensemble'].fillna(df['log_price_per_pyeong'], inplace=True)
    
    df['residual'] = df['log_price_per_pyeong'] - df['pred_ensemble']

    # 이상치 경계 계산 (첫 번째 fold 제외)
    q_low, q_high = quantile_clip
    
    # 잔차가 0이 아닌 (실제 예측이 수행된) 데이터만 필터링
    non_zero_residuals = df[df['residual'] != 0]['residual']
    
    if non_zero_residuals.empty:
        print(&quot;경고: 유효한 잔차가 없음&quot;)
        lower, upper = -np.inf, np.inf
    else:
        # 이 유효한 잔차들만을 기준으로 경계를 계산
        lower = non_zero_residuals.quantile(q_low)
        upper = non_zero_residuals.quantile(q_high)

    display(f&quot;잔차 경계: {q_low*100:.1f}%={lower:.4f}, {q_high*100:.1f}%={upper:.4f}&quot;)

    # 일반시장 / 특수시장 분리
    is_main = df['residual'].between(lower, upper)
    
    # 기본: log_price_per_pyeong 유지
    main_df = df[is_main].copy()
    specialty_df = df[~is_main].copy()

    # 저장
    main_df.to_csv(main_output_path, index=False, encoding='utf-8-sig')
    specialty_df.to_csv(specialty_output_path, index=False, encoding='utf-8-sig')

    display(f&quot; 일반 시장: {len(main_df):,}건 &amp;rarr; '{main_output_path}'&quot;)
    display(f&quot; 특수 시장: {len(specialty_df):,}건 &amp;rarr; '{specialty_output_path}'&quot;)
    display(f&quot; 분리 비율: 일반 {len(main_df)/len(df)*100:.1f}% / 특수 {len(specialty_df)/len(df)*100:.1f}%&quot;)

if __name__ == &quot;__main__&quot;:
    INPUT_PATH = &quot;03_featured_data.csv&quot;
    OUTPUT_MAIN = &quot;04_main_market_data.csv&quot;
    OUTPUT_SPECIAL = &quot;04_specialty_market_data.csv&quot;
    pipeline(
        input_path=INPUT_PATH,
        main_output_path=OUTPUT_MAIN,
        specialty_output_path=OUTPUT_SPECIAL,
        quantile_clip=(0.01, 0.99))&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. GWR을 통한 회복기, 상승기, 조정기별 양상&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/sTB1Q/dJMcadndjso/ivyVCGYxJRqOauHeYX5Muk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sTB1Q/dJMcadndjso/ivyVCGYxJRqOauHeYX5Muk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1561&quot; data-origin-height=&quot;1334&quot; data-filename=&quot;gwr_회복기.png&quot; width=&quot;395&quot; height=&quot;338&quot; style=&quot;width: 49.7668%; margin-right: 10px;&quot; data-widthpercent=&quot;50.35&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sTB1Q/dJMcadndjso/ivyVCGYxJRqOauHeYX5Muk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsTB1Q%2FdJMcadndjso%2FivyVCGYxJRqOauHeYX5Muk%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;1561&quot; height=&quot;1334&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0lh5Y/dJMcabXhQok/0SZN5ca5SvPqh3HGruK9Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0lh5Y/dJMcabXhQok/0SZN5ca5SvPqh3HGruK9Gk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1538&quot; data-origin-height=&quot;1333&quot; data-filename=&quot;gwr_상승기.png&quot; width=&quot;392&quot; data-widthpercent=&quot;49.65&quot; style=&quot;width: 49.0704%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0lh5Y/dJMcabXhQok/0SZN5ca5SvPqh3HGruK9Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0lh5Y%2FdJMcabXhQok%2F0SZN5ca5SvPqh3HGruK9Gk%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;1538&quot; height=&quot;1333&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;gwr_조정기.png&quot; data-origin-width=&quot;1551&quot; data-origin-height=&quot;1335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pGTgd/dJMcaiWnuW3/kIgoBvMfV1zHLvRbtLzrRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pGTgd/dJMcaiWnuW3/kIgoBvMfV1zHLvRbtLzrRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pGTgd/dJMcaiWnuW3/kIgoBvMfV1zHLvRbtLzrRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpGTgd%2FdJMcaiWnuW3%2FkIgoBvMfV1zHLvRbtLzrRK%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;390&quot; height=&quot;1335&quot; data-filename=&quot;gwr_조정기.png&quot; data-origin-width=&quot;1551&quot; data-origin-height=&quot;1335&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분기별 변화가 있는지 확인하기 위해 시도한 여러 방법 중 하나이다. GWR은 어떤 피쳐가 해당 지역에 얼마나 영향을 미쳤는지 확인 하는 분석 방법 중 하나로 시각화를 통해 간단하게 확인할 수 있다는 장점이 있다.&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;이러한 GWR을 통해 서울시 아파트 시장을 회복기(2010~2014), 상승기(2015~2021), 조정기(2022~)로 구분해 GWR로 공간적 이질성을 분석했다. 회복기에는 변동성이 상승 기대를 반영하며 가격에 +영향이 나타났고, 상승기에는 거래량 증가가 핵심 상승 동력으로 특정 지역에서 강한 양(+) 효과가 관찰됐다. 조정기에는 변동성이 리스크로 전환되며 음(-) 영향이 확대되었고, 거래량 효과도 둔화되며 지역별 구조 차이가 뚜렷해졌다.&lt;/p&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. 머신러닝 아키텍쳐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1)거래 원천데이터(건별) &amp;rarr; 2) 월별 집계(시계열) &amp;rarr; 3) 라그/캘린더 피처 생성 &amp;rarr; 4) 타깃을 1개월 ahead로 시프트 &amp;rarr; 5) 각 타깃별 XGBRegressor 학습/평가(최근 24개월 테스트)&lt;/p&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;1. 월x동 인덱스&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. 거래 구성비 (주거, 상업 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 외부 거시 변수 (미분양, 금리, 입주물량)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 시간 변수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. lag 피쳐(1, 2, 3, 6, 12)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 결과 및 인사이트&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&gt;&lt;b&gt;target&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;RMSE(m2)&lt;/td&gt;
&lt;td&gt;MAPE&lt;/td&gt;
&lt;td&gt;NRMSE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;price_index&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;97.54&lt;/td&gt;
&lt;td&gt;6.45%&lt;/td&gt;
&lt;td&gt;10.74%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;단독다가구_price&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;57.94&lt;/td&gt;
&lt;td&gt;7.55%&lt;/td&gt;
&lt;td&gt;10.44%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;아파트_price&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;90.69&lt;/td&gt;
&lt;td&gt;6.97%&lt;/td&gt;
&lt;td&gt;8.22%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;연립다세대_price&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;93.02&lt;/td&gt;
&lt;td&gt;11.65%&lt;/td&gt;
&lt;td&gt;14.04%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;오피스텔_price&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;41.25&lt;/td&gt;
&lt;td&gt;4.52%&lt;/td&gt;
&lt;td&gt;5.53%&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) 오피스텔은 예측 정확도가 가장 높았다 (MAPE 4.52%, NRMSE 5.53%)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실거주 수요보다 임대 수익 기반의 투자 성격이 강해서 정책, 거시 변수의 단기 충격에 덜 민감한 편이다. 이로 인해 가격 변동 구조가 비교적 단순하며, 월 단위 시계열에서 추세, 관성 효과가 강하게 나타나 lag기반 피쳐가 효과적으로 작동한것으로 보인다.&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;2) 아파트는 절대 오차 (RMSE)는 크지만 상대 성능은 양호함(NRMSE 8.22%)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아파트는 거래 규모와 가격 레벨 자체가 높기 대문에 RMSE처럼 절대 단위 기반 지표에서는 오차가 크게 나타나기 쉽다. 반면 평균 대비 정규화 지표를 기준으로 보면 상대적으로 낮은 수준으로 전반적인 가격 흐름과 추세는 안정적으로 예측할 수 있다.&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;3) 연립다세대는 예측 난이도가 가장 높음(MAPE 11.65%, NRMSE 14.04)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연립/다세대는 동일 유형 내에서도 입지, 노후도, 리모델링 여부 등 개별 특성 편차가 크고, 거래량이 아파트 대비 적어 월 단위 집계시 노이즈가 크게 반영될 가능성이 높았다. 또한 특정 지역이나 특정 시점에 거래가 집중되는 구조적 특성이 존재해 단순 lag 기반 시계열 모형에서 설명하기 어려운 변동성이 발생하여 예측 불확실성이 가장 크다.&lt;/p&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) 단독다가구는 절대 오차는 낮지만, 상대 오차는 중간 수준이었다(RMSE 57.94, MAPE 7.55%, NRMSE 10.44%)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단독다가구는 아파트 대비 가격 레벨이 낮거나 거래가 지역적으로 분산되어 RMSE는 상대적으로 작게 나타났다. 다만 NRMSE와 MAPE관점에서는 시장 평균 대비 변동성이 작지 않아 추세 예측은 가능하지만 지역, 개별거래 특성(노후도, 리모델링, 대지지분)으로 인한 비정형 변동이 남아 있는 세그먼트로 해석 할 수 있다.&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;6. 회고 - 아쉬웠던 점&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 무엇을 위한 분석인가?&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;2) 기술 선택이 목적이 되면서 리소스가 분산됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GWR, 다양한 이상치 분리 방법, 다양한 피쳐 엔지니어링 등 여러 기법을 시도했지만, 일부는 필요해서라기 보다는 배운것을 적용해보고 싶어서 선택된 측면이 있다. 학습에는 도움이 되었지만, 프로젝트 완성도 관점에서는 우선순위가 불분명해지고 실행 비용이 증가되었다. 결과적으론 다음 프로젝트(Olist 프로젝트)까지의 시간이 얼마 남지 않아서 황급히 마무리 하면서 완성도도 떨어졌다.&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;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;4) 정리의 필요성&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼에도 불구하고 데이터를 직접 탐색하고, 필요한 변수를 만들고, 로직상 논리적이지 않은 부분은 없는지 파악하고, 좀 더 고도화 하기 위해서는 어떻게 해야할지 고민하면서 데이터 기반의 문제 해결의 순서를 몸으로 익힌 프로젝트가 아니였나 하는 생각이 든다.&amp;nbsp;&lt;/p&gt;</description>
      <category>공부 기록/회고</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/27</guid>
      <comments>https://cysk.tistory.com/27#entry27comment</comments>
      <pubDate>Thu, 22 Jan 2026 20:27:50 +0900</pubDate>
    </item>
    <item>
      <title>두번째 프로젝트 [Olist 전자상거래 데이터 분석]</title>
      <link>https://cysk.tistory.com/26</link>
      <description>&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두번째로 진행한 프로젝트다. 이전 프로젝트에서 내배캠 매니저님이 &quot; 팀원이 틀려도 실행하는게 좋다. 프로젝트의 목적은 배움이고, 실패에서 배운다&quot; 라고 하여서 내 의견을 최대한 배제하고 팀원의 자율성을 존중 한 프로젝트이다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;어느정도로 개입하고 리드해야 하는지 확인할 수 있었던 프로젝트다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;진행 기간 :&amp;nbsp; 2025년 10/13~10/23(9일)/4인&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사용된 데이터 : 캐글에 공개된 2016-09~ 2018-10 &lt;a href=&quot;https://www.kaggle.com/datasets/olistbr/brazilian-ecommerce&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;u&gt;Oilst 전자상거래 데이터&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기여 내역 : 전처리, 분석, 인사이트 도출, 자료수집&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. Olist 기업 분석&lt;/h4&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Olist는 2015년에 설립된 브라질 내 최대 규모 마켓플레이스 중 하나이다. 여러 대형 마켓플레이스(아마존 등)에 Olist store라는 이름으로 상품을 노출, 판매하도록 도와주는 판매자 통합 플랫폼이다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. 데이터 소개&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zlOcc/dJMcaacYR2a/KSSPd66zkXEd9Zk1MeX4C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zlOcc/dJMcaacYR2a/KSSPd66zkXEd9Zk1MeX4C0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zlOcc/dJMcaacYR2a/KSSPd66zkXEd9Zk1MeX4C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzlOcc%2FdJMcaacYR2a%2FKSSPd66zkXEd9Zk1MeX4C0%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;509&quot; height=&quot;1232&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 8개의 주요 테이블로 이루어져 있으며 카테고리의 이름을 영어로 번역한 1개의 추가적인 테이블로 이루어져 있다.(총 9개의 테이블)&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;3. 전처리 내역&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 테이블의 PK를 통해 데이터를 합쳤다.&lt;/li&gt;
&lt;li&gt;Payment_type에서 not_defined를 제거하였다.&lt;/li&gt;
&lt;li&gt;배송시간을 파악하기 위해 배송상태가 배송 완료인 것만 필터링 하였다.&lt;/li&gt;
&lt;li&gt;좌표 결측치를 도시의 좌표 중앙값으로 채웠다.&lt;/li&gt;
&lt;li&gt;컬럼 삭제 [리뷰 제목, 내용, 리뷰답변 타임스탬프, 리뷰 작성일, 제품 길이, 높이, 너비, 순차 결제 번호]&lt;/li&gt;
&lt;li&gt;좌표기반 거리 산출 : 판매자와 구매자간 거리산출을 위해 하버사인 공식을 활용하여 거리를 산출하였다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;배송 지연 파생 컬럼 생성 : 예상 배송 완료일 - 고객 배송 완료일(음수는 xx일만큼 배송 지연, 양수면 xx일만큼 빠른 배송)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;남은 결측치 내역&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;1068&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8RqEM/dJMcai9RE26/geyuPQ4bUglAxoy3AP6rYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8RqEM/dJMcai9RE26/geyuPQ4bUglAxoy3AP6rYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8RqEM/dJMcai9RE26/geyuPQ4bUglAxoy3AP6rYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8RqEM%2FdJMcai9RE26%2FgeyuPQ4bUglAxoy3AP6rYK%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;187&quot; height=&quot;415&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;1068&quot;/&gt;&lt;/span&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;이 중 [product_category_name, product_name_lenght, product_description_lenght, product_photos_qty]는 중복 결측치(4개 컬럼 동일 결측치)인것을 확인하였고, 제품 카테고리, 이름, 설명, 사진이 모두 없기에 테스트 페이지나 페이크 상품이라 가정하고 삭제를 진행하였다.&lt;/li&gt;
&lt;li&gt;브라질 좌표계 밖의 데이터가 존재하여 해외구매라 생각하였고, 해외구매의 경우 [1. 구매자가 받았을 때 배송확인을 누른다. 2. 배대지등의 중간 물류 업체가 받고 확인을 누른다] 를 확인 할 수 없어 지오제이슨을 기준으로 필터링 하였다.&lt;/li&gt;
&lt;li&gt;월별 판매 건수를 확인한 결과 2016-9~2016-12까지의 데이터와 2018-09~2018-10의 데이터는 구매횟수가 매우 적어 제거하였다.(2016-9~2016-12 까지는 서비스 극초기, 2018-09~2018-10는 자료 제공을 위한 가공 중에서 데이터가 손실된게 아닌가 하는 생각을 하였다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5iiFC/dJMcadgq6eg/laX0hs1BdPXDZUibqRy8b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5iiFC/dJMcadgq6eg/laX0hs1BdPXDZUibqRy8b0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5iiFC/dJMcadgq6eg/laX0hs1BdPXDZUibqRy8b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5iiFC%2FdJMcadgq6eg%2FlaX0hs1BdPXDZUibqRy8b0%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;605&quot; height=&quot;296&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 분석&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선적인 목표 설정을 재구매율 개선이였다. Olist는 데이터 상 신생 기업이였고, 재구매율이 약 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;/p&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;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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HXWj7/dJMcaaD2J1v/i12CkgqFPRY4cT41Mz5eL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HXWj7/dJMcaaD2J1v/i12CkgqFPRY4cT41Mz5eL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HXWj7/dJMcaaD2J1v/i12CkgqFPRY4cT41Mz5eL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHXWj7%2FdJMcaaD2J1v%2Fi12CkgqFPRY4cT41Mz5eL1%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;549&quot; height=&quot;425&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차적으론 배송 지연과 배송 소요시간이 채택되었다. 다만 데이터의 수가 많을수록 작은 차이여도 P-value는 유의하다고 나오기에 참고용으로만 사용하였다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2차로 box plot과 Q-Q plot, 히스토그램과 기술통계를 통해 분석을 진행하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1579&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKo1cd/dJMcabbSO0E/mKZHdnYkwH3axqx4LFeld1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKo1cd/dJMcabbSO0E/mKZHdnYkwH3axqx4LFeld1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKo1cd/dJMcabbSO0E/mKZHdnYkwH3axqx4LFeld1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKo1cd%2FdJMcabbSO0E%2FmKZHdnYkwH3axqx4LFeld1%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;544&quot; height=&quot;554&quot; data-origin-width=&quot;1579&quot; data-origin-height=&quot;554&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;&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;std로 표기된 표준편차는 11.64로 어떤 배송은 평균보다 11.64일 빨리오거나 늦게 오는 것이 통계적으로 정상범위라는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;min과 max값을 보면 -56과 55로 어떤 경우에는 56일 일찍, 어떤 경우에는 55일 늦게 도착한다는 것으로 배송 프로세스를 전혀 통제하고 있지 않다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 통계도 같은 의미를 지니고 있는데 이는 하단의 접은글에 적도록 하겠다.&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지연일에 대한 박스 플롯 해석&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;박스 크기는 75%값과 25%의 차이인 13일로 박스가 좁게 형성되어 있습니다. 이는 데이터의 절반이 13일내 좁은 범위에 밀집되어 있음을 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 박스의 위치를 보시면 상자 전체가 음수 영역에 치우쳐져 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 배송의 50%가 최소 6일에서 19일 조기 도착 구간에 몰려있음을 보여줍니다.&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;/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;q-q플롯 해석.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파란색 점들은 빨간색 직선인 정규 분포를 따르지 않고 뚜렷한 s자 곡선을 그립니다.&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;/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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;다만 오른쪽 꼬리가 0을 넘어 50일까지 끊이지 않고 길게 이어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 꼬리 때문에 평균이 중앙값보다 높게 왜곡됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&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;그렇기에 재구매율에 영향을 끼치는 요소들이 무엇인지 확인하기 위해 머신러닝을 사용하였고, 교차검증을 위해 XGBoost와 CatBoost를 활용하여 확인하고자 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신러닝은 Accuracy, Recall, Precision, F1 말고도 예측하고자 하는 항목에 어떤 컬럼[특성]이 영향을 미치는지 확인 할 수 있고, 이를 통해 재구매율에 대해 배송관련 소요 시간이 얼마나 영향을 미치는지, 그보다 더 중요한 요소는 없는지 확인하려 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불균형 데이터를 증강하기 위해 SMOTE와 그리드 서치를 사용하였고, SMOTE는 범주형 피쳐도 넣을 수 있는 SMOTENC를 선택하였다. 또한 변수나 모델의 관리를 위하여 PipeLine 라이브러리를 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 해석의 용이성을 위하여&amp;nbsp; SHAP를 사용하였다.&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;514&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/53Qji/dJMcab31kWg/bh5UkWNZLn7Y1ZW3ZVkkkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/53Qji/dJMcab31kWg/bh5UkWNZLn7Y1ZW3ZVkkkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/53Qji/dJMcab31kWg/bh5UkWNZLn7Y1ZW3ZVkkkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F53Qji%2FdJMcab31kWg%2Fbh5UkWNZLn7Y1ZW3ZVkkkK%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;346&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;514&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1583&quot; data-origin-height=&quot;474&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VWT2A/dJMcah4eUoK/zCXChtizrKuQIIBBr8fxAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VWT2A/dJMcah4eUoK/zCXChtizrKuQIIBBr8fxAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VWT2A/dJMcah4eUoK/zCXChtizrKuQIIBBr8fxAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVWT2A%2FdJMcah4eUoK%2FzCXChtizrKuQIIBBr8fxAK%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;737&quot; height=&quot;474&quot; data-origin-width=&quot;1583&quot; data-origin-height=&quot;474&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1338&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d7gFzn/dJMcacaNY72/DH2sC0sEhZc2XXVXngbMZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d7gFzn/dJMcacaNY72/DH2sC0sEhZc2XXVXngbMZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d7gFzn/dJMcacaNY72/DH2sC0sEhZc2XXVXngbMZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd7gFzn%2FdJMcacaNY72%2FDH2sC0sEhZc2XXVXngbMZ1%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;314&quot; data-origin-width=&quot;1338&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shap 영향도 분석 결과 상위 3개 변수는 총 주문량, 배송 기간, 할부 개월수로 동일.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #2c2c2b;&quot; data-token-index=&quot;0&quot;&gt;두 모델 모두 주문 수량, 배송기간, 할부 개월을 동일하게, 동일한 순서로 식별 하였고 &lt;/span&gt;변수 영향 방향성 면에서 색상과 x축, 영향력의 크기 및 분포 면에서 x축, 스케일 및 플롯 모양을 확인 하였을 때 각 변수의 데이터 밀집형태도 거의 동일하여 신뢰할 수 있는 결과라고 판단하였다.&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;span style=&quot;color: #2c2c2b;&quot; data-token-index=&quot;0&quot;&gt;주문 수량이 많고, 할부 기간이 길며, 배송이 빠르면 재구매 확률이 높아진다고 요약 할 수 있다.&lt;/span&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;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 결과를 통해 다음과 같은 결과를 얻을 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Olist의 배송 시스템은 전혀 관리되고 있지 않음.&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;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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7HdQZ/dJMcaiWlFDv/LgnYWjmkZ4BZK8kzVnObgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7HdQZ/dJMcaiWlFDv/LgnYWjmkZ4BZK8kzVnObgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7HdQZ/dJMcaiWlFDv/LgnYWjmkZ4BZK8kzVnObgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7HdQZ%2FdJMcaiWlFDv%2FLgnYWjmkZ4BZK8kzVnObgK%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;1370&quot; height=&quot;682&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 배송 소요 시간이 긴 지역은 북부, 그 다음으로 북동부가 배송소요 시간이 15일 이상으로 물류 효율화가 되지 않은 지역임을 확인하였다.&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;또한 북부의 경우 Olist의 판매자가 남부에 비해 적어 거의 진출하지 않은 지역임을 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 왜 Olist는 북부에 진입하지 않았는가? 왜 남부 먼저 진입하였는지 궁금하여 좀 더 확인하였다&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 data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&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;/div&gt;
&lt;/div&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 data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;998&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cerOPu/dJMcafeinkA/kSGaApC6Vk1A3NbAtcSqr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cerOPu/dJMcafeinkA/kSGaApC6Vk1A3NbAtcSqr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cerOPu/dJMcafeinkA/kSGaApC6Vk1A3NbAtcSqr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcerOPu%2FdJMcafeinkA%2FkSGaApC6Vk1A3NbAtcSqr0%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;344&quot; height=&quot;998&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;998&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오히려 인구 밀집도는 북서부와 남부가 별 차이가 없음을 확인하였다. 또한 북서부 6개주는 인구가 많다는 것을 확인하였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;6개주 인구 다 합치면 2900만으로 브라질 전체 인구 중 27.2%&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각각&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Cear&amp;aacute; :&lt;b&gt;CE : 8904459&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Rio Grande do Norte :&lt;b&gt;RN : 3442175&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Para&amp;iacute;ba :&lt;b&gt;PB : 3972202&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Pernambuco :&lt;b&gt;PE : 9345173&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Alagoas :&lt;b&gt;AL : 3340932&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Sergipe :&lt;b&gt;SE : 22423937&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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 data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;721&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwW1vt/dJMcahJXaPJ/adWHxfq3kYpUHISMGvu380/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwW1vt/dJMcahJXaPJ/adWHxfq3kYpUHISMGvu380/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwW1vt/dJMcahJXaPJ/adWHxfq3kYpUHISMGvu380/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwW1vt%2FdJMcahJXaPJ%2FadWHxfq3kYpUHISMGvu380%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;354&quot; height=&quot;721&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;721&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;북서부는 도시화율이 낮은 낙후지역임을 확인&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지니 계수 및 GDP&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7eLLg/dJMcacPpm6w/WKNzbZpdsYf5X78JGGWxOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7eLLg/dJMcacPpm6w/WKNzbZpdsYf5X78JGGWxOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7eLLg/dJMcacPpm6w/WKNzbZpdsYf5X78JGGWxOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7eLLg%2FdJMcacPpm6w%2FWKNzbZpdsYf5X78JGGWxOK%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;575&quot; height=&quot;550&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;GDP 14.4%를 차지하는 2번째로 부유한 지역이지만 지니계수는 0.559로 불평등이 가장 심한 지역이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약하자면 브라질 내에서 인구와 GDP를 차지하는 비율이 두번째로 많은 고인구, 부유한 지역이지만 지니계수 0.559로 빈부격차가 큰 지역이다. 또한 도시화율이 낮고 내륙의 토지가 역시 낮게 형성되어 있음을 확인할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2326&quot; data-origin-height=&quot;1636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kFdAc/dJMcadAIHoV/ihkJrM2PJTPvwPcyJ5VdlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kFdAc/dJMcadAIHoV/ihkJrM2PJTPvwPcyJ5VdlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kFdAc/dJMcadAIHoV/ihkJrM2PJTPvwPcyJ5VdlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkFdAc%2FdJMcadAIHoV%2FihkJrM2PJTPvwPcyJ5VdlK%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;532&quot; height=&quot;374&quot; data-origin-width=&quot;2326&quot; data-origin-height=&quot;1636&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;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;/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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이를 정리하니 다음과 같은 생각이 들었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;p data-ke-size=&quot;size16&quot;&gt;북서부 지역은 인구 밀집도가 높음에도 물류 인프라 부재로 배송 지연이 심각하다. 이는 해당 지역의 잠재 수요를 저해하는 요소이므로, 물류 거점 확보 혹은 추가적인 판매자 유치를 통한 재구매율 제고 전략이 필요하다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기대 효과&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물류 센터를 지음으로써 얻는 이익은 다음과 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 배송비, 배송일 감소&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Felo6/dJMcaa47vDO/Tyo8K1ehPKe9NBOtsLSHDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Felo6/dJMcaa47vDO/Tyo8K1ehPKe9NBOtsLSHDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Felo6/dJMcaa47vDO/Tyo8K1ehPKe9NBOtsLSHDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFelo6%2FdJMcaa47vDO%2FTyo8K1ehPKe9NBOtsLSHDk%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;1675&quot; height=&quot;245&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 배송비가 평균 64% 감소하여 추가적인 가격 경쟁력을 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타지역에서(남부) 북부로 이송하는 시간을 단축하여 배송일 역시 감소 시킬 수 있다. (67%감소)&lt;/p&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. BM 다각화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올리스트는 판매자와 쇼핑몰, 구매자와 물류 파트너의 관계에서 수수료를 메인 BM으로 삼았다. 이것을 물류 서비스를 통한 수수료로 보완 가능하다.&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. 현재 BM 강화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Olist의 문제점 중 하나는 배송 품질이 전혀 관리되고 있지 않다는 것이다. 이를 물류센터를 지음으로써 해결하고 운영을 통해 물류 시스템을 최적화 하며 남부 판매자의 디메리트(배송기간)을 제거할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 현재의 배송 시스템은 판매자는 개개인의 물류 창고에서 반출하여 배송하는 형식이다. 이는 판매자가 물류 창고를 관리한다는 의미이며 이를 Olist의 물류창고에 입고함으로써 불편도를 하락시킬 수 있다.&amp;nbsp;&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;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 어디에 지어야 할까? 이것을 확인하기 위해 인구밀도와 함께 브라질 내 도로망을 확인하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하단의 접은글은 브라질의 도로 생태계이다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;1120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CDOp6/dJMcafSUk52/S7cGKcg6ZBWx0OUbFh1aTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CDOp6/dJMcafSUk52/S7cGKcg6ZBWx0OUbFh1aTk/img.png&quot; data-alt=&quot;https://link.springer.com/chapter/10.1007/978-3-031-93619-7_9&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CDOp6/dJMcafSUk52/S7cGKcg6ZBWx0OUbFh1aTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCDOp6%2FdJMcafSUk52%2FS7cGKcg6ZBWx0OUbFh1aTk%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;1373&quot; height=&quot;1120&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;1120&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://link.springer.com/chapter/10.1007/978-3-031-93619-7_9&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;671&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9SEFA/dJMcaaYlW4z/3Lc5KMkZEKU0azM67aoZcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9SEFA/dJMcaaYlW4z/3Lc5KMkZEKU0azM67aoZcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9SEFA/dJMcaaYlW4z/3Lc5KMkZEKU0azM67aoZcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9SEFA%2FdJMcaaYlW4z%2F3Lc5KMkZEKU0azM67aoZcK%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;749&quot; height=&quot;671&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;671&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJl2x5/dJMcabXf8PP/23UXHlartmmJaIASdikn9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJl2x5/dJMcabXf8PP/23UXHlartmmJaIASdikn9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJl2x5/dJMcabXf8PP/23UXHlartmmJaIASdikn9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJl2x5%2FdJMcabXf8PP%2F23UXHlartmmJaIASdikn9k%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;1366&quot; height=&quot;674&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&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;&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;첫번째 프로젝트에서 1달이 지난 뒤 진행한 프로젝트이다. 그동안 배운것을 거의 전부 사용한 프로젝트인 것 같다.&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;</description>
      <category>공부 기록/회고</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/26</guid>
      <comments>https://cysk.tistory.com/26#entry26comment</comments>
      <pubDate>Sun, 18 Jan 2026 15:46:31 +0900</pubDate>
    </item>
    <item>
      <title>첫번째 프로젝트 회고[서울시 부동산 데이터 분석]</title>
      <link>https://cysk.tistory.com/25</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;가장 처음으로 했던 프로젝트다. 파이썬을 배운지 2주 뒤에 진행했던것으로 기억난다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 프로젝트다 보니 아쉬운 점도 많고 기간이 7일, 주말 포함하면 9일이 주어졌기에 하지 못한것도 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 파악 및 전처리에 3일, 분석에 2일, 그 외는 ppt제작 및 대본작성을 했으며 사실상 동시에 진행하였다.&lt;/p&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; 2025년 09/04~09/12(7일)/4인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용된 데이터 : 서울 열린 데이터 광장 내 2018~2024 서울시 부동산 거래&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. 프로젝트 배경 및 문제 설정&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;/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;/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;2. 전처리 내역&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;신축(건축 5년 이내), 구축(11년 이상), 준신축(6~10) 파생 컬럼 생성&lt;/li&gt;
&lt;li&gt;평당가 파생 컬럼 생성(단독 다가구는 거래금액 / (토지면적/3.305785)/ 그 외 거래금액/(건물면적/3.305785)&lt;/li&gt;
&lt;li&gt;이상치 및 결측치 제거(토지 면적 결측치 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 기초 분석&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1494&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKojlC/dJMcacojVVI/FRAsKFAKjpOZyRbumC1MCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKojlC/dJMcacojVVI/FRAsKFAKjpOZyRbumC1MCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKojlC/dJMcacojVVI/FRAsKFAKjpOZyRbumC1MCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKojlC%2FdJMcacojVVI%2FFRAsKFAKjpOZyRbumC1MCK%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;1494&quot; height=&quot;709&quot; data-origin-width=&quot;1494&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;/figure&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;건물 유형별로 변동성과 변동폭이 다르다&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1679&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byCQ5y/dJMb99SFZWm/I27uBqlEYniIPkin5vb5ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byCQ5y/dJMb99SFZWm/I27uBqlEYniIPkin5vb5ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byCQ5y/dJMb99SFZWm/I27uBqlEYniIPkin5vb5ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyCQ5y%2FdJMb99SFZWm%2FI27uBqlEYniIPkin5vb5ok%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;1679&quot; height=&quot;593&quot; data-origin-width=&quot;1679&quot; data-origin-height=&quot;593&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가격은 꾸준히 사승하고 있으나 자치구, 법정동별로 상승, 보합, 하락하는 곳이 있다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 분석 설계&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;5. 가설 설정을 위한 단순 테스트&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWO0Qv/dJMcaaRz5El/YeHZQvONmxm7FeVAOZ0ZGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWO0Qv/dJMcaaRz5El/YeHZQvONmxm7FeVAOZ0ZGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWO0Qv/dJMcaaRz5El/YeHZQvONmxm7FeVAOZ0ZGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWO0Qv%2FdJMcaaRz5El%2FYeHZQvONmxm7FeVAOZ0ZGK%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;625&quot; height=&quot;627&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 분석 설계가 가능한지 알아보기 위해 단순하게 나눈 4분면 산점도이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;충분히 의미 있는 분석이 가능하다고 생각해 진행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 분석을 위해 4개의 파생 컬럼을 생성하였다&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;li&gt;CAGR(연평균 복합 성장률)&lt;/li&gt;
&lt;li&gt;변동성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;942&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GcXLy/dJMcabbSpDx/ZV9QUqYg5IhyYpVoKQi1t0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GcXLy/dJMcabbSpDx/ZV9QUqYg5IhyYpVoKQi1t0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GcXLy/dJMcabbSpDx/ZV9QUqYg5IhyYpVoKQi1t0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGcXLy%2FdJMcabbSpDx%2FZV9QUqYg5IhyYpVoKQi1t0%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;612&quot; height=&quot;942&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;942&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;해당 파생 컬럼별로 상 중 하로 분류하였다.&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;6. 결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1490&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAq7P8/dJMb99LS4uY/deWRUCuN64xh3UUkvkJb0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAq7P8/dJMb99LS4uY/deWRUCuN64xh3UUkvkJb0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAq7P8/dJMb99LS4uY/deWRUCuN64xh3UUkvkJb0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAq7P8%2FdJMb99LS4uY%2FdeWRUCuN64xh3UUkvkJb0k%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;627&quot; height=&quot;696&quot; data-origin-width=&quot;1490&quot; data-origin-height=&quot;696&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;다만 여기서 실수가 있었는데 CAGR과 안정성(변동성)에 수식 실수가 있어 전년대비로 나왔다.&lt;/p&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;전처리에 참여한 것은 2일, 분석에 2일을 소모하였는데 분석에 좀 더 시간을 배분했어야 했다.&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;그리고 수면의 중요성을 정말 크게 느꼈는데 분석 중에는 시간이 부족하여 6시에 일어나서 00시에 잠드는 형식으로 진행했었는데 점차 머리가 무거워지면서 머리가 잘 안돌아가서 힘들었다. 이 이후 프로젝트에서는 늦어도 10시, 수면 8시 기상 패턴을 꾸준히 지켰고 어느정도의 퍼포먼스 유지가 되었다.(수면의 중요성..)&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;아래는 프로젝트 종료 이후 스스로 리뷰한 내용이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;1635&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HfnN5/dJMcachybZT/pf0mXLGLFiPc96kn63vi0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HfnN5/dJMcachybZT/pf0mXLGLFiPc96kn63vi0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HfnN5/dJMcachybZT/pf0mXLGLFiPc96kn63vi0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHfnN5%2FdJMcachybZT%2Fpf0mXLGLFiPc96kn63vi0K%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;317&quot; height=&quot;447&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;1635&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>공부 기록/회고</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/25</guid>
      <comments>https://cysk.tistory.com/25#entry25comment</comments>
      <pubDate>Sat, 17 Jan 2026 11:54:46 +0900</pubDate>
    </item>
    <item>
      <title>딕셔너리 및 세트 컴프리헨션</title>
      <link>https://cysk.tistory.com/24</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리스트 컴프리헨션과 마찬가지로 for루프를 한줄로 축약하여 딕셔너리와 세트를 간결하게 생성하는 문법이다.&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;1. 딕셔너리 컴프리헨션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딕셔너리의 {key : value}쌍을 for 루프를 통해 생성한다. 리스트 컴프리헨션과 유사하지만 콜론:을 사용하여 키와 값을 명시해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761737749721&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;new_dict = {key_expression: value_expression for item in iterable}&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;pre id=&quot;code_1761737908026&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n_item = ['asd', 'asdf', 'asdfg']

# 각 이름(key)과 그 이름의 길이(value)를 매핑
item_lengths = {name: len(name) for name in n_item}

print(item_lengths)
출력: {'asd': 3, 'asdf': 4, 'asdfg': 5}&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;리스트 컴프리헨션과 같이 for 루프 뒤에 if를 추가하여 특정 조건을 만족하는 항목들만 딕셔너리로 구성할 수 있다.&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;set을 간결하게 생성하는 방법으로 문법은 리스트 컴프리헨션과 거의 동일하나 []대신 {}를 쓴다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세트 컴프리헨션의 가장 큰 특징은 중복을 자동으로 제거한다는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1761738047275&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;new_set = {expression for item in iterable}&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;pre id=&quot;code_1761738082810&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;numbers = [1, 2, 2, 3, 3, 3, 4]

# 각 숫자를 제곱하여 세트에 저장 중복은 자동 제거
unique_squares = {n**2 for n in numbers}

print(unique_squares)
출력: {1, 4, 9, 16}&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;딕셔너리 vs 세트는 콜론 :의 유무로 판별한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- {k: v for } 딕셔너리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- {v for } 세트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드에서 {}를 그냥 쓰면 파이썬은 이를 빈 딕셔너리로 해석한다. 그렇기에 빈 세트를 만들고 싶다면 컴프리핸션이 아니라 set()를 써야한다&lt;/p&gt;
&lt;pre id=&quot;code_1761738238168&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = {}
print(type(a)) # 출력: &amp;lt;class 'dict'&amp;gt;

b = set()
print(type(b)) # 출력: &amp;lt;class 'set'&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>공부 정리/파이썬</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/24</guid>
      <comments>https://cysk.tistory.com/24#entry24comment</comments>
      <pubDate>Wed, 29 Oct 2025 20:44:10 +0900</pubDate>
    </item>
    <item>
      <title>정말 쉽고 편한 컨텍스트 관리자 Context Manager 기능</title>
      <link>https://cysk.tistory.com/23</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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 예시&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761552664351&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with open('data.txt', 'w') as f:
    f.write('hi')&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;pre id=&quot;code_1761552774881&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;f = open('data.txt', 'w')
f.write('hi')
f.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;컨텍스트 관리자가 없을 때의 문제를 살펴보면 f.write()와 f.close() 사이에서 예외가 발생하면 f.close()가 호출되지 않는다는 것이다. 이로인해 자원이 해제되지 않고 시스템에 남아있게 될 수 있다.&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;이에 대한 전통적인 해결책으로는 try-finally를 사용하는것인데 finally 블록은 try블록에서 예외가 발생하더라도 항상 실행되기 때문이다.&lt;/p&gt;
&lt;pre id=&quot;code_1761552979801&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;f = None
try:
    f = open('test.txt', 'w')
    f.write('hello\n')
    # result = 10 / 0
finally:
    if f is not None:
        f.close()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;result에서 오류가 나도 finally는 항상 실행된다. 그러나 코드가 길어지고 손목도 점점 아파지게 된다.&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;이에 대한 해결책인 with를 이용한 예시&lt;/p&gt;
&lt;pre id=&quot;code_1761553177650&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with open('test.txt', 'w') as f:
    f.write('hi')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 open()이 반환하는 파일 객체(f)가 컨텍스트 관리자이다.&lt;/p&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;pre id=&quot;code_1761553286083&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with open('smote_reg.txt', 'w', encoding='utf-8') as f:
    for i, (name, result) in enumerate(results.items(), 1):
        f.write(f&quot;\n{'='*70}\n{i}. {name} x 재구매율\n{'='*70}\n&quot;)
        f.write(str(result.summary()) + &quot;\n&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1761553307757&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df = pd.read_csv('02_preprosessed_data.csv')
mcs= &quot;컬럼별 결측치 개수\n&quot;
for col in df.columns:
    missing_c = df[col].isnull().sum()
    mcs += f&quot;'{col}' : {missing_c}개\n&quot;
with open('02결측치.txt', 'w', encoding='utf-8') as f:
    f.write(mcs)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ed4QA/dJMcadUAgf4/cpdc38xpmUj5ScJQRqOWvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ed4QA/dJMcadUAgf4/cpdc38xpmUj5ScJQRqOWvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ed4QA/dJMcadUAgf4/cpdc38xpmUj5ScJQRqOWvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEd4QA%2FdJMcadUAgf4%2Fcpdc38xpmUj5ScJQRqOWvK%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;164&quot; height=&quot;533&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;861&quot; data-origin-height=&quot;1485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQC79W/dJMcafkyVy8/h5dDFrdhqkzsSTPshMG1B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQC79W/dJMcafkyVy8/h5dDFrdhqkzsSTPshMG1B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQC79W/dJMcafkyVy8/h5dDFrdhqkzsSTPshMG1B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQC79W%2FdJMcafkyVy8%2Fh5dDFrdhqkzsSTPshMG1B0%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;174&quot; height=&quot;1485&quot; data-origin-width=&quot;861&quot; data-origin-height=&quot;1485&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장 할 수 있어서 전처리 과정에 따른 차이를 따로 메모할 필요가 없고, print()나 display()에서 짤리거나, 이상하게 나올 걱정이 없어서 정말 편하다.&lt;/p&gt;</description>
      <category>공부 정리/파이썬</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/23</guid>
      <comments>https://cysk.tistory.com/23#entry23comment</comments>
      <pubDate>Mon, 27 Oct 2025 17:25:56 +0900</pubDate>
    </item>
    <item>
      <title>pipeline의 개념과 활용</title>
      <link>https://cysk.tistory.com/22</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;scikit-learn의 pipeline은 데이터 전처리 단계와 모델 학습 단계를 하나의 객체로 묶어 순차적으로 실행하도록 돕는 라이브러리다.&lt;/p&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;pipeline을 사용한 것과 사용하지 않은것을 간략하게 도식화 하면 다음과 같다.&lt;/p&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-&amp;gt;변수 선택 -&amp;gt; X_select -&amp;gt; 표준화 -&amp;gt; X_standard + y -&amp;gt; 모델 학습&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pipeline은 여기서 변수 선택부터 모델 클래스까지를 묶어주는 라이브러리로&lt;/p&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,y -&amp;gt; pipeline -&amp;gt; 모델 학습&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드의 구조도 훨씬 간략해지며 pipeline의 구조 자체도 쉽기에 재사용성도 올라가게 된다.&lt;/p&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;데이터 누수란 모델 학습(train)과정에 검증 또는 테스트(test) 데이터의 정보가 포함되어 모델 성능이 비정상적으로 높게 평가되는 현상으로 GridSearchCV나 cross_val_score를 사용하기 전에 전체 데이터셋에 StandardScaler를 적용하면 훈련 데이터뿐만 아니라 검증 데이터의 평균과 표준편차까지 학습에 반영되게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 pipeline을 사용하게 되면 교차 검증의 각 폴드마다 훈련용 폴드 데이터로만 스케일러를 fit하고 검증용 폴드 데이터에는 해당 스케일러 중 transform만 적용하게 된다.&lt;/p&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;pre id=&quot;code_1761551477453&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from xgboost import XGBClassifier
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer

# 'imputer' (변환기) -&amp;gt; 'scaler' (변환기) -&amp;gt; 'model' (추정기/모델)
pipe_xgb = Pipeline([
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler()),
    ('model', XGBClassifier(use_label_encoder=False, eval_metric='logloss'))
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;xgboost를 사용한 예시 코드&lt;/p&gt;
&lt;pre id=&quot;code_1761551613540&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pipe_xgb = Pipeline([
    ('imputer', SimpleImputer(strategy='median')), # 1단계
    ('scaler', StandardScaler()),                  # 2단계
    ('model', XGBClassifier(                       # 3단계
        use_label_encoder=False, 
        eval_metric='logloss', 
        random_state=42
    )) # 3단계
])
pipe_xgb.fit(X_train, y_train)

pipe_cat = Pipeline([
    ('imputer', SimpleImputer(strategy='median')), # 1단계
    ('scaler', StandardScaler()),                  # 2단계
    ('model', CatBoostClassifier(                  # 3단계
        verbose=0,
        random_state=42
    ))
])
pipe_cat.fit(X_train, y_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;catboost와 xgboost를 사용한 예제 코드&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;eval_metric이라는 항목이 있는데 이것은 분류 문제에서 이진분류인지, 다중분류인지에 따라 지정하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;logloss : 이진분류, 모델이 예측한 확률을 평가하며 실제 정담 (0 or 1)에 가까운 확률을 예측할수록 점수가 낮아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mlogloss : 다중 분류, 다중 클래스에서의 logloss이며 클래스의 개수에 따라 logloss로 지정해도 mlogloss로 계산해주는 경우도 있다.&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;회귀 문제 : rmse, mae, rmsle, mape&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순위 문제 : ndcg, map&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>공부 정리/라이브러리</category>
      <author>cysk</author>
      <guid isPermaLink="true">https://cysk.tistory.com/22</guid>
      <comments>https://cysk.tistory.com/22#entry22comment</comments>
      <pubDate>Mon, 27 Oct 2025 17:01:03 +0900</pubDate>
    </item>
  </channel>
</rss>