<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Box World</title>
    <link>https://box-world.tistory.com/</link>
    <description>인공지능 /  앱 개발의 모든 것</description>
    <language>ko</language>
    <pubDate>Wed, 20 May 2026 14:13:52 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Box형</managingEditor>
    <image>
      <title>Box World</title>
      <url>https://tistory1.daumcdn.net/tistory/3830113/attach/2e3ff9f7c2aa4d86b97198eae200c626</url>
      <link>https://box-world.tistory.com</link>
    </image>
    <item>
      <title>GPT-5가 바꾸는 LLM의 법칙: 단일 모델 시대의 종말과 새로운 전략</title>
      <link>https://box-world.tistory.com/85</link>
      <description>&lt;h3&gt;&lt;strong&gt;소개&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;지난 몇 년간 우리는 더 크고, 더 강력한 단일 모델의 등장을 숨 가쁘게 지켜봐왔습니다. 하지만 이제 게임의 규칙이 바뀌고 있습니다. &amp;quot;가장 강력한 모델 하나&amp;quot;를 넘어, 여러 모델이 유기적으로 협력하는 &amp;#39;지능형 시스템&amp;#39;의 시대가 열리고 있습니다. 이 글에서는 가상의 GPT-5 출시를 통해 드러난 새로운 LLM 패러다임을 심층적으로 분석합니다. 단순히 새로운 모델의 성능을 나열하는 대신, 이 변화가 개발자, 기획자, 그리고 기술 리더의 의사결정에 어떤 영향을 미치는지 구체적인 전략과 함께 살펴보겠습니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;strong&gt;본문&lt;/strong&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;strong&gt;1. 거대 모델의 시대는 끝났다: 팀 스포츠로의 전환&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;과거의 LLM 선택은 수동 변속기 차량을 운전하는 것과 같았습니다. 빠른 응답이 필요하면 가벼운 모델을, 깊이 있는 추론이 필요하면 무거운 모델을 직접 선택해야 했습니다. 모든 작업에 동일한 모델을 사용하며 성능과 비용 사이에서 끊임없이 저울질해야 했습니다.&lt;/p&gt;
&lt;p&gt;이제 LLM은 하나의 거대한 두뇌가 아닌, 각기 다른 역할을 수행하는 전문가들로 구성된 &amp;#39;팀&amp;#39;으로 진화하고 있습니다. 이 팀의 중심에는 모든 요청을 지능적으로 분배하는 컨트롤 타워, 즉 &amp;#39;실시간 라우터&amp;#39;가 있습니다.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;2. GPT-5의 심장, &amp;#39;실시간 라우터&amp;#39;의 작동 방식&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;[수정된 설명]&lt;/strong&gt;&lt;br&gt;스크립트에서는 라우터가 항상 최고 성능 모델(GPT-5 Pro)로 요청을 보내 품질을 보장한다고 언급했지만, 실제 핵심은 그 반대입니다. 실시간 라우터의 진정한 역할은 &lt;strong&gt;&amp;#39;동적 컴퓨팅(Dynamic Compute)&amp;#39;&lt;/strong&gt; 입니다. 즉, 모든 요청을 가장 비싸고 강력한 모델로 보내는 것이 아니라, &lt;strong&gt;요청의 복잡도와 의도를 실시간으로 파악하여 가장 적합한 모델에 동적으로 할당&lt;/strong&gt;하는 것입니다.&lt;/p&gt;
&lt;p&gt;이 시스템은 다음과 같이 구성됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;실시간 라우터(Real-time Router):&lt;/strong&gt; 시스템의 총괄 프로젝트 매니저입니다. &amp;quot;오늘 날씨 어때?&amp;quot;와 같은 단순 요청은 빠른 주력 모델에게, &amp;quot;이 복잡한 코드의 버그를 찾고 리팩토링해줘&amp;quot;와 같은 복잡한 요청은 전문가 모델에게 할당하여 자원을 효율적으로 사용합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-5 모델 제품군(Model Suite):&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pro 모델:&lt;/strong&gt; 복잡한 추론, 분석, 창의적 생성을 담당하는 전문가입니다. 비용은 높지만 최고의 성능을 보장합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standard 모델:&lt;/strong&gt; 대부분의 일상적인 작업을 빠르고 효율적으로 처리하는 주력 선수입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;경량 모델(Mini/Nano):&lt;/strong&gt; 대규모 트래픽을 저비용, 저지연으로 처리하는 데 특화된 모델입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;[보강된 설명]&lt;/strong&gt;&lt;br&gt;이 라우터는 단순히 사전에 정의된 규칙에 따라 움직이는 if-else 구문이 아닙니다. 사용자의 피드백(&amp;quot;깊게 생각해봐&amp;quot;와 같은 명시적 지시 포함)을 통해 지속적으로 학습하고 라우팅 정책을 개선하는 &lt;strong&gt;강화 학습(Reinforcement Learning) 루프&lt;/strong&gt;를 포함하고 있습니다. 이는 개발자가 직접 라우팅 로직을 구현해야 했던 기존 방식(e.g., Claude Opus/Sonnet/Haiku)과 차별화되는 지점으로, &amp;#39;그냥 더 잘 작동하는&amp;#39; 매끄러운 경험을 제공하는 핵심 기술입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;strong&gt;[시각 자료 제안]&lt;/strong&gt;&lt;br&gt;&lt;em&gt;사용자 요청 -&amp;gt; 실시간 라우터 -&amp;gt; (분기) -&amp;gt; Pro 모델 / Standard 모델 / 경량 모델&lt;/em&gt; 로 이어지는 간단한 아키텍처 다이어그램을 삽입하면 독자의 이해를 도울 수 있습니다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h4&gt;&lt;strong&gt;3. 열린 생태계와 닫힌 생태계의 공존: OpenAI의 이중 전략&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;이번 변화에서 가장 주목할 만한 전략적 움직임은 최고 성능의 독점 API와 함께, 매우 유능한 &lt;strong&gt;오픈 가중치 모델(Open-weight Model)&lt;/strong&gt;을 동시에 제공한다는 점입니다. 이는 단순한 선택지 추가가 아닌, 시장 전체를 장악하려는 고도의 플랫폼 전략입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;진입 장벽 완화:&lt;/strong&gt; 개발자와 기업은 오픈 가중치 모델을 통해 비교적 낮은 비용으로 LLM 도입을 시작하고, 자체 데이터로 미세 조정(Fine-tuning)하며 기술 내재화를 꾀할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;생태계 포섭(Ecosystem Envelopment):&lt;/strong&gt; &lt;strong&gt;[보강된 설명]&lt;/strong&gt; 이는 경쟁 오픈소스 모델(e.g., Llama, Mistral)의 위협을 무력화하고, 오픈소스 개발자들을 자사 생태계 안으로 끌어들이는 &amp;#39;깔때기(funnel)&amp;#39; 역할을 합니다. 일단 생태계에 진입한 사용자가 더 높은 성능이나 안정성을 원할 때, 가장 자연스러운 다음 단계는 자사의 상위 API 모델로 전환하는 것이기 때문입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;결과적으로, 조직은 데이터 주권과 규제 준수가 중요한 작업은 온프레미스(On-premise, 자체 서버에 직접 설치) 환경의 오픈 가중치 모델로 처리하고, 최고 수준의 성능이 필요한 작업은 API를 호출하는 유연한 하이브리드 아키텍처를 구축할 수 있게 됩니다.&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;4. 개발자의 새로운 현실: &amp;#39;바이브 코딩&amp;#39;과 책임의 균형&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;LLM의 발전은 개발 생산성을 극적으로 끌어올렸습니다. 아이디어를 즉시 코드로 구현하는 이른바 &lt;strong&gt;&amp;#39;바이브 코딩(Vibe Coding)&amp;#39;&lt;/strong&gt; 은 프로토타이핑과 데모 제작 속도를 혁신적으로 단축시킵니다.&lt;/p&gt;
&lt;p&gt;하지만 이는 양날의 검입니다. AI가 생성한 코드를 검증 없이 운영 환경에 적용하는 것은 조용히 기술 부채와 보안 취약점을 쌓는 것과 같습니다. &lt;strong&gt;[보강된 설명]&lt;/strong&gt; 우리는 AI를 &amp;#39;엄청나게 똑똑하지만 사회 경험이 없는 인턴&amp;#39;으로 대해야 합니다. 아이디어 구현 속도는 뛰어나지만, 그 결과물은 반드시 숙련된 시니어 개발자의 감독과 검증을 거쳐야 합니다.&lt;/p&gt;
&lt;p&gt;따라서 다음과 같은 &lt;strong&gt;AI 거버넌스 원칙&lt;/strong&gt;을 개발 파이프라인에 내장해야 합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;인간 검토 필수:&lt;/strong&gt; 모든 AI 생성 코드는 머지(Merge) 전에 반드시 동료 개발자의 코드 리뷰를 거칩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;보안 요구사항 명시:&lt;/strong&gt; 프롬프트에 입력값 검증, 비밀 정보 처리(환경 변수 사용), 일반적인 웹 취약점 방어 등 보안 요구사항을 명확히 포함시킵니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD 파이프라인 자동화:&lt;/strong&gt; 코드 통합 시 정적 분석 보안 테스트(SAST)와 비밀 정보 스캐닝을 자동화하여 사람의 실수를 방지합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;생성 속도가 빨라진 만큼, 검증과 감사의 속도도 자동화를 통해 높여야만 지속 가능한 개발이 가능합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;strong&gt;결론: 당신의 다음 행동 계획&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;거대한 단일 모델에 모든 것을 의존하던 시대는 저물고 있습니다. 이제는 상황에 맞게 최적의 도구를 조합하고 지능적으로 분배하는 &amp;#39;시스템 아키텍처&amp;#39; 관점이 중요해졌습니다.&lt;/p&gt;
&lt;p&gt;당장 내일부터 적용할 수 있는 액션 아이템은 다음과 같습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI 게이트웨이 구축:&lt;/strong&gt; 모든 LLM 요청을 단일 창구(게이트웨이)를 통해 관리하세요. 이를 통해 요청의 민감도, 복잡도, 비용 기준에 따라 사내 모델과 외부 API로 라우팅하는 규칙을 중앙에서 관리할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;내부 벤치마크 수립:&lt;/strong&gt; 공개된 순위표에만 의존하지 마세요. 우리 회사의 실제 데이터와 핵심 과제를 바탕으로 한 내부 성능 평가 기준을 만들고, 주기적으로 여러 모델을 테스트하여 최적의 솔루션을 찾아야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI 코드 검증 프로세스 확립:&lt;/strong&gt; &amp;#39;바이브 코딩&amp;#39;의 생산성을 수용하되, 프롬프트 가이드라인, 자동화된 보안 스캔, 동료 리뷰를 포함한 코드 검증 프로세스를 개발 문화의 기본값으로 설정하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API의 민첩함과 온프레미스의 통제력을 현명하게 조합하고, 빠른 생성 속도를 자동화된 검증으로 뒷받침하는 팀이 앞으로의 AI 시대를 주도하게 될 것입니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;&lt;strong&gt;핵심 내용 퀴즈&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;이 글을 잘 이해했는지 간단한 퀴즈로 확인해보세요!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q1. GPT-5 시스템의 &amp;#39;실시간 라우터&amp;#39;는 사용자 요청을 어떻게 처리하는 것이 핵심 원칙인가요?&lt;/strong&gt;&lt;br&gt;a) 모든 요청을 항상 최고 성능의 Pro 모델로 보내 최고의 품질을 보장한다.&lt;br&gt;b) 요청의 복잡도를 분석하여 가장 비용 효율적인 모델에 동적으로 할당한다.&lt;br&gt;c) 사용자가 직접 모델을 선택할 때까지 대기한다.&lt;br&gt;d) 무작위로 여러 모델에 요청을 분산시킨다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q2. OpenAI가 강력한 API와 함께 오픈 가중치 모델을 출시하는 가장 큰 전략적 이유는 무엇일까요?&lt;/strong&gt;&lt;br&gt;a) 모든 소프트웨어를 무료로 제공하기 위한 자선 활동이다.&lt;br&gt;b) 개발자들이 쉽게 LLM을 시작하게 하여 자사 생태계로 유입시키고, 궁극적으로 상위 API 사용자로 전환시키기 위함이다.&lt;br&gt;c) API 서버의 부하를 줄이기 위해서다.&lt;br&gt;d) 오픈소스 커뮤니티의 피드백을 받아 모델을 개선하기 위해서다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q3. &amp;#39;바이브 코딩&amp;#39;으로 AI가 생성한 코드를 운영 환경에 적용할 때, 보안과 품질을 위해 가장 중요한 원칙은 무엇인가요?&lt;/strong&gt;&lt;br&gt;a) AI가 만든 코드는 완벽하므로 별도의 검증 없이 즉시 배포한다.&lt;br&gt;b) 코드 생성 속도를 높이기 위해 동료 리뷰와 같은 절차는 생략한다.&lt;br&gt;c) AI가 똑똑한 주니어 개발자라고 생각하고, 반드시 인간의 코드 리뷰와 자동화된 보안 검증 절차를 거친다.&lt;br&gt;d) 프롬프트 작성에만 집중하고, 생성된 코드의 내용은 신경 쓰지 않는다.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;정답 확인&lt;/summary&gt;
&lt;p&gt;Q1: b) 요청의 복잡도를 분석하여 가장 비용 효율적인 모델에 동적으로 할당한다.&lt;/p&gt;
&lt;p&gt;Q2: b) 개발자들이 쉽게 LLM을 시작하게 하여 자사 생태계로 유입시키고, 궁극적으로 상위 API 사용자로 전환시키기 위함이다.&lt;/p&gt;
&lt;p&gt;Q3: c) AI가 똑똑한 주니어 개발자라고 생각하고, 반드시 인간의 코드 리뷰와 자동화된 보안 검증 절차를 거친다.&lt;/p&gt;
&lt;/details&gt;</description>
      <category>AI</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/85</guid>
      <comments>https://box-world.tistory.com/85#entry85comment</comments>
      <pubDate>Thu, 21 Aug 2025 09:27:04 +0900</pubDate>
    </item>
    <item>
      <title>이제 트랜스포머의 시대는 끝날까? Google Titans 논문 리뷰</title>
      <link>https://box-world.tistory.com/84</link>
      <description>&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot; data-huuid=&quot;16401997114476225749&quot;&gt;무언가가 충분히 중요하다면 확률이 당신에게 유리하지 않더라도 시작하라&lt;/span&gt;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot; data-huuid=&quot;16401997114476225749&quot;&gt;- 일론 머스크 -&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Introduction:&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.gif&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;924&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9m3qy/btsMcPKMdXI/LNZR5AkHsIic9ml4buTbgk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9m3qy/btsMcPKMdXI/LNZR5AkHsIic9ml4buTbgk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9m3qy/btsMcPKMdXI/LNZR5AkHsIic9ml4buTbgk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/9m3qy/btsMcPKMdXI/LNZR5AkHsIic9ml4buTbgk/img.gif&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;1640&quot; height=&quot;924&quot; data-filename=&quot;1.gif&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;924&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ChatGPT 같은 AI 모델이 이전 대화 내용을 기억하는 것처럼 보이는 게 신기하지 않으셨나요? 마치 진짜 기억력이 있는 것 같죠! 하지만 기존 AI 모델, 특히 엄청나게 강력한 &lt;b&gt;Transformer&lt;/b&gt; 모델들은 사실 기억력에 약간 문제가 있습니다. 엄청나게 큰 책을 읽으려고 하는데 한 번에 몇 페이지만 집중할 수 있는 상황이라고 생각해보세요. &lt;b&gt;Transformer&lt;/b&gt;의 &quot;attention&quot; 메커니즘이 대단하긴 하지만, 너무 많은 걸 기억하려고 하면 속도가 느려지고 엄청난 컴퓨팅 파워를 잡아먹거든요. 이 논문에서는 &quot;Titans&quot;라는 새로운 종류의 AI 아키텍처를 소개합니다. 이 녀석은 방대한 양의 정보를 다룰 때도 효과적으로 기억하는 방법을 &lt;i&gt;스스로 학습&lt;/i&gt;하도록 설계되었죠. AI 모델에게 우리처럼 더 나은 장기 기억 능력을 부여하는 거라고 보시면 됩니다!&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Motivation &amp;amp; Contribution:&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 AI에게 기억력이 왜 그렇게 중요할까요? 만약 영화의 마지막 몇 장면만 기억할 수 있다면 전체 줄거리를 이해할 수 있을까요? 연결고리나 큰 그림을 놓치게 되겠죠. 마찬가지로, AI가 긴 이야기, 비디오, 심지어 시간의 흐름에 따른 과학 데이터 같은 복잡한 데이터를 제대로 이해하려면, 최근 정보뿐만 아니라 &lt;i&gt;훨씬 이전&lt;/i&gt;의 정보도 기억해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제점:&lt;/b&gt; 현대 AI의 핵심인 &lt;b&gt;Transformer&lt;/b&gt;는 제한된 &quot;context window&quot; 내에서 관계를 파악하는 데는 환상적입니다. 마치 책의 몇 페이지처럼요. 하지만 context가 책 전체처럼 엄청 길어지면, &lt;b&gt;Transformer&lt;/b&gt;는 힘들어합니다. 속도가 느려지고 엄청난 컴퓨터 메모리를 필요로 하죠. 왜냐하면 &lt;b&gt;Transformer&lt;/b&gt;의 attention 메커니즘은 quadratic cost를 갖기 때문입니다. 즉, context 길이가 길어질수록 처리 비용이 &lt;i&gt;엄청나게&lt;/i&gt; 빠르게 증가한다는 뜻이죠. &lt;b&gt;Linear Transformer&lt;/b&gt;는 이 속도 문제를 해결하기 위해 발명되었지만, 정보를 작은, 고정 크기 메모리에 너무 많이 압축하기 때문에 정확도가 떨어지는 경우가 많습니다. 마치 전체 책을 몇 개의 요점으로 요약하는 것과 같아요. 많은 세부 정보가 사라지죠!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;새로운 점 &amp;amp; 기여: Titans와 Neural Long-Term Memory의 등장!&lt;/b&gt; 이 논문의 핵심 아이디어는 AI 모델에게 attention의 단기 기억과는 &lt;i&gt;별개의&lt;/i&gt;, 학습 가능한 &lt;b&gt;long-term memory&lt;/b&gt; 모듈을 제공하는 겁니다. 마치 현재 문장에 집중하는 작업 기억 (attention)과 전체 책에서 얻은 지식 (long-term memory)을 함께 사용하는 것과 같죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심적인 새로운 점:&lt;/b&gt; Titans는 &lt;i&gt;테스트 시간에 기억하는 법을 학습하는&lt;/i&gt; &lt;b&gt;neural long-term memory&lt;/b&gt;를 도입합니다. 이건 단순히 데이터를 저장하는 게 아니라, AI가 정보를 처리하면서 효과적으로 기억하는 &lt;i&gt;방법&lt;/i&gt;을 능동적으로 학습하는 거죠. 인간의 기억에서 영감을 얻어 &quot;surprise&quot; 메트릭을 사용하여 무엇을 기억할지 결정합니다. 이건 &lt;b&gt;meta-learning&lt;/b&gt; 접근 방식입니다. 메모리 모듈이 &lt;i&gt;학습하고 기억하는 방법&lt;/i&gt;을 학습하는 거죠. 게다가, 이들은 이 &lt;b&gt;long-term memory&lt;/b&gt;를 Titans라고 부르는 아키텍처에서 전통적인 attention (short-term memory)과 통합하는 다양한 방법을 설계하여 유연성과 효율성을 제공합니다. 이것은 단순히 attention을 더 빠르게 만드는 것에서 벗어나, AI 모델이 메모리를 처리하는 방식을 근본적으로 다시 생각하는 중대한 변화입니다. 인간의 인지에서 영감을 얻은 거죠! 한마디로: &quot;Attention은 현재에 집중하는 데는 좋지만, 과거를 위해서는 &lt;i&gt;다른 종류의 메모리&lt;/i&gt;가 필요하고, AI는 그걸 효과적으로 사용하는 법을 &lt;i&gt;학습&lt;/i&gt;할 수 있다!&quot;라고 말하는 겁니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Method:&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이제 Titans가 실제로 어떻게 기억하는 법을 배우는지 자세히 알아봅시다. 좀 복잡하게 들릴 수도 있지만, 차근차근 살펴볼게요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Neural Long-Term Memory: Surprise로부터 배우기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Titans의 핵심은 &lt;b&gt;neural long-term memory module&lt;/b&gt;입니다. 이 모듈은 과거의 정보를 저장하고 검색하는 방법을 배우는 별도의 neural network와 같습니다. 그런데 &lt;i&gt;무엇&lt;/i&gt;을 기억할지는 어떻게 결정할까요? 핵심 아이디어는 바로 &lt;b&gt;surprise&lt;/b&gt;입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각해보세요. 놀랍거나 예상치 못한 일을 더 잘 기억하는 경향이 있잖아요? Titans의 메모리 모듈도 비슷하게 작동합니다. &lt;b&gt;surprise metric&lt;/b&gt;을 사용해서 각각의 새로운 정보가 얼마나 &quot;예상 밖&quot;인지 파악하는 거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 surprise metric은 neural network의 입력에 대한 &lt;b&gt;gradient&lt;/b&gt;를 사용하여 계산됩니다. &quot;gradient&quot;라는 기술 용어에 너무 얽매이지 마세요. 그냥 모델의 &quot;기대&quot;가 새로운 입력에 의해 얼마나 위반되는지를 측정하는 거라고 생각하면 됩니다. &lt;i&gt;큰 gradient&lt;/i&gt;는 높은 surprise를 의미합니다. 즉, 모델이 새롭거나 예상치 못한 것을 배우고 있다는 거죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메모리 업데이트 방정식 (초기 Surprise Metric):&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$M_t = M_{t-1} - \theta_t \nabla l(M_{t-1}; x_t)$$&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;$M_t$: 현재 시점 $t$에서의 메모리입니다. 장기 기억의 현재 상태라고 생각하면 됩니다.&lt;/li&gt;
&lt;li&gt;$M_{t-1}$: 이전 시점의 메모리입니다. 지금까지 쌓아온 메모리죠.&lt;/li&gt;
&lt;li&gt;$x_t$: 현재 시점의 새로운 입력입니다.&lt;/li&gt;
&lt;li&gt;$\nabla l(M_{t-1}; x_t)$: 이게 바로 &lt;b&gt;surprise metric&lt;/b&gt;입니다. loss function $l$ (모델이 얼마나 잘 수행하고 있는지를 측정)의 메모리 $M_{t-1}$과 입력 $x_t$에 대한 gradient입니다. gradient가 클수록 surprise가 크다는 뜻이죠.&lt;/li&gt;
&lt;li&gt;$\theta_t$: surprise에 따라 메모리가 얼마나 업데이트되는지를 제어하는 learning rate입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쉽게 말하면:&lt;/b&gt; 메모리 $M_t$는 이전 메모리 $M_{t-1}$을 가져와서 surprise ($\nabla l(M_{t-1}; x_t)$)에 따라 조정하는 방식으로 업데이트됩니다. surprise가 클수록, 이 새롭고 예상치 못한 정보를 통합하기 위해 메모리가 더 많이 변합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개념 체크포인트:&lt;/b&gt; 지금까지, 새로운 정보가 얼마나 놀라운지에 따라 업데이트되는 메모리 모듈을 살펴봤습니다. 이건 마치 장기 기억을 돋보이고 기대에 어긋나는 일에 집중시키는 것과 같죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Surprise Metric 개선: Past and Momentary Surprise&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 surprise metric도 좋지만, 더 개선할 수 있습니다. 때로는 중요한 정보가 큰 surprise &lt;i&gt;이후&lt;/i&gt;에 나타날 수 있는데, surprise metric이 너무 빨리 작아지면 모델이 놓칠 수 있습니다. 이걸 해결하기 위해, Titans는 surprise metric을 두 부분으로 나누어 개선합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Past Surprise ($S_{t-1}$):&lt;/b&gt; 최근 과거의 surprise를 측정합니다. &lt;i&gt;최근&lt;/i&gt;에 놀라운 일이 있었는지를 추적하는 것과 같습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Momentary Surprise ($\nabla l(M_{t-1}; x_t)$):&lt;/b&gt; &lt;i&gt;현재&lt;/i&gt; 입력으로부터의 surprise입니다. 초기 metric과 동일하죠.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개선된 메모리 업데이트 방정식:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$M_t = M_{t-1} + S_t$$&lt;br /&gt;$$S_t = \eta_t S_{t-1} - \theta_t \nabla l(M_{t-1}; x_t)$$&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;$M_t$와 $M_{t-1}$는 이전과 마찬가지로 현재 및 이전 시점의 메모리입니다.&lt;/li&gt;
&lt;li&gt;$S_t$: 시점 $t$에서의 &lt;b&gt;total surprise&lt;/b&gt;입니다. 과거와 현재 surprise의 조합이죠.&lt;/li&gt;
&lt;li&gt;$S_{t-1}$: 이전 시점의 &lt;b&gt;past surprise&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li&gt;$\eta_t$: &lt;b&gt;data-dependent surprise decay&lt;/b&gt;입니다. 과거 surprise ($S_{t-1}$)가 현재로 얼마나 많이 전달되는지를 제어합니다. $\eta_t$가 1에 가까우면 과거 surprise가 강한 영향을 미칩니다. 0에 가까우면 과거 surprise는 빠르게 잊혀지죠. 이건 context 변화를 처리하는 데 중요합니다.&lt;/li&gt;
&lt;li&gt;$\theta_t$: 여전히 learning rate이며, momentary surprise가 업데이트에 얼마나 영향을 미치는지 제어합니다.&lt;/li&gt;
&lt;li&gt;$\nabla l(M_{t-1}; x_t)$: 이전과 동일한 &lt;b&gt;momentary surprise&lt;/b&gt;입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쉽게 말하면:&lt;/b&gt; 메모리 $M_t$는 &lt;i&gt;total surprise&lt;/i&gt; $S_t$를 더하여 업데이트됩니다. total surprise $S_t$는 &lt;i&gt;past surprise*의 감쇠된 버전 ($&amp;eta;&lt;i&gt;t S&lt;/i&gt;{t-1}$)을 취하고 *momentary surprise&lt;/i&gt; ($\theta_t \nabla l(M_{t-1}; x_t)$)를 빼서 계산됩니다. $S_t$를 surprise의 &quot;모멘텀&quot;이라고 생각하면 됩니다. 과거 surprise를 축적하지만, 현재 surprise에 의해서도 구동되죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Gradient Descent with Momentum과의 유사성:&lt;/b&gt; 흥미롭게도, 저자들은 이 공식이 neural network에서 일반적인 최적화 기술인 &lt;b&gt;gradient descent with momentum&lt;/b&gt;과 유사하다고 지적합니다. $S_t$는 모멘텀처럼 작용하여 &quot;surprise&quot; 신호를 시간 경과에 따라 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개념 체크포인트:&lt;/b&gt; 이제 과거와 현재 surprise를 모두 고려하는 더 정교한 surprise metric을 갖게 되었습니다. surprise decay ($\eta_t$)는 모델이 데이터 context에 따라 기억하는 방식을 조정할 수 있게 해줍니다. 이건 즉각적인 surprise에 반응할 뿐만 아니라 시간 경과에 따른 surprise 패턴에도 민감한 메모리를 갖는 것과 같죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Forgetting Mechanism: Adaptive Memory Management&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매우 긴 시퀀스를 다룰 때, 단순히 메모리를 축적하기만 하면 &quot;memory overflow&quot;가 발생하고 성능이 저하될 수 있습니다. Titans는 메모리 용량을 관리하기 위해 &lt;b&gt;forgetting mechanism&lt;/b&gt;을 도입합니다. 이 메커니즘은 과거 메모리를 &lt;i&gt;얼마나&lt;/i&gt; 잊을지 적응적으로 결정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Forgetting Mechanism을 포함한 방정식:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$M_t = (1 - \alpha_t) M_{t-1} + S_t$$&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$M_t$, $M_{t-1}$, $S_t$는 이전과 동일합니다.&lt;/li&gt;
&lt;li&gt;$\alpha_t$: &lt;b&gt;data-dependent forgetting gate&lt;/b&gt;이며, 0과 1 사이의 값입니다. &lt;i&gt;이전 메모리&lt;/i&gt; $M_{t-1}$을 얼마나 유지할지 제어합니다. $\alpha_t$가 0에 가까우면 이전 메모리의 대부분이 유지됩니다. 1에 가까우면 이전 메모리의 대부분이 잊혀지죠.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쉽게 말하면:&lt;/b&gt; 메모리 $M_t$는 이전 메모리 $M_{t-1}$의 &lt;i&gt;일부분&lt;/i&gt; $(1 - \alpha_t)$을 가져와서 total surprise $S_t$를 더하여 업데이트됩니다. forgetting gate $\alpha_t$는 현재 입력을 기반으로 과거 메모리를 얼마나 &quot;decay&quot;하거나 잊을지 학습합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Weight Decay와의 유사성:&lt;/b&gt; 저자들은 또한 이 forgetting mechanism이 overfitting을 방지하는 데 도움이 되는 neural network의 regularization 기술인 &lt;b&gt;weight decay&lt;/b&gt;와 관련이 있다고 언급합니다. 여기서는 memory overflow를 방지하고 관련 정보에 집중하는 데 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개념 체크포인트:&lt;/b&gt; forgetting mechanism을 통해 Titans의 메모리는 적응적이고 효율적이 됩니다. 인간의 기억처럼 중요한 정보는 기억하고 덜 중요한 세부 사항은 잊는 법을 배울 수 있죠!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. Titans 아키텍처: Long-Term Memory 통합&lt;/b&gt;&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/pfALr/btsMcAG3P3k/5ZL0El8MEO6kdZrOkNHV21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pfALr/btsMcAG3P3k/5ZL0El8MEO6kdZrOkNHV21/img.png&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;244&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.6925%; margin-right: 10px;&quot; data-widthpercent=&quot;33.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pfALr/btsMcAG3P3k/5ZL0El8MEO6kdZrOkNHV21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpfALr%2FbtsMcAG3P3k%2F5ZL0El8MEO6kdZrOkNHV21%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;766&quot; height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2zrTg/btsMaVlHprk/5FBtr0WSsXtKB8hKxn2DI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2zrTg/btsMaVlHprk/5FBtr0WSsXtKB8hKxn2DI1/img.png&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;249&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.1615%; margin-right: 10px;&quot; data-widthpercent=&quot;32.93&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2zrTg/btsMaVlHprk/5FBtr0WSsXtKB8hKxn2DI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2zrTg%2FbtsMaVlHprk%2F5FBtr0WSsXtKB8hKxn2DI1%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;769&quot; height=&quot;249&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lICqb/btsMaQY4yo1/Gqj2Dn9Cen50nEf5r8ZfnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lICqb/btsMaQY4yo1/Gqj2Dn9Cen50nEf5r8ZfnK/img.png&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;244&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.8205%;&quot; data-widthpercent=&quot;33.6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lICqb/btsMaQY4yo1/Gqj2Dn9Cen50nEf5r8ZfnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlICqb%2FbtsMaQY4yo1%2FGqj2Dn9Cen50nEf5r8ZfnK%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;769&quot; height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 neural long-term memory module이 있으니, 이걸 실제로 neural network 아키텍처에서 어떻게 사용할까요? 이 논문에서는 이 메모리를 &lt;b&gt;Titans&lt;/b&gt;라고 부르는 아키텍처에 통합하는 세 가지 주요 방법을 제안합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Memory as a Context (MAC):&lt;/b&gt; 이 아키텍처에서는 long-term memory의 출력이 attention에 의해 처리되기 전에 현재 입력과 결합되는 추가 &quot;context&quot;로 취급됩니다. attention이 short-term (현재 입력) 및 long-term memory context 모두에 접근할 수 있도록 하는 것과 같죠.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memory as a Gate (MAG):&lt;/b&gt; 여기서 long-term memory는 핵심 처리 분기 (attention과 같은 short-term memory를 사용)의 정보가 persistent memory와 결합되는 방식을 제어하는 &quot;gate&quot; 역할을 합니다. long-term memory를 사용하여 정보 흐름을 필터링하거나 조절하는 것과 같죠.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memory as a Layer (MAL):&lt;/b&gt; 이 경우, long-term memory module 자체가 neural network의 layer 역할을 하여 attention 메커니즘을 통과하기 &lt;i&gt;전에&lt;/i&gt; 입력 시퀀스를 처리합니다. attention이 현재 context에 집중하기 전에 전용 메모리 처리 단계를 갖는 것과 같죠.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, &lt;b&gt;LMM (Long-term Memory Module)&lt;/b&gt;을 attention이 없는 독립형 모델로 평가하여 long-term memory 자체가 얼마나 효과적인지 확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개념 체크포인트:&lt;/b&gt; Titans는 short-term (attention) 및 long-term memory를 결합하는 다양한 방법을 제공하여 네트워크 내에서 메모리가 활용되는 방식에 유연성을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 효율성을 위한 병렬화:&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4iYjp/btsMaTVEHQx/krcVkABWF2vUXeHrX4xhz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4iYjp/btsMaTVEHQx/krcVkABWF2vUXeHrX4xhz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4iYjp/btsMaTVEHQx/krcVkABWF2vUXeHrX4xhz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4iYjp%2FbtsMaTVEHQx%2FkrcVkABWF2vUXeHrX4xhz1%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;683&quot; height=&quot;147&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 long-term memory module을 효율적으로 훈련하는 것은 매우 중요합니다. 이 논문에서는 &lt;b&gt;mini-batch gradient descent&lt;/b&gt;와 &lt;b&gt;matmul operations&lt;/b&gt;를 사용하여 훈련 프로세스를 병렬화하는 영리한 방법을 설명합니다. 시퀀스를 청크로 나누고 메모리 업데이트 규칙을 GPU 및 TPU에서 고도로 최적화된 행렬 곱셈 (matmuls)을 사용하여 효율적으로 계산할 수 있도록 재구성합니다. 이렇게 하면 특히 긴 시퀀스의 경우 Titans 훈련 속도가 훨씬 빨라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전체 방법 요약:&lt;/b&gt; Titans는 surprise를 기반으로 기억하는 법을 배우고, 과거 surprise를 통합하고, 적응적으로 잊고, 다양한 아키텍처에 통합될 수 있는 neural long-term memory module을 도입합니다. 훈련 프로세스도 효율성을 위해 병렬화됩니다. AI 모델에 효과적인 long-term memory를 장착하기 위한 포괄적인 접근 방식이죠!&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실험 결과:&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Titans가 실제로 작동하는지 확인하기 위해 연구자들은 다양한 까다로운 task에 대한 광범위한 실험을 수행했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Language Modeling and Common Sense Reasoning:&lt;/b&gt; 표준 언어 벤치마크와 상식 추론 task에서 Titans를 테스트했습니다. &lt;b&gt;결과:&lt;/b&gt; Titans, 특히 MAC, MAG, MAL 변형은 최첨단 linear recurrent 모델과 context window가 제한된 &lt;b&gt;Transformer&lt;/b&gt;보다 우수한 성능을 보였습니다. 독립형 LMM도 강력한 성능을 보여 long-term memory module 자체의 강력함을 강조했습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Needle-in-a-Haystack (NIAH) Task:&lt;/b&gt; 이건 long-context 이해를 테스트하기 위해 특별히 설계된 task입니다. 모델은 매우 긴 문서 (&quot;haystack&quot;) 안에 숨겨진 특정 정보 (&quot;needle&quot;)를 찾아야 합니다. &lt;b&gt;결과:&lt;/b&gt; Titans (특히 MAC)는 &lt;b&gt;GPT-4&lt;/b&gt;와 같은 매우 큰 모델을 포함한 모든 baseline보다 훨씬 뛰어난 성능을 보였습니다. 이는 Titans가 극도로 긴 context를 처리하고 먼 과거로부터 정보를 검색하는 능력이 탁월함을 입증했습니다. haystack이 길어져도 Titans의 성능은 다른 모델만큼 저하되지 않아 더 나은 확장성을 보여주었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;BABILong Benchmark:&lt;/b&gt; 매우 긴 문서에 분산된 사실들을 추론해야 하는 훨씬 더 어려운 long-context 추론 task입니다. &lt;b&gt;결과:&lt;/b&gt; 다시 한번, Titans (MAC)는 &lt;b&gt;GPT-4&lt;/b&gt;와 같은 매우 큰 모델과 심지어 다른 모델의 fine-tuned 버전을 포함한 모든 baseline보다 뛰어난 성능을 보였습니다. 이는 Titans가 복잡한 long-context 시나리오에서 효과적임을 더욱 입증했습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Time Series Forecasting:&lt;/b&gt; Titans는 시계열 데이터의 미래 값을 예측하는 데 테스트되었습니다. &lt;b&gt;결과:&lt;/b&gt; neural memory module (LMM)은 specialized time series 모델을 포함한 모든 baseline보다 뛰어난 성능을 보여 언어뿐만 아니라 다양한 분야에 적용될 수 있음을 보여주었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DNA Modeling:&lt;/b&gt; Titans는 DNA 모델링 task에서도 평가되어 과학 데이터에 대한 적용 가능성을 보여주었습니다. &lt;b&gt;결과:&lt;/b&gt; LMM은 genomics 분야의 최첨단 아키텍처와 경쟁할 만한 성능을 보여 광범위한 적용 가능성을 보여주었습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ablation Studies:&lt;/b&gt; Titans의 각 구성 요소의 기여도를 이해하기 위해 convolution, momentum, weight decay, persistent memory와 같은 부분을 제거하는 ablation studies를 수행했습니다. &lt;b&gt;결과:&lt;/b&gt; 모든 구성 요소가 성능에 긍정적인 영향을 미쳤으며, weight decay, momentum, convolution, persistent memory가 가장 큰 영향을 미쳤습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memory Depth Analysis:&lt;/b&gt; neural memory module의 다양한 깊이를 테스트했습니다. &lt;b&gt;결과:&lt;/b&gt; 더 깊은 메모리 (더 많은 layer)는 일반적으로 특히 더 긴 시퀀스에서 더 나은 성능으로 이어졌지만, 훈련 속도는 약간 느려졌습니다. 이는 메모리 깊이, 성능, 효율성 간의 trade-off를 보여주었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전반적인 실험 검증:&lt;/b&gt; 실험 결과는 neural long-term memory module을 갖춘 Titans가 기존 모델보다 특히 long-context 이해가 필요한 task에서 훨씬 더 효과적임을 설득력 있게 보여줍니다. 또한 효율적이고 확장 가능하여 방대한 양의 정보를 처리하고 기억해야 하는 미래 AI 시스템에 유망한 접근 방식입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;리뷰:&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문은 AI 메모리 분야에서 정말 흥미로운 발전을 제시합니다! 학습 가능한 &lt;b&gt;neural long-term memory&lt;/b&gt;를 갖춘 &quot;Titans&quot; 아키텍처는 AI 모델이 긴 context를 처리하고 시간이 지나도 정보를 &quot;기억&quot;할 수 있는 강력하고 효율적인 방법을 제공합니다. 핵심 혁신은 &quot;surprise&quot; 기반 학습 메커니즘으로, 메모리 모듈이 인간의 인지에서 영감을 받아 무엇을 기억하고 언제 잊을지 적응적으로 학습할 수 있도록 합니다. 실험 결과는 인상적이며, Titans는 특히 long-context 시나리오에서 다양한 까다로운 task에서 최첨단 모델을 능가하는 성능을 보여줍니다. 이 연구는 방대한 양의 데이터로부터 효과적으로 추론하고 학습할 수 있는 AI 시스템을 구축할 수 있는 새로운 가능성을 열어줍니다. 마치 인간처럼요. AI 모델이 고정 크기 메모리에 의존하는 대신 테스트 시간에 &lt;i&gt;어떻게&lt;/i&gt; 기억하는지 능동적으로 학습한다는 아이디어는 중대한 진전이며 AI의 미래에 큰 영향을 미칠 수 있습니다!&lt;/p&gt;</description>
      <category>AI</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/84</guid>
      <comments>https://box-world.tistory.com/84#entry84comment</comments>
      <pubDate>Sun, 9 Feb 2025 15:34:15 +0900</pubDate>
    </item>
    <item>
      <title>[떠먹여주는 논문] CVPR 2024 Best Paper : Generative Image Dynamics</title>
      <link>https://box-world.tistory.com/82</link>
      <description>&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;틀린 질문에서 올바른 답이 나올 수 없다&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;- 최민식, 이상한 나라의 수학자 -&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2YAK1/btsLL6BeAch/ZsKQgIMc2odrs4VuReU5j1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2YAK1/btsLL6BeAch/ZsKQgIMc2odrs4VuReU5j1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2YAK1/btsLL6BeAch/ZsKQgIMc2odrs4VuReU5j1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/2YAK1/btsLL6BeAch/ZsKQgIMc2odrs4VuReU5j1/img.gif&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;512&quot; height=&quot;288&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는&amp;nbsp;종종&amp;nbsp;정지된&amp;nbsp;이미지를&amp;nbsp;보면서도&amp;nbsp;그&amp;nbsp;속에&amp;nbsp;담긴&amp;nbsp;움직임을&amp;nbsp;상상하곤&amp;nbsp;합니다.&amp;nbsp;촛불이&amp;nbsp;흔들리는&amp;nbsp;모습,&amp;nbsp;바람에&amp;nbsp;나뭇잎이&amp;nbsp;바스락거리는&amp;nbsp;소리,&amp;nbsp;잔잔한&amp;nbsp;호숫가의&amp;nbsp;물결&amp;nbsp;등,&amp;nbsp;이러한&amp;nbsp;움직임은&amp;nbsp;우리의&amp;nbsp;지각&amp;nbsp;능력과&amp;nbsp;밀접하게&amp;nbsp;연결되어&amp;nbsp;있습니다.&amp;nbsp;그렇다면&amp;nbsp;이러한&amp;nbsp;자연스러운&amp;nbsp;움직임을&amp;nbsp;컴퓨터가&amp;nbsp;스스로&amp;nbsp;모델링하고&amp;nbsp;생성할&amp;nbsp;수&amp;nbsp;있다면&amp;nbsp;어떨까요?&amp;nbsp;&quot;Generative&amp;nbsp;Image&amp;nbsp;Dynamics&quot;&amp;nbsp;논문은&amp;nbsp;바로&amp;nbsp;이러한&amp;nbsp;질문에서&amp;nbsp;시작되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문에서는 우리가 자연에서 관찰할 수 있는 움직임을 모델링하는 데 집중합니다. 특히, 앞서 언급했던 자연스럽게 반복되는 움직임을 모델링하는 데 초점을 맞추고 있습니다. 단순히&amp;nbsp;움직임을&amp;nbsp;예측하는&amp;nbsp;것을&amp;nbsp;넘어,&amp;nbsp;사용자의&amp;nbsp;상호작용에&amp;nbsp;반응하는&amp;nbsp;인터랙티브&amp;nbsp;시뮬레이션까지&amp;nbsp;가능하게&amp;nbsp;하는&amp;nbsp;것이&amp;nbsp;이&amp;nbsp;논문의&amp;nbsp;핵심&amp;nbsp;목표입니다.&amp;nbsp;이러한&amp;nbsp;목표를&amp;nbsp;달성하기&amp;nbsp;위해&amp;nbsp;이&amp;nbsp;논문에서는&amp;nbsp;&lt;b&gt;스펙트럴&amp;nbsp;볼륨(Spectral&amp;nbsp;Volume)&lt;/b&gt; 이라는 새로운 모션 표현 방법을 도입하고, 이를 &lt;b&gt;diffusion model&lt;/b&gt;과 결합하여 효과적으로 모델링하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스펙트럴&amp;nbsp;볼륨(Spectral&amp;nbsp;Volume):&amp;nbsp;움직임을&amp;nbsp;주파수로&amp;nbsp;표현하다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논문의&amp;nbsp;핵심&amp;nbsp;아이디어&amp;nbsp;중&amp;nbsp;하나는&amp;nbsp;이미지&amp;nbsp;내&amp;nbsp;움직임을&amp;nbsp;주파수&amp;nbsp;공간에서&amp;nbsp;표현하는&amp;nbsp;것입니다.&amp;nbsp;이를&amp;nbsp;위해&amp;nbsp;이&amp;nbsp;논문에서는&amp;nbsp;스펙트럴&amp;nbsp;볼륨(Spectral&amp;nbsp;Volume)이라는&amp;nbsp;새로운&amp;nbsp;개념을&amp;nbsp;도입합니다.&amp;nbsp;스펙트럴&amp;nbsp;볼륨은&amp;nbsp;이미지&amp;nbsp;내&amp;nbsp;각&amp;nbsp;픽셀의&amp;nbsp;시간적&amp;nbsp;움직임&amp;nbsp;변화를&amp;nbsp;푸리에&amp;nbsp;변환하여&amp;nbsp;얻어진&amp;nbsp;주파수&amp;nbsp;기반&amp;nbsp;표현입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&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;&lt;/b&gt;예를&amp;nbsp;들어,&amp;nbsp;바람에&amp;nbsp;흔들리는&amp;nbsp;나뭇잎의&amp;nbsp;움직임을&amp;nbsp;생각해보면,&amp;nbsp;그&amp;nbsp;움직임은&amp;nbsp;여러&amp;nbsp;주파수&amp;nbsp;성분의&amp;nbsp;조합으로&amp;nbsp;표현될&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;나뭇잎의&amp;nbsp;전체적인&amp;nbsp;흔들림은&amp;nbsp;저주파&amp;nbsp;성분으로,&amp;nbsp;나뭇잎&amp;nbsp;끝의&amp;nbsp;미세한&amp;nbsp;떨림은&amp;nbsp;고주파&amp;nbsp;성분으로&amp;nbsp;표현되는&amp;nbsp;것이죠.&amp;nbsp;이러한&amp;nbsp;움직임을&amp;nbsp;각&amp;nbsp;주파수&amp;nbsp;성분으로&amp;nbsp;분해하여&amp;nbsp;표현하는&amp;nbsp;것이&amp;nbsp;스펙트럴&amp;nbsp;볼륨의&amp;nbsp;핵심입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ S(p) = FFT(F(p)) $$&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;수식은&amp;nbsp;픽셀&amp;nbsp;p에서의&amp;nbsp;움직임&amp;nbsp;F(p)를&amp;nbsp;푸리에&amp;nbsp;변환(FFT,&amp;nbsp;Fast&amp;nbsp;Fourier&amp;nbsp;Transform)하여&amp;nbsp;스펙트럴&amp;nbsp;볼륨&amp;nbsp;S(p)를&amp;nbsp;얻는&amp;nbsp;과정을&amp;nbsp;나타냅니다.&amp;nbsp;여기서&amp;nbsp;F(p)는&amp;nbsp;픽셀의&amp;nbsp;움직임을&amp;nbsp;시간&amp;nbsp;축에&amp;nbsp;따라&amp;nbsp;나타낸&amp;nbsp;것이고,&amp;nbsp;FFT를&amp;nbsp;통해&amp;nbsp;이&amp;nbsp;움직임을&amp;nbsp;각&amp;nbsp;주파수&amp;nbsp;성분으로&amp;nbsp;분해합니다.&amp;nbsp;즉,&amp;nbsp;복잡한&amp;nbsp;움직임을&amp;nbsp;여러&amp;nbsp;주파수&amp;nbsp;성분으로&amp;nbsp;분해하여&amp;nbsp;분석하기&amp;nbsp;위한&amp;nbsp;수식입니다.&amp;nbsp;이렇게&amp;nbsp;얻어진&amp;nbsp;S(p)는&amp;nbsp;각&amp;nbsp;주파수&amp;nbsp;성분의&amp;nbsp;진폭과&amp;nbsp;위상을&amp;nbsp;포함하는&amp;nbsp;복소수로&amp;nbsp;표현됩니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;움직임을&amp;nbsp;주파수&amp;nbsp;공간에서&amp;nbsp;표현하는&amp;nbsp;이유는&amp;nbsp;무엇일까요?&amp;nbsp;&lt;b&gt;자연&amp;nbsp;현상의&amp;nbsp;움직임은&amp;nbsp;대부분&amp;nbsp;진동&amp;nbsp;운동이나&amp;nbsp;반복&amp;nbsp;운동과&amp;nbsp;같은&amp;nbsp;주기성을&amp;nbsp;가지기&amp;nbsp;때문입니다.&amp;nbsp;&lt;/b&gt;이러한&amp;nbsp;주기적인&amp;nbsp;움직임은&amp;nbsp;푸리에&amp;nbsp;변환을&amp;nbsp;통해&amp;nbsp;다양한&amp;nbsp;주파수&amp;nbsp;성분으로&amp;nbsp;분해할&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;각&amp;nbsp;주파수&amp;nbsp;성분의&amp;nbsp;진폭과&amp;nbsp;위상을&amp;nbsp;조절함으로써&amp;nbsp;다양한&amp;nbsp;움직임을&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게&amp;nbsp;말해,&amp;nbsp;우리가&amp;nbsp;음악을&amp;nbsp;들을&amp;nbsp;때&amp;nbsp;여러&amp;nbsp;악기의&amp;nbsp;소리가&amp;nbsp;섞여&amp;nbsp;있는&amp;nbsp;것처럼,&amp;nbsp;자연의&amp;nbsp;움직임도&amp;nbsp;여러&amp;nbsp;주파수의&amp;nbsp;진동이&amp;nbsp;섞여&amp;nbsp;있다고&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이러한&amp;nbsp;각&amp;nbsp;주파수&amp;nbsp;성분을&amp;nbsp;분리해서&amp;nbsp;분석하고&amp;nbsp;조작하는&amp;nbsp;것이&amp;nbsp;스펙트럴&amp;nbsp;볼륨의&amp;nbsp;핵심입니다.&amp;nbsp;따라서&amp;nbsp;스펙트럴&amp;nbsp;볼륨은&amp;nbsp;장기간에&amp;nbsp;걸친&amp;nbsp;움직임을&amp;nbsp;효율적으로&amp;nbsp;모델링하는&amp;nbsp;데&amp;nbsp;효과적인&amp;nbsp;표현&amp;nbsp;방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Frequency-Coordinated Diffusion Model 을 이용한 스펙트럴 볼륨 예측&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스펙트럴 볼륨을 얻었다면 이제 이를 예측하는 방법을 알아야 합니다. 이 논문에서는 Latent Diffusion Model을 사용하여 스펙트럴 볼륨을 예측합니다. LDM은 이미지 또는 데이터의 잠재 공간에서 점진적으로 노이즈를 제거하여 새로운 데이터를 생성하는 생성 모델입니다. LDM은 VAE(Variational Autoencoder)를 통해 입력 데이터를 잠재 공간(latent space)으로 인코딩 한 뒤, 확산 과정을 통해 노이즈를 추가하고, 디노이즈 과정을 통해 다시 복원하여 원본과 유사한 데이터를 생성하는 방식으로 학습됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1470&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4001r/btsLM6Aqm99/K5DCHPNAK4FKGFnHpFkgJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4001r/btsLM6Aqm99/K5DCHPNAK4FKGFnHpFkgJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4001r/btsLM6Aqm99/K5DCHPNAK4FKGFnHpFkgJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4001r%2FbtsLM6Aqm99%2FK5DCHPNAK4FKGFnHpFkgJ0%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;1470&quot; height=&quot;612&quot; data-origin-width=&quot;1470&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&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;확산 모델을 사용하여 스펙트럴 볼륨을 예측하는 과정을 보여줍니다. 입력 이미지를 VAE를 통해 latent space로 인코딩한 후, LDM을 사용하여 점진적으로 노이즈를 제거하면서 스펙트럴 볼륨을 예측합니다. 그림에서는 각 단계를 시각적으로 나타내어 이해를 돕습니다. 특히, 그림에서 각 블록이 2D 공간 레이어와 어텐션 레이어를 번갈아 사용하는 모습을 확인할 수 있습니다. 이는 주파수 성분 간의 의존성을 효율적으로 모델링하기 위한 핵심적인 구조입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 논문에서는 특히 Diffusion Model을 사용하여, 모션의 움직임을 표현하는 스펙트럴 볼륨을 예측합니다. 자연스러운 움직임은 다양한 주파수 성분의 조합으로 이루어져 있으며, 각 주파수 성분은 서로 긴밀하게 연결되어 있습니다. &lt;b&gt;따라서 스펙트럴 볼륨을 예측할 때 각 주파수 성분 간의 상관관계를 고려하는 것이 중요합니다.&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 단일 확산 모델을 사용하여 모든 주파수 성분을 한 번에 예측하거나, 각 주파수에 대해 독립적인 확산 모델을 사용하는 방식이 있었습니다. &lt;b&gt;하지만 이 논문에서는 각 주파수 성분에 대해 독립적인 확산 모델을 사용하되, 각 확산 모델의 중간 레이어에 어텐션 레이어를 도입하여 주파수 성분 간의 의존성을 학습합니다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 함으로써 각 주파수 성분이 독립적으로 예측되는 것이 아니라, 서로 연관된 정보를 공유하면서 더욱 자연스러운 스펙트럴 볼륨을 생성할 수 있습니다. 예를 들어, 나뭇잎의 흔들림을 모델링할 때, 저주파 성분이 전체적인 움직임을 담당하고 고주파 성분이 미세한 떨림을 담당한다면, 이 둘 간의 관계를 명시적으로 학습하여 더욱 현실적인 움직임을 예측할 수 있는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ ​L_{LDM}&amp;nbsp;=&amp;nbsp;E_{n\in&amp;nbsp;U[1,N],&amp;nbsp;e_n\in&amp;nbsp;N(0,1)}&amp;nbsp;[||e_n&amp;nbsp;-&amp;nbsp;\epsilon_\theta&amp;nbsp;(z_n;&amp;nbsp;n,&amp;nbsp;c)&amp;nbsp;||^2] $$&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;DM(Latent Diffusion Model)의 학습 손실 함수입니다. 여기서 $e_n$은 실제 노이즈, $\epsilon_\theta (z_n; n, c)$는 확산 모델이 예측한 노이즈를 의미하며, 이&amp;nbsp;둘&amp;nbsp;사이의&amp;nbsp;차이를&amp;nbsp;최소화하는&amp;nbsp;방향으로&amp;nbsp;모델을&amp;nbsp;학습합니다.&amp;nbsp;즉,&amp;nbsp;확산&amp;nbsp;모델이&amp;nbsp;노이즈를&amp;nbsp;제거하는&amp;nbsp;과정을&amp;nbsp;모방하면서&amp;nbsp;실제&amp;nbsp;데이터를&amp;nbsp;복원하는&amp;nbsp;능력을&amp;nbsp;학습하는&amp;nbsp;것입니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 한 가지 더 중요한 것이 있습니다. 스&lt;b&gt;펙트럴 볼륨은 저주파 성분이 크고 고주파 성분이 작다는 특징을 가지고 있습니다.&lt;/b&gt; 만약 주파수 성분에 대한 아무런 처리 없이 그대로 사용하면 모델이 저주파 성분에만 집중하고 고주파 성분을 무시할 수 있습니다. 이러한 문제를 해결하기 위해 &lt;b&gt;frequency&amp;nbsp;adaptive&amp;nbsp;normalization &lt;/b&gt;과정이 필요합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rGQfa/btsLN00CcaU/sPfgKaLTvF2pZUTo3nYzJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rGQfa/btsLN00CcaU/sPfgKaLTvF2pZUTo3nYzJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rGQfa/btsLN00CcaU/sPfgKaLTvF2pZUTo3nYzJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrGQfa%2FbtsLN00CcaU%2FsPfgKaLTvF2pZUTo3nYzJk%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;597&quot; height=&quot;196&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$ S&amp;rsquo;{fj}(p)&amp;nbsp;=&amp;nbsp;sign(S{fj}(p))&amp;nbsp;*&amp;nbsp;\sqrt{|S_{fj}(p)|&amp;nbsp;/&amp;nbsp;s_{fj}} $$&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;이 수식은 스펙트럴 볼륨 S의 푸리에 계수를 정규화하는 과정입니다. 푸리에 계수의 크기가 이미지의 크기에 따라 달라지는 문제를 해결하고, 모델 학습 시 모든 주파수에서 균등한 학습이 이루어지도록 하기 위해 주파수별로 푸리에 계수를 스케일링합니다. 즉, $s_{fj}$는 각 주파수 $fj$​에 대한 푸리에 계수 크기의 95번째 백분위수이며, 이를 이용하여 푸리에 계수를 재조정하여 모든 주파수 성분이 학습에 균등하게 기여할 수 있도록 합니다. 이 과정을 통해 모델이 특정 주파수 성분에만 편향되지 않고, 전체적인 움직임을 더 정확하게 모델링할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Image-Based&amp;nbsp;Rendering&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이제 힘들게 예측한 스펙트럴 볼륨을 눈으로 볼 수 있도록 만들어야겠죠? 이 단계를 Image-Based Rendering이라 칭합니다. 이미지 기반 렌더링은 3D 모델링 없이 2D 이미지들을 사용하여 새로운 시점의 이미지를 생성하는 기술입니다. 마치 사진들을 짜깁기하여 새로운 풍경을 만드는 것처럼, 이미지 기반 렌더링은 기존 이미지들을 활용하여 움직임을 만들어냅니다. 이 논문에서는 다음과 같은 단계를 거쳐 이미지 기반 렌더링을 수행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgwYni/btsLMon4niT/ahrkUdJ89WcXuhDYPxztJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgwYni/btsLMon4niT/ahrkUdJ89WcXuhDYPxztJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgwYni/btsLMon4niT/ahrkUdJ89WcXuhDYPxztJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgwYni%2FbtsLMon4niT%2FahrkUdJ89WcXuhDYPxztJk%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;585&quot; height=&quot;341&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;341&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;&lt;b&gt;특징 맵 추출&lt;/b&gt;: 먼저, 입력 이미지에서 다양한 스케일의 특징 맵을 추출합니다. 특징 맵은 이미지의 중요한 특징들을 추출한 것으로, 이미지의 윤곽선, 질감, 색상과 같은 정보를 포함합니다. 이 특징 맵들은 마치 이미지의 뼈대와 같은 역할을 합니다. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;움직임&amp;nbsp;텍스처&amp;nbsp;적용&lt;/b&gt;:&amp;nbsp;다음으로,&amp;nbsp;예측된&amp;nbsp;스펙트럴&amp;nbsp;볼륨을&amp;nbsp;기반으로&amp;nbsp;움직임&amp;nbsp;텍스처를&amp;nbsp;생성합니다.&amp;nbsp;움직임&amp;nbsp;텍스처는&amp;nbsp;각&amp;nbsp;픽셀이&amp;nbsp;시간에&amp;nbsp;따라&amp;nbsp;어떻게&amp;nbsp;움직이는지를&amp;nbsp;나타내는&amp;nbsp;벡터&amp;nbsp;정보의&amp;nbsp;집합입니다.&amp;nbsp;이&amp;nbsp;움직임&amp;nbsp;텍스처는&amp;nbsp;마치&amp;nbsp;그림의&amp;nbsp;움직임을&amp;nbsp;표현하는&amp;nbsp;화살표와&amp;nbsp;같은&amp;nbsp;역할을&amp;nbsp;합니다. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&amp;nbsp;맵&amp;nbsp;변형(Warping)&lt;/b&gt;:&amp;nbsp;생성된&amp;nbsp;움직임&amp;nbsp;텍스처를&amp;nbsp;사용하여&amp;nbsp;특징&amp;nbsp;맵을&amp;nbsp;변형합니다.&amp;nbsp;이&amp;nbsp;과정은&amp;nbsp;마치&amp;nbsp;지도&amp;nbsp;위에&amp;nbsp;화살표를&amp;nbsp;따라&amp;nbsp;움직이는&amp;nbsp;것처럼,&amp;nbsp;특징&amp;nbsp;맵의&amp;nbsp;픽셀들을&amp;nbsp;움직임&amp;nbsp;텍스처에&amp;nbsp;따라&amp;nbsp;이동시키는&amp;nbsp;것입니다. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이미지&amp;nbsp;합성&lt;/b&gt;:&amp;nbsp;마지막으로,&amp;nbsp;변형된&amp;nbsp;특징&amp;nbsp;맵을&amp;nbsp;이미지&amp;nbsp;합성&amp;nbsp;네트워크에&amp;nbsp;입력하여&amp;nbsp;최종적으로&amp;nbsp;애니메이션된&amp;nbsp;이미지를&amp;nbsp;생성합니다.&amp;nbsp;이&amp;nbsp;단계는&amp;nbsp;마치&amp;nbsp;화가들이&amp;nbsp;물감을&amp;nbsp;덧칠하고&amp;nbsp;혼합하여&amp;nbsp;그림을&amp;nbsp;완성하는&amp;nbsp;과정과&amp;nbsp;유사합니다. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 핵심은 픽셀을 1대1로 대응시키는 것이 아니라, 여러 픽셀의 값을 부드럽게 혼합하여 더 자연스러운 애니메이션을 생성한다는 점입니다. 만약 픽셀을 단순히 이동시키기만 하면 이미지가 찢어지거나 구멍이 생길 수 있습니다. 이러한 문제를 해결하기 위해 &lt;b&gt;feature pyramid soft splatting&lt;/b&gt;이라는 방법을 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마치 물감을 흩뿌리듯이, 소스 픽셀의 값을 여러 타겟 픽셀에 가중치를 두어 분산시켜 보다 부드러운 움직임을 표현하는 것이죠. 또한, 이미지의 여러 스케일에서 특징 맵을 추출하여 움직임 텍스처를 적용함으로써, 저해상도에서는 큰 움직임을, 고해상도에서는 미세한 움직임을 표현하여 애니메이션의 디테일을 향상시킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;Quantitative Results&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WSUNW/btsLMLDARsS/HOYAQ9ZEb5pvB0D2YZ9x00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WSUNW/btsLMLDARsS/HOYAQ9ZEb5pvB0D2YZ9x00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WSUNW/btsLMLDARsS/HOYAQ9ZEb5pvB0D2YZ9x00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWSUNW%2FbtsLMLDARsS%2FHOYAQ9ZEb5pvB0D2YZ9x00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;273&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;273&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;낮은&amp;nbsp;FID,&amp;nbsp;KID,&amp;nbsp;FVD,&amp;nbsp;DTFVD&amp;nbsp;점수:&amp;nbsp;논문에서&amp;nbsp;제시하는&amp;nbsp;방법이&amp;nbsp;기존의&amp;nbsp;single-image&amp;nbsp;animation&amp;nbsp;방법들보다&amp;nbsp;이미지&amp;nbsp;합성&amp;nbsp;품질&amp;nbsp;(FID,&amp;nbsp;KID)&amp;nbsp;및&amp;nbsp;비디오&amp;nbsp;합성&amp;nbsp;품질&amp;nbsp;(FVD,&amp;nbsp;DTFVD)&amp;nbsp;측면에서&amp;nbsp;월등히&amp;nbsp;뛰어난&amp;nbsp;성능을&amp;nbsp;보임.&amp;nbsp;특히,&amp;nbsp;DTFVD&amp;nbsp;(Dynamic&amp;nbsp;Texture&amp;nbsp;Frechet&amp;nbsp;Video&amp;nbsp;Distance)&amp;nbsp;점수는&amp;nbsp;제안&amp;nbsp;방법이&amp;nbsp;자연스러운&amp;nbsp;동적&amp;nbsp;텍스처를&amp;nbsp;잘&amp;nbsp;생성한다는&amp;nbsp;것을&amp;nbsp;입증. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;슬라이딩 윈도우 (Sliding Window) 평가: 슬라이딩 윈도우 FID 및 DTFVD 평가에서 제안 방법이 기존 방법들보다 시간이 지나도 영상 품질 저하가 적고, 일관적인 움직임을 유지함을 확인. 이는 제안 방법이 장기적인 움직임 모델링에 강점을 가지고 있다는 것을 의미함.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;Qualitative Results&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sHGMq/btsLMJZ2JM8/UHexCDkLdcSK9qURRbKrK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sHGMq/btsLMJZ2JM8/UHexCDkLdcSK9qURRbKrK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sHGMq/btsLMJZ2JM8/UHexCDkLdcSK9qURRbKrK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsHGMq%2FbtsLMJZ2JM8%2FUHexCDkLdcSK9qURRbKrK1%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;1198&quot; height=&quot;497&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;497&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;X-t&amp;nbsp;slices&amp;nbsp;시각화:&amp;nbsp;제안&amp;nbsp;방법으로&amp;nbsp;생성한&amp;nbsp;비디오의&amp;nbsp;X-t&amp;nbsp;슬라이스(시간에&amp;nbsp;따른&amp;nbsp;움직임을&amp;nbsp;시각화한&amp;nbsp;그래프)가&amp;nbsp;ground&amp;nbsp;truth&amp;nbsp;비디오의&amp;nbsp;X-t&amp;nbsp;슬라이스와&amp;nbsp;가장&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;</description>
      <category>AI</category>
      <category>AI</category>
      <category>CVPR</category>
      <category>Diffusion</category>
      <category>논문리뷰</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>생성형</category>
      <category>인공지능</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/82</guid>
      <comments>https://box-world.tistory.com/82#entry82comment</comments>
      <pubDate>Tue, 14 Jan 2025 21:09:54 +0900</pubDate>
    </item>
    <item>
      <title>[ 떠먹여주는 논문 ] Best Paper of NeurIPS 2024, Visual Autoregressive Modeling: Scalable ImageGeneration via Next-Scale Prediction</title>
      <link>https://box-world.tistory.com/81</link>
      <description>&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #9feec3; color: #001d35; text-align: left;&quot;&gt;무언가가 충분히 중요하다면 확률이 당신에게 유리하지 않더라도 시작하라 &lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;span style=&quot;color: #001d35;&quot;&gt;- 일론 머스크-&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;안녕하세요! 오늘은 NeurIPS 2024 베스트 페이퍼로 선정된 &lt;b&gt;&quot;Visual Autoregressive Modeling: Scalable Image Generation via Next-Scale Prediction&quot;&lt;/b&gt; 논문에 대해 이야기해보려고 합니다. 이 논문은 기존 이미지 생성 모델의 한계를 뛰어넘는 새로운 방법론, VAR (Visual Autoregressive Modeling)을 제시합니다. VAR은 이미지의 구조적 특성을 효과적으로 학습하고, 고품질 이미지를 놀라운 속도로 생성할 수 있게 해줍니다. 특히, 이 논문에서는 이미지 생성 분야에서 diffusion 모델이 주류였던 흐름을 뒤집고, autoregressive 모델의 새로운 가능성을 제시했다는 점에서 주목할 만합니다. 본 포스트에서는 VAR의 핵심 아이디어와 작동 원리를 자세히 살펴보고, 실제 적용 가능성과 한계점에 대해 논의해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;이미지 생성 모델의 두 가지 축: Diffusion과 Autoregressive&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지 생성 모델은 크게 두 가지 축으로 나눌 수 있습니다. 첫 번째는 우리가 흔히 아는 diffusion 모델입니다. Diffusion 모델은 이미지에 점진적으로 노이즈를 추가하고, 이를 역으로 제거하는 과정을 학습하여 고품질 이미지를 생성합니다. 최근 몇 년간 diffusion 모델은 이미지 생성 분야에서 뛰어난 성능을 보여주며 많은 발전을 이루어왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;반면, autoregressive (AR) 모델은 이미지의 일부를 생성하고, 이를 기반으로 다음 부분을 생성하는 방식을 사용합니다. AR 모델은 텍스트 생성 분야에서 GPT와 같은 large language model (LLM)의 기반이 되었으며, 이미지 생성 분야에서도 연구가 진행되어 왔습니다. AR 모델은 주로 컨볼루션 또는 트랜스포머 기반의 네트워크를 사용하여 이미지를 생성합니다. 이 논문에서 다루는 VAR 모델도 이러한 AR 모델의 일종으로 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;기존 Autoregressive 모델의 문제점&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존 AR 모델은 이미지를 생성할 때, 이미지를 1차원 토큰 시퀀스로 변환하고 raster-scan 방식으로 순차적으로 토큰을 예측합니다. 이러한 방식은 다음과 같은 문제점을 야기합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;563&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBOqKf/btsLFeE1ekd/c1qPGfE7uth8rbieaFjewK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBOqKf/btsLFeE1ekd/c1qPGfE7uth8rbieaFjewK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBOqKf/btsLFeE1ekd/c1qPGfE7uth8rbieaFjewK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBOqKf%2FbtsLFeE1ekd%2Fc1qPGfE7uth8rbieaFjewK%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;1108&quot; height=&quot;563&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;563&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;&lt;b&gt;&lt;span&gt;Mathematical Premise Violation (수학적 전제 위반):&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 이미지의 토큰들은 양방향 상관관계를 가지지만, 기존 AR 모델은 토큰들을 일방향으로 순차적으로 생성합니다. 이는 모델이 이미지의 전체적인 구조를 이해하는 데 어려움을 초래합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Inability to Perform Some Generalization (일반화 능력 부족):&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 순차적인 생성 방식은 모델이 학습하지 않은 순서로 입력이 주어질 때 성능 저하를 야기합니다. 예를 들어, 이미지를 위에서 아래로 학습한 모델은 아래에서 위로 생성하는 작업을 잘 수행하지 못합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Structural Degradation (구조적 손상):&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 이미지를 1차원으로 펼치는 과정에서 인접 토큰 간의 공간적 관계가 손실됩니다. 이로 인해 모델이 이미지의 구조적 정보를 효과적으로 학습하기 어렵습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Inefficiency (비효율성):&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 이미지 토큰의 개수가 증가함에 따라, AR 모델의 계산 복잡도가 급격하게 증가합니다 (O(n⁶)). 이러한 계산 복잡도는 고해상도 이미지 생성에 큰 제약으로 작용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;VAR: Next-Scale Prediction 기반의 새로운 패러다임&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;VAR은 이러한 기존 AR 모델의 문제점을 해결하기 위해, 이미지를 &quot;next-token prediction&quot;이 아닌 &quot;next-scale prediction&quot; 방식으로 생성합니다. VAR은 이미지를 여러 단계의 해상도를 가지는 토큰 맵으로 표현하고, autoregressive하게 낮은 해상도부터 높은 해상도 순서로 토큰 맵을 생성합니다. 이 과정을 coarse-to-fine 방식으로 명명하며, 기존의 raster-scan 방식과 차별점을 둡니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Multi-scale VQVAE:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; VAR은 먼저 이미지를 multi-scale VQVAE (Vector Quantized Variational Autoencoder)를 사용하여 여러 해상도의 토큰 맵으로 인코딩합니다. VQVAE는 이미지의 고차원 feature를 이산적인 코드 벡터로 양자화하는 모델입니다. 각 해상도 레벨에서 추출된 feature map은 코드북을 사용하여 양자화되어 토큰 맵으로 표현됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;VAR Transformer:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 그 다음으로, VAR transformer는 이전 단계의 모든 토큰 맵을 조건으로 하여 다음 해상도 토큰 맵을 생성합니다. 각 단계에서 토큰 맵 내의 토큰들은 병렬적으로 생성되므로 계산 효율성을 높입니다. 학습 시에는 block-wise causal mask를 사용하여 각 토큰 맵이 이전 단계에만 의존하도록 제한합니다.&lt;/span&gt;&lt;span&gt;&lt;/span&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;1113&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zdLi5/btsLFa3FrNZ/xwjGBFu2K88gcUM06SiFZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zdLi5/btsLFa3FrNZ/xwjGBFu2K88gcUM06SiFZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zdLi5/btsLFa3FrNZ/xwjGBFu2K88gcUM06SiFZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzdLi5%2FbtsLFa3FrNZ%2FxwjGBFu2K88gcUM06SiFZ1%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;1113&quot; height=&quot;518&quot; data-origin-width=&quot;1113&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;VAR의 작동 방식&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Multi-scale VQVAE 인코딩&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: 입력 이미지는 Multi-scale VQVAE의 인코더를 통해 여러 해상도의 feature map으로 변환됩니다. 각 feature map은 양자화 과정을 거쳐 해당 해상도의 토큰 맵으로 변환됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;VAR Transformer 생성&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: VAR Transformer는 가장 낮은 해상도의 토큰 맵부터 시작하여 autoregressive 방식으로 다음 해상도의 토큰 맵을 생성합니다. 각 단계에서 모델은 이전 단계의 모든 토큰 맵과 함께 해당 단계의 위치 정보 (position embedding)를 입력으로 받습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Multi-scale VQVAE 디코딩&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: 최종적으로 생성된 모든 토큰 맵은 Multi-scale VQVAE의 디코더를 통해 원본 이미지로 복원됩니다. 디코더는 각 해상도 토큰 맵에서 해당 코드 벡터를 lookup하고, interpolation과 convolution을 통해 이미지로 복원합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;95&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coXgme/btsLEryjFXm/7EYQIBGOrFpejPKhQ040DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coXgme/btsLEryjFXm/7EYQIBGOrFpejPKhQ040DK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coXgme/btsLEryjFXm/7EYQIBGOrFpejPKhQ040DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoXgme%2FbtsLEryjFXm%2F7EYQIBGOrFpejPKhQ040DK%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;567&quot; height=&quot;95&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;95&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;&lt;span&gt;예시: 포뮬레이션 1에서 이미지 조각의 나열된 시퀀스에 대한 확률은 각 조각들의 조건부 확률을 모두 곱한 값입니다. 이는 P(x₁, x₂, ..., xₜ) = &amp;Pi; P(xᵢ | x₁...xᵢ₋₁) 로 표현할 수 있습니다. 여기서 xᵢ 는 각 조각이고, t는 전체 조각의 개수입니다. 이 수식에서, xᵢ 는 이미지 조각을 의미하며 x₁...xᵢ₋₁ 는 xᵢ 이전의 모든 이미지 조각을 나타냅니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;VAR의 장점&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;VAR은 기존 AR 모델의 단점을 극복하고 다음과 같은 장점을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;개선된 수학적 전제:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; VAR은 coarse-to-fine 방식으로 이미지를 생성하여 토큰들의 양방향 상관관계 문제를 해결합니다. 각 해상도 단계에서 전체 토큰 맵을 예측하는 방식은 이러한 의존성을 내재적으로 처리합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;향상된 일반화 능력:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; VAR은 이미지의 전체적인 구조를 학습하여 다양한 입력 조건에서도 안정적인 성능을 보입니다. 특히 in-painting, out-painting과 같은 zero-shot task에서도 우수한 성능을 나타냅니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;보존된 공간적 정보:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 이미지의 2D 구조를 유지하면서 토큰 맵을 처리하여 spatial locality를 유지합니다. 멀티스케일 구조는 각 해상도에서 공간 정보를 더 잘 학습하도록 도와줍니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;높은 효율성:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; VAR은 병렬적인 토큰 생성과 재귀적인 스케일 확장을 통해 계산 복잡도를 O(n⁴)로 줄입니다. 이는 기존 AR 모델에 비해 훨씬 효율적인 계산을 가능하게 합니다. [수정된 설명] 원래 스크립트에서 언급된 O(n⁶)이 아닌 O(n⁴)가 맞는 수치입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;뛰어난 이미지 생성 성능:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; VAR은 기존의 diffusion 트랜스포머 모델을 능가하는 이미지 생성 품질과 추론 속도를 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;VAR의 학습 및 추론 과정&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ekqUs1/btsLE2EQO48/SiDIbicqNBIXvmzzEYPTd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ekqUs1/btsLE2EQO48/SiDIbicqNBIXvmzzEYPTd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ekqUs1/btsLE2EQO48/SiDIbicqNBIXvmzzEYPTd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FekqUs1%2FbtsLE2EQO48%2FSiDIbicqNBIXvmzzEYPTd1%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;1040&quot; height=&quot;352&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;VAR 모델의 학습은 크게 두 단계로 나뉩니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Multi-scale VQVAE 학습 (Stage 1)&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: 원본 이미지를 입력으로 하여 Multi-scale VQVAE를 학습합니다. 이때, multi-scale quantization을 통해 여러 해상도 토큰 맵을 생성하고, 복원된 이미지와 원본 이미지 간의 차이를 줄이도록 학습합니다. 코드북은 학습 과정에서 최적화되며, 다양한 정보를 효과적으로 표현할 수 있도록 학습됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;VAR Transformer 학습 (Stage 2)&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: 학습된 VQVAE를 사용하여 이미지를 토큰 맵으로 변환하고, VAR Transformer를 학습합니다. VAR Transformer는 이전 단계의 토큰 맵을 기반으로 다음 단계 토큰 맵을 예측하도록 학습됩니다. 이때, causal masking을 사용하여 미래 정보를 참조하지 않도록 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;VAR 모델의 추론 과정은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Multi-scale VQVAE 인코딩&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: 학습된 VQVAE를 사용하여 입력 이미지를 여러 해상도의 토큰 맵으로 인코딩합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;VAR Transformer 생성&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: 가장 낮은 해상도 토큰 맵부터 시작하여 VAR Transformer를 통해 순차적으로 다음 해상도 토큰 맵을 생성합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;Multi-scale VQVAE 디코딩&lt;/span&gt;&lt;/b&gt;&lt;span&gt;: 생성된 모든 토큰 맵을 Multi-scale VQVAE 디코더를 통해 최종 이미지로 복원합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;실험 결과 및 Scaling Law&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;논문에서는 다양한 실험을 통해 VAR 모델의 우수성을 입증했습니다. ImageNet 데이터셋에서 VAR 모델은 diffusion 트랜스포머보다 더 빠른 속도로 더 나은 품질의 이미지를 생성했습니다. 특히 VAR 모델은 scaling law를 따르며, 모델 크기를 늘릴수록 성능이 지속적으로 향상된다는 점을 보여주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;819&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csFFzJ/btsLE3Rg7Iv/5qd28Jlw02g1CLWia3k2Vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csFFzJ/btsLE3Rg7Iv/5qd28Jlw02g1CLWia3k2Vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csFFzJ/btsLE3Rg7Iv/5qd28Jlw02g1CLWia3k2Vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsFFzJ%2FbtsLE3Rg7Iv%2F5qd28Jlw02g1CLWia3k2Vk%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;905&quot; height=&quot;819&quot; data-origin-width=&quot;905&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;&lt;span&gt;또한, VAR 모델은 in-painting, out-painting과 같은 다양한 downstream task에서 zero-shot generalization 능력을 보여주었습니다. 이는 VAR 모델이 단순히 이미지를 생성하는 것을 넘어 이미지의 구조를 이해하고 활용할 수 있음을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clufr0/btsLFz91ykO/PuWHkPwhndVyjpmIKr29lK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clufr0/btsLFz91ykO/PuWHkPwhndVyjpmIKr29lK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clufr0/btsLFz91ykO/PuWHkPwhndVyjpmIKr29lK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fclufr0%2FbtsLFz91ykO%2FPuWHkPwhndVyjpmIKr29lK%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;907&quot; height=&quot;772&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;
&lt;script&gt;     (adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;한계점 및 개선 방향&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;VAR 모델은 이미지 생성 분야에서 큰 발전을 이루었지만, 다음과 같은 한계점과 개선점이 존재합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;텍스트 기반 이미지 생성 부재:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 논문에서 텍스트를 기반으로 한 이미지 생성 기능은 구현되지 않았습니다. 향후 text-to-image 생성을 지원하고, multi-modal 기능을 확장할 필요가 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;비디오 생성:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; VAR 모델의 비디오 생성 능력은 아직 실험적으로 검증되지 않았습니다. 향후 VAR 모델을 비디오 생성 분야로 확장하기 위한 연구가 필요합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;모델 복잡성:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; Multi-scale VQVAE와 VAR Transformer 두 단계 학습이 필요하여 모델 학습 과정이 복잡할 수 있습니다. 이를 단순화하고 학습 효율을 개선할 필요가 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;결론&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;VAR은 기존 autoregressive 모델의 한계를 극복하고, 이미지 생성 분야에 새로운 가능성을 제시하는 모델입니다. Next-scale prediction이라는 새로운 패러다임을 통해 이미지의 구조적 정보를 효과적으로 학습하고, 고품질 이미지를 매우 효율적으로 생성할 수 있음을 입증했습니다. VAR 모델의 확장성과 일반화 능력은 향후 이미지 생성 분야의 발전에 큰 영향을 미칠 것으로 기대됩니다. &lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다들 새해복 많이 받으세요 :)&lt;/p&gt;</description>
      <category>AI</category>
      <category>CVPR</category>
      <category>neurips</category>
      <category>논문리뷰</category>
      <category>딥러닝</category>
      <category>생성형모델</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/81</guid>
      <comments>https://box-world.tistory.com/81#entry81comment</comments>
      <pubDate>Mon, 6 Jan 2025 19:55:09 +0900</pubDate>
    </item>
    <item>
      <title>데이터의 힘: 학습 이미지가 많아질수록 Accuracy와 F-1 Score가 개선되는 이유</title>
      <link>https://box-world.tistory.com/80</link>
      <description>&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;인공지능(AI)이나 기계학습 분야에서, 모델의 성능을 평가하는 데에는 여러 지표가 사용됩니다. 그 중에서도 'Accuracy(정확도)'와 'F-1 Score(F-1 점수)'는 가장 널리 사용되는 지표 중 두 가지입니다. 이 두 지표는 모델이 얼마나 잘 작동하는지를 나타내는 중요한 척도입니다. 그렇다면, 학습 이미지의 양이 증가할수록 이 두 지표의 성능이 왜 개선될 수 있는지 살펴봅시다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-01-31 17.07.53 - Design a series of minimalistic icons representing key concepts in machine learning_ a database for 'data', a neural network for 'machine learning alg.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFUWtK/btsEd0U1Wgj/nsLgZ0Cvjv4e2lKPUsjNeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFUWtK/btsEd0U1Wgj/nsLgZ0Cvjv4e2lKPUsjNeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFUWtK/btsEd0U1Wgj/nsLgZ0Cvjv4e2lKPUsjNeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFUWtK%2FbtsEd0U1Wgj%2FnsLgZ0Cvjv4e2lKPUsjNeK%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;300&quot; height=&quot;300&quot; data-filename=&quot;DALL&amp;middot;E 2024-01-31 17.07.53 - Design a series of minimalistic icons representing key concepts in machine learning_ a database for 'data', a neural network for 'machine learning alg.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;정확도(Accuracy)란?&lt;/h3&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정확도는 가장 직관적인 성능 지표 중 하나로, 모델이 정확하게 예측한 케이스의 비율을 의미합니다. 즉, 모든 예측 중 올바른 예측의 비율을 나타냅니다. 예를 들어, 100개의 이미지를 분류하는 모델이 90개의 이미지를 올바르게 분류했다면, 정확도는 90%가 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-01-31 17.08.53 - Create a detailed illustration showing a deep learning model's accuracy. The image should depict a dashboard or screen displaying a rising graph, nume.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beU3Pd/btsEeMWxnUr/XaH2CmA8CrDRzFsCbIZWE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beU3Pd/btsEeMWxnUr/XaH2CmA8CrDRzFsCbIZWE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beU3Pd/btsEeMWxnUr/XaH2CmA8CrDRzFsCbIZWE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeU3Pd%2FbtsEeMWxnUr%2FXaH2CmA8CrDRzFsCbIZWE1%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;300&quot; height=&quot;300&quot; data-filename=&quot;DALL&amp;middot;E 2024-01-31 17.08.53 - Create a detailed illustration showing a deep learning model's accuracy. The image should depict a dashboard or screen displaying a rising graph, nume.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;F-1 Score(F-1 점수)란?&lt;/h3&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;F-1 점수는 데이터 세트의 불균형을 고려할 때 유용한 지표입니다. 이는 정밀도(Precision)와 재현율(Recall)의 조화 평균을 기반으로 하며, 특히 양성 클래스(예를 들어, '고양이' 이미지)를 정확하게 식별하는 데 중점을 둡니다. 정밀도는 모델이 양성으로 예측한 항목 중 실제로 양성인 항목의 비율이고, 재현율은 실제 양성 항목 중 모델이 양성으로 올바르게 예측한 항목의 비율입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-01-31 17.09.10 - Illustrate the concept of a deep learning model's F-1 score. The image should feature a balance scale, with one side representing precision and the ot.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Njpi1/btsEihgUCTa/A95J2WnSNCpD0W3fKrDqTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Njpi1/btsEihgUCTa/A95J2WnSNCpD0W3fKrDqTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Njpi1/btsEihgUCTa/A95J2WnSNCpD0W3fKrDqTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNjpi1%2FbtsEihgUCTa%2FA95J2WnSNCpD0W3fKrDqTK%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;300&quot; height=&quot;300&quot; data-filename=&quot;DALL&amp;middot;E 2024-01-31 17.09.10 - Illustrate the concept of a deep learning model's F-1 score. The image should feature a balance scale, with one side representing precision and the ot.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;학습 이미지의 양이 성능 개선에 미치는 영향&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #374151; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 다양성의 증가&lt;/b&gt;: 학습 이미지가 많아질수록, AI 모델은 더 다양한 패턴과 특성을 학습할 기회를 얻습니다. 이는 모델이 실제 세계에서 발생할 수 있는 다양한 시나리오에 더 잘 적응하고, 정확도와 F-1 점수를 향상시키는 데 도움이 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;과적합(Overfitting)의 감소&lt;/b&gt;: 과적합은 모델이 학습 데이터에 너무 잘 맞춰져서 새로운 데이터에는 잘 작동하지 않는 현상을 말합니다. 학습 데이터가 많아질수록, 모델은 일반적인 패턴을 더 잘 학습하고, 과적합 위험을 줄일 수 있습니다. 이는 모델이 새로운 이미지에 대해 더 정확한 예측을 하고, 높은 F-1 점수를 달성하는 데 기여합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;불균형 데이터 처리&lt;/b&gt;: 특히, F-1 점수는 불균형한 데이터 세트에서 모델의 성능을 평가할 때 중요합니다. 학습 이미지가 많을수록 모델은 소수 클래스(덜 대표되는 클래스)에 대해서도 더 잘 학습합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-01-31 17.11.09 - Create an engaging and educational illustration that showcases the impact of the quantity of training images on the performance improvement of machine.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tkDhE/btsEfsRam0U/A8Afy8QQ435OfeEPG8Rwik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tkDhE/btsEfsRam0U/A8Afy8QQ435OfeEPG8Rwik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tkDhE/btsEfsRam0U/A8Afy8QQ435OfeEPG8Rwik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtkDhE%2FbtsEfsRam0U%2FA8Afy8QQ435OfeEPG8Rwik%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;300&quot; height=&quot;300&quot; data-filename=&quot;DALL&amp;middot;E 2024-01-31 17.11.09 - Create an engaging and educational illustration that showcases the impact of the quantity of training images on the performance improvement of machine.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;실제 사례: 의료 이미지 분석&lt;/h3&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;의료 분야에서 AI 모델은 X-레이, MRI와 같은 이미지를 분석하여 질병을 진단하는 데 사용됩니다. 초기에는 제한된 양의 학습 데이터로 모델을 훈련시켰을 때, 모델의 정확도와 F-1 점수가 상대적으로 낮았습니다. 이는 모델이 다양한 질병 상태, 환자의 다양성(예: 나이, 성별, 인종) 및 이미지의 다양한 촬영 조건을 충분히 학습하지 못했기 때문입니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 학습 데이터 세트에 더 많은 이미지가 추가됨에 따라, AI 모델은 다음과 같은 이유로 성능이 개선되었습니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #374151; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;다양성 증가&lt;/b&gt;: 더 많은 이미지는 다양한 환자와 질병 상태를 포함하게 되어, 모델이 더 넓은 범위의 경우를 학습할 수 있게 됩니다. 이로 인해 모델의 일반화 능력이 향상되고, 실제 환경에서의 정확도와 F-1 점수가 개선됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;세부 특성 학습&lt;/b&gt;: 추가된 이미지는 모델이 질병의 미묘한 특성을 더 잘 식별하게 해줍니다. 예를 들어, 특정 유형의 종양이나 조직 변화를 더 정확하게 인식할 수 있게 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;로버스트성 강화&lt;/b&gt;: 더 많은 데이터는 모델이 이미지의 잡음, 촬영 각도의 변화, 조명 조건 등에 더 강건하게 반응하도록 합니다. 이는 실제 의료 환경에서 다양한 조건 하에서도 높은 정확도와 F-1 점수를 유지할 수 있게 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로, 의료 이미지 분석 분야에서 학습 이미지의 양이 증가함에 따라 정확도와 F-1 점수가 개선되는 사례는 AI 모델이 더 정확하고 신뢰할 수 있는 진단을 제공할 수 있게 되었음을 보여줍니다. 이처럼 학습 데이터의 양과 질이 모델 성능에 중요한 영향을 미치며, AI 분야의 발전에 있어 핵심 요소임을 강조합니다.&lt;/p&gt;</description>
      <category>AI</category>
      <category>딥러닝</category>
      <category>인공지능</category>
      <category>초보</category>
      <category>학습</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/80</guid>
      <comments>https://box-world.tistory.com/80#entry80comment</comments>
      <pubDate>Wed, 31 Jan 2024 17:11:27 +0900</pubDate>
    </item>
    <item>
      <title>[문과도 이해하는 선형대수 for 딥러닝] 4. 행렬 분해 (Matrix factorization)</title>
      <link>https://box-world.tistory.com/79</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;의심&lt;span style=&quot;color: #000000; text-align: center;&quot;&gt;으로 가득 찬 마음은 승리로의 여정에&amp;nbsp;&lt;/span&gt;집중&lt;span style=&quot;color: #000000; text-align: center;&quot;&gt;할 수 없다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: center;&quot;&gt;- 아서 골드 -&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이번 포스팅에서 다룰 내용은 행렬 분해 (Matrix factorization)입니다. Matrix Factorization은 데이터를 분석하고 모델링하는데 널리 사용되는 방법 중 하나입니다. 이 방법은 매우 큰 데이터 집합에서 숨겨진 패턴을 추출하고, 예측 모델을 생성하고, 더 나은 결과를 도출할 수 있는 방법을 제공합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이 방법은 행렬을 작은 크기의 더 간단한 행렬로 분해하여 데이터의 복잡성을 줄이는 방법입니다. 이렇게하면 복잡한 문제를 해결하는 데 더 간단한 알고리즘을 사용할 수 있으며, 더 나은 성능을 얻을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이번 포스팅은 이전 개념을 숙지하고 공부하시는 것을 권장드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/78&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[이론/MIT 선형대수] - [문과도 이해하는 선형대수 for 딥러닝] 3. 행렬곱, 역행렬, 가우스-조던 소거법 (Multiplication and Inverse Matrices)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678680899236&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[문과도 이해하는 선형대수 for 딥러닝] 3. 행렬곱, 역행렬, 가우스-조던 소거법 (Multiplication and Inve&quot; data-og-description=&quot;늘 명심하라. 성공하겠다는 너 자신의 결심이 다른 어떤 것보다 중요하다는 것을. - 아브라함 링컨 - 곱셈(multiplication)과 역행렬(inverse matrix)은 선형 대수학에서 가장 기본이 되는 연산 중 하나입&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/78&quot; data-og-url=&quot;https://box-world.tistory.com/78&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rhYxr/hyRVbngHcV/MazM7Zukk5cWuAwCgH0xi0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/jFUMr/hyRTSQngmH/JsDLas8ZxWABB2dYiFfeVk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/pXgYZ/hyRTMbyekW/wiHxZFN1N0qUU2IePFkmDk/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/78&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/78&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rhYxr/hyRVbngHcV/MazM7Zukk5cWuAwCgH0xi0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/jFUMr/hyRTSQngmH/JsDLas8ZxWABB2dYiFfeVk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/pXgYZ/hyRTMbyekW/wiHxZFN1N0qUU2IePFkmDk/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[문과도 이해하는 선형대수 for 딥러닝] 3. 행렬곱, 역행렬, 가우스-조던 소거법 (Multiplication and Inve&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;늘 명심하라. 성공하겠다는 너 자신의 결심이 다른 어떤 것보다 중요하다는 것을. - 아브라함 링컨 - 곱셈(multiplication)과 역행렬(inverse matrix)은 선형 대수학에서 가장 기본이 되는 연산 중 하나입&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 역행렬에 대한 리뷰 (Review of inverse matrix)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기 곱하면 $P$가 나오는 두 행렬 $A$와 $B$가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$A \times B = P$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 행렬에 대한 역행렬이 존재한다고 가정할 때,&lt;b&gt; 행렬 $AB$에 대한 역행렬은 무엇일까요?&lt;/b&gt; 물론 $A^{-1}$과 $B^{-1}$가 곱해진 형태겠지만 중요한건 &lt;b&gt;곱하는 순서도 함께 역으로 바뀌며&lt;/b&gt; $B^{-1}A^{-1}$이라는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것은 마치 우리가 집에 돌아오면 1) 신발을 벗고 2) 양말을 벗는데, 다시 집밖으로 나갈땐 2) 양말을 신고 1) 신발을 신는 것과 같은 맥락입니다^^.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 $A \times A^{-1}=I$를 &lt;b&gt;전치 (transpose)&lt;/b&gt; 시킨다면 마찬가지로 앞 뒤 순서가 바뀌어 다음과 같이 나타납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$(A^{-1})^TA^T=I$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하겠지만, 단위 행렬은 전치를 해도 여전히 단위 행렬입니다! 어쨌든 여기서 우리가 얻을 수 있는 것은 $(A^{-1})^T$와 $A^T$를 곱했을 때 $I$가 나왔기 때문에 &lt;b&gt;이 둘은 역행렬 관계라는 겁니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. $A =LU$&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 우리는 본격적으로 &lt;b&gt;행렬 분해 (Matrix factorization)&lt;/b&gt;에 대해 살펴보려합니다. 우선 그전에 &lt;b&gt;소거 행렬 (Elimination matrix)&lt;/b&gt;에 대해 간단히 짚고 가겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}-&amp;amp;-\\-&amp;amp;-\end{bmatrix}\begin{bmatrix}2&amp;amp;1\\8&amp;amp;7\end{bmatrix}=\begin{bmatrix}2&amp;amp;1\\0&amp;amp;3\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식에 대하여, 좌변의 행렬에 어떤 Elimination matrix를 곱하여 우변처럼 Upper triangle matrix의 형태로 나타내고 싶다면 &lt;b&gt;Elimination matrix는 어떤 형태가 되어야할까요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좌변 행렬의 첫번째 row는 그대로 유지되고 두번째 row의 경우 $\begin{bmatrix}0&amp;amp;3\end{bmatrix}$이 되어야 하므로 [&lt;b&gt;첫번째 row의 (-4)배 +두번째 row의 (1)배]&lt;/b&gt;를 해야하므로 Elimination matrix는 $\begin{bmatrix}1&amp;amp;0\\-4&amp;amp;1\end{bmatrix}$가 되고 지금부터 이를 2번째 row의 첫번째 component를 0으로 만드는 행렬이라는 의미로 $E_{21}$이라고 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 식은 $E_{21}A=U$의 형태이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1&amp;amp;0\\-4&amp;amp;1\end{bmatrix}\begin{bmatrix}2&amp;amp;1\\8&amp;amp;7\end{bmatrix}=\begin{bmatrix}2&amp;amp;1\\0&amp;amp;3\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나의 아래 식은 $A=LU$ 형태의 식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}2&amp;amp;1\\8&amp;amp;7\end{bmatrix}=\begin{bmatrix}-&amp;amp;-\\-&amp;amp;-\end{bmatrix}\begin{bmatrix}2&amp;amp;1\\0&amp;amp;3\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 &lt;b&gt;$L$은 직관적으로 $E_{21}$의 역행렬이라는 것을 알 수 있습니다!&lt;/b&gt; 그렇다면 이는 어떻게 구할까요? &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;그냥 $E_{21}$에서 -4를 4로 바꿔주면 됩니다!&lt;/span&gt; &lt;/b&gt;왜냐하면 $E_{21}$이 4배를 빼는 거였는데, 역행렬은 이를 되돌리는 것이기 때문입니다. 그렇기에 부호만 바꾸면 되는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}2&amp;amp;1\\8&amp;amp;7\end{bmatrix}=\begin{bmatrix}1&amp;amp;0\\4&amp;amp;1\end{bmatrix}\begin{bmatrix}2&amp;amp;1\\0&amp;amp;3\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식에서 $U$의 pivot을 빼내면 다음과 같이 표현할 수 있습니다. pivot을 빼내면 $U$의 첫번째 row는 2로, 2번째 row는 3으로 나눠주는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}2&amp;amp;1\\8&amp;amp;7\end{bmatrix}=\begin{bmatrix}1&amp;amp;0\\4&amp;amp;1\end{bmatrix}\begin{bmatrix}2&amp;amp;0\\0&amp;amp;3\end{bmatrix}\begin{bmatrix}1&amp;amp;1\over2\\0&amp;amp;1\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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 \times 2$의 경우를 봤으니 $3 \times 3$의 경우도 살펴보겠습니다. 그렇다면 $3 \times 3$ 행렬 $A$가 다음과 같을때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$A=\begin{bmatrix}(1,1)&amp;amp;(1,2)&amp;amp;(1,3)\\(2,1)&amp;amp;(2,2)&amp;amp;(2,3)\\(3,1)&amp;amp;(3,2)&amp;amp;(3,3)\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬 $A$를 Upper triangle matrix $U$의 형태로 바꿔주는 Elimination matrix들의 조합은 다음과 같이 표현할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$E_{32}E_{31}E_{21}=U$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각은 행렬 $A$의 $(3,2),(3,1),(2,1)$ 자리를 0으로 만들어줍니다. 이것을 $A=LU$형태로 만들어주면, 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$A=E^{-1}_{21}E^{-1}_{31}E^{-1}_{32}U$$&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 자꾸 $E_{32}E_{31}E_{21}$을 그대로 처리하지 않고, $E^{-1}_{21}E^{-1}_{31}E^{-1}_{32}$의 형태로 바꾸어 처리하려는 것일까요? 다음은 $E_{32}E_{21}=E$의 경우를 임의로 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1&amp;amp;0&amp;amp;0\\0&amp;amp;1&amp;amp;0\\0&amp;amp;-5&amp;amp;1\end{bmatrix}\begin{bmatrix}1&amp;amp;0&amp;amp;0\\-2&amp;amp;1&amp;amp;0\\0&amp;amp;0&amp;amp;1\end{bmatrix}=\begin{bmatrix}1&amp;amp;0&amp;amp;0\\-2&amp;amp;1&amp;amp;0\\10&amp;amp;-5&amp;amp;1\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 다음은 $E^{-1}_{32}E^{-1}_{21}=L$의 경우입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1&amp;amp;0&amp;amp;0\\2&amp;amp;1&amp;amp;0\\0&amp;amp;0&amp;amp;1\end{bmatrix}\begin{bmatrix}1&amp;amp;0&amp;amp;0\\0&amp;amp;1&amp;amp;0\\0&amp;amp;5&amp;amp;1\end{bmatrix}=\begin{bmatrix}1&amp;amp;0&amp;amp;0\\2&amp;amp;1&amp;amp;0\\0&amp;amp;5&amp;amp;1\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보다시피 일반 행렬의 곱셈과 달리, 역행렬의 곱셈의 경우 배수 2나 5와 같은 배수 부분이 결과로 도출되는 행렬 $L$에 그대로 위치하기 때문에 연산과정이 훨씬 단순해집니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 만약 행 변환 (row change)가 없다면, 행렬 $A$를 Elimination하면 자연스럽게 $A$는 $LU$를 만들어내게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 소거에 대한 연산량 (Complexity of Elimination)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;$n \times n$ 차원 행렬에 대해 Elimination을 위해 필요한 연산은 얼마나 클까요?&lt;/b&gt; $n=100$을 예로 들겠습니다. 처음에는 1st row는 두고 2nd row부터 $99 \times 100$의 성분에 대한 연산이 필요하니 $100^2$의 연산이 필요합니다. 이런식으로 반복되면 최종적으로는&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$n^2+(n-1)^2+\dots+2^2+1^2$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 됩니다. 즉 정석적으로라면, $n$개의 항복이 $n^2$이 되지만, $n$개의 항목이 &lt;b&gt;점점 숫자가 작아지므로 대략 $1 \over 3 n^3$정도가 됩니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긴 글 읽어주셔서 감사합니다! 오늘도 행복한 하루 보내세요 :)&lt;/p&gt;</description>
      <category>이론/MIT 선형대수</category>
      <category>elimination</category>
      <category>inverse</category>
      <category>Linear Algebra</category>
      <category>MIT</category>
      <category>선형대수</category>
      <category>소거 행렬</category>
      <category>역행렬</category>
      <category>행렬</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/79</guid>
      <comments>https://box-world.tistory.com/79#entry79comment</comments>
      <pubDate>Mon, 13 Mar 2023 15:45:41 +0900</pubDate>
    </item>
    <item>
      <title>[문과도 이해하는 선형대수 for 딥러닝] 3. 행렬곱, 역행렬, 가우스-조던 소거법 (Multiplication and Inverse Matrices)</title>
      <link>https://box-world.tistory.com/78</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;늘 명심하라. 성공하겠다는 너&amp;nbsp;자신의 결심이 &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;다른 어떤 것보다 중요하다는 것을.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;- 아브라함 링컨 -&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151;&quot;&gt;곱셈(multiplication)과 역행렬(inverse matrix)은 선형 대수학에서 가장 기본이 되는 연산 중 하나입니다. 곱셈은 행렬 간의 연산으로, 두 개의 행렬을 곱할 때 결과 행렬의 크기와 요소는 입력된 두 행렬의 크기와 요소에 의해 결정됩니다. 반면 역행렬은 주어진 행렬의 역원(inverse)을 찾는 연산입니다. 역행렬은 주어진 행렬과 곱했을 때 단위행렬(identity matrix)을 얻을 수 있는 유일한 행렬입니다. &lt;span style=&quot;color: #374151;&quot;&gt;이번 포스팅에서는 이러한 행렬의 곱셈과 역행렬에 대해 자세히 알아보고, 이를 계산하는 방법에 대해서도 살펴보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151;&quot;&gt;&lt;span style=&quot;color: #374151;&quot;&gt;해당 포스팅은 이전 내용을 공부하고 보시면 더욱 이해하는데 많은 도움이 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/77&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[이론/MIT 선형대수] - [문과도 이해하는 선형대수 for 딥러닝] 2. 행렬 소거 (Elimination with Matrices)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678519467394&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[문과도 이해하는 선형대수 for 딥러닝] 2. 행렬 소거 (Elimination with Matrices)&quot; data-og-description=&quot;성공의 커다란 비결은 결코 지치지 않는 인간으로 인생을 살아가는 것이다. - 알버트 슈바이처 - 안녕하세요 저번 포스팅에서는 선형 대수 공부의 첫 단원으로써, 선형 방정식을 Row picture와 Column&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/77&quot; data-og-url=&quot;https://box-world.tistory.com/77&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bn1AS2/hyRTLWD9iS/upuzGDlP7OYt0GqZ6kvox0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/8JhKS/hyRTIZU0gk/Oia9NDWvO8nUMdY6ME8Thk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bDCbvA/hyRTT1rQU2/87F05JlJ5glk5lOK33N0a1/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/77&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/77&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bn1AS2/hyRTLWD9iS/upuzGDlP7OYt0GqZ6kvox0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/8JhKS/hyRTIZU0gk/Oia9NDWvO8nUMdY6ME8Thk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bDCbvA/hyRTT1rQU2/87F05JlJ5glk5lOK33N0a1/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[문과도 이해하는 선형대수 for 딥러닝] 2. 행렬 소거 (Elimination with Matrices)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;성공의 커다란 비결은 결코 지치지 않는 인간으로 인생을 살아가는 것이다. - 알버트 슈바이처 - 안녕하세요 저번 포스팅에서는 선형 대수 공부의 첫 단원으로써, 선형 방정식을 Row picture와 Column&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. Matrix multiplication&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터는 두 행렬 $A$와 $B$를 곱하는 &lt;b&gt;네 가지 방법&lt;/b&gt;에 대해서 하나하나 살펴보겠습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) $C_ij=\sum(A_ik*B_kj)$&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 위 수식을 이해하기 위해 아래 $C=AB$의 상황을 보며 이해하겠습니다. 두 행렬 $A$와 $B$를 곱한 결과 $C$에서 3번째 row와 4번째 Column에 위치한 $C_{ij}$는 $A$의 세번째 row와 $B$의 네번째 Column간의 &lt;b&gt;내적 (dot product)&lt;/b&gt;로 구할 수 있습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$C_{34}= a_{31}b_{14}+a_{32}b_{24}+\dots=\displaystyle\sum^n_{k=1}a_{3k}b_{k4}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 두 행렬 $A$와 $B$는 언제 곱해질 수 있을까요? 바로 $A$가 $m \times n$이라면, $B$의 row의 개수는 A의 Column의 개수와 동일한 $n$이어야 합니다. 그리고 $B$의 Column의 개수는 어떤 것이 되든 상관이 없기 때문에 여기서는 $p$라고 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그렇다면 각자 차원이 정의된 두 행렬을 곱했을 때 $C$의 차원은 $A$의 row 개수와 $B$의 Column 개수를 곱한 $m \times p$가 되는 것입니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) 행렬 $\times$ 벡터로 바라보기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 앞서 &lt;b&gt;&amp;lt;어떤 행렬 E $\times$ 벡터 = E 컬럼의 선형 결합 (Linear combination)&amp;gt;&lt;/b&gt;이라는 것을 배웠습니다. 우린 행렬 간의 곱셈을 얘기하고 있는데 벡터가 필요한 Linear combination 얘기를 왜 꺼낼까요? 바로 두 행렬 A$와 $B$의 곱을 다음과 같이 $A$와 $B$의 &lt;b&gt;각 Column간의 Linear combination&lt;/b&gt;으로 바라볼 수 있기 때문입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;349&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WfJt3/btr3gMj0baT/QE8KemOeAnCL24QQFjcOc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WfJt3/btr3gMj0baT/QE8KemOeAnCL24QQFjcOc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WfJt3/btr3gMj0baT/QE8KemOeAnCL24QQFjcOc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWfJt3%2Fbtr3gMj0baT%2FQE8KemOeAnCL24QQFjcOc1%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;457&quot; height=&quot;180&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;349&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;3) $A$의 한 row $\times$ $B$ = $C$의 한 row&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 Column의 관점에서 행렬의 곱셈을 바라봤다면, 이번엔&lt;b&gt; row의 관점&lt;/b&gt;에서도 바라볼 수 있겠죠! 2)에선 $A$의 전체와 $B$의 한 Column으로 $C$의 한 Column을 구했다면, row의 관점에서는 $A$의 한 row와 $B$의 전체를 곱하면, 다음과 같이$C$의 한 row를 구하는 것으로 이해할 수 있습니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dO9ejA/btr3dDuzRBy/GZKwLf7xOqpj56cEN5Am50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dO9ejA/btr3dDuzRBy/GZKwLf7xOqpj56cEN5Am50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dO9ejA/btr3dDuzRBy/GZKwLf7xOqpj56cEN5Am50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdO9ejA%2Fbtr3dDuzRBy%2FGZKwLf7xOqpj56cEN5Am50%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;457&quot; height=&quot;179&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 $A$의 3번째 row를 기준으로 $B$의 첫번째 row와 내적하여 나온 값이 $C_{31}$, 두번째 row와 내적하여 나온 값이 $C_{32}$와 같이 되는 것이죠.&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;4) $A$의 한 Column과 $B$의 한 row의 곱셈으로 바라보기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 바로 아래 예시와 함께 살펴보겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}2&amp;amp;7\\3&amp;amp;8\\4&amp;amp;9\end{bmatrix}\begin{bmatrix}1&amp;amp;6\\0&amp;amp;0\end{bmatrix}=\begin{bmatrix}2\\3\\4\end{bmatrix}\begin{bmatrix}1&amp;amp;6\end{bmatrix}+\begin{bmatrix}7\\8\\9\end{bmatrix}\begin{bmatrix}0&amp;amp;0\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말 그대로 같은 인덱스에 위치한 $A$의 Column과 $B$의 row를 곱하고, 그것들을 합쳐버리는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 역행렬 (Inverse matrix)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가&lt;b&gt; &quot;이 행렬은 역행렬을 가질까?&quot;&lt;/b&gt; 에 대해 얘기하려면 다음과 같은 몇가지 조건이 충족되는지를 보아야 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 행렬이 정사각행렬인가?&lt;/li&gt;
&lt;li&gt;invertible한가? or 해당 행렬은 non-singular 행렬인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 우리가 해당 행렬이 invertible한지는 어떻게 알아야할까요? 다음 예시를 보며 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$A=\begin{bmatrix}1&amp;amp;3\\2&amp;amp;6\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 여러분에게 &quot;행렬 $A$는 역행렬을 가질까요?&quot;라고 물어보면 여러분들은&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; &quot;A와 곱하여 단위 행렬 (identity matrix)가 나오게 하는 행렬이 있는지 찾아보겠습니다!&quot;&lt;/b&gt;&lt;/span&gt;라고 대답하셔야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 우리는 단위 행렬은 행렬 $A$와 같은 차원인 $2\times2$를 가지는 $\begin{bmatrix}1&amp;amp;0\\0&amp;amp;1\end{bmatrix}$이라는 것을 배웠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 앞서 배운 행렬 곱셈 방식에서 결과로 도출되야하는 단위 행렬의 '첫번째' Column $\begin{bmatrix}1&amp;amp;0\end{bmatrix}$는 행렬 $A$의 전체와 곱해질 행렬의 '첫번째' Column의 linear combination으로 도출된다고 배웠습니다. 그렇다면 그렇게 만들어주는 Column이 존재할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안타깝게도 $A$ 행렬의 두 Columns $\begin{bmatrix}1&amp;amp;2\end{bmatrix}$와 \begin{bmatrix}3&amp;amp;6\end{bmatrix}은 직선 $y=2x$위에 있고, 해당 직선은 $\begin{bmatrix}1&amp;amp;0\end{bmatrix}$을 지나가지 않기 때문에 &lt;b&gt;그러한 Column은 존재하지 않습니다. 이것이 우리가 역행렬의 존재유무를 판단하는 첫번째 방법입니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Singular matrix의 의미는 해당 행렬의 Linear combination으로 0을 만들 수 있다는 뜻입니다.&lt;/b&gt; 앞서 non-singular 행렬은 역행렬을 가지기 때문에 singular matrix는 역행렬을 가지지 못한다고 해석할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜냐하면 어떤 combination으로 0이 도출된다면 역행렬을 곱했을 때 단위 행렬이 못나오고 0에서 못 빠져나온다는 뜻으로 해석되기 때문입니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 본 행렬 $A$는 벡터 $\begin{bmatrix}3&amp;amp;-1\end{bmatrix}$를 곱했을때 0이 나옵니다. 그렇기 때문에 $A$는 singular matrix고 역행렬을 가질 수 없는 또 하나의 이유가 되는 것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 가우스-조던 소거법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가우스-조던 소거법은 선형 대수를 한번이라도 공부해보셨다면 익히 들어보았을 단어입니다. &lt;span style=&quot;color: #ee2323;&quot;&gt;쉽게 말해서 어떤 행렬 A에 대해 역행렬이 존재한다면, 그 역행렬을 구하는 방법입니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1&amp;amp;3\\2&amp;amp;7\end{bmatrix}\begin{bmatrix}a&amp;amp;b\\c&amp;amp;d\end{bmatrix}=\begin{bmatrix}1&amp;amp;0\\0&amp;amp;1\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 행렬 $A$와 역행렬을 가진다면, 그 역행렬과 곱했을 때는 단위 행렬이 나와야할 것입니다. 그때 이 역행렬을 구해보세요!라고 얘기를 한다면, 다음과 같이 우선 그림을 그려주시면 됩니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;381&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sE8lU/btr3c22uOzM/A8kVXRZqZIeI1lnuhhK3mK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sE8lU/btr3c22uOzM/A8kVXRZqZIeI1lnuhhK3mK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sE8lU/btr3c22uOzM/A8kVXRZqZIeI1lnuhhK3mK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsE8lU%2Fbtr3c22uOzM%2FA8kVXRZqZIeI1lnuhhK3mK%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;264&quot; height=&quot;186&quot; data-origin-width=&quot;381&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 이전에 배웠던 소거법에 따라 행렬 $A$의 2번째 row에 '3'을 0으로 만들어주려고 합니다! 그러려면 첫번째 row에 3을 곱하여 2번째 row에 빼줘야할텐데요. 이때 $A$에만 3을 곱해서 빼주는것이 아니라, &lt;b&gt;$I$에도 같은 연산을 똑같이 적용해주면 됩니다!&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVHQQS/btr3cDPqOrU/KcDUK5uEJ6wDt7j8KNm0X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVHQQS/btr3cDPqOrU/KcDUK5uEJ6wDt7j8KNm0X0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVHQQS/btr3cDPqOrU/KcDUK5uEJ6wDt7j8KNm0X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVHQQS%2Fbtr3cDPqOrU%2FKcDUK5uEJ6wDt7j8KNm0X0%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;264&quot; height=&quot;179&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 행렬 $A$는 &lt;b&gt;상삼각행렬 (Upper triangle matrix)&lt;/b&gt;가 되는데요. 여기서 멈추는 것이 아니라, 행렬 $A$를 단위 행렬이 되게끔 윗쪽 방향으로 소거를 진행해주시는 겁니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니까 가우스-조던 소거법이라 하면 행렬 $A$와 $I$를 나란히 놓고 $A$를 단위 행렬로 바꾸는데 그때 적용되는 연산을 똑같이 $I$에 적용하여 나온 행렬이 $A$의 역행렬이 되는것입니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCLn5O/btr3eWf6lNa/5YoczQ3CzUYlAuGNeT5P00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCLn5O/btr3eWf6lNa/5YoczQ3CzUYlAuGNeT5P00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCLn5O/btr3eWf6lNa/5YoczQ3CzUYlAuGNeT5P00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCLn5O%2Fbtr3eWf6lNa%2F5YoczQ3CzUYlAuGNeT5P00%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;267&quot; height=&quot;184&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 위와같이 $A$의 두번째 row에 3을 곱해서 첫번째 row에 빼주면 나온 오른쪽 행렬이 역행렬이라고 할 수 있습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긴 글 읽어주셔서 감사합니다! 행복한 하루 보내세요 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 다음 강좌로 고고!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/79&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[이론/MIT 선형대수] - [문과도 이해하는 선형대수 for 딥러닝] 4. 행렬 분해 (Matrix factorization)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678689989962&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[문과도 이해하는 선형대수 for 딥러닝] 4. 행렬 분해 (Matrix factorization)&quot; data-og-description=&quot;의심으로 가득 찬 마음은 승리로의 여정에 집중할 수 없다. - 아서 골드 - 이번 포스팅에서 다룰 내용은 행렬 분해 (Matrix factorization)입니다. Matrix Factorization은 데이터를 분석하고 모델링하는데 널&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/79&quot; data-og-url=&quot;https://box-world.tistory.com/79&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bdQPNk/hyRVeK9MOD/i3u7cthIu4npptNBYpaRUK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/u3kDA/hyRTS31iQk/L9kJDAIUDKwYZWbObNZsn0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/jcYoR/hyRTOtMGk1/twAHcX8jb53dacT9r4QATK/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/79&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/79&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bdQPNk/hyRVeK9MOD/i3u7cthIu4npptNBYpaRUK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/u3kDA/hyRTS31iQk/L9kJDAIUDKwYZWbObNZsn0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/jcYoR/hyRTOtMGk1/twAHcX8jb53dacT9r4QATK/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[문과도 이해하는 선형대수 for 딥러닝] 4. 행렬 분해 (Matrix factorization)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;의심으로 가득 찬 마음은 승리로의 여정에 집중할 수 없다. - 아서 골드 - 이번 포스팅에서 다룰 내용은 행렬 분해 (Matrix factorization)입니다. Matrix Factorization은 데이터를 분석하고 모델링하는데 널&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>이론/MIT 선형대수</category>
      <category>Matrix</category>
      <category>가우스</category>
      <category>가우스조던소거법</category>
      <category>선형대수</category>
      <category>역행렬</category>
      <category>조던</category>
      <category>행렬</category>
      <category>행렬곱</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/78</guid>
      <comments>https://box-world.tistory.com/78#entry78comment</comments>
      <pubDate>Sat, 11 Mar 2023 15:50:14 +0900</pubDate>
    </item>
    <item>
      <title>[문과도 이해하는 선형대수 for 딥러닝] 2. 행렬 소거 (Elimination with Matrices)</title>
      <link>https://box-world.tistory.com/77</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;성공의 커다란 비결은 결코&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지치지 않는 인간으로 인생을 살아가는 것이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 알버트 슈바이처 -&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요 저번 포스팅에서는 선형 대수 공부의 첫 단원으로써, 선형 방정식을 Row picture와 Column picture의 관점에서 바라보고 이를 이용하여 식의 솔루션을 구하는 방법들에 대해 간단히 살펴보았습니다. 해당 포스팅을 먼저 읽고 이번 포스팅을 공부하시면 면 이해하는데 큰 도움이 됩니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/76&quot;&gt;[이론/MIT 선형대수] - [문과도 이해하는 선형대수 for 딥러닝] 1. 선형 방정식 (The geometry of linear equations)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678519408676&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[문과도 이해하는 선형대수 for 딥러닝] 1. 선형 방정식 (The geometry of linear equations)&quot; data-og-description=&quot;사람들이 대개 기회를 놓치는 이유는 기회가 작업복 차림의 일꾼같아 일로 보이기 때문이다. - 토마스 A. 에디슨 - 제 블로그의 'MIT 선형대수' 카테고리의 포스팅들은 Gilbert Strang 교수님의 Linear Al&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/76&quot; data-og-url=&quot;https://box-world.tistory.com/76&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cEZ8Vw/hyRSTWgseg/LY1fEbNL7q5okXaaMI09Qk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/41WGU/hyRTRbucdK/vwtGPHC6sexxkCqE3F5JqK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/X0cRv/hyRSN9AVdV/VP99Iyx3lM2fgBVLOKo6l0/img.png?width=279&amp;amp;height=237&amp;amp;face=0_0_279_237&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/76&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/76&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cEZ8Vw/hyRSTWgseg/LY1fEbNL7q5okXaaMI09Qk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/41WGU/hyRTRbucdK/vwtGPHC6sexxkCqE3F5JqK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/X0cRv/hyRSN9AVdV/VP99Iyx3lM2fgBVLOKo6l0/img.png?width=279&amp;amp;height=237&amp;amp;face=0_0_279_237');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[문과도 이해하는 선형대수 for 딥러닝] 1. 선형 방정식 (The geometry of linear equations)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;사람들이 대개 기회를 놓치는 이유는 기회가 작업복 차림의 일꾼같아 일로 보이기 때문이다. - 토마스 A. 에디슨 - 제 블로그의 'MIT 선형대수' 카테고리의 포스팅들은 Gilbert Strang 교수님의 Linear Al&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 시간은 앞서 본 선형 방정식의 해를 구하는 또 하나의 방법인 소거 (Elimination)에 대해 공부해보겠습니다!&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 소거 (Elimination)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래엔 우리가 풀어야 할 선형 방정식이 주어져있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{cases}x+2y+z=2 \\ 3x+8y+z=12 \\ 4y+z=2 \end{cases}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식에서 &lt;b&gt;좌변의 계수 (coefficient)를 행렬로 표현하면&lt;/b&gt; 다음과 같습니다. 우변에 존재하던 벡터 $\begin{bmatrix}2 \\ 12 \\ 2 \end{bmatrix}$는 이따가 함께 다시 고려하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 3 &amp;amp; 8 &amp;amp; 1 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터 &lt;b&gt;elimination&lt;/b&gt;을 해볼텐데요. 이것의 목표는 결국 아래와 같은 모양의 &lt;b&gt;상 삼각행렬 (Upper triangle matrix)&lt;/b&gt;를 도출하는 것입니다. 이렇게 되면 가장 아래의 row에서는 $u_{n,n}=?$의 식부터 미지수가 하나씩 풀리면서 이 값을 바로 위 식들에 차례로 연쇄적으로 대입해가며 풀리게 됩니다! (이 과정이 이따 살펴볼 역 대입입니다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDBK8X/btr2D6R1vxd/4L96QndkZ2lJpgV6YgAIpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDBK8X/btr2D6R1vxd/4L96QndkZ2lJpgV6YgAIpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDBK8X/btr2D6R1vxd/4L96QndkZ2lJpgV6YgAIpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDBK8X%2Fbtr2D6R1vxd%2F4L96QndkZ2lJpgV6YgAIpk%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;311&quot; height=&quot;162&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 $\begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 3 &amp;amp; 8 &amp;amp; 1 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$로 돌아와서 이것을 위 형태로 변형시키기 위해서는 2행의 3을 제거해줘야합니다. &lt;b&gt;이를 위해서 1행에 3을 곱해서 2행에서 빼면 간단히 해결되겠죠?&lt;/b&gt; 결과는 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 우리는 3행의 4를 지우면 Upper triangle matrix (=$U$)의 형태를 얻을 수 있습니다. 이를 위해서 2행에 2를 곱하여 3행에 빼면 될 것이고 결과는 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$U = \begin{bmatrix} \underline{1} &amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; \underline{2} &amp;amp; -2 \\ 0 &amp;amp; 0 &amp;amp; \underline{5} \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 위 식에서 밑줄 친 숫자들은 &lt;b&gt;피봇 (pivot)&lt;/b&gt;이라고 칭합니다. &lt;b&gt;이때 pivot은 절대 0이 될 수 없습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 다른 예로 소거 과정에서 $\begin{bmatrix}0&amp;amp; 2 &amp;amp; 1 \\ 1 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$처럼 1행의 첫번째 자리에 0이 있다고 해서 &lt;b&gt;elimination에 실패한 것일까요? 그렇진 않고 간단하게 1행과 2행을 바꾸어 주면 됩니다!&lt;/b&gt; 그러나 $\begin{bmatrix}0&amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$처럼 어떤 행과 교환해도 소용없다면 이 경우 elimination을 할 수 없다고 판단합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 역 대입 (Back subtitution)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;b&gt;우변까지 고려하여 함께 elimination을 진행해보겠습니다.&lt;/b&gt; 이를 위해 우변의 벡터를 다음과 같이 첨가하겠습니다. 이때 첨가된 우변의 벡터를 &lt;b&gt;augmented matrix&lt;/b&gt;라고 부릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 &amp;amp; 2 \\ 3 &amp;amp; 8 &amp;amp; 1 &amp;amp; 12\\ 0 &amp;amp; 4 &amp;amp; 1 &amp;amp;2 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식을 아까 우리가 같이 했던 소거 방식을 똑같이 적용하면 다음과 같은 결과가 도출됩니다! 계산 과정은 생략하겠습니다..ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1&amp;amp; 2 &amp;amp; 1 &amp;amp; 2 \\ 0 &amp;amp; 2 &amp;amp; -2 &amp;amp; 6\\ 0 &amp;amp; 0 &amp;amp; 5 &amp;amp; -10\end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 위 행렬 식을 아래와 같이 우리에게 친숙한 연립 방정식의 형태로 가져오면, 그 다음은 제가 설명드리지 않아도 모두가 너무나도 잘 아시는 과정이죠? $z$부터 시작하여 아래에서 위로 올라가면서 연쇄적으로 미지수를 구하게 됩니다! 이것을 &lt;b&gt;역 대입 (Back subtitution)&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. Matrix multiplication&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방금까지 우리는 행렬 $A$에서 Upper triangle 행렬 $U$를 도출하는 과정을 보았습니다. 그리고 이때 $A$와의 곱셈을 통해 $U$를 도출시켜주는 행렬을 Elimination matrix라고 부르는데요. 이 과정이 보다 직관적으로 쉽게 다가오게 하는 연산 두가지에 대해 먼저 공부해보겠습니다. 우선 &lt;b&gt;행렬과 Column vector의 곱셈&lt;/b&gt;에 대해 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}-&amp;amp;-&amp;amp;- \\ -&amp;amp;-&amp;amp;-\\ -&amp;amp;-&amp;amp;- \end{bmatrix} \begin{bmatrix}3 \\ 4 \\ 5 \end{bmatrix}=\begin{bmatrix}3 \times Column \ 1 \\ 4 \times Column \ 2 \\ 5 \times Column \ 3 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 보다시피 행렬곱셈, 즉 &lt;b&gt;왼쪽에 행렬이 있고 이것과 벡터를 곱하게 될땐 Columns에 대한 linear combination과 같습니다.&lt;/b&gt; 이제 &lt;b&gt;row vector과 행렬의 곱셈&lt;/b&gt;에 대해 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1 &amp;amp; 2 &amp;amp; 7 \end{bmatrix} \begin{bmatrix}-&amp;amp;-&amp;amp;- \\ -&amp;amp;-&amp;amp;-\\ -&amp;amp;-&amp;amp;- \end{bmatrix}=\begin{bmatrix}1 \times row \ 1 \\ 2 \times row \ 2 \\ 7 \times row \ 2 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 row vector와 행렬의 곱셈은 &lt;b&gt;row에 대한 선형결합&lt;/b&gt;이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 소거 행렬 (Elimination matrix) 구하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}E_{1,1}&amp;amp;E_{1,2}&amp;amp;E_{1,3} \\ E_{2,1}&amp;amp;E_{2,2}&amp;amp;E_{2,3}\\ E_{3,1}&amp;amp;E_{3,2}&amp;amp;E_{3,3} \end{bmatrix} \begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 3 &amp;amp; 8 &amp;amp; 1 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix} = \begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 우리는 앞서 보았듯 행렬 $A$를 $U$로 만드는 Elimination matrix를 구해보려 합니다. 우선 $E_1$의 첫번째 row인 $\begin{bmatrix}E_{1,1}&amp;amp;E_{1,2}&amp;amp;E_{1,3}\end{bmatrix}$는 무엇일까요? &lt;b&gt;쉽게 생각해서 첫번째 row가 무엇이어야 이것을 $A$를 곱하여 $U$의 첫번째 row가 나올까?를 생각하면 됩니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 Elimination matrix의 두번째 row와 $A$를 곱하여 $\begin{bmatrix}0 &amp;amp; 2 &amp;amp; -2 \end{bmatrix}$가 나오게 하는 row는 앞서 말했듯 $A$의 첫번째 row를 3배하여 두번째 row에 빼야하므로 $\begin{bmatrix}-3 &amp;amp; 1 &amp;amp; 0 \end{bmatrix}$이 됩니다. 마찬가지의 원리를 세번째 row에도 적용하면 다음과 같이 나오겠죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1&amp;amp;0&amp;amp;0 \\ -3&amp;amp;1&amp;amp;0\\ 0&amp;amp;0&amp;amp;1 \end{bmatrix} \begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 3 &amp;amp; 8 &amp;amp; 1 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix} = \begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 우리는 $\begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix}$을 최종적인 U로 만들어준 또다른 Elimination matrix를 찾아야합니다. 마찬가지로 구하면 다음과 같겠죠? (계산은 생략하겠습니다!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}1&amp;amp;0&amp;amp;0 \\ 0&amp;amp;1&amp;amp;0\\ 0&amp;amp;-2&amp;amp;1 \end{bmatrix} \begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 4 &amp;amp; 1 \end{bmatrix} = \begin{bmatrix}1 &amp;amp; 2 &amp;amp; 1 \\ 0 &amp;amp; 2 &amp;amp; -2 \\ 0 &amp;amp; 0 &amp;amp; 5 \end{bmatrix}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 앞서 첫번째 찾았던 Elimination matrix를 $E_1$, 방금 구한 Elimination matrix를 $E_2$라고 한다면, 우린 결국 $U$를 구하는 과정을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$E_2(E_1A)$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 표현할 수 있습니다. 이때 본래 행렬 간의 곱셈에선 순서를 바꿀 수 없지만, 누굴 먼저 곱할지는 괄호를 바꿔 $$(E_2E_1)A$$처럼 사용할 순 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 선형 방정식의 Solution을 구하는 또 하나의 방법인 Elimination matrix에 대해 공부해보았습니다.&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;a href=&quot;https://box-world.tistory.com/78&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[이론/MIT 선형대수] - [문과도 이해하는 선형대수 for 딥러닝] 3. 행렬곱, 역행렬, 가우스-조던 소거법 (Multiplication and Inverse Matrices)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678519424191&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[문과도 이해하는 선형대수 for 딥러닝] 3. 행렬곱, 역행렬, 가우스-조던 소거법 (Multiplication and Inve&quot; data-og-description=&quot;늘 명심하라. 성공하겠다는 너 자신의 결심이 다른 어떤 것보다 중요하다는 것을. - 아브라함 링컨 - 곱셈(multiplication)과 역행렬(inverse matrix)은 선형 대수학에서 가장 기본이 되는 연산 중 하나입&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/78&quot; data-og-url=&quot;https://box-world.tistory.com/78&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dvTkNz/hyRSSC5jyZ/Awk45OHVF0Y9qquvJzx701/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/5Lhod/hyRSSbX4Wn/COJkL8nFvKWuX7AG2WlTGK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/A9ZMS/hyRTNUsR4U/ulXoz9q3OGQ9BeDDWDJ25k/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/78&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/78&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dvTkNz/hyRSSC5jyZ/Awk45OHVF0Y9qquvJzx701/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/5Lhod/hyRSSbX4Wn/COJkL8nFvKWuX7AG2WlTGK/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/A9ZMS/hyRTNUsR4U/ulXoz9q3OGQ9BeDDWDJ25k/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[문과도 이해하는 선형대수 for 딥러닝] 3. 행렬곱, 역행렬, 가우스-조던 소거법 (Multiplication and Inve&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;늘 명심하라. 성공하겠다는 너 자신의 결심이 다른 어떤 것보다 중요하다는 것을. - 아브라함 링컨 - 곱셈(multiplication)과 역행렬(inverse matrix)은 선형 대수학에서 가장 기본이 되는 연산 중 하나입&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>이론/MIT 선형대수</category>
      <category>column</category>
      <category>elimination</category>
      <category>Linear Algebra</category>
      <category>Matrix</category>
      <category>MIT</category>
      <category>row</category>
      <category>딥러닝</category>
      <category>선형대수</category>
      <category>행렬</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/77</guid>
      <comments>https://box-world.tistory.com/77#entry77comment</comments>
      <pubDate>Wed, 8 Mar 2023 20:07:49 +0900</pubDate>
    </item>
    <item>
      <title>[문과도 이해하는 선형대수 for 딥러닝] 1. 선형 방정식 (The geometry of linear equations)</title>
      <link>https://box-world.tistory.com/76</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffc9af; color: #252525;&quot;&gt;사람들이 대개 기회를 놓치는 이유는 기회가&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;작업복 차림의 일꾼&lt;span style=&quot;color: #252525;&quot;&gt;같아 일로 보이기 때문이다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffc9af; color: #252525;&quot;&gt;- &lt;span style=&quot;color: #252525;&quot;&gt;토마스 A. 에디슨 -&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;제 블로그의 'MIT 선형대수' 카테고리의 포스팅들은 Gilbert Strang 교수님의 Linear Algebra 강의를 기반으로 작성되었습니다. 이번 포스팅에서는 선형 대수 강의의 첫 포문을 여는 내용인만큼 기본적인 개념부터 시작하여 차근차근 나아가보려 합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;포스팅의 제목 그대로 문과생분들도 이해할 수 있을만큼 차분히 설명드릴테니 잘 따라와주셨으면 좋겠습니다:) (저 또한 고등학교때 문과생이었다가 컴퓨터공학과로 와서 수학 공부에 너무 힘들었기 때문입니다...^^;;;)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 선형 방정식 (Linear equation) 이란?&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;여기 두 개의 식이 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;$$\begin{cases}2x-y=0 \\ -x+2y=3\end{cases}$$&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이것을 행렬로 표현하면 어떻게 될까요? 바로 위 식들의 계수들 (coefficients)만 가져와서 이들의 배열을 만들어주면 됩니다!&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;$$\begin{bmatrix}2 &amp;amp; -1 \\ -1 &amp;amp; 2 \end{bmatrix} \begin{bmatrix}0 \\ 3 \end{bmatrix} = \begin{bmatrix}0 \\ 3 \end{bmatrix}$$&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이때 계수에 대한 행렬은 $A$, 미지수에 대한 벡터&lt;b&gt; (1차원 행렬은 벡터라고 칭합니다)&lt;/b&gt;는 $x$ 그리고 이들을 결합하여 만들어진 우변의 벡터는 $b$라고 합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;따라서 우린 이제부터 선형대수를 공부하는 것이므로 두개의 식을 보았을 때 고등학교에서 배운 연립 방정식이 아닌 저 식들을 행렬의 형태로 구성하여 '선형방정식' $Ax=b$의 형태로 문제를 접근해야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Row picture&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;앞서본 선형 방정식의 Row picture은 무엇인가요? 라고 누군가 물어본다면, 우린 저 선형방정식을 구성하는 두 식을 그림의 형태 즉 좌표평면상에서 표현해주면 됩니다! 다시 말해서 $2x-y=0$과 $-x+2y=3$을 좌표평면에 그려주면 되는것이죠.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;아무래도 이것을 그리는 방법은 워낙 고등학교 때 많이 해왔던 일이기 때문에 아무 생각없이 그릴 수 있겠지만, 이것을 잘 생각해보면 결국 우린 한 직선이 지나는 두 점을 찾아 그것을 연결하고 있음을 떠올릴 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;$2x-y=0$는 $(0,0),(1,2)$와 같은 점들을 지나고, $-x+2y=3$은 원점을 지나진 않지만 $(-3,0),(-1,2)$와 같은 점들을 지난다는 것을 쉽게 떠올릴 수 있습니다. 이를 이용하여 그림을 그려보면 다음과 같겠죠!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbWec1/btr1pXnFIw9/OJML7OuNW3M1V9k3BwcKA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbWec1/btr1pXnFIw9/OJML7OuNW3M1V9k3BwcKA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbWec1/btr1pXnFIw9/OJML7OuNW3M1V9k3BwcKA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbWec1%2Fbtr1pXnFIw9%2FOJML7OuNW3M1V9k3BwcKA1%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;355&quot; height=&quot;202&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 우리가 보통 주목하는 부분은 각 직선의 $y$절편과 두 직선간의 교점 $(1,2)$ 같은 것들이 있습니다. 결국 우리는 선형방정식의 Row picture를 통해서 두 직선을 모두 만족하는 솔루션 $(1,2)$을 찾았다고 얘기할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. Column picture &lt;span style=&quot;color: #ee2323;&quot;&gt;(중요)&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이제 우린 앞서 본 선형 방정식의 Column picture을 살펴보겠습니다. 이름 그대로 행렬의 Column (세로 줄)을 이용하여 다음과 같이 표현한 것이 Column picture라고 할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;$$x\begin{bmatrix}2&amp;nbsp; \\ -1&amp;nbsp; \end{bmatrix}+y\begin{bmatrix}-1 \\ 2 \end{bmatrix}=\begin{bmatrix}0 \\ 3 \end{bmatrix}$$&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이 방정식은 벡터 $\begin{bmatrix}2 \\ 1 \end{bmatrix}$와 $\begin{bmatrix}-1 \\ 2 \end{bmatrix}$를 $x$와 $y$를 통해 올바른 양으로 결합하여 $\begin{bmatrix}0 \\ 3 \end{bmatrix}$을 만들라고 우리에게 요구한다고 볼 수 있습니다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;즉 다시말해 우리에게 올바른 선형 조합 (linear combination)을 요구하는 것입니다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이제 위 Column picture를 그림으로 표현하여 Column들을 결합해보겠습니다. 그림은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/skoMF/btr1bfi1CNJ/g730ghFUqTcmwv6iOTHbt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/skoMF/btr1bfi1CNJ/g730ghFUqTcmwv6iOTHbt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/skoMF/btr1bfi1CNJ/g730ghFUqTcmwv6iOTHbt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FskoMF%2Fbtr1bfi1CNJ%2Fg730ghFUqTcmwv6iOTHbt1%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;355&quot; height=&quot;278&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;우리는 앞서서 $x=1, y=2$일 때 우변의 벡터 $\begin{bmatrix}0 \\ 3 \end{bmatrix}$를 얻는다는 것을 확인했는데, 이것이 위 그림을 통해서 &lt;b&gt;기하적으로는&lt;/b&gt; 어떻게 도출될까요?&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;우선 $\begin{bmatrix}2 \\ 1 \end{bmatrix}$은 $x=1$이므로 변화없이 그대로 멈춰있지만, $\begin{bmatrix}-1 \\ 2 \end{bmatrix}$의 경우 $y=2$이므로 2배가 되면서 이것을 $\begin{bmatrix}2 \\ 1 \end{bmatrix}$과 더해주면 하늘색 벡터 즉 $\begin{bmatrix}0 \\ 3 \end{bmatrix}$가 도출됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWCN91/btr06WcREPj/s1IKDawWRRbi7L20JWNKBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWCN91/btr06WcREPj/s1IKDawWRRbi7L20JWNKBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWCN91/btr06WcREPj/s1IKDawWRRbi7L20JWNKBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWCN91%2Fbtr06WcREPj%2Fs1IKDawWRRbi7L20JWNKBk%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;355&quot; height=&quot;272&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 $\begin{bmatrix}0 \\ 3 \end{bmatrix}$과 상관없이, 어떠한 값이든 $x, y$에 들어갈 수 있게되면서 솔루션은 좌표평면의 모든 공간을 채우게 됩니다. 여기까지는 2개의 방정식과 2개의 미지수를 가지고 다룰 수 있는 개념이었습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이제는 3개의 방정식과 3개의 미지수에 대해서 다뤄보겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;$$\begin{cases}2x-y+0z=0\\-x+2y-z=-1\\0x-3y+4z=4\end{cases}$$&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;제가 여러분들에게 위 연립 방정식을 선형대수의 관점에서 어떻게 풀수 있습니까?라고 물어보면 머릿속에서는 &lt;b&gt;1) Row picture 2) Column picture&lt;/b&gt; 두가지가 생각나야 합니다. 우선 Row picture의 관점에서 생각하려면 &lt;b&gt;계수 행렬 (Coefficient matrix)&lt;/b&gt;부터 표현해야겠죠.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;$$A=\begin{bmatrix}2&amp;amp;-1&amp;amp;0\\-1&amp;amp;2&amp;amp;-1\\0&amp;amp;-3&amp;amp;4\end{bmatrix} \; b=\begin{bmatrix}0\\-1\\4\end{bmatrix}$$&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;우선 저 선형 방정식의 솔루션을 구하기 앞서서 각 식에 대한 솔루션부터 생각해보겠습니다. $-x+2y-z=-1$의 솔루션부터 생각하면 $\begin{bmatrix}0 \\ 0 \\ 1 \end{bmatrix}$같은 것이 솔루션이 될 것이고 모든 해를 구하면 다음과 같은 평면으로 나타날 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl3wi0/btr01THxiTC/CJeQ7ZtjtOnLvGbCnOC7T1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl3wi0/btr01THxiTC/CJeQ7ZtjtOnLvGbCnOC7T1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl3wi0/btr01THxiTC/CJeQ7ZtjtOnLvGbCnOC7T1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl3wi0%2Fbtr01THxiTC%2FCJeQ7ZtjtOnLvGbCnOC7T1%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;355&quot; height=&quot;285&quot; data-origin-width=&quot;272&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 $2x-y+0z=0$나 $0x-3y+4z=4$의 경우엔 계산해보면 아래와 같은 평면으로 나타날 것입니다.&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;285&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmq7Jg/btr1beqJS88/QJcYtuIzJQeqppxkib9031/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmq7Jg/btr1beqJS88/QJcYtuIzJQeqppxkib9031/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmq7Jg/btr1beqJS88/QJcYtuIzJQeqppxkib9031/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdmq7Jg%2Fbtr1beqJS88%2FQJcYtuIzJQeqppxkib9031%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;285&quot; height=&quot;272&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;제 미숙한 그림 실력으로 이해 하시기 어려우실 순 있으시겠지만(^^;;) 중요한건 저 세 평면들은 평행하지 않기에 하나의 점에서 만나게 되고 그것이 곧 선형 방정식의 솔루션이 되는 것입니다. &lt;b&gt;우리가 느낄 수 있는건 2차원까진 Row picture로도 풀만 했지만 차원이 높아질수록 Row picture로 풀기 어려워집니다.&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;따라서 우리는 Column picture를 더욱 선호하게 됩니다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 아래와 같이 Column picture로 접근해보겠습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;$$x\begin{bmatrix}2 \\ -1 \\ 0 \end{bmatrix}+y\begin{bmatrix}-1 \\ 2 \\ -3 \end{bmatrix}+z\begin{bmatrix}0 \\ -1 \\ 4 \end{bmatrix}=\begin{bmatrix}0 \\ -1 \\ 4 \end{bmatrix}$$&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;결국 우리는 저 세가지의 벡터를 조합하여 (Linear combination하여) $\begin{bmatrix}0 \\ -1 \\4 \end{bmatrix}$를 얻고 싶은 것입니다. 그렇다면 위 Column picture를 기하적으로 표현하여 접근해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ofZAd/btr1vst11ta/niKOK32aqXl9hyJauHFMP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ofZAd/btr1vst11ta/niKOK32aqXl9hyJauHFMP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ofZAd/btr1vst11ta/niKOK32aqXl9hyJauHFMP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FofZAd%2Fbtr1vst11ta%2FniKOK32aqXl9hyJauHFMP0%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;355&quot; height=&quot;302&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이제 솔루션을 생각해보자면 가장 쉬운 솔루션 중 하나는 Column 3가 $b$와 동일한 $\begin{bmatrix}0 \\ -1 \\4 \end{bmatrix}$이기 때문에 $(0,0,1)$입니다. 이 점이 결국 앞서 Row picture에서 봤던 세 개의 평면이 만나는 한 점인 것입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. Non-singular ( invertible ) matrix&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;앞서서 특정 $b$에 대해 선형 방정식의 솔루션을 구하는 과정에 대해 살펴보았습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;그렇다면 앞서 보았던 저 선형 방정식은 모든 3차원 벡터 $b$에 대해 솔루션을 가질까요? 라고 물어본다면 이 말은 곧 저 선형 방정식을 구성하는 Column들의 linear combination은 3차원 공간을 모두 채울 수 있나요?를 물어보는 것입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;앞서 우리가 계속 다뤘던 아래 컬럼에 대해서는 우린 'yes'라고 얘기할 수 있습니다. 이런 행렬을 우리는 'non-singular' 혹은 'invertible' 행렬이라고 부릅니다. 반대로 모든 $b$에 대한 솔루션이 존재하지 않고 일부의 $b$에서만 존재한다면 이는 'singular' 행렬입니다. 당연하겠지만 우린 non-singular를 좀더 선호해야겠죠.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;정리하자면 우리는 오늘 하나의 선형 방정식을 푸는 두 가지의 접근 1) Row picture와 2) Column picture에 대해서 살펴보았고, Non-singular ( invertible ) matrix의 개념까지 살펴보았습니다. &lt;b&gt;한가지 유념하면 좋을 것은 $Ax=b$에서 각각의 row와 $x$를 곱하는 관점은 내적 (dot product)의 관점이다라고 보고, Column picture의 관점에서 $A$의 컬럼을 기준으로 해를 푼다면 컬럼들의 Linear combination의 관점이다라고 이해해주시면 좋습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;오늘도 긴 저의 포스팅을 읽어주셔서 감사합니다. 행복한 하루 보내세요! :)&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;다음 포스팅도 보러 바로 고고!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/77&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[이론/MIT 선형대수] - [문과도 이해하는 선형대수 for 딥러닝] 2. 행렬 소거 (Elimination with Matrices)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678519388073&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[문과도 이해하는 선형대수 for 딥러닝] 2. 행렬 소거 (Elimination with Matrices)&quot; data-og-description=&quot;성공의 커다란 비결은 결코 지치지 않는 인간으로 인생을 살아가는 것이다. - 알버트 슈바이처 - 안녕하세요 저번 포스팅에서는 선형 대수 공부의 첫 단원으로써, 선형 방정식을 Row picture와 Column&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/77&quot; data-og-url=&quot;https://box-world.tistory.com/77&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bn1AS2/hyRTLWD9iS/upuzGDlP7OYt0GqZ6kvox0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/8JhKS/hyRTIZU0gk/Oia9NDWvO8nUMdY6ME8Thk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bDCbvA/hyRTT1rQU2/87F05JlJ5glk5lOK33N0a1/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/77&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/77&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bn1AS2/hyRTLWD9iS/upuzGDlP7OYt0GqZ6kvox0/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/8JhKS/hyRTIZU0gk/Oia9NDWvO8nUMdY6ME8Thk/img.jpg?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bDCbvA/hyRTT1rQU2/87F05JlJ5glk5lOK33N0a1/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[문과도 이해하는 선형대수 for 딥러닝] 2. 행렬 소거 (Elimination with Matrices)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;성공의 커다란 비결은 결코 지치지 않는 인간으로 인생을 살아가는 것이다. - 알버트 슈바이처 - 안녕하세요 저번 포스팅에서는 선형 대수 공부의 첫 단원으로써, 선형 방정식을 Row picture와 Column&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>이론/MIT 선형대수</category>
      <category>column</category>
      <category>Linear Algebra</category>
      <category>MIT</category>
      <category>row</category>
      <category>singular</category>
      <category>딥러닝</category>
      <category>딥러닝 수학</category>
      <category>선형대수</category>
      <category>선형방정식</category>
      <category>수학</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/76</guid>
      <comments>https://box-world.tistory.com/76#entry76comment</comments>
      <pubDate>Wed, 1 Mar 2023 15:16:54 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] 앱 시작할때 나오는 로딩 화면 구현하기! (Splash Screen)</title>
      <link>https://box-world.tistory.com/75</link>
      <description>&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-origin-width=&quot;1500&quot; data-origin-height=&quot;1100&quot; width=&quot;691&quot; height=&quot;507&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FVMOG/btrbgoiOfdM/TK3Oa6bsGIKV6j8iow1H7k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FVMOG/btrbgoiOfdM/TK3Oa6bsGIKV6j8iow1H7k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FVMOG/btrbgoiOfdM/TK3Oa6bsGIKV6j8iow1H7k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFVMOG%2FbtrbgoiOfdM%2FTK3Oa6bsGIKV6j8iow1H7k%2Fimg.jpg&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;1100&quot; width=&quot;691&quot; height=&quot;507&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;배민이든, 넷플릭스 등 우리가 쓰고 있는 99%의 앱은 처음 실행하면 바로 메인 페이지가 나오지 않고, 위처럼 로고가 떠있는 화면을 지나서 들어가게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;이러한 화면이 필요한 이유&lt;/b&gt;는 단순히 로고 자랑을 하려고 보여준다기보다는, 여기에 머무는 동안 자동 로그인을 통해 데이터를 가져오거나, 보안과 관련되어 검사를 진행하는데 약간의 시간이 필요하기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;혹은 경우에 따라서 서비스 점검을 위해 이 화면에서 더 이상 접근을 못하게 막는다던가 간단해 보이지만 상당히 의미있는 화면이라고 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이러한 화면을 &lt;b&gt;Splash Screen&lt;/b&gt;이라고 합니다. 이번 포스팅에서는 이러한 SplashScreen을 구현하는 방법에 대해 알아보겠습니다.&lt;/p&gt;

&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;화면 준비하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우선 SplashScreen이 될 화면을 준비해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628059593542&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@override
  Widget build(BuildContext context) {
    final String imageLogoName = 'assets/images/public/PurpleLogo.svg';

    var screenHeight = MediaQuery.of(context).size.height;
    var screenWidth = MediaQuery.of(context).size.width;

    return WillPopScope(
      onWillPop: () async =&amp;gt; false,
      child: MediaQuery(
        data: MediaQuery.of(context).copyWith(textScaleFactor:1.0),
        child: new Scaffold(
          backgroundColor: hexToColor('#6F22D2'),
          body: new Container(
            //height : MediaQuery.of(context).size.height,
            //color: kPrimaryColor,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: &amp;lt;Widget&amp;gt;[
                SizedBox(height: screenHeight * 0.384375),
                Container(
                  child: SvgPicture.asset(
                    imageLogoName,
                    width: screenWidth * 0.616666,
                    height: screenHeight * 0.0859375,
                  ),
                ),
                Expanded(child: SizedBox()),
                Align(
                  child: Text(&quot;&amp;copy; Copyright 2020, 내방니방(MRYR)&quot;,
                      style: TextStyle(
                        fontSize: screenWidth*( 14/360), color: Color.fromRGBO(255, 255, 255, 0.6),)
                  ),
                ),
                SizedBox( height: MediaQuery.of(context).size.height*0.0625,),
              ],
            ),

          ),
        ),
      ),
    );
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;initState에 다음 화면으로 넘어가는 코드를 추가&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;화면이 준비됐으면, 일정 시간 이후 다음 화면으로 넘어가는 코드를 추가해줍니다. 아래 코드는 1.5초 후에 자동으로 Navigate하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628059758340&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@override
  void initState() {
  	Timer(Duration(milliseconds: 1500), () {
                  Navigator.push(context, MaterialPageRoute(
                      builder: (context) =&amp;gt; LoginMainScreen()
                  )
                  );
                });
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 구현된 결과입니다.&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/v/421262621&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/wAwX9/hyK7xREvmr/Xl83RVynQMkCmopZET2L00/img.jpg?width=360&amp;amp;height=652&amp;amp;face=0_0_360_652&quot; data-video-width=&quot;360&quot; data-video-height=&quot;652&quot; data-video-origin-width=&quot;360&quot; data-video-origin-height=&quot;652&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-play-service=&quot;daum_tistory&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/421262621?service=daum_tistory&quot; width=&quot;360&quot; height=&quot;652&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;(응용) 특정 조건을 만족시키지 않으면 Navigate 막고 앱 종료하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;앞서 말씀드린대로 SplashScreen에서는 상황에 따라, 서비스 점검이나 기타 사안들에 의해 더 이상이 Navigate를 막고 앱을 종료시켜야하는 경우도 있습니다. 이 또한 initState()에서 구현합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1628060031719&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@override
  void initState() {
  	Timer(Duration(milliseconds: 1500), () {
    		if(Condition){
					exit(0);
                }
                else{              
                      Navigator.push(context, MaterialPageRoute(
                      builder: (context) =&amp;gt; LoginMainScreen()
                  )
                  );
                }
                });
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>개발/Flutter</category>
      <category>Android</category>
      <category>DART</category>
      <category>exit(0)</category>
      <category>flutter</category>
      <category>IOS</category>
      <category>react</category>
      <category>SplashScreen</category>
      <category>로딩화면</category>
      <category>앱</category>
      <category>앱 강제 종료</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/75</guid>
      <comments>https://box-world.tistory.com/75#entry75comment</comments>
      <pubDate>Wed, 4 Aug 2021 15:56:09 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] PageView 자동 스크롤 기능 넣기!</title>
      <link>https://box-world.tistory.com/74</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;735&quot; data-filename=&quot;blob&quot; width=&quot;254&quot; height=&quot;318&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctHE5t/btra1YZVJ7P/zOkpOSwvGASkTClPiKRG00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctHE5t/btra1YZVJ7P/zOkpOSwvGASkTClPiKRG00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctHE5t/btra1YZVJ7P/zOkpOSwvGASkTClPiKRG00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctHE5t%2Fbtra1YZVJ7P%2FzOkpOSwvGASkTClPiKRG00%2Fimg.png&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;735&quot; data-filename=&quot;blob&quot; width=&quot;254&quot; height=&quot;318&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;대부분 스타트업에서 만든 플랫폼 서비스 앱의 첫 메인페이지를 들어가게 되면 보통 우리는 위 사진처럼 상단에 프로모션 광고가 보이는 대형 PageView를 보게됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그리고 일정 시간마다 이들은 돌아가면서 다른 광고들을 순차적으로 보여줍니다. 이번 포스팅에서는 &lt;b&gt;Flutter&lt;/b&gt;에서 &lt;b&gt;PageView&lt;/b&gt;에서 일정 시간마다 &lt;b&gt;자동으로 스크롤되는 기능&lt;/b&gt;을 구현해보겠습니다!&lt;/p&gt;

&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PageView 준비하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;당연하겠지만 우선 &lt;b&gt;PageView&lt;/b&gt;가 있어야겠죠? 여기에 대한 코드를 준비해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627978545860&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PageView.builder(
                        pageSnapping: true,
                        controller: _PageController,
                        itemCount: itemList.length,
                        onPageChanged: (value) {
                         
                        },
                        itemBuilder: (context, index) {
                          return Container(
                            child: Image.asset(
                                bannerPNG[index],
                                width: screenWidth,
                                height: screenWidth * (140/360),
                                fit: BoxFit.cover),
                          );
                        },
                      ),&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 &lt;b&gt;PageView.builder&lt;/b&gt;에서 우리가 주목해야할 부분은 두 가지 입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;controller&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;onPageChanged&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;자동 스크롤 기능 넣기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제&lt;b&gt; initState()&lt;/b&gt; 메서드 내에 자동 스크롤 기능을 넣겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627978824569&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int currentPage = 0;
PageController _PageController = PageController(
    initialPage: 0,
  );
  
@override
  void initState() {
    super.initState();

    Timer.periodic(Duration(seconds: 5), (Timer timer) {
      if (currentPage &amp;lt; 2) {
        currentPage++;
      } else {
        currentPage = 0;
      }

      _PageController.animateToPage(
        currentPage,
        duration: Duration(milliseconds: 350),
        curve: Curves.easeIn,
      );
    });
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;필요한 변수는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;currentPage&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;_PageController&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;저와 변수명이 같다는 가정하에 &lt;b&gt;initState&lt;/b&gt;내에 저 코드만 그대로 넣어주시면 자동 스크롤 기능 구현 끝입니다! &lt;b&gt;만약 넘겨지는 시간을 조정&lt;/b&gt;하고 싶다면 &lt;b&gt;Timer.periodic&lt;/b&gt; 내 &lt;b&gt;Duration&lt;/b&gt; 값을 수정해주시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;실행시키면 다음과 같은 결과가 나옵니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/v/421240544&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bxJV2l/hyK6nh29jl/UJA3XarlGUboh2wM5ytEAk/img.jpg?width=360&amp;amp;height=272&amp;amp;face=0_0_360_272&quot; data-video-width=&quot;360&quot; data-video-height=&quot;272&quot; data-video-origin-width=&quot;360&quot; data-video-origin-height=&quot;272&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-play-service=&quot;daum_tistory&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/421240544?service=daum_tistory&quot; width=&quot;360&quot; height=&quot;272&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;</description>
      <category>개발/Flutter</category>
      <category>Android</category>
      <category>Auto Scroll</category>
      <category>DART</category>
      <category>flutter</category>
      <category>IOS</category>
      <category>PageView</category>
      <category>PageView.builder</category>
      <category>scroll</category>
      <category>앱</category>
      <category>자동 스크롤</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/74</guid>
      <comments>https://box-world.tistory.com/74#entry74comment</comments>
      <pubDate>Tue, 3 Aug 2021 17:25:19 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] LSTM의 모든 것</title>
      <link>https://box-world.tistory.com/73</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;아무리 어려워도 한번 시작한 일은 끝까지 해라&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;- 안드레아 정 (에어본 회장) -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;저번 포스팅에서 우리는 &lt;b&gt;RNN&lt;/b&gt;을 이용하여 주어진 &lt;b&gt;Time-Series 데이터&lt;/b&gt;를 이용하여 미래를 예측하는 &lt;b&gt;forecasting&lt;/b&gt;에 대해 공부해보았습니다. 하지만 이전에 우리가 다뤘던 데이터들의 길이는 상대적으로 짧은 축에 속했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;몇달이 아닌 몇 년 치의 데이터에도 RNN은 좋은 성능을 보일까요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;긴 시퀀스(상대적으로 많은 타임 스텝을 가지는 Time-Series Data)로 훈련하려면 많은 타임 스텝에 걸쳐 실행해야 하므로 RNN은 그만큼 매우&lt;b&gt; 깊은 네트워크&lt;/b&gt;가 됩니다. 보통 이렇게 깊어진 RNN은 다음과 같은 문제가 발생할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;깊어진만큼 &lt;b&gt;Gradient Vanishing&lt;/b&gt; 문제나 &lt;b&gt;Exploding&lt;/b&gt; 문제가 발생할 수 있습니다.&lt;/li&gt;
&lt;li&gt;길어진 데이터를 처리하면서 Input data의 &lt;b&gt;초기 타임 스텝을 점점 잊어버릴 것입니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;이번 포스팅에서는 RNN으로 긴 시퀀스 데이터를 다루기 위해서 어떤 점을 보완해야하는지 알아보겠습니다. 그리고 더 나아가서 LSTM과 GRU까지 모든 것을 파헤쳐보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;이번 포스팅은 RNN을 공부하고 정독하시면 더욱 효과적입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/72&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Hands-On Machine Learning 2판] - [ 머신러닝 순한 맛 ] 시계열 데이터의 모든 것, RNN 정복하기!&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1627749545964&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 머신러닝 순한 맛 ] 시계열 데이터의 모든 것, RNN 정복하기!&quot; data-og-description=&quot;사는 데 더 나은 방법을 찾아라 - 엘빈 토플러 - &amp;nbsp;코로나로 인해 가장 크게 떠오른 분야가 무엇이냐고 한다면, 저는 주식만한게 없다고 생각합니다. 우린 결국 돈을 벌고 싶고, 미래를 예측하여 &quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/72&quot; data-og-url=&quot;https://box-world.tistory.com/72&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ecsJch/hyK3BONduv/5H5tvqGu7PkqPXSkkkc810/img.png?width=441&amp;amp;height=189&amp;amp;face=0_0_441_189,https://scrap.kakaocdn.net/dn/cVGwrP/hyK4O6NDaf/pa9wQWHzkANJKMEkJ0kG1k/img.png?width=441&amp;amp;height=189&amp;amp;face=0_0_441_189,https://scrap.kakaocdn.net/dn/fsG8v/hyK3HhaUlH/trG0BNS3Das6OEtLoNzIT0/img.png?width=434&amp;amp;height=333&amp;amp;face=0_0_434_333&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/72&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/72&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ecsJch/hyK3BONduv/5H5tvqGu7PkqPXSkkkc810/img.png?width=441&amp;amp;height=189&amp;amp;face=0_0_441_189,https://scrap.kakaocdn.net/dn/cVGwrP/hyK4O6NDaf/pa9wQWHzkANJKMEkJ0kG1k/img.png?width=441&amp;amp;height=189&amp;amp;face=0_0_441_189,https://scrap.kakaocdn.net/dn/fsG8v/hyK3HhaUlH/trG0BNS3Das6OEtLoNzIT0/img.png?width=434&amp;amp;height=333&amp;amp;face=0_0_434_333');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ 머신러닝 순한 맛 ] 시계열 데이터의 모든 것, RNN 정복하기!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;사는 데 더 나은 방법을 찾아라 - 엘빈 토플러 - &amp;nbsp;코로나로 인해 가장 크게 떠오른 분야가 무엇이냐고 한다면, 저는 주식만한게 없다고 생각합니다. 우린 결국 돈을 벌고 싶고, 미래를 예측하여&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RNN으로 긴 시퀀스 다루기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;앞서 간단하게 언급한대로, Gradient Vanishing/Exploding 문제때문에 있는 그대로의 RNN을 바로 긴 시퀀스에 적용하는 것은 어렵다는 것을 알았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이전에 우리가 공부한 Neural Network에서도 깊을 경우 이러한 Gradient 문제가 존재했고, 이를 위해 &lt;b&gt;Gradient Initialization / Fast Optimization / DropOut&lt;/b&gt; 등 다양한 해결 방법이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이러한 방법은 RNN에도 똑같이 적용될 수 있는데, 딱 하나 &lt;b&gt;Relu&lt;/b&gt;(수렴되지 않는 activation 함수)와 같은 방법은 도움이 되지 않고 되려 더 불안하게 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;예를 들어 이유를 설명드리겠습니다. Gradient Descent 알고리즘에 의해 첫번째 타임 스텝에서 Output을 조금 증가시키는 방향으로 Gradient Update가 이뤄졌다고 가정해보겠습니다. 그런데 이러한 방향의 Update가 두번째에도, 세 번째에도 계속 반복된다면 &lt;b&gt;Gradient Exploding&lt;/b&gt; 문제가 일어나게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;즉 RNN에서는 Relu와 같은 함수가 Gradient 문제를 해결하는데 도움이 되지 않습니다. 작은 Learning Rate를 사용하면 이런 위험을 감소시킬 수 있지만, 간단하게 &lt;b&gt;tanh 함수&lt;/b&gt;와 같이 &lt;b&gt;'수렴하는'&lt;/b&gt; activation 함수를 사용할 수 있습니다.&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;Batch Normalization&lt;/b&gt;은 RNN에서 그다지 효율적이지 않습니다. 정확하게 말하자면 타임 스텝을 넘어갈 때 사용할 수는 없고 하나의 타임 스텝을 처리하는 Layer들 사이에만 적용할 수 있습니다. 그렇지만 크게 기대할만큼 좋은 성능을 내지 못합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그럼 RNN에 잘 맞는 Normalization은 뭘까요? 그것은 바로 &lt;b&gt;층 정규화(Layer Normalization)&lt;/b&gt;입니다. 2016년에 소개된 이 개념은 Batch Normalization와 비슷하지만, Batch 차원이 아닌 &lt;b&gt;Feature 차원&lt;/b&gt;에 대해 정규화가 이뤄집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;555&quot; width=&quot;577&quot; height=&quot;323&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lfoWU/btra1YYc1KU/oLl0dHvJ7mJcptVG55HyPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lfoWU/btra1YYc1KU/oLl0dHvJ7mJcptVG55HyPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lfoWU/btra1YYc1KU/oLl0dHvJ7mJcptVG55HyPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlfoWU%2Fbtra1YYc1KU%2FoLl0dHvJ7mJcptVG55HyPk%2Fimg.png&quot; data-origin-width=&quot;992&quot; data-origin-height=&quot;555&quot; width=&quot;577&quot; height=&quot;323&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;말로만 하면 잘 감이 안오실텐데 위 그림을 보면서 다시 생각해보겠습니다. feature 1, 2로 이루어진 50개의 데이터가 있다고 했을 때, 기존 BN(Batch Normalization)은 50개의 데이터를 &lt;b&gt;Batch&lt;/b&gt;라는 단위로 몇개 그룹으로 분할하여 각 그룹의 평균과 분산을 구하여 정규화를 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;반대로 &lt;b&gt;LN(Layer Normalization)&lt;/b&gt;은 Batch 단위가 아니라, 50개 데이터에 존재하는 feature 1의 값을 모조리 모아 정규화를 진행하고, feature 2를 모아 모조리 정규화하는 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이렇게 전체 데이터를 feature를 기준으로 정규화를 하면, 내가 뽑는 batch에 따라 통계값이 달라지지 않고, 데이터에 독립적으로 필요한 통계값을 계산할 수 있기 때문에 Training과 Test에서 동일한 방식으로 작동하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;LN도 BN과 마찬가지로 Input마다 하나의 &lt;b&gt;Scale&lt;/b&gt;과 &lt;b&gt;Shift&lt;/b&gt; 파라미터를 학습합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LSTM(Long, Short-Term Memory)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;RNN을 거치면서 데이터의 길이가 길 수록 초기 타임 스텝의 정보는 사라지게 됩니다. 이는 중요한 문제이고 이를 해결하기 위해 소실되지 않게 &lt;b&gt;장기적인 메모리를 가진 여러 종류의 셀&lt;/b&gt;이 연구되었습니다. 이 중 현재 가장 많이 쓰이는게 &lt;b&gt;LSTM입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;LSTM&lt;/b&gt;은 훈련이 빠르게 수렴하고 데이터 내 장기간의 dependancy를 감지할 수 있습니다. 코드 상에선 기존에 사용하던 SimpleRNN 대신 LSTM을 사용해주면 되겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627751457894&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.LSTM(20, return_sequences=True, input_shape=[None, 1]),
    keras.layers.LSTM(20, return_sequences=True),
    keras.layers.TimeDistributed(keras.layers.Dense(10))
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그렇다면 LSTM은 어떻게 작동할까요? 다음은 LSTM의 구조입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;241&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFqKVj/btraSYrUENz/WWJzEiafPv2R3LfSjPI6I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFqKVj/btraSYrUENz/WWJzEiafPv2R3LfSjPI6I0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFqKVj/btraSYrUENz/WWJzEiafPv2R3LfSjPI6I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFqKVj%2FbtraSYrUENz%2FWWJzEiafPv2R3LfSjPI6I0%2Fimg.png&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;241&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;셀 내부를 들여다보지 않는다면, LSTM 셀은 기존 한개의 셀에서 &lt;b&gt;두개의 셀&lt;/b&gt; $h_{(t)}$와 $c_{(t)}$을 받는다는 점 빼고는 정확히 일반 셀처럼 보입니다. 여기서 $h_{(t)}$는 &lt;b&gt;단기 상태&lt;/b&gt;, $c_{(t)}$는 &lt;b&gt;장기 상태&lt;/b&gt;를 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;본격적으로 박스 내부를 하나하나 살펴보겠습니다. 핵심은 장기 상태 $c_{(t)}$에 저장할 것, 버릴 것, 그리고 읽어들일 것을 학습하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;장기 기억 $c_{(t-1)}$은 타임 스텝에 따라 네트워크를 지나면서 &lt;b&gt;'삭제 게이트'&lt;/b&gt;를 지나 일부 기억을 잃고, 그 다음 덧셈 연산으로 &lt;b&gt;'입력 게이트'&lt;/b&gt;에서 선택한 기억을 추가합니다. 그렇게 해서 만들어진 $c_{(t)}$는 별도의 변환없이 바로 출력으로 보내집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;$c_(t-1)$은 삭제 게이트를 지나 덧셈연산 후 복사되어(두 갈래로 나뉩니다) $tanh$ 함수로 전달되는데, 이는 &lt;b&gt;'출력 게이트'&lt;/b&gt;에 의해 걸러집니다. 이것이 단기 상태 $h_{(t)}$입니다.(셀의 출력 $y_{(t)}$와 동일합니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 현재 타임 스텝의 입력 벡터 $x_{(i)}$와 이전 단기 상태 $h_{(t-1)}$가 주입되는 네 개의 다른 FC Layer에 대해 사렾보겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네 개 중 $g_{(i)}$&lt;b&gt;를 출력하는 Layer&lt;/b&gt;는 input 벡터와 단기 상태를 분석하는 일반적이면서 Major한 Layer입니다. 기본 셀에서는 이 layer 외에 다른 것 없이 바로 $y_{(t)}$와 $h_{(t)}$를 출력했었습니다. 하지만 LSTM에서는 바로 출력되지 않고, &lt;b&gt;장기 상태에 가장 중요한 부분만 저장되고 나머지는 버립니다&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;나머지 세 개의 layer는 &lt;b&gt;Gate controller&lt;/b&gt;입니다. 이들은 logistic 함수를 사용하여 Output range가 0~1 사이입니다. 그림에서 보듯이 이들의 출력은 곱셉 연산으로 주입되어 0을 출력하면 게이트를 닫고, 1을 출력하며 게이트를 엽니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;삭제 게이트&lt;/b&gt; ($f_{(t)}$)는 장기 상태 $c_(t-1)$의 어느 부분이 삭제되어야하는지 제어합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;입력 게이트&lt;/b&gt; ($i_{(t)}$)는 $g_{(t)}$의 어느 부분이 장기 상태 $c_{(t)}$에 더해져야 하는지 제어합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력 게이트&lt;/b&gt; ($o_{(i)}$)는 장기 상태의 어느 부분을 읽어 현재 타임스텝의 $h_{(i)}$와 $y_{(i)}$로 출력해야 하는지 제어합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;꽤나 복잡해보이지만 간단하게 얘기하면 LSTM은 중요한 Input을 인식하고(입력게이트), 이 Input을 필요한 기간만큼 장기 상태에 저장하고(삭제게이트), 그리고 필요할때마다 이를 추출하기 위해 학습합니다.&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-origin-width=&quot;213&quot; data-origin-height=&quot;229&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diFWw2/btraVp3SYBy/fB1kZzLjLIbk0Rb9J68iLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diFWw2/btraVp3SYBy/fB1kZzLjLIbk0Rb9J68iLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diFWw2/btraVp3SYBy/fB1kZzLjLIbk0Rb9J68iLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiFWw2%2FbtraVp3SYBy%2FfB1kZzLjLIbk0Rb9J68iLK%2Fimg.png&quot; data-origin-width=&quot;213&quot; data-origin-height=&quot;229&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;핍홉 연결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;일반적인 LSTM은 하나의 셀에서 입력 $x_{(t)}$와 이전 단기 상태 $h_{(t)}$를 받아들입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;그런데 게이트 제어기에 이 둘 외에도 '장기 상태'도 조금 노출 시키면 좀 더 많은 context(문맥)을 감지할 수 있지 않을까요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그래서 제안된 것이 2000년대 &lt;b&gt;핍홀 연결(peephole connection)&lt;/b&gt;이라 부르는 추가적인 연결이 있는 LSTM 변종입니다. 이것은 이전 장기 기억 상태 $c_{(t-1)}$이 삭제와 입력 게이트&amp;nbsp; $f_{(t)}$와 $i_{(t)}$에 입력으로 추가됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이는 성능을 향상하는 경우가 많지만, 매번 그렇지는 않기 때문에 직접 확인 후에 적용을 해야합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GRU&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;GRU(Gated Recurrent Unit)&lt;/b&gt;은 2014년에 제안된 LSTM의 &lt;b&gt;간소화&lt;/b&gt;된 버전입니다. 어떤 차이점이 있는지 살펴보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;238&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ML2lw/btraWT4rrZ6/pezqCxUxA8yK81JqC11qwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ML2lw/btraWT4rrZ6/pezqCxUxA8yK81JqC11qwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ML2lw/btraWT4rrZ6/pezqCxUxA8yK81JqC11qwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FML2lw%2FbtraWT4rrZ6%2FpezqCxUxA8yK81JqC11qwk%2Fimg.png&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;238&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;기존 LSTM의 장기 상태 $c_{(t)}$와 단기 상태 $h_{(t-1)}$가 $h_{(t-1)}$로 &lt;b&gt;합쳐졌습니다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;하나의 게이트 제어기 $z_{(t)}$가 삭제와 입력 게이트 &lt;b&gt;모두를 제어합니다.&lt;/b&gt; 이것이 1을 출력하면 삭제가 열리고 입력이 닫힙니다. 반대로 0을 출력하면 반대가 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력 게이트는 존재하지 않기 때문에&lt;/b&gt; $h_{(t-1)}$가 매 타임 스텝마다 출력됩니다. 그러나 이전 상태의 어느 부분이 Major 층 ($g_{(t)}$)에 노출될지 제어하는 $r_{(t)}$가 있습니다.&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 alignCenter&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;152&quot; width=&quot;325&quot; height=&quot;190&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK1oIP/btraWSYMERO/BTf6zKYVX6hSU9gG5rqLUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK1oIP/btraWSYMERO/BTf6zKYVX6hSU9gG5rqLUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK1oIP/btraWSYMERO/BTf6zKYVX6hSU9gG5rqLUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcK1oIP%2FbtraWSYMERO%2FBTf6zKYVX6hSU9gG5rqLUk%2Fimg.png&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;152&quot; width=&quot;325&quot; height=&quot;190&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;LSTM과 GRU는 RNN을 보편화하는데 매우 큰 역할들을 하였습니다. 그러나 100 타임 스텝 이상의 시퀀스에서 이들 역시 장기 패턴을 학습하는데 어려움이 있습니다. 이를 해결하기 위해 몇가지 방법들을 시도해볼 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1D &lt;span style=&quot;color: #4d5156;&quot;&gt;Convolutional&lt;/span&gt;Layer를 사용해 시퀀스 처리하기&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;297&quot; data-origin-height=&quot;170&quot; width=&quot;388&quot; height=&quot;222&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB2fzQ/btraL1JB0TW/6iQQEguTlkuWkjzP0G5Ssk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB2fzQ/btraL1JB0TW/6iQQEguTlkuWkjzP0G5Ssk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB2fzQ/btraL1JB0TW/6iQQEguTlkuWkjzP0G5Ssk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB2fzQ%2FbtraL1JB0TW%2F6iQQEguTlkuWkjzP0G5Ssk%2Fimg.png&quot; data-origin-width=&quot;297&quot; data-origin-height=&quot;170&quot; width=&quot;388&quot; height=&quot;222&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;nbsp;&lt;b&gt;Convolutional Layer&lt;/b&gt;라고 하면 본래 CNN에서 이미지가 입력으로 들어왔을 때 이미지의 &lt;b&gt;주요한 특징&lt;/b&gt;을 잡아내기 위해 &lt;b&gt;3x3&lt;/b&gt;과 같은 &lt;b&gt;필터(커널)&lt;/b&gt;을 이용해 슬라이딩하면서 &lt;b&gt;2D feature feature map&lt;/b&gt;을 뽑아내는 과정에서 쓰이는 용어였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;nbsp;특히 일반적인 구조라면 이 Conv Layer를 거치면서 중요한 특성만 뽑아내기 때문에 점점 네트워크를 통과하면서 &lt;b&gt;기존 이미지보다 사이즈가 작아집니다.&lt;/b&gt; 바로 여기서도 이러한 원리를 이용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;nbsp;일반적으로 Time-Series는 이미지처럼 사각형이 아니라 지렁이처럼 하나의 긴줄로 들어오기 때문에 1D에서 존재합니다. 결국 LSTM이나 GRU가 일정 타임 스텝 이상의 시퀀스를 다루기 어렵기 때문에 매우 긴 시퀀스가 들어왔을 때, &lt;b&gt;여기에 필터를 슬라이딩시켜 중요한 특징을 가진 1D feature map을 추출하여 데이터의 크기를 줄이자는게 핵심이 되겠습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;nbsp;만약 10개의 필터를 사용하면 해당&amp;nbsp; layer의 출력은 10개의 1D 시퀀스로 구성됩니다. 이것을 10차원 시퀀스로 볼 수 있겠죠. 이 말은 즉 RNN의 &lt;b&gt;Recurrent Layer&lt;/b&gt;(우리가 지금까지 RNN에서 보던 &lt;b&gt;SimpleRNN&lt;/b&gt; Layer)와 &lt;b&gt;1D Conv Layer&lt;/b&gt; 심지어 &lt;b&gt;1D Pooling&lt;/b&gt; 층까지 섞어서 Neural Network를 구성할 수 있다는 뜻이 됩니다.&lt;/span&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;nbsp;코드를 통해 구현을 살펴보겠습니다. &lt;b&gt;stride = 1&lt;/b&gt;과 &lt;b&gt;&quot;same&quot;&lt;/b&gt; 패딩으로 1D conv Layer를 사용하면 input과 output의 길이는 같습니다. 그러나 &lt;b&gt;&quot;valid&quot;&lt;/b&gt; 패딩과 &lt;b&gt;1보다 큰 스트라이드&lt;/b&gt;를 사용하면 output 시퀀스의 길이는 input보다 짧아지게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;nbsp;다음은 &lt;b&gt;stride = 2&lt;/b&gt;를 사용해 입력 시퀀스를 두 배로 &lt;b&gt;Down-Sampling(반으로 줄이는)&lt;/b&gt; 1D Conv Layer를 사용합니다. 이렇게 길이를 줄이면 GRU 층이 더 긴 패턴을 감지하는데 도움이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1627757030674&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.Conv1D(filters=20, kernel_size=4, strides=2, padding=&quot;valid&quot;,
                        input_shape=[None, 1]),
    keras.layers.GRU(20, return_sequences=True),
    keras.layers.GRU(20, return_sequences=True),
    keras.layers.TimeDistributed(keras.layers.Dense(10))
])

model.compile(loss=&quot;mse&quot;, optimizer=&quot;adam&quot;, metrics=[last_time_step_mse])
history = model.fit(X_train, Y_train[:, 3::2], epochs=20,
                    validation_data=(X_valid, Y_valid[:, 3::2]))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2) WAVENET&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2016년도에 등장한 WAVENET은 앞서 살펴본 1D Conv Layer의 개념을 이용합니다. 이 네트워크는 Layer마다 &lt;b&gt;팽창 비율(dilation rate)을 두 배로 늘리는&lt;/b&gt; 1D Conv Layer를 쌓습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;여기서 &lt;b&gt;dilation rate&lt;/b&gt;를 설명하기 전 &lt;b&gt;receptive field&lt;/b&gt;에 대해 상기해보자면, 하나의 뉴런이 받아들이는 이미지 내 local한 영역입니다. dilation rate는 계산량 증가 없이 이 receptive field를 효과적으로 높이기 위해 아래처럼 &lt;b&gt;필터 내부에 zero padding&lt;/b&gt;을 추가해 강제로 receptive field를 늘립니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;381&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rXHA6/btraWTXF3JP/Ask14AOUuzcccfkIGCyz50/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rXHA6/btraWTXF3JP/Ask14AOUuzcccfkIGCyz50/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rXHA6/btraWTXF3JP/Ask14AOUuzcccfkIGCyz50/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/rXHA6/btraWTXF3JP/Ask14AOUuzcccfkIGCyz50/img.gif&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;381&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 그림에서 파란색이 Input이고, 초록색이 feature map입니다. 여기서 Input의 진한 파랑 부분에만 weight가 있고, 나머지는 0으로 채워넣습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이것이 등장한 이유는 필터의 크기를 크게하면 receptive field도 커져 이미지의 일반적인 feature를 잡기에 용이하지만 연산의 양이 늘어나고, Overfitting의 우려가 있습니다. 보통의 CNN에서는 이를 해결하기 위해 Pooling을 사용합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그러나 &lt;b&gt;Pooling&lt;/b&gt;을 사용하면 기존 정보의 손실이 일어납니다. 따라서 이러한 dilation rate를 활용한 &lt;b&gt;dilated Conv&lt;/b&gt;는 &lt;b&gt;pooling없이&lt;/b&gt; receptive field의 크기를 크게 가져갈 수 있다는 점에서 이점을 가집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그래서 결국 이 dilation rate가 커질 수록 filter의 크기가 커지면서 아래처럼 0으로 채워지는 부분이 많아집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;575&quot; width=&quot;733&quot; height=&quot;329&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPNuAx/btraLckdcxX/n68WbtPA91EiPGKbD7XREk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPNuAx/btraLckdcxX/n68WbtPA91EiPGKbD7XREk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPNuAx/btraLckdcxX/n68WbtPA91EiPGKbD7XREk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPNuAx%2FbtraLckdcxX%2Fn68WbtPA91EiPGKbD7XREk%2Fimg.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;575&quot; width=&quot;733&quot; height=&quot;329&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;아래는 WAVENET의 구조인데, Input과 가까운 하위 층은 dilation rate가 적으므로, 필터의 크기가 작기 때문에 일반적인 것보단 단기 패턴을 학습하고, 점점 dilation rate가 높아지는 상위층으로 갈수록 일반적인 장기 패턴을 학습하게 됩니다. 이러한 원리로 dilation rate를 두 배씩 늘리는 형태의 네트워크로 아주 긴 시퀀스도 효율적으로 처리합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;254&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccjhdg/btraXWs6bum/4IxWCskK8DHrSEARMJNEQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccjhdg/btraXWs6bum/4IxWCskK8DHrSEARMJNEQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccjhdg/btraXWs6bum/4IxWCskK8DHrSEARMJNEQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fccjhdg%2FbtraXWs6bum%2F4IxWCskK8DHrSEARMJNEQ1%2Fimg.png&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;254&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;262&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n65hO/btraZLrjWsU/vMJ2eqE3uSqT3AUyuMsSZK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n65hO/btraZLrjWsU/vMJ2eqE3uSqT3AUyuMsSZK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n65hO/btraZLrjWsU/vMJ2eqE3uSqT3AUyuMsSZK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/n65hO/btraZLrjWsU/vMJ2eqE3uSqT3AUyuMsSZK/img.gif&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;262&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 WaveNet의 구현입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627758176565&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential()
model.add(keras.layers.InputLayer(input_shape=[None, 1]))
for rate in (1, 2, 4, 8) * 2:
    model.add(keras.layers.Conv1D(filters=20, kernel_size=2, padding=&quot;causal&quot;,
                                  activation=&quot;relu&quot;, dilation_rate=rate))
model.add(keras.layers.Conv1D(filters=10, kernel_size=1))
model.compile(loss=&quot;mse&quot;, optimizer=&quot;adam&quot;, metrics=[last_time_step_mse])
history = model.fit(X_train, Y_train, epochs=20,
                    validation_data=(X_valid, Y_valid))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2204003234852125&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서는 RNN과 Attention 기법을 이용한 NLP에 대해 공부해보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>forecast</category>
      <category>GRU</category>
      <category>LSTM</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>Time Series</category>
      <category>WaveNet</category>
      <category>시계열</category>
      <category>시퀀스</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/73</guid>
      <comments>https://box-world.tistory.com/73#entry73comment</comments>
      <pubDate>Sun, 1 Aug 2021 02:33:14 +0900</pubDate>
    </item>
    <item>
      <title>[ 머신러닝 순한 맛 ] 시계열 데이터의 모든 것, RNN 정복하기!</title>
      <link>https://box-world.tistory.com/72</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&amp;nbsp; 사는 데 더 나은 방법을 찾아라&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;- 엘빈 토플러 -&lt;/b&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;&amp;nbsp;이미 월가를 비롯해 주식시장의 최전방에 위치해있는 기업들은 실제로 다양한 기술을 이용하여 주식 가격의 미래를 예측하여 이를 실제로 수익과 연결시킵니다. 이번 포스팅에서는 &lt;b&gt;순환 신경망 RNN(Recurrent Neural Network)&lt;/b&gt;에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 RNN은 우리가 그동안 봐왔던 대부분의 네트워크처럼 고정된 길이의 Input이 아닌 &lt;b&gt;임의의 길이를 가진 시퀀스&lt;/b&gt;를 다룰 수 있습니다. 시퀀스의 예로는 문장, 문서, 오디오 샘플 등 가변적인 길이가 가진 것들을 예시로 들 수 있고, 이것은 자동 번역, Speech to Text 같은 &lt;b&gt;자연어 처리(NLP)&lt;/b&gt;에 매우 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2192657103&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Recurrent Neuron and Recureent Layer&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;지금까지 우리가 봐온 네트워크들에서 Input이라 하면, 출력층을 향해서 한 방향으로만 흘러가는 &lt;b&gt;Feed-Forward Network&lt;/b&gt;였습니다. 그러나 지금부터 우리가 볼 RNN은 &lt;b&gt;출력으로 나온 Output이 다시 입력으로 순환하여 들어가는 연결이 있다는 점&lt;/b&gt;에서 기존과 차이점을 보입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;189&quot; width=&quot;579&quot; height=&quot;248&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2HIyV/btraGGxWMYR/CdvG4015GI3UDoxkyP5c7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2HIyV/btraGGxWMYR/CdvG4015GI3UDoxkyP5c7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2HIyV/btraGGxWMYR/CdvG4015GI3UDoxkyP5c7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2HIyV%2FbtraGGxWMYR%2FCdvG4015GI3UDoxkyP5c7k%2Fimg.png&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;189&quot; width=&quot;579&quot; height=&quot;248&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 위 그림의 가장 왼쪽에 있는 것은 입력 $x$를 받아서 출력 $y$를 내보내고 이것을 다시 자기 자신에게 입력으로 보내는 가장 간단한 RNN입니다. 이것은 각 &lt;b&gt;타임 스텝&lt;/b&gt; $t$(하나의 단위 데이터가 들어올 때마다)마다 $x_{(t)}$와 이전 타임 스텝의 출력인 $y_{(t-1)}$을 입력으로 받습니다. 이때 가장 첫번째 타임 스텝에서는 이전 출력이 없기 때문에 $y_{(t-1)}$를 0으로 잡습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;왼쪽의 가장 간단한 RNN이 매 타임스텝마다 $x$와 $y_{(t-1)}$를 받아 $y_{(t)}$를 내보내는 과정을 시간을 축으로 하여 위 그림의 오른쪽처럼 표현할 수 있습니다. 이를 &lt;b&gt;시간에 따라 네트워크를 펼쳤다&lt;/b&gt;라고 말합니다.(즉 동일 뉴런을 타임 스텝마다 하나로 표현한 것입니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이러한 하나의 순환 뉴런 여러개가 모여 구성된 층(Layer)는 쉽게 만들 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;168&quot; width=&quot;581&quot; height=&quot;221&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWP0Ep/btraKD7515o/Ha7p34SR6ijpVkWld0Xfs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWP0Ep/btraKD7515o/Ha7p34SR6ijpVkWld0Xfs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWP0Ep/btraKD7515o/Ha7p34SR6ijpVkWld0Xfs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWP0Ep%2FbtraKD7515o%2FHa7p34SR6ijpVkWld0Xfs0%2Fimg.png&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;168&quot; width=&quot;581&quot; height=&quot;221&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;뉴런이 여러개라는 건 입력이 여러 개라는 것이기 때문에 이제 입력은 스칼라가 아닌 &lt;b&gt;벡터&lt;/b&gt; $x_(t)$가 되고, 이전 타임 스텝의 출력 $y_{(t)}$ 또한 벡터가 됩니다. (하나의 뉴런의 출력은 스칼라입니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;각 순환 뉴런은 두 개의 가중치 벡터를 가집니다. 하나는 입력 벡터 $x_(t)$, 다른 하나는 이전 타임 스텝의 출력 $y_{(t)}$을 위한 것입니다. 이것들을 각각 $W_x$, $W_y$라고 하겠습니다. 그렇다면 순환 뉴런의 출력 $y_{(t)}$는 다음 식으로 계산될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;$&lt;span style=&quot;color: #202124;&quot;&gt;&amp;empty;&lt;/span&gt;$는 &lt;b&gt;Relu&lt;/b&gt;와 같은 활성화 함수입니다. 보통 RNN에서는 Relu보단&lt;b&gt; tanh 함수&lt;/b&gt;를 선호합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;165&quot; data-origin-height=&quot;50&quot; width=&quot;224&quot; height=&quot;68&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djfdX8/btraBSzqMyn/xlBPe9f369yQm37d1vVEzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djfdX8/btraBSzqMyn/xlBPe9f369yQm37d1vVEzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djfdX8/btraBSzqMyn/xlBPe9f369yQm37d1vVEzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjfdX8%2FbtraBSzqMyn%2FxlBPe9f369yQm37d1vVEzK%2Fimg.png&quot; data-origin-width=&quot;165&quot; data-origin-height=&quot;50&quot; width=&quot;224&quot; height=&quot;68&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;여기에 더 나아가서 이번엔 입력이 벡터 단위가 아니라, &lt;b&gt;미니 배치&lt;/b&gt;로써 &lt;b&gt;여러 벡터&lt;/b&gt;가 들어온다고 하면 이를 행렬 $X_{(t)}$로 만들어 출력을 한번에 계산할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;92&quot; width=&quot;322&quot; height=&quot;121&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eSwWJA/btraLsFfqvF/2wHK7KPWB4BpnEiAPnHhO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eSwWJA/btraLsFfqvF/2wHK7KPWB4BpnEiAPnHhO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eSwWJA/btraLsFfqvF/2wHK7KPWB4BpnEiAPnHhO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeSwWJA%2FbtraLsFfqvF%2F2wHK7KPWB4BpnEiAPnHhO1%2Fimg.png&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;92&quot; width=&quot;322&quot; height=&quot;121&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;$Y_{(t)}$는 $X_{(t)}$와 $Y_{(t-1)}$을 입력으로 받는 함수이고, &amp;nbsp;$Y_{(t-1)}$는 $X_{(t-1)}$와 $Y_{(t-2)}$을 입력으로 받고, 다시 &amp;nbsp;$Y_{(t-2)}$는 $X_{(t-2)}$와 $Y_{(t-3)}$을 입력으로 받게됩니다. 여기서 알 수 있는 점은 $Y_{(t)}$는 맨 처음 $t=0$에서부터 &lt;b&gt;모든 입력을 받은 뉴런의 출력값&lt;/b&gt;이라는 점입니다.&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Memory Cell&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;타임 스텝 $t$에서 뉴런의 출력은 &lt;b&gt;이전 타임 스텝의 모든 입력에 대한 함수&lt;/b&gt;이므로 이를 일종의 메모리 형태라고 할 수 있습니다. 그래서 타임 스텝에 걸쳐 형성된 어떤 상태를 보존하는 RNN의 구성 요소를&lt;b&gt; 메모리 셀&lt;/b&gt; 간단하게 &lt;b&gt;셀&lt;/b&gt;이라고 부릅니다. -&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;하나의 순환 뉴런 Layer는 일반적으로 10 타임 스텝 내외를 학습할 수 있는 기본적인 셀이지만, 뒤에서 더욱 긴 패턴을 학습할 수 있는 강력한 셀에 대해 공부하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;일반적으로 타임 스텝 $t$에서의 셀의 상태 $h_{(t)}$는 $t$에서의 Input과 이전 타임 스텝의 셀 $h_{(t-1)}$에 대한 함수입니다. 타임 스텝 $t$에서의 출력 $y_{(t)}$도 이전 $h$와 현재 Input에 대한 함수이므로, 기본적인 셀의 경우 출력 $y_{(t)}$와 $h_{(t)}$는 같다고 할 수 있습니다. 하지만 모든 종류의 셀에서 그런 것은 아닙니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;187&quot; width=&quot;507&quot; height=&quot;215&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eDaG5a/btrazvqBN7q/WEf7e2AafcKaT6nEqUGwg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eDaG5a/btrazvqBN7q/WEf7e2AafcKaT6nEqUGwg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eDaG5a/btrazvqBN7q/WEf7e2AafcKaT6nEqUGwg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeDaG5a%2FbtrazvqBN7q%2FWEf7e2AafcKaT6nEqUGwg0%2Fimg.png&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;187&quot; width=&quot;507&quot; height=&quot;215&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2192657103&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Input Sequence and Output Sequence&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;333&quot; width=&quot;551&quot; height=&quot;423&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4n7Ch/btraHr1FkOO/5NQKaBseXSSvcOxnzsgL21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4n7Ch/btraHr1FkOO/5NQKaBseXSSvcOxnzsgL21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4n7Ch/btraHr1FkOO/5NQKaBseXSSvcOxnzsgL21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4n7Ch%2FbtraHr1FkOO%2F5NQKaBseXSSvcOxnzsgL21%2Fimg.png&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;333&quot; width=&quot;551&quot; height=&quot;423&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; RNN에는 다양한 네트워크 구조가 있습니다. 크게 &lt;b&gt;&amp;lt;(입력)-투-(출력) 네트워크&amp;gt;&lt;/b&gt;에서 입출력의 형태가 시퀀스냐, 벡터냐에 따라 구조의 이름이 결정됩니다. 시퀀스와 벡터를 나누는 기준은 간단합니다. 벡터가 여러개가 들어가거나 여러개가 나가면 시퀀스, 하나의 벡터만 들어가거나 나오면 벡터입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;시퀀스-투-시퀀스 네트워크(좌측 상단&lt;/span&gt;&lt;/b&gt;) &lt;b&gt;ex)&lt;/b&gt; 주식가격 같은 시계열 데이터를 예측하는데 유용합니다. 최근 $0~N$ 일치의 주식 가격을 주입하면 네트워크는 하루 앞선 가격 즉 $1~N+1$일치 주식 가격을 출력해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;시퀀스-투-벡터 네트워크(우측 상단)&lt;/span&gt; &lt;/b&gt;: 마지막 출력($Y_{(3)}$)을 제외한 나머지 출력을 모두 무시하는 네트워크 입니다. &lt;b&gt;ex)&lt;/b&gt; 한 문장의 영화 리뷰가 있다고 할때, 문장을 구성하는 단어를 하나의 입력 벡터라고 생각할 수 있습니다.&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이때 이 리뷰의 평점을 계산한다 할때, 각 단어(입력 벡터)가 들어갈 때마다 평점이 계산되어 나오는 것이 아니라, 모든 단어(시퀀스)가 들어간 후에 최종적인 한번의 평점(벡터)이 출력되는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;벡터-투-시퀀스 네트워크&lt;/span&gt;&lt;/b&gt; &lt;b&gt;ex)&lt;/b&gt; 하나의 이미지(입력 벡터)를 넣어주면 이미지에 대한 설명문(문장은 단어로 구성된 시퀀스이다)으로 출력할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;(우측 하단)&lt;/span&gt; &lt;/b&gt;: 마지막은 인코더라 부르는 시퀀스-투-벡터 네트워크 뒤에 디코더라 부르는 벡터-투-시퀀스 네트워크를 연결한 구조입니다. &lt;b&gt;ex)&lt;/b&gt; 한국말을 영어로 번역하는데 사용될 수 있습니다. 즉 한국어 문장으 주입하면 인코더는 이를 하나의 벡터 표현으로 변환하고 디코더가 이 벡터를 영어 문장으로 디코딩합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이러한 인코더-디코더 모델은 시퀀스-투-시퀀스 RNN을 사용하여 한 단어씩 번역하는 것보다 훨씬 더 잘 작동합니다. 왜냐하면 RNN의 경우엔 문장의 마지막 단어가 번역의 첫번째 단어에 영향을 줄 수 있기 때문입니다. 따라서 하나의 단어가 들어올때 마다 번역해서 단어를 뽑아내는 것&lt;b&gt;(RNN의 방식)&lt;/b&gt;이 아닌 전체 문장이 주입될 때까지 기다렸다 번역해야 더 좋은 성능을 낼 수 있습니다.&lt;b&gt;(인코더-디코더 모델)&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RNN 훈련하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;RNN 훈련 방식으로 타임 스텝으로 네트워크를 펼치고, 보통의 역전파(Back Propagation)을 사용하는 것인데 이를 &lt;b&gt;BPTT(Backpropagation through time)&lt;/b&gt;이라고 합니다. 본격적으로 훈련 방식을 차례대로 살펴보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;204&quot; width=&quot;559&quot; height=&quot;261&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn1Bbr/btraEfuboOw/4kqMwqI4VfsG7VVCUSlATk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn1Bbr/btraEfuboOw/4kqMwqI4VfsG7VVCUSlATk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn1Bbr/btraEfuboOw/4kqMwqI4VfsG7VVCUSlATk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn1Bbr%2FbtraEfuboOw%2F4kqMwqI4VfsG7VVCUSlATk%2Fimg.png&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;204&quot; width=&quot;559&quot; height=&quot;261&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 위 그림을 살펴보면서 이해해보겠습니다. 우선 &lt;b&gt;회색 점선 화살표 방향으로 네트워크를 통과하면서&lt;/b&gt; 비용 함수 $C(Y_{(0)}, Y_{(1)} ... Y_{(T)})$(T는 최대 타임 스텝)을 사용하여 출력 시퀀스를 평가됩니다. 이때 비용 함수는 Y_{(0)}, Y_{(1)}과 같은 일부 출력을 무시할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그 다음 비용함수의 Gradient는 &lt;b&gt;짙은 회색선의 방향으로 전파되면서 모델 파라미터는 업데이트 됩니다.&lt;/b&gt; 이때 Gradient는 마지막 출력 $Y_{(4)}$에만 전달되어 노란색 박스 간의 수평방향으로 전달되는 것이 아니라, 비용 함수에 사용된 Y_{(2)}, Y_{(3)}, Y_{(4)}에 모두 각각 전달됩니다. 또한 각 타임 스텝마다 같은 매개변수 $W$와 $b$가 사용되기 때문에 역전파가 진행되면 모든 타임 스텝에 걸쳐 합산될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Time-Series Forecasting&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;어떤 웹사이트에서&lt;b&gt; 1)&lt;/b&gt; 시간당 접속 사용자의 수, &lt;b&gt;2)&lt;/b&gt; 도시의 날짜별 온도, &lt;b&gt;3)&lt;/b&gt; 여러 feature를 사용하여 기업의 분기별 재정 안정성 등을 연구한다고 가정해보겠습니다. 이 경우 들어오는 Input Data는 타임 스텝마다 하나 이상의 값을 가지는 시퀀스이며 이를 &lt;b&gt;Time-Series Data&lt;/b&gt;라고 부릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;[1) 시간당 접속 사용자의 수, 2) 도시의 날짜별 온도]는 타임 스텝마다 하나의 feature를 가지므로 &lt;b&gt;단변량 시계열 (univariate time series)&lt;/b&gt;이고, 3)기업의 분기별 재정 안정성은 회사의 수입, 부채 등의 여러 feature를 이용하므로 &lt;b&gt;다변량 시계열(multiivariate time series)&lt;/b&gt;입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이런 Time-Series Data를 가지고 할 수 있는 몇가지 Task가 있는데 첫번째가&lt;b&gt; 미래 예측(Forecasting)&lt;/b&gt;입니다. 또 하나는 기존 데이터에서 비어 있는 값을 채우는 &lt;b&gt;Imputation&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 앞서 예시로 든 데이터와 별개의 3개의 단변량 시계열입니다. 각 타임 스텝은 50개이며, 목표는 51번째 타임 스텝의 값을 예측 하는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;170&quot; width=&quot;578&quot; height=&quot;223&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xH26O/btrazvqEhCn/58kLxLDXc66QgWaJRFWTb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xH26O/btrazvqEhCn/58kLxLDXc66QgWaJRFWTb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xH26O/btrazvqEhCn/58kLxLDXc66QgWaJRFWTb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxH26O%2FbtrazvqEhCn%2F58kLxLDXc66QgWaJRFWTb0%2Fimg.png&quot; data-origin-width=&quot;441&quot; data-origin-height=&quot;170&quot; width=&quot;578&quot; height=&quot;223&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음 코드에서 간단하게 $sin$ 곡선과 약간의 잡음으로 이뤄진 시계열 데이터를 생성해보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1627454358286&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def generate_time_series(batch_size, n_steps):
    freq1, freq2, offsets1, offsets2 = np.random.rand(4, batch_size, 1)
    time = np.linspace(0, 1, n_steps)
    series = 0.5 * np.sin((time - offsets1) * (freq1 * 10 + 10))  #   wave 1
    series += 0.2 * np.sin((time - offsets2) * (freq2 * 20 + 20)) # + wave 2
    series += 0.1 * (np.random.rand(batch_size, n_steps) - 0.5)   # + noise
    return series[..., np.newaxis].astype(np.float32)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 함수는 &lt;b&gt;n_steps&lt;/b&gt; 길이의 시계열을 &lt;b&gt;batch_size&lt;/b&gt;만큼 만들어냅니다. 각 시계열의 타임 스텝에는 하나의 값이 존재 즉 단변량이며 &lt;b&gt;[배치 크기, 타임 스텝 수, 1]&lt;/b&gt;크기의 &lt;b&gt;넘파이&lt;/b&gt; 배열을 반환합니다. 이러한 리턴 타입은 일반적으로 임의 길이의 time-series 데이터를 다룰 때 사용하며, &lt;b&gt;단변량은 dimensionallity가 1이고, 다변량은 1이상입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 이 함수를 사용해 데이터를 &lt;b&gt;train, validation, test set&lt;/b&gt;으로 나누겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627454527818&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;np.random.seed(42)

n_steps = 50
series = generate_time_series(10000, n_steps + 1)
X_train, y_train = series[:7000, :n_steps], series[:7000, -1]
X_valid, y_valid = series[7000:9000, :n_steps], series[7000:9000, -1]
X_test, y_test = series[9000:, :n_steps], series[9000:, -1]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기준 성능&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;본격적으로 RNN을 구현하기 전, 우리가 구현할 RNN이 잘 작동하는지 판단하기 위해서는 기준이 되는 무언가가 필요합니다. 가장 간단한건 &lt;b&gt;각 시계열의 마지막 값을 그대로 예측하는 것&lt;/b&gt;입니다. 이를 &lt;b&gt;naive forecasting&lt;/b&gt;이라고 부르는데 이 성능을 뛰어넘는 것이 매우 어렵스빈다. 이 경우 &lt;b&gt;MSE&lt;/b&gt;가 0.020이 나오네요&lt;/p&gt;
&lt;pre id=&quot;code_1627476713398&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_pred = X_valid[:, -1]
np.mean(keras.losses.mean_squared_error(y_valid, y_pred))

&amp;gt;&amp;gt; 0.020211367&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;또 다른 방법은 &lt;b&gt;Fully Connected Network&lt;/b&gt;를 사용하는 것입니다. 이 네트워크는 입력마다 &lt;b&gt;1차원 feature 배열&lt;/b&gt;을 기대하므로 &lt;b&gt;Flatten Layer&lt;/b&gt;를 추가해줘야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1627476814849&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[50, 1]),
    keras.layers.Dense(1)
])

model.compile(loss=&quot;mse&quot;, optimizer=&quot;adam&quot;)
history = model.fit(X_train, y_train, epochs=20,
                    validation_data=(X_valid, y_valid))
                    
model.evaluate(X_valid, y_valid)

&amp;gt;&amp;gt;0.004168086685240269&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;0.004의 &lt;b&gt;MSE&lt;/b&gt;의 값을 얻었는데 naive한 forecasting보다 훨씬 낫습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2192657103&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;간단한 RNN 구현하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 간단한 RNN을 사용해 방금 구현한 네트워크들을 앞설 수 있는지 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627477077874&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.SimpleRNN(1, input_shape=[None, 1])
])

optimizer = keras.optimizers.Adam(lr=0.005)
model.compile(loss=&quot;mse&quot;, optimizer=optimizer)
history = model.fit(X_train, y_train, epochs=20,
                    validation_data=(X_valid, y_valid))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 코드가 가장 간단하게 만들 수 있는 RNN으로 하나의 뉴런을 가지는 하나의 layer로 이루어져 있습니다. 코드에서 &lt;b&gt;input_shape&lt;/b&gt;에 &lt;b&gt;None&lt;/b&gt;이 들어있는 이유는 &lt;b&gt;RNN은 어떤 길이의 타임 스텝도 처리할 수 있기 때문에 길이를 지정해 줄 필요가 없습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;기본적으로 SimepleRNN Layers는 tanh를 activation function으로 사용합니다.&lt;/b&gt; 작동방식은 앞서 이론에서 살펴보았던 것과 완전히 동일합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627477230034&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model.evaluate(X_valid, y_valid)
&amp;gt;&amp;gt; 0.010881561785936356&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우리가 구현한 RNN을 통해 얻은 0.014의 &lt;b&gt;MSE&lt;/b&gt;는 naive forecasting보단 낫지만, 간단한 &lt;b&gt;FC Layer 기반 선형 모델을 앞지르지 못합니다.&lt;/b&gt; 이는 &lt;b&gt;선형 모델&lt;/b&gt;에서는 전체 타임스텝이 50개라 했을 때, 50개의 뉴런이 준비되어 각 입력을 받고 하나의 입력마다 하나의 파라미터를 가지고 편향까지 존재합니다. 최종적으로 &lt;b&gt;51개의 파라미터&lt;/b&gt;가 있는 셈이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;반면 &lt;b&gt;기본 RNN의 순환 뉴런&lt;/b&gt;은 Input과 셀 h의 차원마다 하나의 파라미터를 가지고 편향이 있습니다. 그러니 &lt;b&gt;3개의 파라미터&lt;/b&gt;가 있는 셈인데, 선형 모델보다 파라미터 갯수가 월등히 적기 때문에 성능도 그만큼 덜 나오는 것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;트렌드와 계절성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;가중 이동 평균(weighted moving average)&lt;/b&gt;이나 &lt;b&gt;자동 회귀 누적 이동 평균(ARIMA)&lt;/b&gt;같이 Time-Series Data를 forecasting하는 방법은 많습니다. 그런데 올바른 forecasting을 위해서 일부는 &lt;b&gt;트렌드(Trend)&lt;/b&gt;나 &lt;b&gt;계절성(Seasonality)&lt;/b&gt;를 제거해야 합니다. &lt;b&gt;트렌드&lt;/b&gt;라 하면 전체적인 데이터가 상승하거나 내려가거나 하는 추세를 의미합니다. 예를 들어 매달 10% 성장하는 추세의 웹사이트의 접속 사용자 수를 조사한다면, 시계열에서 트렌드를 삭제하고 예측한 후 최종 결과에 다시 이 트렌드를 더해야합니다.&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;하지만 RNN을 사용하면 이런 작업이 필요 없습니다. 그만큼 RNN은 좋은 성능을 내기에 단순합니다. 더 많은 Layer를 추가하면 됩니다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;심층 RNN&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RNN은 셀을 여러 층으로 쌓는 것이 일반적입니다. 이렇게 만든 것을 &lt;b&gt;심층 RNN (Deep RNN)&lt;/b&gt;이라 부릅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;225&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4QYdS/btraMphDnYp/MzDvfYRe4A3sGmyaLianlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4QYdS/btraMphDnYp/MzDvfYRe4A3sGmyaLianlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4QYdS/btraMphDnYp/MzDvfYRe4A3sGmyaLianlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4QYdS%2FbtraMphDnYp%2FMzDvfYRe4A3sGmyaLianlK%2Fimg.png&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;225&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;구현은 그저 SimpleRNN을 쌓아주면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627478318387&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
    keras.layers.SimpleRNN(20, return_sequences=True),
    keras.layers.SimpleRNN(1)
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 모델의 &lt;b&gt;MSE&lt;/b&gt;는 0.003으로 드디어 선형 모델을 이기게 되었습니다! 그러나 마지막 층을 좀 더 손볼 필요가 있어 보입니다. 단변량 시계열을 예측한다는 건 하나의 유닛이 필요하고 이는 타임 스텝마다 하나의 출력을 만들어야 한다는 뜻입니다. 하나의 유닛을 가진다는 건 h가 스칼라 값이라는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그런데 마지막 Layer의 h는 그리 필요하지 않습니다. 게다가 SimpleRNN Layer는 tanh 함수를 사용하여 forecasting 값이 -1과 1 사이의 범위에 놓입니다. 따라서 보통은 이런 이유로 &lt;b&gt;출력층을 Dense 층으로 바꾸는데&lt;/b&gt;, 이를 통해 빠르면서 정확도는 거의 비슷합니다. 다만 이렇게 바꾸려면 두 번째 순환 층에 &lt;b&gt;return_sequences=True&lt;/b&gt;를 제거해줘야합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627478937238&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
    keras.layers.SimpleRNN(20),
    keras.layers.Dense(10)
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2192657103&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;여러 타임 스텝 앞을 예측하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;지금까지는 다음 타임 스텝의 값만 예측했지만, 1스텝 앞이 아니라, 10스텝 앞의 값으로 타깃을 바꾸어 10 스텝 앞을 예측하는 것도 그리 어려운 일이 아닙니다. 하지만 1개의 값이 아니라 &lt;b&gt;한번에 10개를 예측하고 싶다면 어떻게 해야할까요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;첫 번째 방법은 &lt;b&gt;pre-trained model&lt;/b&gt;을 사용하여 다음 스텝의 값을 예측한 후 이 값을 다시 입력으로 추가해나가며 10개를 예측하는 것입니다. 코드는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627480047158&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;series = generate_time_series(1, n_steps + 10)
X_new, Y_new = series[:, :n_steps], series[:, n_steps:]
X = X_new
for step_ahead in range(10):
    y_pred_one = model.predict(X[:, step_ahead:])[:, np.newaxis, :]
    X = np.concatenate([X, y_pred_one], axis=1)

Y_pred = X[:, n_steps:]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;당연하지만 다음 스텝에 대한 예측이 훨씬 더 미래의 예측보다 정확합니다. 훨씬 더 미래의 예측은 오차가 누적될 수 있기 때문입니다. 어쨌든 위 방식을 적용하면 약 0.029의 &lt;b&gt;MSE&lt;/b&gt;를 얻습니다. 성능은 비슷할지라도 task가 훨씬 어렵기 때문에 단순 비교는 어렵습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;234&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dl7Gcv/btraMq1VL7J/8UKYsszmKJ42hK5dtknWO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dl7Gcv/btraMq1VL7J/8UKYsszmKJ42hK5dtknWO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dl7Gcv/btraMq1VL7J/8UKYsszmKJ42hK5dtknWO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdl7Gcv%2FbtraMq1VL7J%2F8UKYsszmKJ42hK5dtknWO0%2Fimg.png&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;234&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;두 번째 방법은 &lt;b&gt;RNN을 훈련하여 다음 값 10개를 한번에 예측하는 것입니다.&lt;/b&gt; &lt;b&gt;시퀀스-투-벡터 모델&lt;/b&gt;을 사용하지만, 1개가 아닌&amp;nbsp; 값 10개를 출력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627480264141&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;series = generate_time_series(10000, n_steps + 10)
X_train, Y_train = series[:7000, :n_steps], series[:7000, -10:, 0]
X_valid, Y_valid = series[7000:9000, :n_steps], series[7000:9000, -10:, 0]
X_test, Y_test = series[9000:, :n_steps], series[9000:, -10:, 0]

model = keras.models.Sequential([
    keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
    keras.layers.SimpleRNN(20),
    keras.layers.Dense(10)
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 모델의 다음 10개 스텝에 대한 &lt;b&gt;MSE&lt;/b&gt;는 약 0.008로 선형 모델보다 훨씬 좋습니다. 다만 개선할 여지가 있는데, 마지막 타임스텝에서만 10개를 예측하도록 훈련하는게 아니라, &lt;b&gt;모든 타임 스텝에서 다음 10개를 예측하도록 모델을 훈련할 수 있습니다.&lt;/b&gt; 즉 시퀀스-투-벡터에서 &lt;b&gt;시퀀스-투-시퀀스&lt;/b&gt;로 바꿀 수 있는 것입니다.(타임 스텝 0에서는 타임 스텝 1~10까지 예측을 담은 벡터를, 타임 스텝 1에서는 2~11까지의 예측을 담는 벡터를 출력합니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이것의 장점은 모든 타임 스텝에서 forecasting을 진행하며 이것들에 대한 출력이 loss에 포함되면서 더 많은 오차 그레디언트가 모델로 흐르게 되고 결과적으로 안정적인 훈련과 함께 훈련 속도를 높이게 됩니다. 다음은 구현 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1627480645371&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
    keras.layers.SimpleRNN(20, return_sequences=True),
    keras.layers.TimeDistributed(keras.layers.Dense(10))
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;시퀀스-투-시퀀스 모델로 바꾸려면 우선 모든 &lt;b&gt;SimpleRNN&lt;/b&gt; 층의 &lt;b&gt;return_sequences=True&lt;/b&gt;로 지정합니다. 그 다음 &lt;b&gt;모든 타임 스텝 층에 Dense 층을 적용해야하는데&lt;/b&gt; 이를 위해 바로 &lt;b&gt;TimeDistributed Layer&lt;/b&gt;를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; TimeDistributed Layer&lt;/b&gt;는 각 타임 스텝을 별개의 샘플처럼 다루도록 입력의 크기를 바꿉니다. &lt;b&gt;([배치 크기, 타임 스텝 수, 입력 차원] -&amp;gt; [배치 크기 x 타임 스텝 수, 입력 차원])&lt;/b&gt; 그 다음 &lt;b&gt;Dense Layer&lt;/b&gt;에 적용하고 마지막으로 출력 크기를 시퀀스로 되돌립니다. &lt;b&gt;([배치 크기 x 타임 스텝 수, 입력 차원] -&amp;gt; [배치 크기, 타임 스텝 수, 입력 차원])&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1627480925696&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def last_time_step_mse(Y_true, Y_pred):
    return keras.metrics.mean_squared_error(Y_true[:, -1], Y_pred[:, -1])

model.compile(loss=&quot;mse&quot;, optimizer=keras.optimizers.Adam(lr=0.01), metrics=[last_time_step_mse])
history = model.fit(X_train, Y_train, epochs=20,
                    validation_data=(X_valid, Y_valid))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;검증 &lt;b&gt;MSE&lt;/b&gt;로 0.006을 얻었는데, 이는 이전 모델보다 25%나 향상된 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 시간에는 좀 더 긴 시퀀스의 예측 시 사용하는 LSTM과 경량화된 모델인 GRU에 대해 공부해보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>CNN</category>
      <category>forecast</category>
      <category>GRU</category>
      <category>LSTM</category>
      <category>nlp</category>
      <category>rnn</category>
      <category>Time Series</category>
      <category>시계열</category>
      <category>자연어처리</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/72</guid>
      <comments>https://box-world.tistory.com/72#entry72comment</comments>
      <pubDate>Wed, 28 Jul 2021 23:13:41 +0900</pubDate>
    </item>
    <item>
      <title>[ 머신러닝 순한맛 ] Regularization in 딥러닝의 모든 것</title>
      <link>https://box-world.tistory.com/71</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&quot;나는 네 개의 파라미터가 있으면 코끼리 모양을 학습시킬 수 있고, &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px; background-color: #99cefa;&quot;&gt;다섯 개가 있으면 코를 꿈틀거리게 할 수 있다.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;- 존 폰 노이만 -&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Neural Network는 수만 개에서 수백만 개까지 파라미터를 가집니다. 그만큼 크고 복잡한 데이터셋을 학습할 수 있을만큼 네트워크의 자유도가 높다는 것을 의미합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그러나 이러한 자유도가 높을 수록 네트워크는 Training set에 과대적합(Overfitting)되기 쉬워집니다. 이번 포스팅에서는 Neural Network에서 Overfitting을 막기 위해 사용하는 다양한 규제(Regularization) 방법들에 대해 알아보겠습니다.&lt;/p&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;a href=&quot;https://box-world.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Coursera ( Machine Learning )] - [ 핸즈온 머신러닝 2판 ] Linear Regression 속 Regularization이란?&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1625414781637&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈온 머신러닝 2판 ] Linear Regression 속  Regularization이란?&quot; data-og-description=&quot;&amp;quot;이끌거나, 따르거나, 비켜서라.&amp;quot; -&amp;nbsp;Ted Turner (CNN 설립자) - 4.5 선형 모델(Linear Model)에서의 규제(Regularization) &amp;nbsp;Regularization은 모델이 Overfit되었을 때, 이를 감소시키는 대표적인 방법입니다...&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/53&quot; data-og-url=&quot;https://box-world.tistory.com/53&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bKTo2D/hyKMIsvN8l/3hhV4KNuRd5mGigAkj0OHk/img.jpg?width=198&amp;amp;height=255&amp;amp;face=0_0_198_255,https://scrap.kakaocdn.net/dn/bjgOlQ/hyKML3Q3Zb/JOW3K0VCQEymvxDhiBbbG1/img.jpg?width=198&amp;amp;height=255&amp;amp;face=0_0_198_255,https://scrap.kakaocdn.net/dn/biucgR/hyKMMuU4Bm/v1Xa8XZKVFrwW1GEJT9G71/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/53&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bKTo2D/hyKMIsvN8l/3hhV4KNuRd5mGigAkj0OHk/img.jpg?width=198&amp;amp;height=255&amp;amp;face=0_0_198_255,https://scrap.kakaocdn.net/dn/bjgOlQ/hyKML3Q3Zb/JOW3K0VCQEymvxDhiBbbG1/img.jpg?width=198&amp;amp;height=255&amp;amp;face=0_0_198_255,https://scrap.kakaocdn.net/dn/biucgR/hyKMMuU4Bm/v1Xa8XZKVFrwW1GEJT9G71/img.jpg?width=625&amp;amp;height=625&amp;amp;face=0_0_625_625');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ 핸즈온 머신러닝 2판 ] Linear Regression 속 Regularization이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&quot;이끌거나, 따르거나, 비켜서라.&quot; -&amp;nbsp;Ted Turner (CNN 설립자) - 4.5 선형 모델(Linear Model)에서의 규제(Regularization) &amp;nbsp;Regularization은 모델이 Overfit되었을 때, 이를 감소시키는 대표적인 방법입니다...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2192657103&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;L1, L2 규제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우리가 이전에 Linear Regression을 공부한다면, 자연스럽게 Overfitting을 막기 위해 별도의 규제 항을 추가하였던 것을 기억할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Neural Network에서도 가중치를 제한하기 위해 &lt;b&gt;L2 규제&lt;/b&gt;를 사용하거나, Sparse한(많은 가중치가 0인) 모델을 만들기 위해 &lt;b&gt;L1 규제&lt;/b&gt;를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 규제 강도를 0.01을 사용하여 L2 규제를 적용하는 방법을 보여줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625415204907&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;layer = keras.layers.Dense(100, activation=&quot;elu&quot;,
                           kernel_initializer=&quot;he_normal&quot;,
                           kernel_regularizer=keras.regularizers.l2(0.01))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;L2() 함수는 각 스텝마다 규제 Loss가 들어있는 객체를 반환하고, 이것은 최종 Loss에 반영됩니다. L1 규제를 사용하고 싶다면 &lt;b&gt;keras.regularizaers.l1()&lt;/b&gt;을 사용하면 되고, L1, L2 두가지가 모두 필요하면 k&lt;b&gt;eras.regularizers.l1_l2()&lt;/b&gt;를 사용하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;일반적으로 네트워크를 구성하는 Hidden Layer들에는 동일한 activation 함수, Initialization 전략을 사용하거나, 동일한 규제를 적용하여 동일한 파라미터 값을 반복하는 경우가 많습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625415570936&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.Dense(300, activation=&quot;elu&quot;,
                       kernel_initializer=&quot;he_normal&quot;,
                       kernel_regularizer=keras.regularizers.l2(0.01)),
    keras.layers.Dense(100, activation=&quot;elu&quot;,
                       kernel_initializer=&quot;he_normal&quot;,
                       kernel_regularizer=keras.regularizers.l2(0.01)),
    keras.layers.Dense(10, activation=&quot;softmax&quot;,
                       kernel_regularizer=keras.regularizers.l2(0.01))
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 코드는 보다시피 &lt;b&gt;매 Layer마다 반복되는 파라미터가 존재합니다.&lt;/b&gt; 이 경우 매번 입력하는 대신 파이썬의 &lt;b&gt;functools.partial()&lt;/b&gt; 함수를 사용하여 동일하게 사용하는 기본적인 매개변수 값을 사용하게 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625415626049&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RegularizedDense = partial(keras.layers.Dense,
                           activation=&quot;elu&quot;,
                           kernel_initializer=&quot;he_normal&quot;,
                           kernel_regularizer=keras.regularizers.l2(0.01))

model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    RegularizedDense(300),
    RegularizedDense(100),
    RegularizedDense(10, activation=&quot;softmax&quot;)
])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Dropout&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;266&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKpQgY/btq8Ost00HG/PbFLgt2FDYvkdkXKU2HhL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKpQgY/btq8Ost00HG/PbFLgt2FDYvkdkXKU2HhL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKpQgY/btq8Ost00HG/PbFLgt2FDYvkdkXKU2HhL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKpQgY%2Fbtq8Ost00HG%2FPbFLgt2FDYvkdkXKU2HhL0%2Fimg.png&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;266&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;드롭아웃은 Neural Network에서 가장 인기 있는 규제 기법중 하나입니다. 최고 성능을 내는 네트워크도 드롭아웃 적용 후 정확도를 1~2% 높였습니다. &lt;b&gt;이러한 1~2%의 상승은 오차율이 거의 40% 줄어드는 것을 의미합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;드롭아웃의 알고리즘은 간단합니다. 매 Training 스텝에서 네트워크를 구성하는 각 뉴런은 임시적으로 드롭아웃될 확률 $p$를 가집니다.(입력 뉴런은 포함되고, 출력 뉴런은 제외됩니다.) 다시 말해서 &lt;b&gt;드롭아웃된 뉴런은 완전히 없는 셈치고 학습을 진행하는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다만 무시됐던 뉴런은 다음 훈련 스텝에서는 드롭아웃 확률에 따라 다시 활성화될 수 있습니다. 드롭아웃 확률 $p$는 하이퍼파라미터로 보통 10~30% 사이를 지정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;훈련이 끝난 후, &lt;b&gt;Test set에서는 드롭아웃을 적용하지 않습니다.&lt;/b&gt; 그렇다면 이러한 드롭아웃이 성능을 높이는 이유는 무엇일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;매 훈련 스텝마다 일정 드롭아웃 확률 $p$에 따라 각 뉴런들은 비활성화되거나 활성화됩니다. &lt;b&gt;다시 말해 매 훈련 스텝마다 네트워크의 모양은 다릅니다. 그러니까 우린 매 훈련 스텝마다 서로 다른 Neural Network를 사용한 셈이 되는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그래서 예를들어 10000번의 훈련 스텝을 진행했다면 10000개의 서로 다른 Neural Network를 &lt;b&gt;앙상블해서 훈련시킨 효과를 가지게 되는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다만 한가지 사소하지만 유의해야할 사항이 있습니다. $p=50%$로 하면 Test시 하나의 뉴런은 훈련 때보다 평균적으로 두배 더 많은 입력 뉴런과 연결됩니다. 이런 점을 보상하기 위해 &lt;b&gt;훈련 후 각 뉴런의 연결 가중치에 0.5를 곱하여 늘어난 입력 뉴런을 상쇄시켜야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다시 말해 훈련이 끝나면 각 입력의 연결 가중치에 보존 확률$(1-p)$을 곱해줘야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;케라스의 keras.layers.Dropout은 훈련 동안 일부 Input을 랜덤하게 버립니다. 그리고 남은 입력을 보존 확률로 나눕니다. 우리가 착각하면 안될 것이 dropout이라든지, 보존 확률로 입력을 나눈다든지 이런 프로세싱은 훈련 단계에서 일어나는 일이지 Test 단계에서는 그냥 입력을 다음 층으로 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 드롭아웃 비율 0.2를 사용하여 구성한 model입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625421294017&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.Dropout(rate=0.2),
    keras.layers.Dense(300, activation=&quot;elu&quot;, kernel_initializer=&quot;he_normal&quot;),
    keras.layers.Dropout(rate=0.2),
    keras.layers.Dense(100, activation=&quot;elu&quot;, kernel_initializer=&quot;he_normal&quot;),
    keras.layers.Dropout(rate=0.2),
    keras.layers.Dense(10, activation=&quot;softmax&quot;)
])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Max-Norm 규제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;마지막으로 우리가 살펴볼 규제는 &lt;b&gt;Max-Norm 규제&lt;/b&gt;입니다. 이 방식은 각 뉴런에 대해 입력의 연결 가중치 $w$가 다음과 같도록 제한합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;40&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deYNJH/btq8L6ZXXl5/xyAMQ5OWkTZhd3f51Ydft1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deYNJH/btq8L6ZXXl5/xyAMQ5OWkTZhd3f51Ydft1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deYNJH/btq8L6ZXXl5/xyAMQ5OWkTZhd3f51Ydft1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdeYNJH%2Fbtq8L6ZXXl5%2FxyAMQ5OWkTZhd3f51Ydft1%2Fimg.png&quot; data-origin-width=&quot;119&quot; data-origin-height=&quot;40&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;Max-Norm 규제는 &lt;b&gt;전체 Loss 함수에 규제 항을 추가하지 않습니다. 대신 매 훈련 스텝이 끝날때마다 $w$의 norm을 계산하여 다음고 같이 스케일을 조정합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;96&quot; data-origin-height=&quot;58&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bigq7w/btq8HFO9fP6/3PsrKM2k8eW3EDK6gkMne1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bigq7w/btq8HFO9fP6/3PsrKM2k8eW3EDK6gkMne1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bigq7w/btq8HFO9fP6/3PsrKM2k8eW3EDK6gkMne1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbigq7w%2Fbtq8HFO9fP6%2F3PsrKM2k8eW3EDK6gkMne1%2Fimg.png&quot; data-origin-width=&quot;96&quot; data-origin-height=&quot;58&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;$r$은 하이퍼 파라미터이며,&amp;nbsp; r을 줄이면 줄일 수록 w에 더 작은 값이 곱해지니 가중치가 작아질 것이고 그렇게 되면 &lt;b&gt;Overfitting을 감소시키는데 도움이 될 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 keras에서 구현한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625421707216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;layer = keras.layers.Dense(100, activation=&quot;selu&quot;, kernel_initializer=&quot;lecun_normal&quot;,
                           kernel_constraint=keras.constraints.max_norm(1.))&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서는 텐서플로우에 대해 다뤄보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내세요 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>dropout</category>
      <category>hands on</category>
      <category>l1 norm</category>
      <category>l2 norm</category>
      <category>max norm</category>
      <category>overfit</category>
      <category>Regularization</category>
      <category>드롭아웃</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/71</guid>
      <comments>https://box-world.tistory.com/71#entry71comment</comments>
      <pubDate>Mon, 5 Jul 2021 03:04:33 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 학습률 스케줄링의 모든 것</title>
      <link>https://box-world.tistory.com/70</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&quot;경쟁자의 성공을 탐하지 마라&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;- 제럴딘 레이본느 (옥시전 미디어 회장 겸 ceo) -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;저번 포스팅에서 우리는 가중치 파라미터의 최적화를 속도, 그리고 리소스 효율성의 측면에서 바라보았습니다. 이번 포스팅에서는 최적화의 속도에 관여하는 또 하나의 하이퍼파라미터인 &lt;b&gt;학습률(Learning Rate) 스케줄링&lt;/b&gt;을 통해 파라미터 최적화의 성능을 방법에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;학습률 스케줄링&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;가중치를 최적화하는데 있어서 '좋은 학습률'을 찾는 것은 중요한데 이유는 다음과 같습니다. 우리가 가장 Loss가 적은 Local minimum까지 걸어간다고 할때, &lt;b&gt;학습률은 걸음의 보폭&lt;/b&gt;이라고 할 수 있습니다. &lt;b&gt;학습률이 너무 크면&lt;/b&gt; Local minimum을 지나치거나 수렴하기 어렵습니다. &lt;b&gt;반대로 너무 작아도&lt;/b&gt; Local minimum까지 도달할 순 있어도 그 시간이 매우 오래 걸릴 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;246&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qIcIC/btq8Gqq0yy4/sCwv17HThb7UhX8mAK7tvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qIcIC/btq8Gqq0yy4/sCwv17HThb7UhX8mAK7tvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qIcIC/btq8Gqq0yy4/sCwv17HThb7UhX8mAK7tvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqIcIC%2Fbtq8Gqq0yy4%2FsCwv17HThb7UhX8mAK7tvK%2Fimg.png&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;246&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1) 거듭제곱 기반 스케줄링(Power Scheduling)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT3y0K/btq8JjxxVM8/0wcuQVwz0P5wDLyGNeHjVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT3y0K/btq8JjxxVM8/0wcuQVwz0P5wDLyGNeHjVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT3y0K/btq8JjxxVM8/0wcuQVwz0P5wDLyGNeHjVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT3y0K%2Fbtq8JjxxVM8%2F0wcuQVwz0P5wDLyGNeHjVk%2Fimg.png&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;214&quot; data-origin-height=&quot;43&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ORSAE/btq8IC48Xny/mbn8wHgsQPptDLbhbs48V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ORSAE/btq8IC48Xny/mbn8wHgsQPptDLbhbs48V1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ORSAE/btq8IC48Xny/mbn8wHgsQPptDLbhbs48V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FORSAE%2Fbtq8IC48Xny%2Fmbn8wHgsQPptDLbhbs48V1%2Fimg.png&quot; data-origin-width=&quot;214&quot; data-origin-height=&quot;43&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- $t$ : Training epoch(반복 횟수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- $n_0$ : 초기 학습률&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- $c$ : 상수&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- $s$ : 스텝 횟수 (우리가 지정해야하는 하이퍼 파라미터로써 스텝은 우리가 지정한 데이터의 크기만큼을 한번 훑으면 1번의 스텝으로 여기므로 전체 데이터셋을 한번 훑었을때 1번으로 여기는 &lt;b&gt;epoch와는 다른 개념입니다.&lt;/b&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 수식을 쉽게 해석해보면 $s$, $c$, $n_0$은 고정된 값이고, $t$는 &lt;b&gt;학습이 진행될 수록 늘어나는 값이다.&lt;/b&gt; 그런데 이 늘어나는 $t$가 늘어날수록 분모가 늘어나면서 $n(t)$는 감소하게 됩니다. 즉 &lt;b&gt;학습이 진행될수록 학습률은 감소하게됩니다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;처음엔 Local Minimum이 멀리있을테니 긴 보폭으로 다가가다가 거의 다왔을때는 보폭을 줄여 Local minimum에게 세심하게 가까이 가려는 건 당연한 순리겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다만 초기 학습률 $n_0$과 &amp;nbsp;$s$는 &lt;b&gt;우리가 지정해줘야하는 하이퍼 파라미터&lt;/b&gt;에 속합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2) 지수 기반 스케줄링 (Exponential Scheduling)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPZsuh/btq8KRtL3uF/MaTljHuZFPXmnWwqXPZR70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPZsuh/btq8KRtL3uF/MaTljHuZFPXmnWwqXPZR70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPZsuh/btq8KRtL3uF/MaTljHuZFPXmnWwqXPZR70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPZsuh%2Fbtq8KRtL3uF%2FMaTljHuZFPXmnWwqXPZR70%2Fimg.png&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;44&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WCgvi/btq8L8B1KjK/4K0ADrZXAvoSHvtPk3iA1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WCgvi/btq8L8B1KjK/4K0ADrZXAvoSHvtPk3iA1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WCgvi/btq8L8B1KjK/4K0ADrZXAvoSHvtPk3iA1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWCgvi%2Fbtq8L8B1KjK%2F4K0ADrZXAvoSHvtPk3iA1K%2Fimg.png&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;44&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;$t$ :&amp;nbsp;Training epoch(반복 횟수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;$s$ :&amp;nbsp;스텝 횟수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;$t=s$일땐 $(0.1)^1$, $t=2s$일땐 $(0.1)^2$ 이런 식으로 t가 늘어날 때마다 학습률이 감소되는 스케줄링 방식입니다. 다만 1)과 달리 s번의 스텝마다 &lt;b&gt;고정적으로 10배씩 감소한다는 점에서 차이를 두고 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3) 구간별 고정 스케줄링 (Piecewise Constant Scheduling)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvFHdd/btq8IfPXAP6/yRH6QBvGkWR9L8IxXUHHKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvFHdd/btq8IfPXAP6/yRH6QBvGkWR9L8IxXUHHKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvFHdd/btq8IfPXAP6/yRH6QBvGkWR9L8IxXUHHKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvFHdd%2Fbtq8IfPXAP6%2FyRH6QBvGkWR9L8IxXUHHKK%2Fimg.png&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;일정 횟수의 에포크 동안 일정한 학습률을 사용하고, 그 다음 또 다른 횟수의 에포크 동안은 더 작은 학습률을 사용하는 식입니다.&lt;/b&gt; 예를 들어 초기 5 에포크 동안에 $n_0= 0.1$, 그 다음 50에포크 동안에 $n_0=0.001$ 이런식으로 우리가 직접 지정하여 스케줄링하는 방식입니다. 다만 성능을 높이기 위한 최적의 조합은 우리가 직접 찾아야합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4) 성능 기반 스케줄링 (Perfomance Scheduling)&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgEL8X/btq8HTsTug7/5iiuKrksPKdlY244iGhJk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgEL8X/btq8HTsTug7/5iiuKrksPKdlY244iGhJk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgEL8X/btq8HTsTug7/5iiuKrksPKdlY244iGhJk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgEL8X%2Fbtq8HTsTug7%2F5iiuKrksPKdlY244iGhJk0%2Fimg.png&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;매 $N$번의 스텝마다 Validation Loss를 측정하고, &lt;b&gt;이것이 줄어들지 않으면&lt;/b&gt; $i$배만큼 학습률을 감소시킵니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5) 1 사이클 스케줄링 (1cycle Scheduling)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 방식은 다른 방식과 조금 다른 방식을 지닙니다. 1 사이클은 &lt;b&gt;훈련 절반 동안&lt;/b&gt; 초기에 지정한 학습률 $n_0$을 선형적으로 $n_1$까지 증가시킵니다. 그 다음 &lt;b&gt;나머지 절반 동안&lt;/b&gt;은 증가되었던 $n_1$을 $n_0$으로 선형적으로 되돌립니다. 그리고 마지막 몇 번의 에포크 동안의 학습률은 &lt;b&gt;소수점 몇 째자리까지 선형적으로 줄입니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;최대 학습률 $n_1$은 우리가 직접 지정해야하며, 초기 학습률 $n_0$은 보통 10배 정도 낮은 값을 선택합니다. &lt;b&gt;모멘텀 사용시&lt;/b&gt;(모멘텀은 마찰을 의미합니다. 모멘텀이 높을 수록 마찰이 심해질수록, 높은 학습률을 가지더라도 앞으로 멀리가기 힘들어진다고 이해하면 됩니다.), 처음에는 높은 모멘텀으로 시작하여 학습률을 제어시켰다가 최대 학습률에 되는 절반 지점까지 점점 모멘텀을 줄입니다. 그리고 나머지 절반동안 학습률이 다시 초기 학습률 $n_0$로 돌아가는 동안 점진적으로 모멘텀을 높입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 방식은 여러 연구를 통해 충분히 검증된 훌륭한 방식입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2013년도 논문에 따르면 모멘텀 최적화를 사용한 음성 인식용 Neural Network를 훈련할 때 가장 널리 알려진 학습률 스케줄링의 성능을 비교했습니다. 저자들은 &lt;b&gt;성능 기반 스케줄링&lt;/b&gt;과 &lt;b&gt;지수 기반 스케줄링&lt;/b&gt;이 둘다 잘 작동했지만, 튜닝이 쉽고 Local minimum에 조금 더 빨리 수렴하는 지수 기반 스케줄링이 선호된다고 결론을 내었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 &lt;b&gt;거듭제곱 기반 스케줄링&lt;/b&gt;을 keras에서 구현한 것입니다. 여기서 decay는 우리가 앞서 보았던 스텝 수 $s$의 역수입니다. (keras는 이를 1로 가정합니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1625317836783&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;optimizer = keras.optimizers.SGD(lr=0.01, decay=le-4)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 &lt;b&gt;지수 기반 스케줄링&lt;/b&gt;입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625317923301&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def exponential_decay_fn(epoch):
	return 0.01 * 0.1**(epoch / 20)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;하지만 위와 같이 하면 $n_0$와 $s$가 바뀔때마다 새로 함수를 정의해야하므로, 이 둘을 매개변수로 추가하여 &lt;b&gt;LearningRateScheduler&lt;/b&gt; 콜백을 만들어보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625318090097&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def exponential_decay(lr0, s):
	def exponential_decay_fn(epoch):
    	return lr0 * 0.1 ** (epoch / s)
    return exponential_decay_fn
exponential_decay_fn = exponential_decay(lr0=0.01, s=20)

lr_scheduler = keras.callbacks.LearningRateScheduler(exponential_decay_fn)
history = model.fit(X_train_scaled, y_train, [...], callbacks=[lr_scheduler])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;구간별 고정 스케줄링 방식&lt;/b&gt;도 별도의 함수를 &lt;b&gt;LearningRateScheduler&lt;/b&gt; 콜백을 만들어 &lt;b&gt;fit()&lt;/b&gt; 메서드에 전달합니다. 다음은 다섯 번의 에포크 동안 향상되지 않을때마다 &lt;b&gt;학습률에 0.5를 곱합니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1625318851969&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def piecewise_constant_fn(epoch):
    if epoch &amp;lt; 5:
        return 0.01
    elif epoch &amp;lt; 15:
        return 0.005
    else:
        return 0.001
        
lr_scheduler = keras.callbacks.LearningRateScheduler(piecewise_constant_fn)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;마지막으로 tf.keras에서는 &lt;b&gt;keras.optimizers.schedules&lt;/b&gt;에 있는 스케줄 중에 하나를 사용해 학습률을 정의하고 이것을 옵티마이저에 전달하는데 이렇게 하면 에포크가 아니라 매 스텝마다 학습률을 업데이트합니다. 다음은 이를 이용해 지수 기반 스케줄링을 구현하는 방법입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1625319131274&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s = 20 * len(X_train) // 32 # number of steps in 20 epochs (batch size = 32)
learning_rate = keras.optimizers.schedules.ExponentialDecay(0.01, s, 0.1)
optimizer = keras.optimizers.SGD(learning_rate)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서는 Regularization을 이용해 Overfitting을 피하는 방법에 대해 알아보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내세요 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>norm</category>
      <category>PYTHON</category>
      <category>pytorch</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>스케줄링</category>
      <category>학습률</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/70</guid>
      <comments>https://box-world.tistory.com/70#entry70comment</comments>
      <pubDate>Sat, 3 Jul 2021 22:37:04 +0900</pubDate>
    </item>
    <item>
      <title>[ 머신러닝 순한 맛 ] Adam, RMSProp, AdaGrad, 모멘텀 최적화, NAG의 모든 것</title>
      <link>https://box-world.tistory.com/69</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;시련은 있어도, 실패란 없다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;- 정주영 ( 현대 그룹 창업자 )&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 지금까지 우리는 모델을 훈련할 때, 표준적인 경사하강법(Gradient Descent Algorithm)만 써왔습니다. 하지만 이러한 훈련과정의 속도를 높이는 방법에 대해 초기화 / activation function / Batch-Normalization / 전이 학습 4가지를 공부했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이번 포스팅에서 공부할 것은 훈련 속도를 높이기 위해 경사 하강법 대신에 쓸 수 잇는 고속 옵티마이저에 대해서 공부해보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음 포스팅을 먼저 정독하시고 이번 포스팅을 보시면 더욱 쉽게 이해하실 수 있습니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/67&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Hands-On Machine Learning 2판] - [머신러닝 순한맛] 그레디언트 소실(Vanishing) / 폭주(Exploding)이란?&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1621609430220&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] 그레디언트 소실(Vanishing) / 폭주(Exploding)이란?&quot; data-og-description=&quot;잘못된 전략이라도 제대로 실행만 하면 반드시 성공할 수 있다. 반대로 뛰어난 전략이라도 제대로 실행하지 못하면 반드시 실패한다. - 선 마이크로시스템즈 CEO, 스콧 맥닐리 - &amp;nbsp;Deep Neural Network, &quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/67&quot; data-og-url=&quot;https://box-world.tistory.com/67&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QRGyW/hyKhqf5K8k/DkKH4pcHINOukaKGHFOKK1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/Ab7Z1/hyKhCHAguL/ltuwsnzg7dBbqIkAdipeAK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/HKrws/hyKieE4MyY/vnolM7swac0V5ya6sxdVf1/img.png?width=708&amp;amp;height=401&amp;amp;face=0_0_708_401&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/67&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/67&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QRGyW/hyKhqf5K8k/DkKH4pcHINOukaKGHFOKK1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/Ab7Z1/hyKhCHAguL/ltuwsnzg7dBbqIkAdipeAK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/HKrws/hyKieE4MyY/vnolM7swac0V5ya6sxdVf1/img.png?width=708&amp;amp;height=401&amp;amp;face=0_0_708_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[머신러닝 순한맛] 그레디언트 소실(Vanishing) / 폭주(Exploding)이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;잘못된 전략이라도 제대로 실행만 하면 반드시 성공할 수 있다. 반대로 뛰어난 전략이라도 제대로 실행하지 못하면 반드시 실패한다. - 선 마이크로시스템즈 CEO, 스콧 맥닐리 - &amp;nbsp;Deep Neural Network,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;모멘텀 최적화(Momentum Optimization)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우리가 기존에 배웠던 경사 하강법은 경사면을 따라 일정한 크기의 스텝으로 조금씩 내려갑니다. 반대로 모멘텀 최적화는 경사를 굴러가는 &lt;b&gt;볼링공&lt;/b&gt;과 같습니다. 즉 처음에는 느리게 출발하지만, 시간이 지날수록 빠르게 가속되어 결과적으로 더 빠릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;경사 하강법은 다음과 같이 loss 그레디언트 * 학습률을 기존 가중치에 뺌으로써 갱신이 이뤄집니다. 이러한 방식이 이전 그레디언트가 얼마였는지 고려하지 않습니다. 그렇기 때문에 &lt;b&gt;부분적으로 그레디언트가 작으면 매우 느려집니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;98&quot; data-origin-height=&quot;23&quot; width=&quot;213&quot; height=&quot;50&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzikBT/btq5rP2dILa/4P0kbUUqKeEzj1jczVdfKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzikBT/btq5rP2dILa/4P0kbUUqKeEzj1jczVdfKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzikBT/btq5rP2dILa/4P0kbUUqKeEzj1jczVdfKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzikBT%2Fbtq5rP2dILa%2F4P0kbUUqKeEzj1jczVdfKk%2Fimg.png&quot; data-origin-width=&quot;98&quot; data-origin-height=&quot;23&quot; width=&quot;213&quot; height=&quot;50&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 모멘텀 최적화는 경사 하강법과 반대로 &lt;b&gt;이전 그레디언트가 얼마였는지가 중요합니다.&lt;/b&gt; 여기서는 매 반복에서 그레디언트 * 학습률를 구하여 이를 모멘텀 벡터 $m$에 더한 값을 빼서 가중치를 갱신하게 됩니다. 쉽게 생각해서 이 모멘텀 벡터에 &lt;b&gt;이전 그레디언트에 대한 정보가 담겨있다고 생각하면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그런데 여기서 볼링공이 너무 빠르게 내려가지 않도록 일종의 마찰 저항을 주기 위해 새로운 하이퍼 파라미터 $&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;beta;&lt;/span&gt;$가 등장합니다. 이 값이 커질수록 마찰 저항이 없어지는데 보통은 $0.9$로 설정합니다. 이렇게 설정하면 경사 하강법보다 10배 정도 빠르게 최적화를 진행할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;149&quot; data-origin-height=&quot;89&quot; width=&quot;214&quot; height=&quot;128&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpla8w/btq5uuCje0I/A4tD5wftf2V6KVVssmmDa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpla8w/btq5uuCje0I/A4tD5wftf2V6KVVssmmDa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpla8w/btq5uuCje0I/A4tD5wftf2V6KVVssmmDa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbpla8w%2Fbtq5uuCje0I%2FA4tD5wftf2V6KVVssmmDa1%2Fimg.png&quot; data-origin-width=&quot;149&quot; data-origin-height=&quot;89&quot; width=&quot;214&quot; height=&quot;128&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;어떤 입력 데이터의 스케일이 다르면, 비용 함수는 길쭉한 타원형의 모양을 가지게 됩니다. 경사 하강법은 이러한 경우에 매우 느립니다. 그러나 모멘텀 최적화는 굉장히 빠르게 minimum loss에 도달할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이러한 모멘텀 최적화는 &lt;b&gt;Batch-Normalization을 사용하지 않아서 스케일이 다른 입력이 들어오는 Neural Network에 적용하면 좋습니다.&lt;/b&gt; 다음은 Keras에서 모멘텀 최적화를 구현하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1621615867867&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;optimizer = keras.optimizers.SGD(lr=0.001, momentum=0.9)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;네스테로프 가속 경사&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;NAG라 부르는 네스테로프 가속 경사는 모멘텀 최적화의 변종으로 기존보다 거의 항상 빠릅니다. 기존에는 현재 위치에서 그레디언트를 계산했었다면, &lt;b&gt;모멘텀의 방향으로 즉 볼링공이 흘러가는 방향으로 조금 앞선 위치에서 그레디언트를 계산합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;190&quot; data-origin-height=&quot;89&quot; width=&quot;250&quot; height=&quot;117&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/viIhF/btq5tD7lbgP/StNytjkx59akkvHr6Kg9e0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/viIhF/btq5tD7lbgP/StNytjkx59akkvHr6Kg9e0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/viIhF/btq5tD7lbgP/StNytjkx59akkvHr6Kg9e0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FviIhF%2Fbtq5tD7lbgP%2FStNytjkx59akkvHr6Kg9e0%2Fimg.png&quot; data-origin-width=&quot;190&quot; data-origin-height=&quot;89&quot; width=&quot;250&quot; height=&quot;117&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 아래 그래프를 보면 알 수 있듯이 NAG가 minimum loss에 좀더 가깝습니다. 이러한 작은 개선이 쌓여서 NAG가 기존 모멘텀 회적화보다 확연히 빨라지게 됩니다. 게다가 기존 모멘텀 업데이트는 방향이 정해져 있기 때문에 의도와 달리 minimum loss쪽으로 가중치가 흘러가지 않을 수 있습니다. 그러나 &lt;b&gt;NAG의 경우는 minimum loss쪽으로 가중치를 끌어당겨 진동을 감소시키고 수렴을 빠르게 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;235&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V0pgD/btq5vNBfphZ/nA4s5WBFKVKCaQFPtxL7Q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V0pgD/btq5vNBfphZ/nA4s5WBFKVKCaQFPtxL7Q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V0pgD/btq5vNBfphZ/nA4s5WBFKVKCaQFPtxL7Q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV0pgD%2Fbtq5vNBfphZ%2FnA4s5WBFKVKCaQFPtxL7Q0%2Fimg.png&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;235&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 NAG를 Keras에서 사용한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1621616391884&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;optimizer = keras.optimizers.SGD(lr=0.001, momentum=0.9, nesterov=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AdaGrad&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;방금 우리가 NAG와 경사 하강법의 최적화를 비교했던 바로 위 그래프를 다시 보겠습니다. 경사하강법은 가장 가파른 경사를 빠르게 내려가기 시작하여 골짜기 아래로 느리게 이동합니다. 만약 알고리즘이 이를 빠르게 감지하여 global minimum 쪽으로 정확한 방향을 잡아줬다면 좋았을 것입니다. 이를 위해 &lt;b&gt;그레디언트 벡터의 스케일을 감소시켜 해결하고자 하는게 AdaGrad 알고리즘입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;195&quot; data-origin-height=&quot;88&quot; width=&quot;290&quot; height=&quot;131&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cavcnU/btq5uImMBzH/aHHXnCbtME5q48sY6Pima0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cavcnU/btq5uImMBzH/aHHXnCbtME5q48sY6Pima0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cavcnU/btq5uImMBzH/aHHXnCbtME5q48sY6Pima0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcavcnU%2Fbtq5uImMBzH%2FaHHXnCbtME5q48sY6Pima0%2Fimg.png&quot; data-origin-width=&quot;195&quot; data-origin-height=&quot;88&quot; width=&quot;290&quot; height=&quot;131&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;첫번째 단계&lt;/b&gt;는 그레디언트의 제곱을 벡터 x에 누적합니다. 만약 비용함수가 i번째 차원을 따라 가파르다면, 기울기가 클 것이므로 $s_i$또한 반복이 진행됨에 따라 점점 커지게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;두번째 단계&lt;/b&gt;는 경사 하강법과 거의 같습니다. 다만 한 가지 차이는 그레디언트 벡터를 루트값으로 나누어 스케일을 조정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;AdaGrad는 학습률을 감소시키지만, 경사가 완만한 차원보다 가파른 차원에 대해 더 빠르게 감소됩니다. 이를 &lt;b&gt;적응적 학습률이라 부르며 global minimum 방향으로 곧장 가도록 갱신하는데 도움을 줍니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;267&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uIFI3/btq5qWfMFd3/KIE1y9C5yGJ4NnUkHzT9U0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uIFI3/btq5qWfMFd3/KIE1y9C5yGJ4NnUkHzT9U0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uIFI3/btq5qWfMFd3/KIE1y9C5yGJ4NnUkHzT9U0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuIFI3%2Fbtq5qWfMFd3%2FKIE1y9C5yGJ4NnUkHzT9U0%2Fimg.png&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;267&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;AdaGrad는 간단한 2차 방정식 문제에 대해서는 잘 작동하지만, 학습률이 너무 감소되어서 global minimum이 도착하기 전 알고리즘이 멈추는 경우도 있습니다. 따라서 간단한 작업에서만 사용하고, Neural Network같이 복잡한 작업에서는 사용하지 않는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RMSProp&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; AdaGrad이 global minimum에 잘 도달할 수 있는 이유는 빠르게 내려가는 학습률이 방향 전환을 쉽게 해주기 때문입니다. 그러나 &lt;b&gt;너무 빨리 느려져 global minimum에 도달하지 못할 수 있다는 위험도 내재되어있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;RMSProp은 전체가 아닌 최근 반복에서 비롯된 그레디언트만 누적하여 이 문제를 해결했습니다. 이를 위해 알고리즘의 첫번째 단계로 &lt;b&gt;지수 감소(Exponential Decay)&lt;/b&gt;를 사용합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;88&quot; width=&quot;300&quot; height=&quot;125&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IC2RA/btq5vOGVYJk/qufHwkVvdS6jum7WmddZv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IC2RA/btq5vOGVYJk/qufHwkVvdS6jum7WmddZv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IC2RA/btq5vOGVYJk/qufHwkVvdS6jum7WmddZv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIC2RA%2Fbtq5vOGVYJk%2FqufHwkVvdS6jum7WmddZv1%2Fimg.png&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;88&quot; width=&quot;300&quot; height=&quot;125&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;보통 감쇠율 $&lt;span style=&quot;color: #4d5156;&quot;&gt;&amp;beta;$는 0.9로 설정합니다. 다음은 Keras로 구현한 코드입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1621618214688&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;optimizer = keras.optimizers.RMSprop(lr=0.001, rho=0.9)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Adma과 Nadam&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;adaptive moment estimation의 줄임말인 Adam은 모&lt;b&gt;멘텀 최적화와 RMSProp의 아이디어를 합친 것입니다.&lt;/b&gt; 모멘텀 최적화처럼 지난 그레디언트의 지수 감소 평균을 따르고, RMSProp처럼 지난 그레디언트 제곱의 지수 감소 평균을 따릅니다.&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/bxeeIL/btq5tbKgzCw/GwAljqH1Bbp2WDCgkehIKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxeeIL/btq5tbKgzCw/GwAljqH1Bbp2WDCgkehIKk/img.png&quot; data-origin-width=&quot;218&quot; data-origin-height=&quot;122&quot; width=&quot;318&quot; height=&quot;178&quot; style=&quot;width: 42.8135%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxeeIL/btq5tbKgzCw/GwAljqH1Bbp2WDCgkehIKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxeeIL%2Fbtq5tbKgzCw%2FGwAljqH1Bbp2WDCgkehIKk%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;218&quot; height=&quot;122&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btqNGt/btq5tjhk5mF/H0jF8TIeyywXeZtS4ygqIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btqNGt/btq5tjhk5mF/H0jF8TIeyywXeZtS4ygqIk/img.png&quot; data-origin-width=&quot;159&quot; data-origin-height=&quot;68&quot; style=&quot;width: 56.0237%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btqNGt/btq5tjhk5mF/H0jF8TIeyywXeZtS4ygqIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtqNGt%2Fbtq5tjhk5mF%2FH0jF8TIeyywXeZtS4ygqIk%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;159&quot; height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;단계 1,2,5를 보면 Adam이 모멘텀 최적화, RMSProp과 아주 비슷하다는 것을 알 수 있습니다. 차이점은 단계 1에서 지수 감소 합 대신 지수 감소 평균을 계산하는 것이지만, 사실 상수 배인 것을 제외하면 동일합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;$m$,$s$는 초기화로 인해 훈련 초기에 0쪽으로 치우치게 될 것입니다. 그래서 이 두 단계가 훈련 초기에 $m$과$s$를 증폭시키는데 도움을 줄 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 Keras에서 적용한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1621618599714&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;optimizer = keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Adam 또한 적응적 학습률 알고리즘이기 때문에, 학습률 하이퍼파라미터를 튜닝해주지 않아도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2192657103&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 지금껏 나온 옵티마이저를 비교해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;193&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIY1YR/btq5t2sA2Ol/IqjyNDvdBZ6s2ghtv2k3pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIY1YR/btq5t2sA2Ol/IqjyNDvdBZ6s2ghtv2k3pK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIY1YR/btq5t2sA2Ol/IqjyNDvdBZ6s2ghtv2k3pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIY1YR%2Fbtq5t2sA2Ol%2FIqjyNDvdBZ6s2ghtv2k3pK%2Fimg.png&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;193&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음 포스팅에서는 학습률 스케줄링에 대해 공부해보겠습니다. 오늘도 함께해주셔서 감사합니다. 행복한 하루 보내세요 :)&lt;/p&gt;</description>
      <category>AdaGrad</category>
      <category>ADAM</category>
      <category>Nadam</category>
      <category>PYTHON</category>
      <category>rmsprop</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>모멘텀 최적화</category>
      <category>옵티마이저</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/69</guid>
      <comments>https://box-world.tistory.com/69#entry69comment</comments>
      <pubDate>Mon, 21 Jun 2021 11:25:13 +0900</pubDate>
    </item>
    <item>
      <title>[ 머신러닝 순한 맛] 전이학습은 어떻게 이뤄질까? with Code</title>
      <link>https://box-world.tistory.com/68</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;큰 야망을 품었을 때&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;커다란 결실을 얻을 수 있다.&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 힐러리 클린턴미국 상원의원 -&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 글을 읽는 여러분의 AI 공부를 어렵게 하는 것은 무엇인가요? 어려운 개념이나 수식도 한몫하겠지만, 저는 높은 연산량을 감당하기 위해, 값비싼 GPU가 필요하다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이런 맥락에서 대부분의 AI를 초기에 공부하는 우리들이 아주 큰 규모의 DNN을 처음부터 훈련시킨다는 건 매우 어려운 일입니다. 이럴 경우 생각해볼 수 있는 방법이 비슷한 유형의 문제를 처리한 신경망이 있는지 찾아보고 이를 이용하는 전이 학습입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우리는 이를 통해 훈련 속도도 크게 높일 수 있으며 필요한 훈련 데이터도 크게 줄어듭니다. 이번 포스팅에서는 실무에서도 많이 쓰이는 &lt;b&gt;전이학습&lt;/b&gt;에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&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;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사전 훈련된 층 재사용하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;여기 동물, 식물, 자동차 등 100개의 구분된 이미지를 분류하도록 훈련된 DNN이 있다고 가정하겠습니다. 그리고 &lt;b&gt;우리는 지금부터 구체적인 자동차의 종류를 분류하는 DNN을 훈련시키고자 합니다.&lt;/b&gt; 바로 이때 이렇게 두 DNN에 대해서 비슷한 점이 많고, 일부 겹치는 부분이 있을 때 신경망을 재사용하는 것을 고려해봐야합니다.&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-origin-width=&quot;455&quot; data-origin-height=&quot;332&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAmFFd/btq4EdHvIvZ/cxHcykXW4KaSLkjC1duDok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAmFFd/btq4EdHvIvZ/cxHcykXW4KaSLkjC1duDok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAmFFd/btq4EdHvIvZ/cxHcykXW4KaSLkjC1duDok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAmFFd%2Fbtq4EdHvIvZ%2FcxHcykXW4KaSLkjC1duDok%2Fimg.png&quot; data-origin-width=&quot;455&quot; data-origin-height=&quot;332&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;첫번째로 해야할 일은 &lt;b&gt;재사용하려는 모델의 출력층을 바꿔줘야 합니다&lt;/b&gt;. 물건을 구분하던 기존 신경망과 자동차의 종류를 구분하고자 하는 우리의 신경망은 그 출력이 다를 것이기 때문에 바꿔주는게 당연히 맞을 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;비슷한 맥락에서 재사용하려는 &lt;b&gt;신경망의 상위 은닉층(출력층에 가까운 층들)은 하위 은닉층보다 덜 유용합니다.&lt;/b&gt; 왜냐하면 상위 은닉층이라 하면 구체적이고 세부적이고 지엽적인 특성을 학습하고 있기 때문에 이런 특성들은 도움되지 않을것입니다. &lt;b&gt;쉽게 말해서&lt;/b&gt; 우리는 이야기의 대략적인 개요나 줄거리 정도가 필요하지, 그 안에 등장인물의 이름이나 생김새와 같은 정보는 필요하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그렇다면 우리가 방금 단계에서 재사용할 층의 개수까지 정하고 나면 무엇을 해야할까요? 우선은 &lt;b&gt;재사용하는 층의 가중치는 모두 동결합니다.&lt;/b&gt; 즉 이들은 경사 하강법으로 가중치가 바뀌지 않습니다. 그 다음 모델을 훈련하고 평가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이후에 맨 위에 있는 가장 깊은 층부터 동결을 해제하면서 역전파 알고리즘을 이용하여 가중치를 조정하여 성능을 확인합니다. 이때 데이터가 많을 수록 더 많은 층을 동결 해제할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;한 가지 주의할 점은 &lt;b&gt;가중치를 세밀하게 튜닝하기 위해 학습률은 줄이는게 좋습니다.&lt;/b&gt; 만약 여전히 좋은 성능을 내지 못한다면 상위 은닉층을 제거하거나 추가하면서 재사용할 층의 개수를 적절히 찾아야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&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;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;Keras를 이용한 전이 학습&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이번엔 직접 코드와 함께 전이 학습을 살펴보겠습니다. 우리가 여기서 활용한 데이터셋은 8개의 클래스로 나뉜 Fashion MNIST 데이터셋입니다. 누군가 &lt;b&gt;이 데이터의 클래스를 90%이상의 정확도로 분류시키는 모델 'A'를 생성&lt;/b&gt;했다고 하겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우리가 하고자하는 작업은 Fashion MNIST 데이터셋에는 없는 '샌들'과 '셔츠' 이미지를 구분하는 Binary Classifier를 구현하고자 합니다(True = 셔츠, False = 샌들). 레이블된 이미지는 200개 정도로 매우 적습니다. 그래서 우리는 모델 A와 구조가 매우 비슷한 모델 B를 만들었고 97.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;&amp;nbsp;우선 모델 A를 로드하여 &lt;b&gt;출력층을 제외하고 모든 층을 재사용해보겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1620663123156&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model_A = keras.models.load_model(&quot;my_model_A.h5&quot;)
model_B_on_A = keras.models.Sequential(model_A.layers[:-1])
model_B_on_A.add(keras.layers.Dense(1, activation=&quot;sigmoid&quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;model_A와 model_B_on_A는 일부 층을 공유합니다. 즉 &lt;span style=&quot;color: #333333;&quot;&gt;model_B_on_A가 훈련할 때 model_A도 함께 학습됩니다. 이를 원하지 않는다면, 훈련 전 클론시켜놔야합니다. 이를 위해 clone_model() 메서드를 사용하여 모델 A의 구조를 복제한 후 가중치를 복사합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1620663256181&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model_A_clone = keras.models.clone_model(model_A)
model_A_clone.set_weights(model_A.get_weights())&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;이제 재사용할 층과 가중치까지 가져왔기 때문에 훈련만 하면 됩니다. 그렇지만 &lt;b&gt;바로 훈련으로 들어간다면&lt;/b&gt; 새로운 출력층이 랜덤하게 초기화되어있어 큰 오차를 만들 것이고 이로 인한 큰 오차 그레디언트는 최적화를 방해할 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;이를 피하기 위해 처음 몇번의 에포크 동안에는 재사용된 층을 동결하고 새로운 층에게 적절한 가중치를 학습할 시간을 줘야합니다. 이를 위해 모든 층의 trainable 속성을 False로 지정하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1620663570600&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for layer in model_B_on_A.layers[:-1]:
    layer.trainable = False

model_B_on_A.compile(loss=&quot;binary_crossentropy&quot;,
                     optimizer=keras.optimizers.SGD(lr=1e-3),
                     metrics=[&quot;accuracy&quot;])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 몇번의 에포크 동안 훈련을 하고 나면 동결을 해제하고 &lt;b&gt;작업 B에 맞게 이 재사용된 층들을 세밀하게 튜닝해야합니다.&lt;/b&gt; &lt;b&gt;이때&lt;/b&gt; &lt;b&gt;학습률을 낮춰 가중치가 망가지는 것을 막아야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1620663634583&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;history = model_B_on_A.fit(X_train_B, y_train_B, epochs=4,
                           validation_data=(X_valid_B, y_valid_B))

for layer in model_B_on_A.layers[:-1]:
    layer.trainable = True

model_B_on_A.compile(loss=&quot;binary_crossentropy&quot;,
                     optimizer=keras.optimizers.SGD(lr=1e-3),
                     metrics=[&quot;accuracy&quot;])
history = model_B_on_A.fit(X_train_B, y_train_B, epochs=16,
                           validation_data=(X_valid_B, y_valid_B))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;최종점수를 확인해보면 그 정확도는 99.25%로 오차율을 2.8%에서 0.7%로 네 배나 낮췄습니다,&lt;/p&gt;
&lt;pre id=&quot;code_1620663740951&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model_B.evaluate(X_test_B, y_test_B)
&amp;gt;&amp;gt; [0.1408407837152481, 0.9704999923706055]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;전이 학습은 작은 규모의 Fully-Connected 네트워크에서는 잘 동작하지 않습니다.&lt;/b&gt; &lt;b&gt;작은 규모&lt;/b&gt;는 패턴 수를 적게 학습한다는 뜻이고, &lt;b&gt;Fully-Connected 라는 것&lt;/b&gt;은 특정 패턴을 학습하기 때문일 것입니다. 실제로 이러한 특정 패턴이 다른 작업에서도 유용하게 쓰일 확률은 적다고 봐야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;반대로 규모가 어느정도 있는 심층 합성곱 신경망은 일반적인 특성을 훨씬 잘 파악하기 때문에 잘 동작할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&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;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음 포스팅에서는 최적화를 위해 일반적으로 우리가 사용하는 고속 옵티마이저의 종류에 대해서 알아보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내세요 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;&amp;lt;a href=https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&amp;gt;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&amp;lt;/a&amp;gt;&quot;&gt;&lt;/script&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;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>AI</category>
      <category>hands on</category>
      <category>numpy</category>
      <category>PYTHON</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>전이학습</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/68</guid>
      <comments>https://box-world.tistory.com/68#entry68comment</comments>
      <pubDate>Tue, 11 May 2021 01:38:10 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 그레디언트 소실(Vanishing) / 폭주(Exploding)이란?</title>
      <link>https://box-world.tistory.com/67</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; background-color: #99cefa;&quot;&gt;잘못된 전략이라도 제대로 실행만 하면 반드시 성공할 수 있다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; background-color: #99cefa;&quot;&gt;반대로 뛰어난 전략이라도 제대로 실행하지 못하면 반드시 실패한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; background-color: #99cefa;&quot;&gt;- &lt;span style=&quot;color: #333333;&quot;&gt;선 마이크로시스템즈 CEO, 스콧 맥닐리 -&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;b&gt;Deep Neural Network&lt;/b&gt;, 줄여서 DNN이라고 부르는 심층 신경망은 그 구조에 따라 수백 개에서 수 만개에 이르는 노드들이 엮어있는 구조를 지닙니다. 구조가 복잡한 것만큼 이것을 훈련하는 것 또한 쉽지 않습니다. 예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;신경망의 아래쪽으로 갈 수록 그레디언트가 작아지거나 커지는 &lt;b&gt;그레디언트 소실/폭주(Gradient Vanishing/Exploding)&lt;/b&gt; 문제가 발생할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;훈련을 위한 데이터가 충분하지 않거나 데이터에 레이블을 붙이는데 많은 Cost가 들어갈 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;과대적합(Overfitting)&lt;/b&gt;의 위험이 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;이번 포스팅에서는 우리가 신경망을 훈련시키면서 발생할 수 있는 다양한 문제들에 대해 알아보고, 이들을 어떻게 해결할 수 있는지에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그레디언트 소실/폭주&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;b&gt;신경망을 훈련시킨다는 것&lt;/b&gt;은 Back Propagation 알고리즘으로 Output Layer에서 Input Layer로 loss에 대한 그레디언트를 전파하고, 경사 하강법을 통해 이 그레디언트로 loss가 가장 적도록 파라미터를 수정하는 것을 의미합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;그런데 알고리즘이 하위층으로 진행될수록 그레디언트가 더 작아지는 경우가 있는데, 이것을 &lt;b&gt;그레디언트 소실&lt;/b&gt;이라고 합니다. 반대로 그레디언트가 비정상적으로 커지는 문제를 &lt;b&gt;그레디언트 폭주&lt;/b&gt;라고 합니다. 이러한 불안정한 그레디언트는 Layer마다 상이한 학습 속도를 유발할 수 있기 때문에 좋지 않은 현상입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;이런 부정적인 현상이 오랫동안 관측되었지만 그 원인이 명확하게 규명되지 않았습니다. 그러다 2010년의 한 논문에 의해 우리가 많이 사용하는 &lt;b&gt;logistic sigmoid 활성화 함수&lt;/b&gt;와 당시 가장 인기 있던 &lt;b&gt;가중치 초기화 방법&lt;/b&gt;(표준정규분포를 이용한 초기화)의 조합 때문이라는 것이 밝혀졌습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;538&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mpxtp/btq3UtFmHCp/OD6zvHdscGdTQb4BvCanA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mpxtp/btq3UtFmHCp/OD6zvHdscGdTQb4BvCanA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mpxtp/btq3UtFmHCp/OD6zvHdscGdTQb4BvCanA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmpxtp%2Fbtq3UtFmHCp%2FOD6zvHdscGdTQb4BvCanA1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;538&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이 활성화 함수와 초기화 방식을 조합하여 사용했을 때, 신경망의 &lt;b&gt;각 Layer에서 출력의 분산이 입력의 분산보다 더 크다는 것이 밝혀졌습니다.&lt;/b&gt; 이로 인해 신경망의 더 깊은 층으로 들어갈 수록 분산이 계속 커져 양 옆으로 퍼지면서 활성화 함수가 0이나 1로 수렴하게 되는 것이었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;게다가 logistic 함수의 평균이 0.5라는 사실 때문에 더 나빠졌습니다 (하이퍼볼릭 탄젠트 함수는 평균이 0이라 그나마 나았습니다) 다시 돌아와서 로지스틱 함수의 이러한 수렴이 문제가 되는 이유는 0이나 1로 수렴시 &lt;b&gt;기울기가 0에 가깝기 때문에 깊어질수록 훈련을 위한 아무런 정보도 도달하게 되지 않게 되는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;글로럿과 He 초기화&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp; 결국 우리가 지향하고자 하는 이상적인 상황은 예측 시엔 정방향으로, 훈련 시엔 역방향으로 양방향 신호가 적절하게 흘러가야 하는데, 이때 신호가 죽거나 폭주 혹은 소멸하지 않는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이에 대해 한 논문에선 &lt;b&gt;이렇게 적절한 신호가 흐르기 위해서는&lt;/b&gt; 정방향의 경우, 각 층의 출력에 대한 분산이 입력에 대한 분산과 같아야하고. 역방향에선 층을 통과하기 전과 후의 그레디언트 분산이 동일해야 한다고 주장합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;근본적으로 Layer의 Input과 Output의 연결 개수(fan in과 fan out)이 같지 않다면 위 두 가지를 보장할 수 없습니다. 그러나 저자들은 실전에서 매우 잘 작동한다고 입증된 대안을 제안하였는데, 바로 각 Layer들을 연결하는 가중치를 다음과 같이 무작위로 초기화하는 것입니다. 이를 &lt;b&gt;글로럿 초기화(Glorot initialization)&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;159&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czxyof/btq3Wm6ApYV/oZBKvHOnifycvlDT47r0hK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czxyof/btq3Wm6ApYV/oZBKvHOnifycvlDT47r0hK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czxyof/btq3Wm6ApYV/oZBKvHOnifycvlDT47r0hK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczxyof%2Fbtq3Wm6ApYV%2FoZBKvHOnifycvlDT47r0hK%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;159&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbhVhR/btq3SY7qGeN/pKkxOXr30EtnLJG83oU4b1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbhVhR/btq3SY7qGeN/pKkxOXr30EtnLJG83oU4b1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbhVhR/btq3SY7qGeN/pKkxOXr30EtnLJG83oU4b1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbhVhR%2Fbtq3SY7qGeN%2FpKkxOXr30EtnLJG83oU4b1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 여기서 $fan_{avg}$를 $fan_{in}$으록 바꾸면 &lt;b&gt;르쿤 초기화&lt;/b&gt;가 됩니다. 어쨌든 글로럿 초기화는 훈련 속도를 상당히 높이는데 기여하였습니다. 다음 표는 다른 논문들에서 로지스틱외에 다른 활성화함수를 사용하여 제안한 다양한 초기화 전략들입니다. 보다시피 분산의 스케일링이나 &lt;span style=&quot;color: #333333;&quot;&gt;$fan_{avg}$이나 $fan_{in}$을 쓰는 것이 다릅니다. He 초기화나 SELU에 대한 내용은 이따 다시 설명하겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hd4Xn/btq3TKU8dEp/fx5zhrFZZ8aNivigGjoxXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hd4Xn/btq3TKU8dEp/fx5zhrFZZ8aNivigGjoxXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hd4Xn/btq3TKU8dEp/fx5zhrFZZ8aNivigGjoxXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHd4Xn%2Fbtq3TKU8dEp%2Ffx5zhrFZZ8aNivigGjoxXK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;케라스는 기본적으로 &lt;b&gt;균등분포의 글로럿 초기화&lt;/b&gt;를 사용합니다. 여기서 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;kernel_inializer = &quot;he_uniform&quot;&lt;/span&gt;이나 &lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;kernel_inializer = &quot;he_normal&quot;&lt;/span&gt;로 바꾸어 He 초기화를 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1619884909517&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;keras.layers.Dense(10, activation=&quot;relu&quot;, kernel_initializer=&quot;he_normal&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$fan_{in}$ 대신 &lt;span style=&quot;color: #333333;&quot;&gt;$fan_{out}$ 기반의 &lt;b&gt;균등분포 He 초기화&lt;/b&gt;를 사용하고 싶다면&lt;span style=&quot;background-color: #dddddd;&quot;&gt; Variance Scaling&lt;/span&gt;을 다음과 같이 사용하면 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1619884971950&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;init = keras.initializers.VarianceScaling(scale=2., mode='fan_avg',
                                          distribution='uniform')
keras.layers.Dense(10, activation=&quot;relu&quot;, kernel_initializer=init)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;수렴하지 않는 활성화 함수&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;결국 우린 활성화 함수를 잘 선택해야 그레디언트 소실이나 폭주로 이어지지 않을 수 있습니다. 기존에 logistic 활성화 함수가 최선일거라고 생각하였지만, 특정 양수값에 수렴하지 않고 계산도 빠른 &lt;b&gt;Relu 함수&lt;/b&gt;가 있었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;하지만 Relu도 완벽하지 않습니다. 왜냐하면 &lt;b&gt;큰 학습률(learning rate)를 사용 시&lt;/b&gt; 신경망 속 노드들의 절반이 죽어 있는 경우가 있었기 때문입니다.(노드가 0이외의 값을 출력하지 않을때 죽었다고 합니다)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Relu함수 이용시 노드가 죽는 이유는 모든 Input data에 대한 가&lt;b&gt;중치의 합이 음수가 되면 아래 그래프에서 볼 수 있듯이그레디언트가 0이기 때문에&lt;/b&gt; 경사 하강법이 더 이상 작동하지 않게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;382&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byvegY/btq3Ta7O9A4/m6OaTfsJkuoZy64ORBvhGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byvegY/btq3Ta7O9A4/m6OaTfsJkuoZy64ORBvhGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byvegY/btq3Ta7O9A4/m6OaTfsJkuoZy64ORBvhGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyvegY%2Fbtq3Ta7O9A4%2Fm6OaTfsJkuoZy64ORBvhGK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;382&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이러한 문제 해결을 위해 &lt;b&gt;LeakyReLU&lt;/b&gt;와 같은 변종을 사용합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baQtjP/btq3UTRkhEl/O8hLem9eX0JoX87sYBR9U1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baQtjP/btq3UTRkhEl/O8hLem9eX0JoX87sYBR9U1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baQtjP/btq3UTRkhEl/O8hLem9eX0JoX87sYBR9U1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaQtjP%2Fbtq3UTRkhEl%2FO8hLem9eX0JoX87sYBR9U1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p5oOv/btq3UsT1Ys3/1Djjyi4QewopBYUmc1PNo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p5oOv/btq3UsT1Ys3/1Djjyi4QewopBYUmc1PNo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p5oOv/btq3UsT1Ys3/1Djjyi4QewopBYUmc1PNo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp5oOv%2Fbtq3UsT1Ys3%2F1Djjyi4QewopBYUmc1PNo1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;하이퍼 파라미터 $&lt;span&gt;&amp;alpha;&lt;/span&gt;$는 이 함수가 &lt;b&gt;새는 정도&lt;/b&gt;를 결정합니다. 즉 샌다는 것은 음수 영역에서의 함수의 기울기를 의미하며 보통 $0.01$로 설정합니다. 바로 이 작은 기울기가 LeakyRelu가 절대 죽지 않게 해주는 것입니다. 실제로 성능도 훨씬 좋습니다. 다음은 &lt;span style=&quot;color: #333333;&quot;&gt;LeakyRelu 사용법입니다. 적용하려는 층 뒤에 붙여주면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1619886436411&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.Dense(300, kernel_initializer=&quot;he_normal&quot;),
    keras.layers.LeakyReLU(),
    keras.layers.Dense(100, kernel_initializer=&quot;he_normal&quot;),
    keras.layers.LeakyReLU(),
    keras.layers.Dense(10, activation=&quot;softmax&quot;)
])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이외에 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;alpha;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$를 무작위로 선택하여 테스트 시에는 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;alpha;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$들의 평균을 사용하는 &lt;b&gt;RRelu&lt;/b&gt;나 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;alpha;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$가 훈련하는 동안 학습되는 &lt;b&gt;PReLU&lt;/b&gt;가 있습니다. 마지막으로 볼 활성화 함수는 다른 모든 ReLU 변종들의 성능을 앞서는 &lt;b&gt;ELU&lt;/b&gt;입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;572&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cV0awe/btq3YKFTwuU/hgrOb9VUFVksz1HBu7F6dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cV0awe/btq3YKFTwuU/hgrOb9VUFVksz1HBu7F6dk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cV0awe/btq3YKFTwuU/hgrOb9VUFVksz1HBu7F6dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcV0awe%2Fbtq3YKFTwuU%2FhgrOb9VUFVksz1HBu7F6dk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;572&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 함수는 몇가지를 제외하고 ReLU와 유사한 특성을 지닙니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$z &amp;lt; 0$일때 음수값을 내보내므로, 활성화함수의 &lt;b&gt;평균 출력이 0에 가까워지고 이는 그레디언트 소실 문제를 완화해줍니다.&lt;/b&gt; 여기서의 알파값은 ELU가 수렴할 값을 정의하는데 보통 1로 설정합니다.&lt;/li&gt;
&lt;li&gt;$z&amp;lt;0$이어도 그레디언트가 0이 아니기 때문에 죽은 뉴런을 만들지 않습니다.&lt;/li&gt;
&lt;li&gt;알파가 1일 때, $z=0$에서 급격한 변동이 일어나지 않는 즉 모든 구간에서 매끄럽기때문에 &lt;b&gt;최적화의 속도를 높이는데 기여합니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;ELU의 주요한 단점은 &lt;b&gt;계산이 느리다는 것입니다.&lt;/b&gt; 물론 수렴 속도가 빨라 상쇄가 되지만, 테스트의 경우엔 ReLU를 이용한 네트워크보단 느릴 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;ELU의 변종인 &lt;b&gt;SELU&lt;/b&gt;를 살펴보겠습니다. 저자들은 네트워크가 Fully-Connected한 상태에서 활성화함수로 SELU를 사용하면 &lt;b&gt;자기 정규화&lt;/b&gt;(각 층의 출력의 평균이 0이고, 표준편차가 1이 유지됨)된다는 것을 보였습니다. 다음은 자기 정규화를 위한 몇가지 조건입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Input은 반드시 &lt;b&gt;표준화&lt;/b&gt;(평균 0, 표준편차 1)이어야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;hidden layer의 &lt;b&gt;가중치는 르쿤 정규분포로 초기화&lt;/b&gt;되어 있어야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;순환 신경망이나, skip connection과 같은 &lt;b&gt;순차적이지 않은 구조를 사용시 자기 정규화를 보장하지 않습니다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;다음은 일반적으로 우선순위시 되는 활성화 함수입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dc49jd/btq3YKTqNP3/dyflHUH9mBOH1DwyVBRGLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dc49jd/btq3YKTqNP3/dyflHUH9mBOH1DwyVBRGLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dc49jd/btq3YKTqNP3/dyflHUH9mBOH1DwyVBRGLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdc49jd%2Fbtq3YKTqNP3%2FdyflHUH9mBOH1DwyVBRGLK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&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;네트워크가 자기 정규화 되지 못한다면 SELU보단 ELU&lt;/li&gt;
&lt;li&gt;실행 속도가 중요하다면 LeakyReLU&lt;/li&gt;
&lt;li&gt;신경망이 Overfitting되었다면 RReLU&lt;/li&gt;
&lt;li&gt;그러나 대부분의 라이브러리와 하드웨어 가속기들은 ReLU에 특화되어있으므로, 속도를 위한다면 Relu&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배치 정규화(Batch Normalization)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;우리가 앞서 살펴본 초기화 방법들은 훈련 초기 단계에서 그레디언트 소실이나 폭주를 방지하는 방법입니다. 하지만 훈련 도중에 이러한 현상들이 다시 발생하지 않으리라는 보장은 없습니다. 이에 따라 제시된 해결책이 &lt;b&gt;배치 정규화&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 기법은 활성화 함수 통과 전이나 후에 &lt;b&gt;입력을 정규화한 후, 결과값의 스케일을 조정하고 이동시킵니다.&lt;/b&gt; 대부분의 경우 신경망의 첫번째 층에 배치 정규화를 추가하면 training set을 표준화할 필요가 없습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우리가 고등학교때 배웠지만, input data를 정규화하기 위해서는 평균과 표준편차가 필요하기 때문에 이를 추정해야합니다. 다음은 이 추정을 위해 mini-batch에서 Input의 입력과 표준편차를 추정하는 알고리즘입니다.&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/Vt84Z/btq3U7ICOyZ/W0952V2BwrbFAs5aGkCV8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vt84Z/btq3U7ICOyZ/W0952V2BwrbFAs5aGkCV8k/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 28.7633%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vt84Z/btq3U7ICOyZ/W0952V2BwrbFAs5aGkCV8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVt84Z%2Fbtq3U7ICOyZ%2FW0952V2BwrbFAs5aGkCV8k%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vFjlP/btq3UcRp9qO/5Eu20NzX5l1e9hlAZjUKJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vFjlP/btq3UcRp9qO/5Eu20NzX5l1e9hlAZjUKJ0/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 70.074%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vFjlP/btq3UcRp9qO/5Eu20NzX5l1e9hlAZjUKJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvFjlP%2Fbtq3UcRp9qO%2F5Eu20NzX5l1e9hlAZjUKJ0%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;하지만 &lt;b&gt;테스트 시엔 데이터가 하나씩 들어오기 때문에&lt;/b&gt;, 전체 test data에 대한 평균과 표준편차를 계산할 방법이 없습니다. 이에 한가지 방법은 훈련이 끝난 후 test data가 포함된 전체 training set을 신경망에 통과시켜 각 input에 대한 평균과 표준편차를 계산하여 이를 예측에 활용하는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이러한 배치 정규화는 그레디언트 소실 / 폭주 문제 해결이나 학습 속도 향상에 크게 기여하였습니다. 그러나&lt;b&gt; 배치 정규화는 층마다 추가되는 계산으로 인하여 복잡도와 실행 시간을 높입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다행히 훈련이 끝난 후에 이전 층과 배치 정규화 층을 합쳐 실행 속도 저하를 피합니다. 즉 이전 층의 가중치를 바꾸어 바로 스케일이 조정되고 이동된 출력을 만듭니다. 다음은 이를 케라스로 구현한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1619887732412&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.BatchNormalization(),
    keras.layers.Dense(300, activation=&quot;relu&quot;),
    keras.layers.BatchNormalization(),
    keras.layers.Dense(100, activation=&quot;relu&quot;),
    keras.layers.BatchNormalization(),
    keras.layers.Dense(10, activation=&quot;softmax&quot;)
])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;그레디언트 클리핑&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;그레디언트 문제 그 중에서도 폭주 문제를 완화하는 인기 있는 방법은 역전파 시 일정 임곗값을 넘어가지 않도록 그레디언트를 잘라내는 것입니다. 이를 &lt;b&gt;그레디언트 클리핑&lt;/b&gt;이라고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 방법은 앞서 우리가 배치 정규화를 적용하기 어렵다고 한 순환 신경망같은 구조에서 사용합니다. 다음은 이를 keras에서 구현한 것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1619888911857&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;optimizer = keras.optimizers.SGD(clipvalue=1.0)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이 옵티마이저는 그레디언트 벡터의 모든 원소를 $-1.0$에서 $1.0$ 사이로 클리핑합니다. 즉 loss에 대한 모든 편미분 값을 이 사이로 잘라내는 것입니다. 예를 들어 원래 그레디언트 벡터가 $[0.9, 100.0]$이었다면 이를 클리핑 시 &lt;span style=&quot;color: #333333;&quot;&gt;$[0.9, 1.0]$가 되는 것입니다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;다음 포스팅에서는 신경망 학습에서 많이 활용되는 전이 학습에 대해 알아보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내세요 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>DNN</category>
      <category>neural network</category>
      <category>PYTHON</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>심층 신경망</category>
      <category>인공지능</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/67</guid>
      <comments>https://box-world.tistory.com/67#entry67comment</comments>
      <pubDate>Sun, 2 May 2021 17:45:38 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] TextField 내 hinttext 가운데로 정렬하기</title>
      <link>https://box-world.tistory.com/66</link>
      <description>&lt;p&gt;&amp;nbsp;TextField 내 'textAlign: TextAlign.center'를 삽입해주면 쉽게 해결된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sfDE2/btqYIkNAZlC/QRQPKgVUkMYZkhD7DcguwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sfDE2/btqYIkNAZlC/QRQPKgVUkMYZkhD7DcguwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sfDE2/btqYIkNAZlC/QRQPKgVUkMYZkhD7DcguwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsfDE2%2FbtqYIkNAZlC%2FQRQPKgVUkMYZkhD7DcguwK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1614494277731&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Container(
                          width: screenWidth*(300/360),
                          child: TextField(
                            controller: textfieldController_OpenChatLink,
                            textInputAction: TextInputAction.done,
                            // textAlign: TextAlign.center,
                            decoration: InputDecoration(
                              hintText: 'https://open.kakao.com/12345679',
                              hintStyle: TextStyle(
                                fontSize: screenWidth*(16/360),
                                color: hexToColor('#D2D2D2'),
                                fontWeight: FontWeight.bold,
                              )
                            ),
                          ),
                        )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Oj8BA/btqYJ87aWdV/kbGtaLH9vO4FlKKXdEV7aK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Oj8BA/btqYJ87aWdV/kbGtaLH9vO4FlKKXdEV7aK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Oj8BA/btqYJ87aWdV/kbGtaLH9vO4FlKKXdEV7aK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOj8BA%2FbtqYJ87aWdV%2FkbGtaLH9vO4FlKKXdEV7aK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1614494452621&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Container(
                          width: screenWidth*(300/360),
                          child: TextField(
                            controller: textfieldController_OpenChatLink,
                            textInputAction: TextInputAction.done,
                             textAlign: TextAlign.center,
                            decoration: InputDecoration(
                              hintText: 'https://open.kakao.com/12345679',
                              hintStyle: TextStyle(
                                fontSize: screenWidth*(16/360),
                                color: hexToColor('#D2D2D2'),
                                fontWeight: FontWeight.bold,
                              )
                            ),
                          ),
                        )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Flutter</category>
      <category>Android</category>
      <category>DART</category>
      <category>flutter</category>
      <category>google</category>
      <category>hinttext</category>
      <category>IOS</category>
      <category>textfield</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/66</guid>
      <comments>https://box-world.tistory.com/66#entry66comment</comments>
      <pubDate>Sun, 28 Feb 2021 15:41:05 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] Google Map 현재 위치로 이동하는 버튼 만들기</title>
      <link>https://box-world.tistory.com/65</link>
      <description>&lt;p&gt;&amp;nbsp;이번 포스팅에서는 Flutter에서 Google map을 사용할 때 현재 자신의 위치로 camera position을 이동시키는 버튼을 구현해보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;사실 다음과 같이 &lt;b&gt;myLocationButtonEnabled: true&lt;/b&gt;로 주셔도 버튼이 생성되는데, 이 경우에 버튼이 오른쪽 상단에 생기는데 위치를 변경하지 못하는 문제점이 발생합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1614277118112&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GoogleMap(
            mapType: _googleMapType,
            initialCameraPosition: _initialCameraPostion,
            onMapCreated: (GoogleMapController controller) async {
             //
            },
            myLocationEnabled: true,
            #################################################
            myLocationButtonEnabled: true,
            #################################################
            zoomControlsEnabled: false,
            markers: _markers,

          ),&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그래서 직접 구현해보고자 합니다!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;우선 &lt;b&gt;location&lt;/b&gt; package를 설치해주세요.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pub.dev/packages/location&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pub.dev/packages/location&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1614277265683&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;location | Flutter Package&quot; data-og-description=&quot;A Flutter plugin to easily handle realtime location in iOS and Android. Provides settings for optimizing performance or battery.&quot; data-og-host=&quot;pub.dev&quot; data-og-source-url=&quot;https://pub.dev/packages/location&quot; data-og-url=&quot;https://pub.dev/packages/location&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b3H6AD/hyJnZDdxBV/UJoArcA1l2ySUySLj9cOUk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640,https://scrap.kakaocdn.net/dn/G7TJj/hyJpBgpDLE/fJDDKSO9RfbPZBAVmdKAak/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640&quot;&gt;&lt;a href=&quot;https://pub.dev/packages/location&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pub.dev/packages/location&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b3H6AD/hyJnZDdxBV/UJoArcA1l2ySUySLj9cOUk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640,https://scrap.kakaocdn.net/dn/G7TJj/hyJpBgpDLE/fJDDKSO9RfbPZBAVmdKAak/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;location | Flutter Package&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;A Flutter plugin to easily handle realtime location in iOS and Android. Provides settings for optimizing performance or battery.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;pub.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;그 후 다음과 같이 눌렀을 때 &lt;b&gt;현재 위치로 이동할 버튼&lt;/b&gt;과 &lt;b&gt;onTap&lt;/b&gt; 이벤트 발생 시 현재 위치로 이동하게 해주는 &lt;b&gt;_currentLocation&lt;/b&gt;함수를 정의한 후 코드에 적용해주시면 끝입니다!&lt;/p&gt;
&lt;pre id=&quot;code_1614230198285&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GestureDetector(
            onTap: (){
              _currentLocation();
            },
            child: Container(
              width: screenWidth*(40/360),
              height: screenWidth*(40/360),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(8.0),
                color: Colors.white,
              ),
              child: Padding(
                padding:  EdgeInsets.all(screenWidth*(6/360)),
                child: SvgPicture.asset(
                  GreyMyLocationIcon,
                  width: screenWidth*(28/360),
                  height: screenWidth*(28/360),
                ),
              ),
            ),
          ),
          
          
void _currentLocation() async {
    final GoogleMapController controller = await _controller.future;
    LocationData currentLocation;
    var location = new Location();
    try {
      currentLocation = await location.getLocation();
    } on Exception {
      currentLocation = null;
    }

    controller.animateCamera(CameraUpdate.newCameraPosition(
      CameraPosition(
        bearing: 0,
        target: LatLng(currentLocation.latitude, currentLocation.longitude),
        zoom: 14.0,
      ),
    ));
  }
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발/Flutter</category>
      <category>Android</category>
      <category>DART</category>
      <category>flutter</category>
      <category>google</category>
      <category>google map</category>
      <category>IOS</category>
      <category>react</category>
      <category>구글 맵</category>
      <category>현재 위치</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/65</guid>
      <comments>https://box-world.tistory.com/65#entry65comment</comments>
      <pubDate>Fri, 26 Feb 2021 03:23:05 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] TextField의 prefixIcon 사이즈 내맘대로 조절하기</title>
      <link>https://box-world.tistory.com/64</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddcAOj/btqYpV8LDkb/UhconOkMhDFeKqwX3fiE50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddcAOj/btqYpV8LDkb/UhconOkMhDFeKqwX3fiE50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddcAOj/btqYpV8LDkb/UhconOkMhDFeKqwX3fiE50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddcAOj%2FbtqYpV8LDkb%2FUhconOkMhDFeKqwX3fiE50%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위와 같은 디자인을 구현하기 위해서는 TextField를 이용하는데, 돋보기를 사이즈에 맞게 넣으려는데 애를 먹었다. 다음과 같이 prefixIcon에 Svg나 Png를 넣어주면 TextField 앞에 아이콘이 자리잡게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1614214368654&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Container(
                        height: screenHeight*0.05,
                        width: screenWidth*0.836111,
                        child: TextField(
                          textAlign: TextAlign.left,
                          controller: textfieldControllerSearchLocation,
                          decoration: InputDecoration(
                            hintText: '지역별 검색',
                            hintStyle: TextStyle(
                                fontSize: screenWidth*(12/360),
                                color: hexToColor('#888888')
                            ),
                            ############################
                            prefixIcon: SvgPicture.asset(
                              GreyMagnifyingGlass,
                              width: screenWidth*(16/360),
                            ),
                            ############################
                            fillColor: hexToColor(&quot;#EEEEEE&quot;),
                            filled: true,
                            border: OutlineInputBorder(),
                            isDense: true,
                            contentPadding: EdgeInsets.symmetric(vertical: screenHeight*(8/640)),
                            focusedBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.all(Radius.circular(8)),
                              borderSide: BorderSide(width: 1,color: kPrimaryColor),
                            ),
                            enabledBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.all(Radius.circular(8)),
                              borderSide: BorderSide(width: 1,color: hexToColor((&quot;#EEEEEE&quot;))),
                            ),
                          ),
                          onChanged: (value) {

                          },
                        ),
                      )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;그런데 아무런 옵션 없이 넣게되면 다음과 같이 아무리 width나 height를 바꿔도 사이즈가 고정된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/M1NYL/btqYn5jJecr/YXEgT8rkrltGgpzBIYvm8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/M1NYL/btqYn5jJecr/YXEgT8rkrltGgpzBIYvm8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/M1NYL/btqYn5jJecr/YXEgT8rkrltGgpzBIYvm8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FM1NYL%2FbtqYn5jJecr%2FYXEgT8rkrltGgpzBIYvm8k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이럴 경우 다음과 같이 Padding을 위아래로 주게되면 내가 원하는 크기로 줄일 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1614214546957&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Container(
                        height: screenHeight*0.05,
                        width: screenWidth*0.836111,
                        child: TextField(
                          textAlign: TextAlign.left,
                          controller: textfieldControllerSearchLocation,
                          decoration: InputDecoration(
                            hintText: '지역별 검색',
                            hintStyle: TextStyle(
                                fontSize: screenWidth*(12/360),
                                color: hexToColor('#888888')
                            ),
                            ##############################
                            prefixIcon: Padding(
                              padding: EdgeInsets.symmetric(vertical: screenHeight*(8/640)),
                              child: SvgPicture.asset(
                                GreyMagnifyingGlass,
                                width: screenWidth*(16/360),
                              ),
                            ),
                             ##############################
                            fillColor: hexToColor(&quot;#EEEEEE&quot;),
                            filled: true,
                            border: OutlineInputBorder(),
                            isDense: true,
                            contentPadding: EdgeInsets.symmetric(vertical: screenHeight*(8/640)),
                            focusedBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.all(Radius.circular(8)),
                              borderSide: BorderSide(width: 1,color: kPrimaryColor),
                            ),
                            enabledBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.all(Radius.circular(8)),
                              borderSide: BorderSide(width: 1,color: hexToColor((&quot;#EEEEEE&quot;))),
                            ),
                          ),
                          onChanged: (value) {

                          },
                        ),
                      )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zNr9N/btqYusrhcG5/o8nyfBU4UKyMq0cVyRkGc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zNr9N/btqYusrhcG5/o8nyfBU4UKyMq0cVyRkGc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zNr9N/btqYusrhcG5/o8nyfBU4UKyMq0cVyRkGc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzNr9N%2FbtqYusrhcG5%2Fo8nyfBU4UKyMq0cVyRkGc1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDupkf/btqYxoO9rqm/bRQWUntckuK6o5y5JzQHg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDupkf/btqYxoO9rqm/bRQWUntckuK6o5y5JzQHg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDupkf/btqYxoO9rqm/bRQWUntckuK6o5y5JzQHg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDupkf%2FbtqYxoO9rqm%2FbRQWUntckuK6o5y5JzQHg0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Flutter</category>
      <category>flutter</category>
      <category>google</category>
      <category>IOS</category>
      <category>react</category>
      <category>textfield</category>
      <category>안드로이드</category>
      <category>앱 개발</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/64</guid>
      <comments>https://box-world.tistory.com/64#entry64comment</comments>
      <pubDate>Thu, 25 Feb 2021 09:57:29 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈 온 머신러닝 2 ] 비지도 학습의 모든 것 (K-Means)</title>
      <link>https://box-world.tistory.com/62</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #a6bc00;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;약해지지 말자.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 래리 페이지 (구글 공동창립자) -&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시작하며&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;이전 포스팅에서는 대부분 레이블($y$)이 존재하는 데이터에 대해 다뤄봤습니다. 하지만 우리가 사용하는 대부분의 데이터는 레이블이 없습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;그렇다면 레이블이 없다면 붙이면 되지 않을까요? 예를 들어 제품 결함을 감지하는 시스템을 만들어야 한다고 가정해보겠습니다. 시스템을 학습시키기 위해 수천장의 제품 사진 데이터를 마련하는 건 쉬울지 몰라도 이것들에 각각 결함과 정상을 판단하여 레이블링을 하는 것은 높은 cost를 요합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;물론 최근에는 데이터에 대한 중요성이 대두되면서 정부 차원에서 이러한 데이터 생성 및 가공에 힘을 쓰고 있지만, 이번 포스팅에선 사람의 도움없이 알고리즘이 레이블이 없는 데이터를 바로 사용하는 &lt;b&gt;비지도 학습&lt;/b&gt;에 대해 살펴보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9.1 군집 (Clustering)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;길을 걷다보면 많은 꽃들을 보게 됩니다. 이들이 모두 동일하지는 않지만, 외형적인 모습의 유사성을 통해 비슷한 종류의 꽃들끼리 그룹을 짓는건 굳이 전문가가 필요한 일이 아닙니다. 우리는 이러한 비슷한 특성을 가지는 데이터들끼리 묶는 것을 &lt;b&gt;군집(clustering)&lt;/b&gt;이라고 합니다. 그리고 이때 만들어진 그룹을 &lt;b&gt;Cluster&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QNvpE/btqV36RfCZ9/qWEQYYSentNT24mUbKzyN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QNvpE/btqV36RfCZ9/qWEQYYSentNT24mUbKzyN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QNvpE/btqV36RfCZ9/qWEQYYSentNT24mUbKzyN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQNvpE%2FbtqV36RfCZ9%2FqWEQYYSentNT24mUbKzyN0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;b&gt;Clustering&lt;/b&gt;은 결국 각각의 데이터를 하나의 Cluster에 할당하는 작업입니다. 다음 그림은 동일한 붓꽃 데이터셋에 대해서 한쪽은 레이블링이 되어있고, 다른 한쪽은 그렇지 않은 데이터를 시각화한 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;왼족은 레이블링 되어있는 덕분에 Logistic Regression, SVM 등의 Classification 알고리즘이 잘 맞습니다. 그러나 오른쪽은 레이블링이 없기 때문에 Clustering 알고리즘이 필요합니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;이제 본격적으로 Clustering 알고리즘에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&amp;nbsp;9.1.1 k-평균&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp; 아래 보이는 데이터셋은 레이블이 없고, 육안으로 볼때 샘플 덩어리 5개가 잘 구분되어있는 것을 확인할 수 있습니다. 우리가 배울 첫번째 Clustering 알고리즘인 &lt;b&gt;k-means 알고리즘&lt;/b&gt;은 몇번의 반복으로 이런 종류의 데이터셋을 효율적으로 클러스터로 묶을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbdxbH/btqVTHZ2fzf/2QWKJDhpqm9pKJDTX4Dodk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbdxbH/btqVTHZ2fzf/2QWKJDhpqm9pKJDTX4Dodk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbdxbH/btqVTHZ2fzf/2QWKJDhpqm9pKJDTX4Dodk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbdxbH%2FbtqVTHZ2fzf%2F2QWKJDhpqm9pKJDTX4Dodk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 구체적인 작동 원리를 살펴보기 전 sklearn의 코드를 살펴보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612619394061&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.cluster import KMeans

k = 5
kmeans = KMeans(n_clusters=k, random_state=42)
y_pred = kmeans.fit_predict(X)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;첫번째로는 알고리즘이 찾을 &lt;b&gt;클러스터 개수&lt;/b&gt; $k$를 지정해야 합니다. 지금은 육안으로 보고 $5$라고 설정하였지만, 실제로는 이런 방식으로 정하지 못하는데 이 부분은 조금 이따가 살펴보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;어쨌든 $k=5$라고 할당이 되었다면, 각각의 데이터는 5개의 클러스터 중 하나에 할당되는데, &lt;b&gt;바로 할당되는 클러스터의 index가 데이터의 레이블이 됩니다.&lt;/b&gt;(Classification의 클래스 레이블과는 분명히 다릅니다.)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음 코드처럼 labels_ 변수를 이용하면 훈련된 데이터의 레이블을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612619596533&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_pred
&amp;gt;&amp;gt;
array([0, 4, 1, ..., 2, 1, 4], dtype=int32)

y_pred is kmeans.labels_
&amp;gt;&amp;gt;
True&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음 코드에서는 알고리즘이 찾은 다섯 개의 센트로이드를 나열합니다. 이때 &lt;b&gt;센트로이드&lt;/b&gt;는 하나의 클러스터 내 데이터들의 중심이 되는 점입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612619692200&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kmeans.cluster_centers_

&amp;gt;&amp;gt;
array([[-2.80037642,  1.30082566],
       [ 0.20876306,  2.25551336],
       [-2.79290307,  2.79641063],
       [-1.46679593,  2.28585348],
       [-2.80389616,  1.80117999]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;만약 새로운 데이터가 들어온다면, 다음과 같이 해당 위치에서 가장 가까운 센트로이드가 속해있는 클러스터에 할당할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612619738620&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X_new = np.array([[0, 2], [3, 2], [-3, 3], [-3, 2.5]])
kmeans.predict(X_new)

&amp;gt;&amp;gt;
array([1, 1, 2, 2], dtype=int32)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 클러스터의 결정 경계를 그리면 다음과 같은 다이어그램을 얻을 수 있습니다. 이때 센트로이드는 $X$로 표시되어있습니다. 대부분의 데이터는 잘 할당이 되어있는데, 클러스터의 경계 부근 특히 핑크색과 노란색 클러스터 사이의 데이터 몇개는 잘못된 레이블이 부여되어있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;여기서 알 수 있는건 K-Means 알고리즘은 데이터에서 센트로이드까지의 거리를 고려하는 것이 전부이기 때문에, &lt;b&gt;클러스터 간의 크기가 많이 다르면 성능이 좋지 못합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbkNbz/btqV08WEZeT/A0WAkEkEpGXQKOwvHk186k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbkNbz/btqV08WEZeT/A0WAkEkEpGXQKOwvHk186k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbkNbz/btqV08WEZeT/A0WAkEkEpGXQKOwvHk186k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbkNbz%2FbtqV08WEZeT%2FA0WAkEkEpGXQKOwvHk186k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이렇게 각각의 데이터를 하나의 Cluster에 할당하는 방식을 &lt;b&gt;Hard Clustering&lt;/b&gt;이라고 합니다. 그리고 각각의 데이터마다 모든 클러스터마다 점수를 부여해 이중 하나를 선택하는 방식은 &lt;b&gt;Soft Clustering&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이때 점수를 매기는 방식은 거리가 될 수도 있고, &lt;b&gt;Gaussian RBF Kernel함&lt;/b&gt;수를 이용한 유사도 점수가 될 수도 있습니다. 다음은 &lt;b&gt;transform()&lt;/b&gt; 메서드를 통해 데이터와 센트로이드 사이의 거리를 반환합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;만약 고차원 데이터셋을 이런 방식으로 변환하면, 클러스터 개수가 k일때 k-차원 데이터셋으로 변환하여 효과적인 차원 축소(Dimension Reduction)을 수행할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612620321624&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kmeans.transform(X_new)

&amp;gt;&amp;gt;
array([[2.88633901, 0.32995317, 2.9042344 , 1.49439034, 2.81093633],
       [5.84236351, 2.80290755, 5.84739223, 4.4759332 , 5.80730058],
       [1.71086031, 3.29399768, 0.29040966, 1.69136631, 1.21475352],
       [1.21567622, 3.21806371, 0.36159148, 1.54808703, 0.72581411]])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;K-Means 알고리즘의 작동 방법&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;이제 본격적으로 K-Means 알고리즘의 작동 방법에 대해 알아보겠습니다. &lt;b&gt;센트로이드가 주어진다면,&lt;/b&gt; 각 데이터별로 가장 가까운 센트로이드의 클러스터에 할당하면 됩니다. 반대로 &lt;b&gt;샘플의 레이블이 주어져있다면,&lt;/b&gt; 평균을 계산하여 모든 센트로이드를 구할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 둘다 주어지지 않는다면 어떻게 해야할까요? 처음에는 무작위로 k개의 데이터를 골라 그 위치를 센트로이드로 지정합니다. 그리고 지정된 이 센트로이드에 따라 각 데이터별로 레이블링을 하고 센트로이드를 다시 업데이트합니다. 이 과정을 센트로이드에 변화가 없을 때까지 계속 하는데, 이 알고리즘은 제한된 횟수안에 수렴함을 보장합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 세 번의 반복으로 최적의 클러스터링을 만들어내는 과정입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKGtyh/btqV09usA7j/zKWUELsyZvC5KnGzD5daI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKGtyh/btqV09usA7j/zKWUELsyZvC5KnGzD5daI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKGtyh/btqV09usA7j/zKWUELsyZvC5KnGzD5daI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKGtyh%2FbtqV09usA7j%2FzKWUELsyZvC5KnGzD5daI1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;알고리즘의 수렴성은 보장되지만, 그것이 반드시 최적의 솔루션인 것은 아닙니다. 이것의 성공 여부는 센트로이드의 초기화에 달려있기 때문입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;센트로이드 초기화 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;센트로이드 초기화 방법에는 몇가지가 있는데, 어떻게 센트로이드를 초기화하느냐에 따라 알고리즘의 성능에 큰 영향을 미칩니다. 첫번째 방법은 &lt;b&gt;n_init = 1&lt;/b&gt;로 설정하고, 하나의 numpy 배열로 센트로이드 리스트를 초기화하는 것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612622234467&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;good_init = np.array([[-3, 3], [-3, 2], [-3, 1], [-1, 2], [0, 2]])
kmeans = KMeans(n_clusters=5, init=good_init, n_init=1)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;두 번째 방법은 매번 다른 랜덤 초기화를 하여 여러 번 알고리즘을 실행하고, 이중 가장 좋은 솔루션을 채택하는 것입니다. &lt;b&gt;n_init&lt;/b&gt;이 바로 랜덤 초기화 횟수를 지정하는 변수이며 기본 값은 10입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그렇다면 가장 좋은 솔루션이라고 판단하는 성능 지표는 무엇일까요? 그것은 각 데이터와 센트로이드 사이의 평균 제곱 거리로 도출한 모델의 &lt;b&gt;이너셔(inertia)&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음 그림에서 왼쪽 솔루션의 이너셔는 223.3, 오른쪽은 237.5입니다. KMeans 클래스는 n_init번 실행하여 이너셔가 가장 낮은 모델을 리턴합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9QQr5/btqVV3V4CpA/OnQFI9WuSyfkv4UNtx9tMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9QQr5/btqVV3V4CpA/OnQFI9WuSyfkv4UNtx9tMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9QQr5/btqVV3V4CpA/OnQFI9WuSyfkv4UNtx9tMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9QQr5%2FbtqVV3V4CpA%2FOnQFI9WuSyfkv4UNtx9tMk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 &lt;b&gt;inertia_&lt;/b&gt; 변수로 해당 모델의 이너셔를 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612622652027&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kmeans.inertia_

&amp;gt;&amp;gt;
211.62337889822362&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;score()&lt;/b&gt; 메서드는 이너셔의 음숫값을 반환합니다. 이것은 &lt;b&gt;&quot;큰 값이 좋은 것이다&quot;&lt;/b&gt;라는 sklearn의 규칙을 따르기 위해 더 좋은 모델이 높은 값을 갖도록 하기 위함입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612622725024&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kmeans.score(X)

&amp;gt;&amp;gt;
-211.62337889822362&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;K-Means++ 알고리즘&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이 개선된 알고리즘은 &lt;b&gt;센트로이드 초기화 단계에서 다른 센트로이드와 거리가 먼 센트로이드를 선택하는 방식&lt;/b&gt;으로 기존 알고리즘의 성능을 높이고 최적이 아닌 솔루션으로 수렴할 가능성을 크게 낮췄습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;게다가 최적의 솔루션을 찾기 위한 반복 횟수도 크게 줄이기 때문에 충분한 가치가 있는데, 작동 원리는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ssUB7/btqWc8HJ421/kbFViAIrtHjbfmqJHzvQj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ssUB7/btqWc8HJ421/kbFViAIrtHjbfmqJHzvQj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ssUB7/btqWc8HJ421/kbFViAIrtHjbfmqJHzvQj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FssUB7%2FbtqWc8HJ421%2FkbFViAIrtHjbfmqJHzvQj1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 원래 이 초기화 방법을 사용하는데, 앞서 배웠던 방식을 사용하고 싶다면 &lt;b&gt;init = &quot;random&quot;&lt;/b&gt;으로 설정하면 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;K-Means 속도 개선과 mini-batch&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;2013년도에 한 논문을 통해 &lt;b&gt;불필요한 거리 계산을 피함으로써 알고리즘의 속도를 상당히 높이는 방법이 제안되었습니다.&lt;/b&gt; 여기서 사용된 것은 &lt;b&gt;삼각 부등식&lt;/b&gt;을 사용하였고, 데이터와 센트로이드 사이의 거리를 위한 하한선과 상한선을 두었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;또 다른 논문에서는 전체 데이터셋을 사용해 반복하는 것이 아닌, 각 반복마다&lt;b&gt; mini-batch&lt;/b&gt;를 사용해 센트로이드를 조금씩 이동합니다. 이는 알고리즘의 속도를 3~4배 정도 높이며 큰 데이터셋을 다룰 때 용이합니다. 다음은 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612623609497&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.cluster import MiniBatchKMeans

minibatch_kmeans = MiniBatchKMeans(n_clusters=5, random_state=42)
minibatch_kmeans.fit(X)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;mini-batch K-Means 알고리즘은 속도는 빠르나 이너셔는 조금 더 나쁩니다.&lt;/b&gt; 특히 클러스터의 개수가 증가할 때 그렇습니다. 다음 그림에서 왼쪽 그래프는 클러스터 개수 $k$에 따른 mini-batch k-means와 k-means의 이너셔를 비교한 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;왼쪽 그래프의 경우 곡선의 차이가 일정하게 유지되는 듯 보이지만, 클러스터의 개수가 늘어날 수록 이너셔가 점점 줄어들기 때문에, 차이가 차지하는 비율은 점점 커집니다. 그러나 오른쪽 그래프를 보면 mini-batch K-Means가 일반적인 알고리즘보다 훨씬 빠르다는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RBKlP/btqWn1oh1kN/YA9jUl3F44Lg3HgVHSK6v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RBKlP/btqWn1oh1kN/YA9jUl3F44Lg3HgVHSK6v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RBKlP/btqWn1oh1kN/YA9jUl3F44Lg3HgVHSK6v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRBKlP%2FbtqWn1oh1kN%2FYA9jUl3F44Lg3HgVHSK6v1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;최적의 클러스터 개수 찾기&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;클러스터의 개수는 K-Means 알고리즘의 성능을 결정짓는 매우 중요한 요소입니다. 다음과 같이 클러스터의 개수가 너무 적다면 여러 클러스터가 합쳐지고, 그렇다고 너무 많다면 하나의 클러스터가 여러 개로 나눠질 수도 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u5uyZ/btqWsIvbaH6/ZFz8NQMSM5NdQz5IXjmlAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u5uyZ/btqWsIvbaH6/ZFz8NQMSM5NdQz5IXjmlAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u5uyZ/btqWsIvbaH6/ZFz8NQMSM5NdQz5IXjmlAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu5uyZ%2FbtqWsIvbaH6%2FZFz8NQMSM5NdQz5IXjmlAk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그렇다면 가장 적은 이너셔를 가진 모델을 선택하면 되는걸까요? 다음 그림을 보면 $k=3$일 때 이너셔는 $653.2$이고, $k$가 늘어날 수록 이너셔는 점점 작아지기 때문에 이너셔가 그다지 좋은 성능 지표가 아니라는 걸 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;어차피 클러스터가 늘어날 수록 각각의 데이터는 가까운 센트로이드에 가까워지기 때문에 이너셔가 작아지는 건 당연한 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buwjpf/btqWjpCYNBL/EfyuYGcfmHhcsqkoWOk3rK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buwjpf/btqWjpCYNBL/EfyuYGcfmHhcsqkoWOk3rK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buwjpf/btqWjpCYNBL/EfyuYGcfmHhcsqkoWOk3rK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbuwjpf%2FbtqWjpCYNBL%2FEfyuYGcfmHhcsqkoWOk3rK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 그림에서 보듯이 $k = 4$까지는 빠르게 이너셔가 감소하는걸 확인할 수 있습니다. 이 지점을 &lt;b&gt;Elbow&lt;/b&gt;라 칭하는데, 보통 이 지점을 넘어서면 이너셔가 줄어드는 속도가 매우 줄어들기 때문에 $4$를 넘어선 클러스터의 개수는 크게 도움이 되지 않습니다. 따라서 보통 &lt;b&gt;이 Elbow를 최적의 클러스터 개수로 고르게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 방금과 같은 방법은 조금은 엉성하게 느껴지기도 합니다. 더 정확한 방법은 &lt;b&gt;실루엣 점수(silghouette score)&lt;/b&gt;입니다. 이 점수는 모든 데이터에 대한 &lt;b&gt;실루엣 계수의 평균&lt;/b&gt;입니다. 각 데이터의 실루엣 계수는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;164&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EhIkb/btqV0EozS8Z/E2ZVBudmokpBoizYY7S9pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EhIkb/btqV0EozS8Z/E2ZVBudmokpBoizYY7S9pK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EhIkb/btqV0EozS8Z/E2ZVBudmokpBoizYY7S9pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEhIkb%2FbtqV0EozS8Z%2FE2ZVBudmokpBoizYY7S9pK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;164&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;$a$는 &lt;b&gt;동일한 클러스터 내 다른 데이터와 자기 자신 데이터와의 평균 거리입니다&lt;/b&gt;(클러스터 내부의 평균 거리). $b$는 &lt;b&gt;자기가 속한 클러스터를 제외하고 가장 가까운 클러스터의 데이터까지 평균 거리입니다.&lt;/b&gt; 계수는 $-1$에서 $1$까지 바뀔 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;$+1$에 가까우면 $b$ 즉 다른 클러스터와 멀면서, $a$ 자기가 속한 클러스터 내 데이터들과 가깝고 잘 뭉쳐져있다는 뜻이고, $-1$에 가깝다면, 반대이기 때문에 잘못된 클러스터에 할당되었다는 의미입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;실루엣 점수를 계산하려면 sklearn의 &lt;b&gt;silhouette_score()&lt;/b&gt; 함수를 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612739301041&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import silhouette_score

silhouette_score(X, kmeans.labels_)
&amp;gt;&amp;gt;
0.655517642572828&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;클러스터의 개수에 따라 상이한 실루엣 점수를 살펴보겠습니다. 클수록 잘 클러스터링된 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKLXDC/btqV0DQHYqb/MIUtEu7l3kgIiUUiznoNeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKLXDC/btqV0DQHYqb/MIUtEu7l3kgIiUUiznoNeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKLXDC/btqV0DQHYqb/MIUtEu7l3kgIiUUiznoNeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKLXDC%2FbtqV0DQHYqb%2FMIUtEu7l3kgIiUUiznoNeK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;모든 데이터의 실루엣 계수를 할당된 클러스터와 계수값으로 정렬하여 그리면 더 많은 정보가 있는 그래프를 얻을 수 있습니다. 이를 &lt;b&gt;실루엣 다이어그램&lt;/b&gt;이라고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;클러스터마다 칼 모양이 그려지는 이 그래프의 &lt;b&gt;높이&lt;/b&gt;는 클러스터가 포함하고 있는 데이터의 개수를 의미하고, &lt;b&gt;너비&lt;/b&gt;는 클러스터 내 데이터의 정렬된 실루엣 계수를 나타냅니다.(넓을 수록 좋습니다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ePUjSf/btqV09IwN85/DbtNIWIF5nc1rW026GfyzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ePUjSf/btqV09IwN85/DbtNIWIF5nc1rW026GfyzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ePUjSf/btqV09IwN85/DbtNIWIF5nc1rW026GfyzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FePUjSf%2FbtqV09IwN85%2FDbtNIWIF5nc1rW026GfyzK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;빨간색으로 표시된 수직 파선은 해당 클러스터 개수에 따른 실루엣 점수를 나타냅니다. &lt;b&gt;특정 클러스터의 데이터 대부분이 이 점수보다 낮은 계수를 가지면(파선의 왼쪽에 있다면) 나쁜 클러스터입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 그림의 경우 $k = 4$와 $k=5$일 때 클러스터가 상당히 좋아보이는데, 특히 $k = 5$일 때, 모든 클러스터의 크기가 비슷하기 때문에 이것을 선택하는게 좀 더 좋습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9.1.2 K-Means의 한계&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;K-Means 알고리즘는 몇 가지 단점이 있습니다.&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;&amp;nbsp;위 단점들 중 세 번째에 대해 좀 더 살펴보겠습니다. 다음 그림은 크기, 밀집도, 방향이 다른 세 개의 타원형 클러스터를 가진 데이터에 대해 K-Means를 적용한 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NL9k4/btqV2aNY5lD/NBkKgZqy9KltOtUKQbCrbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NL9k4/btqV2aNY5lD/NBkKgZqy9KltOtUKQbCrbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NL9k4/btqV2aNY5lD/NBkKgZqy9KltOtUKQbCrbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNL9k4%2FbtqV2aNY5lD%2FNBkKgZqy9KltOtUKQbCrbk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 보다시피 둘 다 좋은 솔루션은 아닙니다. 즉 우리는 데이터의 형태에 따라 K-Means가 아닌 다른 알고리즘들도 고려해야할 시점이 온 것입니다. 이 경우 잘 작동하는 것은 &lt;b&gt;가우시안 혼합 모델(&lt;span style=&quot;color: #000000;&quot;&gt;Gaussian Mixture Model&lt;/span&gt;)&lt;/b&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&gt;k-Means에선 input feature의 스케일을 맞추는 것이 중요합니다. 그렇지 않는다면 클러스터가 길쭉해지고, 좋지 않은 결과를 유발할 수 있습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9.1.3 클러스터링을 활용한 Image Segmentation&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;714&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u69rc/btqV0EB2Il2/7dknkMuGvuKB9zhKPLNLP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u69rc/btqV0EB2Il2/7dknkMuGvuKB9zhKPLNLP1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u69rc/btqV0EB2Il2/7dknkMuGvuKB9zhKPLNLP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu69rc%2FbtqV0EB2Il2%2F7dknkMuGvuKB9zhKPLNLP1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;714&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;Image Segmentation&lt;/b&gt;은 이미지를 여러 Segment로 분할하는 작업입니다. 여기서 말하는 Segment란 사람, 자동차 등의 Object입니다. 이러한 Segmentation에서 최고 수준의 성능을 내려면 Neural network를 사용해야하는데, 여기선 훨씬 쉬운 작업인 &lt;b&gt;Color Segmentation&lt;/b&gt;을 수행해보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 이미지를 읽어옵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612741309229&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;images_path = os.path.join(PROJECT_ROOT_DIR, &quot;images&quot;, &quot;unsupervised_learning&quot;)
os.makedirs(images_path, exist_ok=True)
DOWNLOAD_ROOT = &quot;https://raw.githubusercontent.com/rickiepark/handson-ml2/master/&quot;
filename = &quot;ladybug.png&quot;
print(&quot;Downloading&quot;, filename)
url = DOWNLOAD_ROOT + &quot;images/unsupervised_learning/&quot; + filename
urllib.request.urlretrieve(url, os.path.join(images_path, filename))

from matplotlib.image import imread
image = imread(os.path.join(images_path, filename))
image.shape&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이미지는 3차원 배열로 표현됩니다(height, width, number of color channel). 이 경우엔 RGB로 표현된 3차원 벡터가 color channel입니다. 다만 흑백 이미지의 경우는 채널이 하나이고 투명도를 조절하는 경우 사용하는 알파 채널의 경우는 훨씬 더 많은 채널을 가집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 color channel은 RGB 색상의 긴 리스트로 변환 다음 K-Means를 사용해 각각의 색상을 클러스터로 모읍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612741782007&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X = image.reshape(-1, 3)
kmeans = KMeans(n_clusters=8, random_state=42).fit(X)
segmented_img = kmeans.cluster_centers_[kmeans.labels_]
segmented_img = segmented_img.reshape(image.shape)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;예를 들어 모든 초록색을 하나의 컬러 클러스터로 만들 수 있습니다. 그 후 해당 클러스터의 평균 컬러를 찾고, 모든 초록색을 해당 평균 컬러로 바꿀 수도 있습니다. 그 후 이 긴 Color 리스트를 원본 이미지와 동일한 크기로 바꿉니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그 결과는 다음과 같습니다. 8개보다 클러스터 개수를 작게 하면 무당벌레의 화려한 빨간색이 독자적인 클러스터를 만들지 못하고 주위 색에 합쳐집니다. 나눌 수 있는 클러스터의 개수가 적어진다는 건 표현할 수 있는 색깔의 종류도 줄어든다는 의미이기 때문입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nNPwg/btqV07460Ga/WNYk8sMpGqKjtAy2JKqxMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nNPwg/btqV07460Ga/WNYk8sMpGqKjtAy2JKqxMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nNPwg/btqV07460Ga/WNYk8sMpGqKjtAy2JKqxMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnNPwg%2FbtqV07460Ga%2FWNYk8sMpGqKjtAy2JKqxMk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9.1.4 클러스터링을 사용한 전처리&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;클러스터링은 &lt;b&gt;Supervised Learning을 위한 전처리 단계&lt;/b&gt;로 사용할 수 있습니다. 차원 축소에 클러스터링을 사용하는 예시를 위해 MNIST 데이터셋을 다뤄보겠습니다. 우선 데이터를 받아옵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742208351&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.datasets import load_digits

X_digits, y_digits = load_digits(return_X_y=True)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이를 Training과 Test set으로 나눕니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742235965&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import train_test_split


X_train, X_test, y_train, y_test = train_test_split(X_digits, y_digits, random_state=42)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그 후 Logistic Regression 모델을 훈련합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742372029&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import LogisticRegression

log_reg = LogisticRegression(multi_class=&quot;ovr&quot;, solver=&quot;lbfgs&quot;, max_iter=5000, random_state=42)
log_reg.fit(X_train, y_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Test set에서 정확도를 평가해보겠습니다. 우선 별도의 전처리 없이 $96.9%$ 정확도를 얻었습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742404120&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;log_reg.score(X_test, y_test)
&amp;gt;&amp;gt;
0.9688888888888889&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; 이제 K-Means를 전처리로 사용하여 성능이 더 좋아지는지 확인해보겠습니다. 우선 Training set을 50개의 클러스터로 나누고, 이미지를 50개 클러스터까지 거리로 바꿉니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742565984&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.pipeline import Pipeline


pipeline = Pipeline([
    (&quot;kmeans&quot;, KMeans(n_clusters=50, random_state=42)),
    (&quot;log_reg&quot;, LogisticRegression(multi_class=&quot;ovr&quot;, solver=&quot;lbfgs&quot;, max_iter=5000, random_state=42)),
])
pipeline.fit(X_train, y_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;정확도도 상당히 개선된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742620441&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pipeline.score(X_test, y_test)
&amp;gt;&amp;gt;
0.98&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;클러스터링은 데이터셋의 Dimension을 64에서 50으로 감소시켰지만, &lt;b&gt;성능이 향상된 이유는 원본보다 변환된 데이터셋이 더 잘 구분할 수 있기 때문입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이번엔 &lt;b&gt;GridSearchCV&lt;/b&gt;를 사용해 최적의 클러스터 개수를 찾은 후 다시 적용해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742864447&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import GridSearchCV

param_grid = dict(kmeans__n_clusters=range(2, 100))
grid_clf = GridSearchCV(pipeline, param_grid, cv=3, verbose=2)
grid_clf.fit(X_train, y_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 최선의 $k$값과 파이프라인의 성능을 확인해보겠습니다. $k = 99$일 때 정확도가 크게 향상되고, Test set에서 98.22%를 달성했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612742910002&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;grid_clf.best_params_
&amp;gt;&amp;gt;
{'kmeans__n_clusters': 57}


grid_clf.score(X_test, y_test)
&amp;gt;&amp;gt;
0.98&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9.1.5 클러스터링을 사용한 Semi-Supervised Learning&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;준지도학습(&lt;span style=&quot;color: #333333;&quot;&gt;Semi-Supervised Learning&lt;/span&gt;)&lt;/b&gt;은 레이블이 없는 데이터가 많고, 레이블이 있는 데이터는 적을 때 사용합니다. MNIST 데이터셋에서 레이블된 50개의 데이터에 50개 데이터에 Logistic Regression을 훈련시켜보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612743642416&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n_labeled = 50
log_reg = LogisticRegression(multi_class=&quot;ovr&quot;, solver=&quot;lbfgs&quot;, random_state=42)
log_reg.fit(X_train[:n_labeled], y_train[:n_labeled])
log_reg.score(X_test, y_test)

&amp;gt;&amp;gt;
0.8333333333333334&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;겨우 83.3%의 정확도입니다. 전체 데이터셋이 아닌 일부만 사용했기에 나온 당연한 결과입니다. 이제 이를 개선해보겠습니다. 우선 Training set을 50개의 클러스터로 모은 후, 각 클러스터에서 센트로이드에 가장 가까운 이미지를 찾습니다. 우리는 이를 &lt;b&gt;대표 이미지&lt;/b&gt;라고 부르겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612743715421&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;k = 50
kmeans = KMeans(n_clusters=k, random_state=42)
X_digits_dist = kmeans.fit_transform(X_train)
representative_digit_idx = np.argmin(X_digits_dist, axis=0)
X_representative_digits = X_train[representative_digit_idx]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음이 바로 50개의 대표 이미지들입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6s3lE/btqWn2grt24/2rIp8YvSKinhgbmsHXEZvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6s3lE/btqWn2grt24/2rIp8YvSKinhgbmsHXEZvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6s3lE/btqWn2grt24/2rIp8YvSKinhgbmsHXEZvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6s3lE%2FbtqWn2grt24%2F2rIp8YvSKinhgbmsHXEZvK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이미지를 보고 &lt;b&gt;수동으로&lt;/b&gt; 레이블을 할당해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612743753198&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_representative_digits = np.array([
    0, 1, 3, 2, 7, 6, 4, 6, 9, 5,
    1, 2, 9, 5, 2, 7, 8, 1, 8, 6,
    3, 1, 5, 4, 5, 4, 0, 3, 2, 6,
    1, 7, 7, 9, 1, 8, 6, 5, 4, 8,
    5, 3, 3, 6, 7, 9, 7, 8, 4, 9])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 레이블된 50개의 또다른 데이터셋이 준비되었습니다. 다만 무작위가 아니라 &lt;b&gt;각 클러스터들을 대표하는 이미지&lt;/b&gt;입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612743796125&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;log_reg = LogisticRegression(multi_class=&quot;ovr&quot;, solver=&quot;lbfgs&quot;, max_iter=5000, random_state=42)
log_reg.fit(X_representative_digits, y_representative_digits)
log_reg.score(X_test, y_test)
&amp;gt;&amp;gt;
0.9244444444444444&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;성능은 분명 좋아졌습니다. 문제는 각 클러스터 내 데이터들은 해당 클러스터의 대표 이미지의 레이블이 부여되어있습니다. 이렇게 되면 &lt;b&gt;클러스터 경계에 가깝게 위치한 데이터가 포함되어 있고, 잘못 레이블이 부여되어있을 확률이 농후합니다. &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;따라서 모든 데이터가 아닌 각 클러스터에서 &lt;b&gt;센트로이드에 가까운 20%의 데이터&lt;/b&gt;에만 대표 이미지의 레이블을 부여해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612744053567&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;percentile_closest = 20

X_cluster_dist = X_digits_dist[np.arange(len(X_train)), kmeans.labels_]
for i in range(k):
    in_cluster = (kmeans.labels_ == i)
    cluster_dist = X_cluster_dist[in_cluster]
    cutoff_distance = np.percentile(cluster_dist, percentile_closest)
    above_cutoff = (X_cluster_dist &amp;gt; cutoff_distance)
    X_cluster_dist[in_cluster &amp;amp; above_cutoff] = -1
    
partially_propagated = (X_cluster_dist != -1)
X_train_partially_propagated = X_train[partially_propagated]
y_train_partially_propagated = y_train_propagated[partially_propagated]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 이 데이터셋을 모델에 훈련시켜보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612744087358&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;log_reg = LogisticRegression(multi_class=&quot;ovr&quot;, solver=&quot;lbfgs&quot;, max_iter=5000, random_state=42)
log_reg.fit(X_train_partially_propagated, y_train_partially_propagated)
log_reg.score(X_test, y_test)

&amp;gt;&amp;gt;
0.9222222222222223&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;레이블된 데이터 50개만으로 92%의 정확도를 얻었습니다. 이는 그만큼 잘 레이블된 데이터를 사용했기 때문입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9.1.6 DBSCAN&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이 알고리즘은 모여있는 연속된 작은 지역들을 하나의 클러스터로 묶습니다. 작동 방식은 다음과 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선 알고리즘이 각 데이터마다 매우 작은 거리인 $\varepsilon$ 내에 몇개의 다른 데이터가 함께 있는지 셉니다. 이 지역을 데이터의 핵심 샘플($\varepsilon$-neighborhood)라고 부릅니다. (입실론은 보통 매우 작은 수를 말하므로 neighborhood라는건 데이터들끼리 매우 가까이 있다는 뜻입니다.)&lt;/li&gt;
&lt;li&gt;(자기 자신을 포함해) 핵심 샘플 내에 적어도 min_samples개 데이터가 있다면 neighborhood라 칭하는 이 밀집된 지역을 Core-instance로 간주합니다.&lt;/li&gt;
&lt;li&gt;이렇게 전체 데이터셋에 핵심 샘플들을 파악했으면, 이젠 데이터가 아닌 핵심 샘플끼리 $varepsilon$ 내에 위치한다면 서로 이웃으로 판단하여 하나의 클러스터를 형성합니다.&lt;/li&gt;
&lt;li&gt;이렇게 데이터가 모여 핵심 샘플이 되고, 핵심 샘플이 모여 하나의 클러스터를 형성합니다. 그런데 핵심 샘플에도, neighborhood도 아닌 데이터는 이상치(Anomally data)로 판단합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;이 알고리즘은 각 클러스터가 충분히 밀집되어 있고, 이것이 밀집되어있지 않은 지역과 잘 구분될 때 사용하면 좋습니다. 다음은 반달 모양 데이터셋에 sklearn의 DBSCAN을 적용한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612767290089&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN

X, y = make_moons(n_samples=1000, noise=0.05, random_state=42)
dbscan = DBSCAN(eps=0.05, min_samples=5)
dbscan.fit(X)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;모든 데이터의 레이블은 &lt;b&gt;labels_&lt;/b&gt; 변수에 저장되어 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612767332995&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dbscan.labels_[:10]
&amp;gt;&amp;gt;
array([ 0,  2, -1, -1,  1,  0,  0,  0,  2,  5])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;데이터의 레이블이 $-1$이란 것은 이상치라는 뜻입니다. 핵심 샘플의 인덱스는 &lt;b&gt;core_sample_indices&lt;/b&gt;에서 확인할 수 있으며, 핵심 샘플 자체는 &lt;b&gt;components_&lt;/b&gt;에 저장되어 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612767434754&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;len(dbscan.core_sample_indices_)
&amp;gt;&amp;gt; 
808

dbscan.core_sample_indices_[:10]
&amp;gt;&amp;gt;
array([ 0,  4,  5,  6,  7,  8, 10, 11, 12, 13])

dbscan.components_[:3]
&amp;gt;&amp;gt;
array([[-0.02137124,  0.40618608],
       [-0.84192557,  0.53058695],
       [ 0.58930337, -0.32137599]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음 클러스터링 결과입니다. 왼쪽의 경우 클러스터를 7개 만들었고, 많은 데이터를 이상치로 판단했습니다. $X$는 이상치를 의미하는데 상당히 많습니다. 그러나 &lt;b&gt;eps = 0.2&lt;/b&gt;로 설정하여 데이터의 neighborhood 범위를 넓히면 오른쪽처럼 완벽한 클러스터링을 얻습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FzwHE/btqWsHwSBBG/VWZPKAxLgH4kvU7itdFBHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FzwHE/btqWsHwSBBG/VWZPKAxLgH4kvU7itdFBHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FzwHE/btqWsHwSBBG/VWZPKAxLgH4kvU7itdFBHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFzwHE%2FbtqWsHwSBBG%2FVWZPKAxLgH4kvU7itdFBHk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;한 가지 유의할 점이 있습니다. DBSCAN 클래스는 predict() 메서드가 아닌 &lt;b&gt;fit_predict()&lt;/b&gt; 메서드를 제공합니다. 즉 이 알고리즘은 새로운 데이터에 대한 클러스터를 예측할 수 없습니다. 이러한 일은 다른 알고리즘이 더 잘 수행할 수 있기 때문입니다. 그러므로 별도의 예측기를 정의해야합니다. 여기선 &lt;b&gt;KNeiborsClassifier&lt;/b&gt;를 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612768585598&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.neighbors import KNeighborsClassifier


knn = KNeighborsClassifier(n_neighbors=50)
knn.fit(dbscan.components_, dbscan.labels_[dbscan.core_sample_indices_])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 데이터 몇개를 전달하여 어떤 클러스터에 속할 가능성이 높은지 예측하고 각 클러스터에 대한 확률을 추정해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612768674706&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X_new = np.array([[-0.5, 0], [0, 0.5], [1, -0.1], [2, 1]])
knn.predict(X_new)
&amp;gt;&amp;gt;
array([1, 0, 1, 0])

knn.predict_proba(X_new)
&amp;gt;&amp;gt;
array([[0.18, 0.82],
       [1.  , 0.  ],
       [0.12, 0.88],
       [1.  , 0.  ]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;위 Classifier는 핵심 샘플만 훈련했지만, 모든 데이터 혹은 이상치를 제외한 데이터만을 훈련시킬 수도 있습니다. 다음은 이상치를 제외한 데이터를 훈련시켜 만든 결정 경계입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2rIjR/btqV8HdLNd1/vkJKjhqnWpjRQJOlB70ZYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2rIjR/btqV8HdLNd1/vkJKjhqnWpjRQJOlB70ZYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2rIjR/btqV8HdLNd1/vkJKjhqnWpjRQJOlB70ZYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2rIjR%2FbtqV8HdLNd1%2FvkJKjhqnWpjRQJOlB70ZYK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이상치가 없기 때문에 Classifier는 무조건 하나의 클러스터를 선택합니다. &lt;b&gt;knn.kneighbors()&lt;/b&gt; 메서드에 데이터를 전달하면 가장 가까운 k개 이웃의 거리와 인덱스를 반환합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612768966060&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_dist, y_pred_idx = knn.kneighbors(X_new, n_neighbors=1)
y_pred = dbscan.labels_[dbscan.core_sample_indices_][y_pred_idx]
y_pred[y_dist &amp;gt; 0.2] = -1
y_pred.ravel()
&amp;gt;&amp;gt;
array([-1,  0,  1, -1])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;DBSCAN은 매우 간단하고 강력합니다. 또한 클러스터의 모양이나 개수에 상관없이 감지할 수 있는 능력이 있으며 이상치에 안정적이고 하이퍼파라미터도 적습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 클러스터 간 밀집도가 크게 다르면 모든 클러스터를 올바르게 잡아내는 것이 불가능합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;다음 시간에는 이어서 Gaussian mixture model에 대해서 알아보겠습니다. 긴 글 읽어주셔서 감사합니다. 행복한 하루 보내세요 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>k-means</category>
      <category>PYTHON</category>
      <category>pytorch</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>가우시안</category>
      <category>군집</category>
      <category>인공지능</category>
      <category>클러스터</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/62</guid>
      <comments>https://box-world.tistory.com/62#entry62comment</comments>
      <pubDate>Mon, 8 Feb 2021 16:37:02 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈 온 머신러닝 2 ] 차원 축소란? (Dimension Reduction)</title>
      <link>https://box-world.tistory.com/61</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;사람은 어려움 속에서 성장한다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;- 제임스 캐시 페니 (J.C 페니 백화점 창립자) -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시작하며&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;특성(feature)은 얼핏 보면 데이터의 다양한 측면을 보여주기 때문에 많을 수록 좋은 것 같습니다. 실제로 우리가 마주하는 머신러닝 문제에서는 Training set의 feature가 수백만 개까지 가지고 있는 경우가 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 이런 많은 특성은 훈련을 느리게 하기도 하고, 때론 좋은 솔루션을 찾는데 방해하기도 합니다. 우리는 이를 &lt;b&gt;차원의 저주(curse of dimensionality)&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.1 차원의 저주&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drGHoh/btqVSu7nT1W/OvEULafM3kC7p3gzbfnQ81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drGHoh/btqVSu7nT1W/OvEULafM3kC7p3gzbfnQ81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drGHoh/btqVSu7nT1W/OvEULafM3kC7p3gzbfnQ81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrGHoh%2FbtqVSu7nT1W%2FOvEULafM3kC7p3gzbfnQ81%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우리가 살고 있는 세계는 3차원으로, 4차원 이상으로만 가도 직관적으로 상상하기 어렵습니다. 게다가 &lt;b&gt;고차원&lt;/b&gt; 공간에선 우리의 상식과 다르게 작동하는 것들이 많습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 &lt;b&gt;1*1 사각형(2차원)&lt;/b&gt;이 있을 때, 이 안에 있는 임의의 점을 선택할 건데 이 점이 사각형의 경계선과 0.001 이내로 가까울 확률은 &lt;b&gt;0.4%&lt;/b&gt;밖에 되지 않습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그런데 만약에 &lt;b&gt;10000차원&lt;/b&gt;의 단위 면적을 가지는 초입방체에서는 이러한 가능성이 &lt;b&gt;99.99999%&lt;/b&gt;로 커집니다.&amp;nbsp; 간단하게 생각해보면 차원이 하나 늘어날 때마다 뭔가 경계선들이 늘어나니까 10000차원으로 가면 경계선들이 엄청나게 많기 때문에 어떤 점을 선택하든 경계선과 매우 가까울 확률이 높은 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;또 다른 예시로 &lt;b&gt;2차원 단위 면적&lt;/b&gt;에서 임의의 두 점을 선택했을 때 두 점 사이의 거리는 평균적으로 &lt;b&gt;0.52&lt;/b&gt;인데, &lt;b&gt;1000000차원&lt;/b&gt;에서는 이것이 &lt;b&gt;408.25&lt;/b&gt;까지 늘어납니다. 고차원은 훨씬 더 많은 공간을 가지고 있기 때문에 그럴거라는 짐작은 들지만 역시나 직관적이진 않습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;어쨌든 이로 인해 &lt;b&gt;고차원의 데이터셋은 보통 데이터들끼리 멀리 떨어져 가능성이 높다는 걸 유추해볼 수 있습니다.&lt;/b&gt; 이러한 경우 예측을 위한 훨씬 더 많은 외삽(extrapolation : 관찰이 어려운 데이터에 대해 추측하는 것)을 요구하기 때문에 불안정해집니다. 우리는 보통 이것을 고차원일수록 Overfitting 위험이 크다고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이를 해결하기 위한 이론적인 해결법은 &lt;b&gt;고차원에서도 데이터 끼리의 거리가 가까울 수 있도록 즉 밀도가 높아질 때까지 dataset의 크기를 키우는 것입니다.&lt;/b&gt; 그러나 일정한 밀도에 도달하기까지 필요한 데이터 수는 차원 수가 커짐에 따라 기하급수적으로 늘어나기 때문에 현실적으로 어렵습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.2 차원 축소를 위한 접근 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Dimension Reduction 알고리즘을 이해하기 위해서는 &lt;b&gt;투영(projection)&lt;/b&gt;과 &lt;b&gt;매니폴드 학습&lt;/b&gt; 두가지 접근법을 이해해야 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8.2.1 투영&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;대부분 우리가 마주할 dataset은 모든 차원에 대해 균일하게 퍼져있지 않습니다. 즉 &lt;b&gt;많은 feature들 중 특정 feature들끼리 강한 연관을 가지는 경우가 많습니다.&lt;/b&gt; 즉 &lt;b&gt;모든 data들이 고차원 공간 안에서(많은 feature들이 있지만) 저차원 subspace에 놓여있습니다(특정 feature들끼리 강한 연관을 가지는 경우가 많다).&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DALcI/btqVTGzCmTE/O5aPKwBBKGzrUsZaxPW9dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DALcI/btqVTGzCmTE/O5aPKwBBKGzrUsZaxPW9dK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DALcI/btqVTGzCmTE/O5aPKwBBKGzrUsZaxPW9dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDALcI%2FbtqVTGzCmTE%2FO5aPKwBBKGzrUsZaxPW9dK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 위와같은 3차원 데이터셋을 살펴보겠습니다. 보시다시피 모든 data들이 거의 &lt;b&gt;평면&lt;/b&gt; 형태로 놓여있는데 이것이 바로 &lt;b&gt;3차원 공간에 있는 저차원(2차원) subspace&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;여기서 모든 data를 2차원 subspace에 투영하면 다음과 같은 2차원 데이터셋을 얻었는데, 이것으로 우린 데이터셋의 차원을 3에서 2차원으로 줄였다고 할 수 있습니다. 그리고 이에 따라 데이터는 새로운 feature인 $z_1$과 $z_2$에 대응됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GTccc/btqVV3H7wsq/V0tnZrD2ccvbkKeW2JbmUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GTccc/btqVV3H7wsq/V0tnZrD2ccvbkKeW2JbmUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GTccc/btqVV3H7wsq/V0tnZrD2ccvbkKeW2JbmUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGTccc%2FbtqVV3H7wsq%2FV0tnZrD2ccvbkKeW2JbmUk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 다음 그림에서 표현된 &lt;b&gt;스위스 롤 데이터셋&lt;/b&gt;에선 투영이 그다지 좋은 방법은 아닙니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBrimb/btqVZSsLQDR/cvWNJvWKjJN6WoCvpuyFy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBrimb/btqVZSsLQDR/cvWNJvWKjJN6WoCvpuyFy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBrimb/btqVZSsLQDR/cvWNJvWKjJN6WoCvpuyFy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBrimb%2FbtqVZSsLQDR%2FcvWNJvWKjJN6WoCvpuyFy0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;만약 이것을 feature $x_3$를 버리고 평면에 투영시키면, 다음 그림의 왼쪽처럼 스위스 롤의 층이 뭉개집니다. 우리가 원하는 것은 오른쪽처럼 &lt;b&gt;스위스 롤을 펼친 형태의 2차원 데이터를 얻고싶은데 말이죠.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDtjsX/btqV198lyDR/5V6Dvrcw6KRNnHytq4bBK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDtjsX/btqV198lyDR/5V6Dvrcw6KRNnHytq4bBK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDtjsX/btqV198lyDR/5V6Dvrcw6KRNnHytq4bBK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDtjsX%2FbtqV198lyDR%2F5V6Dvrcw6KRNnHytq4bBK0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.2.2 매니폴드 학습&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR5Zju/btqVSu0vnHm/n1ZIAqNjUhGUQg0kmpPwJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR5Zju/btqVSu0vnHm/n1ZIAqNjUhGUQg0kmpPwJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR5Zju/btqVSu0vnHm/n1ZIAqNjUhGUQg0kmpPwJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR5Zju%2FbtqVSu0vnHm%2Fn1ZIAqNjUhGUQg0kmpPwJk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;스위스 롤은 2D 매니폴드의 한 가지 예시였습니다.&lt;/b&gt; 즉 스위스 롤을 펴게 되면 평면이기 때문에 3차원에서 휘어지고 뒤틀려있는 스위스 롤은 2D 매니폴드로 보는 것이죠.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 위 데이터 공간에 &lt;b&gt;개미&lt;/b&gt;가 한마리 산다고 하겠습니다. 우리는 이 롤을 그래프 밖에서 보기때문에 점과 점사이 거리를 구할 때 유클리디안 방식으로 구하게 됩니다. 그러나 개미 입장에선 점프할 수 없기 때문에 롤을 따라 바깥으로 도달하여 점과 점 사이의 거리를 구하게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이를 일반화하면 &lt;b&gt;d차원 매니폴드는 개미 입장에서 d차원 초평면으로 보일 수 있는 n차원 공간의 일부입니다.&lt;/b&gt; ($d &amp;lt; n$)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;많은 차원 축소 알고리즘은 이러한 꼬여있는 매니폴드를 풀어헤친 형태를 모델링하는 식으로 작동하는데, 이를 &lt;b&gt;매니폴드 학습(manifold learning)&lt;/b&gt;이라고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;매니폴드 학습이 많이 활용되는 가장 큰 이유는 &lt;b&gt;Classification이나 Regression같은 작업 시 저차원 매니폴드 형태로 데이터를 표현하면 훨씬 더 간단해질거라고 가정하기 때문입니다.&lt;/b&gt; 그러나 다음 그림을 보면 매번 간단해지는 것은 아니라는 걸 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZnIkr/btqV2VB61Vp/7aOYmfpnzgasAIHYYCf2k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZnIkr/btqV2VB61Vp/7aOYmfpnzgasAIHYYCf2k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZnIkr/btqV2VB61Vp/7aOYmfpnzgasAIHYYCf2k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZnIkr%2FbtqV2VB61Vp%2F7aOYmfpnzgasAIHYYCf2k1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.3 PCA&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;주성분 분석(PCA)&lt;/b&gt;는 가장 보편적인 차원 축소 알고리즘 중 하나인데, 데이터의 분포를 최대한 유지하려 하면서 저차원에 투영시킵니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.1 분산 보존&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;저차원의 초평면에 dataset을 투영시키기 위해 가장 중요한 것은 데이터 분포를 유지하는 것 즉 분산을 보존해야합니다.&lt;/b&gt; 예를 들어 다음 그래프는 2차원 데이터셋을 1차원 축에 투영한 결과입니다. 딱 봐도 첫번재 실선이 분산을 가장 잘 보존하고, 세번째 점선이 분산을 매우 적게 보존한다는 걸 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ADJ8g/btqVSvrzaCL/Hfv7FQmKmQxoK4cuN9Cjk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ADJ8g/btqVSvrzaCL/Hfv7FQmKmQxoK4cuN9Cjk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ADJ8g/btqVSvrzaCL/Hfv7FQmKmQxoK4cuN9Cjk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FADJ8g%2FbtqVSvrzaCL%2FHfv7FQmKmQxoK4cuN9Cjk0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;분산이 최대로 보존되는 1차원 축을 선택해야 정보가 가장 적게 손실되기 때문에 합리적인건 당연한데, 이를 다르게 말하면 &lt;b&gt;투영 되기 전 데이터와 투영된 데이터 간 평균 제곱 거리를 최소화하는 축을 선택해야한다는 말과 동일합니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.2 주성분&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;앞으로 남은 PCA에 대해 구체적으로 설명하기 전에 결론적으로 PCA가 하는 작업에 대해 설명 드리겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;주어진 원본 데이터에 대해서 &lt;b&gt;분산을 가장 많이 보존하는 축&lt;/b&gt;부터 찾으면서 임의의 n개의 축을 찾습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내가 투영할 저차원이 d차원이라면 분산을 가장 많이 보존하는 축부터 d개의 축을 선택한 후&lt;/b&gt; 이 축들로 이뤄진 d차원 공간에 원본 데이터를 투영시키면 끝입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p&gt;만약 그림을 통해 이 과정을 쉽게 이해하고 싶다면 다음 포스팅을 참고해주세요.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/33&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Coursera ( Machine Learning )] - [머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1612540163552&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&quot; data-og-description=&quot;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 &amp;nbsp;우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를 바탕으&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/33&quot; data-og-url=&quot;https://box-world.tistory.com/33&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8MocU/hyJaffJmXF/3a3PjIy3oTatf9SyrHSFrk/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/clq2fK/hyJabxCx8y/6lNw5xM0WNesfC54ckgO9K/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/ipT97/hyJbqzVJlF/WW5ZQsgSKp8ddUl2aWATN1/img.png?width=886&amp;amp;height=401&amp;amp;face=0_0_886_401&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/33&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/33&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8MocU/hyJaffJmXF/3a3PjIy3oTatf9SyrHSFrk/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/clq2fK/hyJabxCx8y/6lNw5xM0WNesfC54ckgO9K/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/ipT97/hyJbqzVJlF/WW5ZQsgSKp8ddUl2aWATN1/img.png?width=886&amp;amp;height=401&amp;amp;face=0_0_886_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 &amp;nbsp;우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를 바탕으&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p&gt;&amp;nbsp;다시 돌아와서 방금 PCA는 분산을 가장 많이 보존하는 축부터 n개의 축을 찾는다고 했는데, 이때 이 축들을 &lt;b&gt;주성분(PC : principal componet)&lt;/b&gt;라고 부릅니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;앞에서 본 예시에선 첫번째 실선이 첫번째 PC이고, 두번째 선이 두번째 PC가 됩니다. 그리고 이 두 PC가 만들어낸 평면과 수직한 축이 세번째 PC가 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러면 이렇게 PC는 어떻게 찾을까요? 우리는 &lt;b&gt;SVD(singular value decomposition)&lt;/b&gt;이라는 표준 행렬 분해 기술을 이용합니다. 쉽게 말해서 이것은 행렬 A를 다음과 같이 분해할 수 있는데 이때 분해된 $V^T$를 전치시켜 $V$를 구하면 여기에 우리가 찾고자하는 모든 PC의 단위 벡터가 담겨있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;228&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/As6o1/btqV08Ppt0q/fiROVCH6NqOr8GHEmKOoGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/As6o1/btqV08Ppt0q/fiROVCH6NqOr8GHEmKOoGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/As6o1/btqV08Ppt0q/fiROVCH6NqOr8GHEmKOoGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAs6o1%2FbtqV08Ppt0q%2FfiROVCH6NqOr8GHEmKOoGk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;228&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.3 d차원으로 투영하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;PC를 모두 추출했다면, 이제 처음 d개의 PC로 정의한 초평면에 투영하여 데이터셋의 차원을 d차원으로 축소해야합니다. 이때의 초평면은 데이터의 분산을 최대한 보존하게 투영시킴을 보장합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 앞서 봤던 다음 그림은 데이터의 분포를 잘 유지하면서 투영된 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHw9va/btqVTHef6Xs/VXKmKBcXo2fAhkQKzmjJhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHw9va/btqVTHef6Xs/VXKmKBcXo2fAhkQKzmjJhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHw9va/btqVTHef6Xs/VXKmKBcXo2fAhkQKzmjJhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHw9va%2FbtqVTHef6Xs%2FVXKmKBcXo2fAhkQKzmjJhK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 d차원으로 축소된 데이터셋 $X^{d-proj}$을 얻고 싶다면 다음 식과 같이 기존 데이터로 이뤄진 행렬 $X$와 분산을 가장 높게 보존하는 d개의 PC의 단위벡터를 가지는 $W_d$를 행렬곱하여 얻을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;232&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFR7oB/btqV0DPD4Tz/ulzGKEYJ6ywMU5eslu5u00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFR7oB/btqV0DPD4Tz/ulzGKEYJ6ywMU5eslu5u00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFR7oB/btqV0DPD4Tz/ulzGKEYJ6ywMU5eslu5u00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFR7oB%2FbtqV0DPD4Tz%2FulzGKEYJ6ywMU5eslu5u00%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;232&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 sklearn에서 PCA를 적용하여 데이터셋을 2차원으로 줄이는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612541103610&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.decomposition import PCA

pca = PCA(n_components = 2)
X2D = pca.fit_transform(X)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.5 &lt;span style=&quot;color: #333333;&quot;&gt;expained_variance_ratio_ 변수&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;expained_variance_ratio_&lt;/b&gt; 변수에는 원본 데이터셋에 대해 &lt;b&gt;PC가 보존하는 분산의 비율&lt;/b&gt;이 들어있습니다. 다음은 가장 높게 보존하는 순으로 두가지 PC의 &lt;span style=&quot;color: #333333;&quot;&gt;expained_variance_ratio_&lt;span&gt; 를 살펴보는 코드입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1612541208551&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pca.explained_variance_ratio_

&amp;gt;&amp;gt;
array([0.84248607, 0.14631839])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이것은 데이터셋 분산의 84.2%가 첫번째 PC에 놓이고, 14.6%의 데이터가 두 번째 PC를 따라 놓임을 의미합니다. $100 - (84.2 + 14.6) = 1.2$이므로 3번째 PC부터는 데이터셋 분산의 1.2% 미만의 데이터가 놓일 것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.6 적절한 차원 수 선택하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;축소할 차원 수는 임의로 정하기 보다는 &lt;b&gt;각 PC별로 표현하는 데이터 분산의 합이 충분할 때까지(ex. 95% 이상) 필요한 PC의 개수로 차원 수를 선택하는 것이 좋습니다.&lt;/b&gt; 물론 데이터 시각화를 위해 차원을 축소하는 경우는 보통 2, 3차원을 씁니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음 코드에선 PCA를 계산한 후 원본 데이터셋의 분산을 95%로 유지하는데 필요한 최소한의 PC 개수 즉 차원 수를 계산합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612541488633&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pca = PCA()
pca.fit(X_train)
cumsum = np.cumsum(pca.explained_variance_ratio_)
d = np.argmax(cumsum &amp;gt;= 0.95) + 1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그 후 &lt;b&gt;n_components&lt;/b&gt;를 설정하여 PCA를 다시 실행하는 인자로 &lt;b&gt;보존할 분산의 비율&lt;/b&gt;을 넣어주면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612543382902&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pca = PCA(n_components=0.95)
X_reduced = pca.fit_transform(X_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;두 번째 방법은 보존되는 분산의 비율을 차원 수에 대한 함수로 그리는 것입니다. 이 그래프에는 보존되는 분산의 비율이 빠르게 성장하다 멈추는 &lt;b&gt;변곡점&lt;/b&gt;이 있는데, 이걸로 축소할 차원 수를 결정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddG1cg/btqVV3VFeDK/Gzdxn1ASnIb0ibgtfiXkPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddG1cg/btqVV3VFeDK/Gzdxn1ASnIb0ibgtfiXkPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddG1cg/btqVV3VFeDK/Gzdxn1ASnIb0ibgtfiXkPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddG1cg%2FbtqVV3VFeDK%2FGzdxn1ASnIb0ibgtfiXkPK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.7 압축을 위한 PCA&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;앞서 봤듯이 &lt;b&gt;차원 축소는 dataset의 크기를 줄입니다.&lt;/b&gt; 이러한 압축은 SVM과 같은 Classification 알고리즘의 속도를 크게 높입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;반대로 &lt;b&gt;압축된 데이터셋에 PCA 투영의 변환을 반대로 적용하여 다시 원래의 차원으로 되돌릴 수 있습니다.&lt;/b&gt; 다만 축소에서 일부 정보를 잃어버렸기 때문에 완벽한 원본 데이터셋을 얻을 순 없지만 매우 비슷합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;원본 데이터와 축소 후 다시 복원된 데이터 사이의 평균 제곱 거리를 &lt;b&gt;재구성 오차(reconstruction error)&lt;/b&gt;라고 합니다. 다음은 차원 축소 후 다시 복원하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612543727585&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pca = PCA(n_components = 154)
X_reduced = pca.fit_transform(X_train)
X_recovered = pca.inverse_transform(X_reduced)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음은 MNIST 데이터셋에 대하여 원본 데이터셋과 압축 후 복원된 결과를 비교한 그림입니다. 이미지의 품질이 손상되긴 했지만 숫자의 모양은 온전한 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBtDtz/btqVV3uDeqp/GClc5hWhrgK6rNMxUzBxuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBtDtz/btqVV3uDeqp/GClc5hWhrgK6rNMxUzBxuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBtDtz/btqVV3uDeqp/GClc5hWhrgK6rNMxUzBxuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBtDtz%2FbtqVV3uDeqp%2FGClc5hWhrgK6rNMxUzBxuK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;데이터를 복원하는 공식&lt;/b&gt;은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;221&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cam0IU/btqV0E8TP4M/XQGcJv3yf1hPBQoQbjTrfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cam0IU/btqV0E8TP4M/XQGcJv3yf1hPBQoQbjTrfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cam0IU/btqV0E8TP4M/XQGcJv3yf1hPBQoQbjTrfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcam0IU%2FbtqV0E8TP4M%2FXQGcJv3yf1hPBQoQbjTrfK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;221&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.8 랜덤 PCA&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;svd_solver = &quot;randomized&quot;&lt;/b&gt;로 지정하면 sklearn은 &lt;b&gt;랜덤 PCA&lt;/b&gt;라는 확률적 알고리즘을 이용하여 &lt;b&gt;축소할 d차원에 대한 d개의 PC를 '근삿값'으로 빠르게 찾습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1612543909537&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rnd_pca = PCA(n_components=154, svd_solver=&quot;randomized&quot;, random_state=42)
X_reduced = rnd_pca.fit_transform(X_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;svd_solver&lt;/b&gt;의 기본값은 &lt;b&gt;&quot;auto&quot;&lt;/b&gt;인데, 원본 데이터의 크기나 차원 수가 500보다 크고, 축소할 차원이 이것들의 80%보다 작으면 sklearn은 자동으로 랜덤 PCA 알고리즘을 사용합니다. 만약 이것을 방지하고 싶다면 &lt;b&gt;&quot;full&quot;&lt;/b&gt;을 사용하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.3.9 점진적 PCA&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;PCA 구현의 문제는 SVD 알고리즘 실행을 위해 전체 데이터셋을 메모리에 올려야 한다는 점입니다. &lt;b&gt;점진적 PCA(IPCA : incremental PCA)는 dataset을 mini-batch로 나눈 뒤 하나 씩 주입하여 적용하여 이를 보완합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음 코드는 MNIST 데이터셋을 100개의 mini-batch로 나눠 차원을 축소하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612544128423&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.decomposition import IncrementalPCA

n_batches = 100
inc_pca = IncrementalPCA(n_components=154)
for X_batch in np.array_split(X_train, n_batches):
    print(&quot;.&quot;, end=&quot;&quot;) # 책에는 없음
    inc_pca.partial_fit(X_batch)

X_reduced = inc_pca.transform(X_train)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.4 커널 PCA&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이전 포스팅에서 고차원 공간을 암묵적으로 매핑하여 SVM의 Classification과 Regression을 가능하게 하는 수학적 기법인 &lt;b&gt;커널 트릭&lt;/b&gt;에 대해 이야기했습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/58&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Hands-On Machine Learning 2판] - [ 핸즈온 머신러닝 2판 ] SVM이란?&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1612544411592&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈온 머신러닝 2판 ] SVM이란?&quot; data-og-description=&quot;인내는 어떤 실력보다 강하다 - 벤 호건 (프로 골퍼) - 시작하며 &amp;nbsp;SVM은 Classification, Regression 등 다양한 곳에서 활용됩니다. 특히 복잡한 데이터셋을 학습하기에 용이하다는 점도 SVM의 인기를 높이&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/58&quot; data-og-url=&quot;https://box-world.tistory.com/58&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/VNCGC/hyJbmdfiMC/V3lhcYHz9XJb1NQ20RL0RK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/l652g/hyJbrMo1qL/KWFVFRq3cLWe9lhVRxLEk0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/sMcda/hyJajoTZGW/ViXZbrRy86SyJI8neSfp80/img.png?width=748&amp;amp;height=496&amp;amp;face=0_0_748_496&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/58&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/58&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/VNCGC/hyJbmdfiMC/V3lhcYHz9XJb1NQ20RL0RK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/l652g/hyJbrMo1qL/KWFVFRq3cLWe9lhVRxLEk0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/sMcda/hyJajoTZGW/ViXZbrRy86SyJI8neSfp80/img.png?width=748&amp;amp;height=496&amp;amp;face=0_0_748_496');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈온 머신러닝 2판 ] SVM이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;인내는 어떤 실력보다 강하다 - 벤 호건 (프로 골퍼) - 시작하며 &amp;nbsp;SVM은 Classification, Regression 등 다양한 곳에서 활용됩니다. 특히 복잡한 데이터셋을 학습하기에 용이하다는 점도 SVM의 인기를 높이&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;우리는 같은 기법을 PCA에 적용하여 차원 축소를 위한 복잡한 비선형 투영을 할 수 있고 이를 &lt;b&gt;커널 PCA(kPCA)&lt;/b&gt;라고 부릅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612544653843&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.decomposition import KernelPCA

rbf_pca = KernelPCA(n_components = 2, kernel=&quot;rbf&quot;, gamma=0.04)
X_reduced = rbf_pca.fit_transform(X)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음은 서로 다른 커널을 사용하여 2차원으로 축소시킨 스위스 롤의 모습입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/42zGo/btqV2a7lloQ/hxakKKENzrxhLadLXnCEv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/42zGo/btqV2a7lloQ/hxakKKENzrxhLadLXnCEv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/42zGo/btqV2a7lloQ/hxakKKENzrxhLadLXnCEv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F42zGo%2FbtqV2a7lloQ%2FhxakKKENzrxhLadLXnCEv0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8.4.1 커널 선택과 하이퍼파라미터 튜닝&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;kPCA는 Unsupervised Learning&lt;/b&gt;이므로 어떤 커널과 하이퍼파라미터를 선택해야 좋은 성능을 내는지 명확하게 알 수 있는 기준이 없습니다. 그러나 &lt;b&gt;그리드 탐색&lt;/b&gt;을 이용하면 이를 보완할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음 코드에서는 kPCA를 이용하여 2차원으로 축소하고 Logistic Regression으로 Classification을 진행합니다. 그 다음 가장 높은 accuracy를 얻기 위해 GridSearchCV를사용하여 kPCA에 가장 좋은 커널과 gamma 파라미터를 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612544855246&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline

clf = Pipeline([
        (&quot;kpca&quot;, KernelPCA(n_components=2)),
        (&quot;log_reg&quot;, LogisticRegression(solver=&quot;lbfgs&quot;))
    ])

param_grid = [{
        &quot;kpca__gamma&quot;: np.linspace(0.03, 0.05, 10),
        &quot;kpca__kernel&quot;: [&quot;rbf&quot;, &quot;sigmoid&quot;]
    }]

grid_search = GridSearchCV(clf, param_grid, cv=3)
grid_search.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 이러한 커널과 파라미터는 다음과 같이 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612544895301&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(grid_search.best_params_)

&amp;gt;&amp;gt;
{'kpca__gamma': 0.043333333333333335, 'kpca__kernel': 'rbf'}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;완전한 Unsupervised learning&lt;/b&gt;으로 가장 낮은 &lt;b&gt;재구성 오차&lt;/b&gt;를 만드는 커널과 하이퍼파라미터를 선택하는 방법도 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다만 재구성은 선형 PCA만큼 쉽지 않습니다. 다행히 커널 트릭을 이용하면 이러한 문제를 해결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0ROPv/btqV35qSaKR/2zH9ko46V4Xq81P2Ulbir1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0ROPv/btqV35qSaKR/2zH9ko46V4Xq81P2Ulbir1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0ROPv/btqV35qSaKR/2zH9ko46V4Xq81P2Ulbir1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0ROPv%2FbtqV35qSaKR%2F2zH9ko46V4Xq81P2Ulbir1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;차원 축소된 데이터를 다시 복원하면 이때의 데이터는 &lt;b&gt;원래 차원의 공간이 아닌 위 그림에서 x로 표시된 feature space&lt;/b&gt;에 놓이게 됩니다. 이것은 &lt;b&gt;무한 차원&lt;/b&gt;이기 때문에 재구성 오차 등의 계산이 불가능합니다. 다행히도 재구성된 데이터의 위치와 가깝게 매핑된 원본 공간의 위치는 찾을 수 있는데 이를 &lt;b&gt;재구성 원상(pre-image)&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;원상을 얻으면 원본 데이터와의 제곱 거리를 측정하여 오차를 구할 수 있게 되고 이에 따른 최적의 커널과 하이퍼파라미터를 찾는 것도 가능해집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이쯤되면 재구성을 어떻게 하는지 궁금해지는데요. 한 가지 방법은 축소된 데이터를 훈련 세트로, 원본 데이터를 타깃으로 하여 &lt;b&gt;Supervised learning model training&lt;/b&gt;을 진행하는 것입니다. sklearn에서는 &lt;b&gt;fit_inverse_transform = True&lt;/b&gt;로 지정하면 이를 자동으로 수행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612545636966&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rbf_pca = KernelPCA(n_components = 2, kernel=&quot;rbf&quot;, gamma=0.0433,
                    fit_inverse_transform=True)
X_reduced = rbf_pca.fit_transform(X)
X_preimage = rbf_pca.inverse_transform(X_reduced)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그 후 다음과 같이 &lt;b&gt;pre-image error&lt;/b&gt;를 계산할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612545663363&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import mean_squared_error

mean_squared_error(X, X_preimage)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;8.5 LLE&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;지역 선형 임베딩이라 부르는 &lt;b&gt;LLE(locally linear embedding)&lt;/b&gt;는 강력한 &lt;b&gt;non-linear dimensionally reduction&lt;/b&gt; 기술로 투영이 아닌 매니폴드 학습입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;LLE는 각 data가 가장 가까운 이웃에 얼마나 선형적으로 연관되어 있는지 측정합니다. 그 후 앞서 언급한 &lt;b&gt;개미의 시선으로 바라본 매니폴드가 가장 잘 보존될 원본 데이터의 저차원 표현&lt;/b&gt;을 찾습니다. 이 방법은 Noise가 많지 않다면, 꼬인 매니폴드를 펼치는데 잘 작동합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612545900659&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.manifold import LocallyLinearEmbedding

lle = LocallyLinearEmbedding(n_components=2, n_neighbors=10, random_state=42)
X_reduced = lle.fit_transform(X)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;결과는 다음 그림에서 볼 수 있습니다. 보다시피 스위스 롤이 잘 펴졌고, 샘플 간 거리도 잘 보존되어있는 듯 하지만, 거시적으로 보면 샘플 간 거리가 잘 유지도히지 않습니다. 그렇지만 LLE는 매니폴드를 펼치는데 잘 동작합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lHUov/btqV2WVht2J/N7kvZ1r6PIvWHNBDwlfmZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lHUov/btqV2WVht2J/N7kvZ1r6PIvWHNBDwlfmZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lHUov/btqV2WVht2J/N7kvZ1r6PIvWHNBDwlfmZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlHUov%2FbtqV2WVht2J%2FN7kvZ1r6PIvWHNBDwlfmZk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8.6 기타 차원 축소 알고리즘&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1nG9m/btqV2VPCcok/BBk4JeUIye9DRnVKIGSvEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1nG9m/btqV2VPCcok/BBk4JeUIye9DRnVKIGSvEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1nG9m/btqV2VPCcok/BBk4JeUIye9DRnVKIGSvEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1nG9m%2FbtqV2VPCcok%2FBBk4JeUIye9DRnVKIGSvEK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) 랜덤 투영&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;말 그대로 linear한 투영을 랜덤하게 하여 데이터를 저차원으로 투영합니다. 놀랍게도 이러한 랜덤 투영이 실제 거리를 잘 보존한다는 것이 수학적으로 증명되었습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) 다차원 스케일링(MDS)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;데이터 간 거리를 보존하면서, 차원을 축소합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3) lsomap&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;각 데이터를 가장 가까운 이웃과 연결하는 식으로 그래프를 만듭니다. 그 후 데이터 간 geodesic distance를 유지하면 차원을 축소합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4) t-SNE&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;비슷한 데이터는 가까이, 그렇지 않다면 멀리 떨어지도록 하여 차원을 축소합니다. 주로 고차원 데이터를 시각화할 때 많이 쓰입니다. (ex. MNIST )&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5) 선형 판별 분석(LDA)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;사실 분류 알고리즘입니다. 이것은 학습 시 클래스들을 가장 잘 구분하는 축을 학습하여 이 축으로 데이터가 투영되는 초평면을 정의하는데 사용합니다. 이것의 장점은 투영을 통해 가능한 한 클래스를 멀리 떨어지게 유지 시키므로 SVM과 같은 알고리즘을 적용하기 전 차원을 축소하는데 용이합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음 포스팅에서는 Unsupervised Learning에 대해 다뤄보겠습니다. 긴 글 읽어주셔서 감사합니다. 행복한 하루 보내세요 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>PCA</category>
      <category>PYTHON</category>
      <category>TensorFlow</category>
      <category>데이터 사이언스</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>빅데이터</category>
      <category>인공지능</category>
      <category>차원 축소</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/61</guid>
      <comments>https://box-world.tistory.com/61#entry61comment</comments>
      <pubDate>Sat, 6 Feb 2021 02:56:22 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈 온 머신러닝 2 ] 앙상블 학습과 랜덤 포레스트란?</title>
      <link>https://box-world.tistory.com/60</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;매일 아침 삶의 목표를 생각하며 일어나라&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- 아이제이아 토마스 (NBA 아이닉스 사장 겸 감독) -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시작하며&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;굉장히 복잡한 질문에 대해서 수천명의 사람들에게 대답을 모으는 것과 전문가에게 답을 듣는 것, 둘 중 어떤 것이 더 정확할까요? 대부분 전자가 더 정확하며 우리는 이를 대중의 지혜라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;마찬가지로 머신러닝에서도 적당한 성능의 모델 여러개들로부터 예측을 수집하는 것이 가장 좋은 하나의 모델의 예측보다 더 좋은 결과를 불러옵니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우리는 이러한 학습 방법을 &lt;b&gt;앙상블 학습(Ensemble Learning)&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이번 포스팅은 &lt;b&gt;Decision Tree&lt;/b&gt;의 이해가 바탕이 되어야 합니다. 다음 포스팅을 참고해주세요!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/59&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Hands-On Machine Learning 2판] - [ 핸즈온 머신러닝 2 ] Decision Tree란?&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1612362890096&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈온 머신러닝 2 ] Decision Tree란?&quot; data-og-description=&quot;성공하려면 이미 했던 일을 제대로 활용하라 - 블레이크 로스 (파이어폭스 공동 개발자) - 시작하며 &amp;nbsp;저번 포스팅에서는 SVM에 대해 다뤄보았습니다. 이번 포스팅에서 다룰 Decision Tree은 SVM처럼 Cl&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/59&quot; data-og-url=&quot;https://box-world.tistory.com/59&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bawERU/hyI8UiqwAh/IkMFIo29Shkw7r3c9vkYtk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/c9NLhk/hyI8RTwWC2/GzXMD53wkG93TWsNyXkkv0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/bR7qSu/hyI812VAjC/kuKUyce8d3wq2kY1UmelpK/img.png?width=687&amp;amp;height=367&amp;amp;face=0_0_687_367&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/59&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/59&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bawERU/hyI8UiqwAh/IkMFIo29Shkw7r3c9vkYtk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/c9NLhk/hyI8RTwWC2/GzXMD53wkG93TWsNyXkkv0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/bR7qSu/hyI812VAjC/kuKUyce8d3wq2kY1UmelpK/img.png?width=687&amp;amp;height=367&amp;amp;face=0_0_687_367');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈온 머신러닝 2 ] Decision Tree란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;성공하려면 이미 했던 일을 제대로 활용하라 - 블레이크 로스 (파이어폭스 공동 개발자) - 시작하며 &amp;nbsp;저번 포스팅에서는 SVM에 대해 다뤄보았습니다. 이번 포스팅에서 다룰 Decision Tree은 SVM처럼 Cl&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.1 투표 기반 Classifier&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDHr43/btqVvOSJws0/mqkOrWDPlP7fJPkZTMs23K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDHr43/btqVvOSJws0/mqkOrWDPlP7fJPkZTMs23K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDHr43/btqVvOSJws0/mqkOrWDPlP7fJPkZTMs23K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDHr43%2FbtqVvOSJws0%2FmqkOrWDPlP7fJPkZTMs23K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;여기 Logistic Regression, SVM, Random Forest 등 정확도가 80%인 여러개의 Classifier가 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uH0yz/btqVyVqvkg6/F2fQAiSk7kZk1xWE5kqIzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uH0yz/btqVyVqvkg6/F2fQAiSk7kZk1xWE5kqIzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uH0yz/btqVyVqvkg6/F2fQAiSk7kZk1xWE5kqIzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuH0yz%2FbtqVyVqvkg6%2FF2fQAiSk7kZk1xWE5kqIzk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 앙상블 학습에서는 각 Classifier의 예측을 모아서 &lt;b&gt;가장 많이 선택된 클래스&lt;/b&gt;를 예측합니다. 이렇게 다수결 투표로 정해지는 Classifier를 &lt;b&gt;직접 투표(hard vote) 분류기&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;주목할 점은 이 다수결 투표 Classifier가 앙상블에 포함된 각각의 Classifier들 중 가장 뛰어난 Classifier보다도 정확도가 높은 경우가 많다는 것입니다. 즉 각 Classifier의 성능은 약할지언정, 개수가 충분히 많은 앙상블이라면 성능이 높을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이것이 가능한 이유는 바로 &lt;b&gt;큰수의 법칙&lt;/b&gt; 때문입니다. 예를 들어 앞면이 51%, 뒷면이 49%가 나오는 불균형한 동전이 있다고 가정하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAJe2S/btqVFBLoM85/L3R1pxoWVf8bw5xKoMFbVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAJe2S/btqVFBLoM85/L3R1pxoWVf8bw5xKoMFbVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAJe2S/btqVFBLoM85/L3R1pxoWVf8bw5xKoMFbVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAJe2S%2FbtqVFBLoM85%2FL3R1pxoWVf8bw5xKoMFbVK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;만약 동전을 1000번 던지면 510번은 앞면, 490번은 뒷면이 나올 것인데, 이를 수학적으로 계산하면 1000번을 던질 때 앞면이 다수일 확률은 75%에 가깝다는 것을 확인할 수 있습니다. 게다가 더 많이 던질 수록 앞면이 나올 확률은 증가합니다.(10000번일 경우 97% 이상으로 올라갑니다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이와 비슷하게 51% 정확도를 가진 1000개의 분류기로 앙상블을 구축한고, 여기에서 가장 많이 나온 클래스를 예측으로 삼는다면 75%의 정확도를 기대할 수 있습니다. 물론 &lt;b&gt;이러한 가정은 모든 Classifier가 완벽하게 독립적이고, 오차에 상관관계가 없어야 가능합니다.&lt;/b&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&gt;앙상블 학습은 Classifier가 가능한 서로 독립적일 때 최고의 성능을 발휘합니다. 이를 위해 가장 좋은 방법은 각 Classifier를 서로 다른 알고리즘으로 학습하는 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;다음은 moons 데이터셋에 대해서 여러 Classifier를 조합한 투표 기반 분류기 VotinClassifier에 대한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612359254057&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC

log_clf = LogisticRegression(random_state=42)
rnd_clf = RandomForestClassifier(random_state=42)
svm_clf = SVC(random_state=42)

voting_clf = VotingClassifier(
    estimators=[('lr', log_clf), ('rf', rnd_clf), ('svc', svm_clf)],
    voting='hard')
voting_clf.fit(X_train, y_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;앙상블 내 들어있는 Classifier의 Testset 정확도를 확인해보겠습니다. 예상대로 &lt;b&gt;VotingClassifier가 개별 Classifier보다 성능이 높은걸 확인할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1612359296364&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import accuracy_score

for clf in (log_clf, rnd_clf, svm_clf, voting_clf):
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    print(clf.__class__.__name__, accuracy_score(y_test, y_pred))
    
&amp;gt;&amp;gt;
LogisticRegression 0.864
RandomForestClassifier 0.872
SVC 0.888
VotingClassifier 0.896&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;앙상블 내 모든 Classifier가 클래스의 확률을 예측할 수 있다면&lt;/b&gt;(predict_proba() 메서드가 있다면), 개별 Classifier의 예측을 평균 내어 확률이 가장 높은 클래스를 예측할 수 있는데, 이를 &lt;b&gt;간접 투표(soft voting)&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 방식은 확률 기반이므로 직접 투표(hard voting) 방식보다 성능이 높습니다. 간접 투표 방식을 사용하기 위해선 voting=&quot;hard&quot;를&amp;nbsp; &quot;soft&quot;로 바꿔주면 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;SVC(SVM Classifier)&lt;/b&gt;에서는 클래스 확률을 제공하지 않으므로 probability 매개변수를 True로 지정하면 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.2 Bagging과 Pasting&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;다양한 Classifier를 만드는 한 가지 방법은 각기 다른 Training 알고리즘을 사용하는 것이고, 다른 하나는 같&lt;b&gt;은 알고리즘을 사용하되 Training datset의 subset을 무작위로 구성하여 Classifier마다 다른 데이터로 학습 시키는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2j3Jn/btqVAIqH6Tz/fpOOHn3DvYAE8c2TWLGyaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2j3Jn/btqVAIqH6Tz/fpOOHn3DvYAE8c2TWLGyaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2j3Jn/btqVAIqH6Tz/fpOOHn3DvYAE8c2TWLGyaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2j3Jn%2FbtqVAIqH6Tz%2FfpOOHn3DvYAE8c2TWLGyaK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이때 Training dataset에서 중복을 허용하여 subset을 나눠 학습하는 것을 &lt;b&gt;배깅(Bagging)&lt;/b&gt;, 중복을 허용하지 않는 것을 &lt;b&gt;페이스팅(Pasting)&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다시 말해서 하나의 Training data가 하나의 Classifier를 위해 여러 번 학습에 사용될 수 있는건 Bagging뿐입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Classifier와 같은 모든 예측기가 학습을 마치면, 앙상블은 이들의 예측을 모아 새로운 data에 대한 예측을 만듭니다. 이때 최종 예측을 하는 수집함수는 Classification일 땐, Hard Voting Classifier처럼 가장 많은 예측 결과를 따르고, Regression에 대해선 평균을 계산합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;원본 데이터 전체이 아닌, subset을 학습한 개별 Classifier는 크게 &lt;b&gt;편향이 되어있지만(Underfit)&lt;/b&gt;, 수집 함수를 통과하면 편향과 분산이 모두 감소합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 앙상블의 결과는 원본 데이터로 하나의 예측기를 훈련시킬 때보다, &lt;b&gt;편향은 비슷하지만 분산은 줄어듭니다(Overfitting이 덜 된다).&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7.2.1 sklearn의 Bagging과 Pasting&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 Bagging과 Pasting을 위해 &lt;b&gt;BaggingClassifier&lt;/b&gt;(회귀의 경우 BaggingRegressor)를 제공합니다. 다음은 Decision Tree 500개로 구성로 구성된 앙상블을 훈련시키는 코드입니다. 각 Classifier는 Bagging으로 훈련됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pasting을 사용하려면 &lt;b&gt;bootstrap = False&lt;/b&gt;로 지정합니다.&lt;/li&gt;
&lt;li&gt;n_jobs는 sklearn에서 훈련과 예측에 사용할 CPU 코어 수를 지정하는데, &lt;b&gt;-1로 설정 시&lt;/b&gt; 가용한 모든 코어를 사용합니다.&lt;/li&gt;
&lt;li&gt;BaggingClassifier는 앙상블에 사용되는 Classifier가 Decision Tree처럼 &lt;b&gt;클래스 확률을 추정할 수 있다면, Soft Voting 방식을 사용합니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1612360561300&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bag_clf = BaggingClassifier(
    DecisionTreeClassifier(random_state=42), n_estimators=500,
    max_samples=100, bootstrap=True, n_jobs=-1, random_state=42)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_test)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음은 하나의 Decision Tree의 결정 경계와 앞서 본 코드로 학습한 Bagging 앙상블의 결정 경계를 비교한 것입니다. Training set의 오차 수는 서로 비슷할지 모르나, &lt;b&gt;경계가 덜 불규칙한 앙상블의 예측이 훨씬 더 일반화를 잘할 것이라고 생각할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sRhPl/btqVyV5bOtA/sCZ0JRHW722xUybCzSJZh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sRhPl/btqVyV5bOtA/sCZ0JRHW722xUybCzSJZh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sRhPl/btqVyV5bOtA/sCZ0JRHW722xUybCzSJZh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsRhPl%2FbtqVyV5bOtA%2FsCZ0JRHW722xUybCzSJZh0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;b&gt;Bootstrapping 즉 Bagging을 중복을 허용하는 특성 상&lt;/b&gt; subset에 다양성을 증가시키므로 편향이 좀 더 높습니다.(More Underfitting) 그러나 다양성을 추가한다는 것은 예측기 간 상관관계를 줄이므로 앙상블의 분산을 감소시킵니다.(Less Overfitting)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이러한 탓에 일반적으로는 Bagging을 더 많이 선호합니다. 편향, 분산 그리고 Overfit과 Underfit에 대한 개념이 궁금하신 분들은 다음 포스팅을 참고해주세요.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Coursera ( Machine Learning )] - [머신러닝] 모델의 과적합(Overfitting)을 피하기 위한 방법&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1612360873648&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝] 모델의 과적합(Overfitting)을 피하기 위한 방법&quot; data-og-description=&quot;시작하며 우리는 지금까지 Linear Regression 그리고 Logistic Regression 두가지에 중점을 두어 Supervised Learning을 공부하였습니다. 이번 포스팅에서는 모델 학습 과정에서 발생할 수 있는 'Overfitting' 이..&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/16&quot; data-og-url=&quot;https://box-world.tistory.com/16&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cBRYAU/hyJahpwGlp/JMH0MyUqyWydmIrOxYMol1/img.png?width=631&amp;amp;height=370&amp;amp;face=48_245_385_358,https://scrap.kakaocdn.net/dn/sAAO2/hyI8RlGwOM/jkomnvIki4ouz1u8gwJTm0/img.png?width=631&amp;amp;height=370&amp;amp;face=48_245_385_358,https://scrap.kakaocdn.net/dn/ed1rqz/hyI86iQP8W/vkNXvtQKjvw5k3KZQ5TzTK/img.png?width=453&amp;amp;height=290&amp;amp;face=0_0_453_290&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cBRYAU/hyJahpwGlp/JMH0MyUqyWydmIrOxYMol1/img.png?width=631&amp;amp;height=370&amp;amp;face=48_245_385_358,https://scrap.kakaocdn.net/dn/sAAO2/hyI8RlGwOM/jkomnvIki4ouz1u8gwJTm0/img.png?width=631&amp;amp;height=370&amp;amp;face=48_245_385_358,https://scrap.kakaocdn.net/dn/ed1rqz/hyI86iQP8W/vkNXvtQKjvw5k3KZQ5TzTK/img.png?width=453&amp;amp;height=290&amp;amp;face=0_0_453_290');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝] 모델의 과적합(Overfitting)을 피하기 위한 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 우리는 지금까지 Linear Regression 그리고 Logistic Regression 두가지에 중점을 두어 Supervised Learning을 공부하였습니다. 이번 포스팅에서는 모델 학습 과정에서 발생할 수 있는 'Overfitting' 이..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;7.2.2 oob 평가&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;Bagging을 사용하면 어떤 데이터는 여러 번 사용되고, 어떤 것은 전혀 선택되지 않을 수 있습니다. 앞서 사용한 BaggingClassifier는 평균적으로 각 에측기에 Training dataset의 63% 정도만 사용하는데, 이때 &lt;b&gt;사용되지 않은 나머지 data를 oob(out of bag) 데이터라고 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 남겨진 oob data들은 별도의 Validation set 없이 &lt;b&gt;각 예측기를 평가하는데 사용됩니다.&lt;/b&gt; 앙상블 자체의 평가는 각 예측기의 oob 평가를 평균하여 얻습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 &lt;b&gt;oob_score=True&lt;/b&gt;로 지정하면, 자동으로 oob 평가를 수행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612361189048&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bag_clf = BaggingClassifier(
    DecisionTreeClassifier(random_state=42), n_estimators=500,
    bootstrap=True, n_jobs=-1, oob_score=True, random_state=40)
bag_clf.fit(X_train, y_train)

print('oob score :', bag_clf.oob_score_)

&amp;gt;&amp;gt; 
oob score : 0.9013333333333333&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;oob 데이터 그리고 Test 데이터 이 둘은 모두 BaggingClassifier가 보지 못했던 데이터들이기 때문에 &lt;b&gt;oob score와 Test&amp;nbsp; set의 accuracy의 정확도는 매우 유사할 것으로 보입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxDnbM/btqVCbzqrd6/ALOeKUzxfP77xzjD7itA5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxDnbM/btqVCbzqrd6/ALOeKUzxfP77xzjD7itA5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxDnbM/btqVCbzqrd6/ALOeKUzxfP77xzjD7itA5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxDnbM%2FbtqVCbzqrd6%2FALOeKUzxfP77xzjD7itA5K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 oob_decision_function을 이용하면, 각 Training data의 클래스 확률을 반환합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612361342187&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bag_clf.oob_decision_function_[:5]

&amp;gt;&amp;gt;
array([[0.31746032, 0.68253968],
       [0.34117647, 0.65882353],
       [1.        , 0.        ],
       [0.        , 1.        ],
       [0.        , 1.        ]])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.3 랜덤 패치와 랜덤 서브스페이스&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;BaggingClassifier에서는 각 예측기를 학습하는데 일부 데이터만 쓰는 기능도 있지만, &lt;b&gt;일부 feature만 반영시키는 기능도 지원합니다.&lt;/b&gt; 예를 들어 데이터가 10개의 feature를 가지고 있는데, 5개의 feature만 학습에 사용하는 방식입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이러한 기법은 매우 고차원의 데이터셋을 다룰 때 유용합니다. feature와 데이터를 모두 일부만 사용하는 것을 &lt;b&gt;랜덤 패치 방식(Random Patches Method)&lt;/b&gt;라고 합니다. 그리고 데이터는 모두 사용하고, feature만 일부를 사용하는 방식을 &lt;b&gt;랜덤 서브스페이스 방식(Random Subspace Method)&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7.4 Random Forest&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;랜덤 포레스트(Random Forest)&lt;/b&gt;는 Bagging 혹은 Pasting을 적용한 Decision Tree의 앙상블입니다. 일부만 사용할 Training set의 크기는 &lt;b&gt;max_samples&lt;/b&gt;로 지정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612362194293&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.ensemble import RandomForestClassifier

rnd_clf = RandomForestClassifier(n_estimators=500, max_leaf_nodes=16, n_jobs=-1, random_state=42)
rnd_clf.fit(X_train, y_train)
y_pred_rf = rnd_clf.predict(X_test)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Random Forest 알고리즘은 트리의 노드를 분할할 때, 전체 feature 중 최선의 feature를 찾는 대신 &lt;b&gt;무작위로 선택한 feature 후보들 중 최적의 feature를 찾음으로써 무작위성을 더 주입합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이러한 무작위성은 트리를 더욱 다양하게 만들고, 이러한 &lt;b&gt;다양성은 편향을 감소시키지만(More Underfitting), 분산을 낮추어(Less Overfitting) 더 훌륭한 모델을 만들어냅니다.&lt;/b&gt; 다음은 &lt;b&gt;BaggingClassifier&lt;/b&gt;로 RandomForestClassifier와 거의 유사하게 만든 것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612362330467&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bag_clf = BaggingClassifier(
    DecisionTreeClassifier(splitter=&quot;random&quot;, max_leaf_nodes=16, random_state=42),
    n_estimators=500, max_samples=1.0, bootstrap=True, n_jobs=-1, random_state=42)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_test)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7.4.1 엑스트라 트리&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;앞서 본 Random Forest는 각 노드의 분할을 위해 feature의 subset을 사용했습니다. 트리를 더욱 무작위하게 만들기 위해 최적의 임곗값 $t_k$를 찾는 대신 &lt;b&gt;feature의 subset을 사용해 무작위로 분할 후 그중 최상의 분할을 선택합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 극단적으로 무작위한 Random Forest를 &lt;b&gt;Extreme random Tree 앙상블 혹은 Extra tree&lt;/b&gt;라고 부릅니다. 이 역시 무작위성은 다양성을 늘려 편향을 늘리는 대신 분산을 줄이게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;기존엔 노드 분할 시 최적의 임곗값을 찾는 것이 트리 알고리즘에서 가장 많이 시간을 잡아먹는 부분이었는데 이것이 없어졌으므로 &lt;b&gt;일반적인 Random Forest보다 Extra Tree가 훨씬 빠릅니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 ExtraTreesClassifier를 사용해 이를 구현할 수 있으며 기타 메서드나 파라미터는 동일합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7.4.2 특성 중요도&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;Random forest의 또 다른 장점은 &lt;b&gt;어떤 feature가 예측에 중요한 비중을 차지하는지 상대적인 중요도를 측정하기 쉽다는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 &lt;b&gt;어떤 feature를 사용한 노드가 gini(불순도)를 감소시키는지 확인하여 feature의 중요도를 측정합니다.&lt;/b&gt; 더 정확히는 가중치의 평균이며 각 노드의 가중치는 연관된 Training data 수와 같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;훈련이 끝난 뒤 feature마다 자동으로 이 점수를 계산하고 중요도의 전체 합이 1이 되도록 결과값을 정규화하여 이를 &lt;b&gt;feature_importances_&lt;/b&gt; 변수에 저장합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 Iris 데이터셋을 이용한 코드 적용입니다. 수치를보면 &lt;b&gt;petal length와 petal width&lt;/b&gt;가 가장 중요한 특성들이라는 걸 알 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612363524220&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.datasets import load_iris

iris = load_iris()
rnd_clf = RandomForestClassifier(n_estimators=500, n_jobs=-1, random_state=42)
rnd_clf.fit(iris[&quot;data&quot;], iris[&quot;target&quot;])
for name, score in zip(iris[&quot;feature_names&quot;], rnd_clf.feature_importances_):
    print(name, score)
    
 &amp;gt;&amp;gt;
sepal length (cm) 0.11249225099876374
sepal width (cm) 0.023119288282510326
petal length (cm) 0.44103046436395765
petal width (cm) 0.4233579963547681&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이러한 특징은 이미지를 Classification하는데 모델이 어느 곳을 중점적으로 보는지 판단하는데 활용될 수 있습니다. 다음은 MNIST 데이터셋에서 Random Forest Classifier를 학습하고 각 픽셀의 중요도를 그래프로 나타낸 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qT1HN/btqVzSf1qKv/sCkkDVDamGpBGWdH0URYm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qT1HN/btqVzSf1qKv/sCkkDVDamGpBGWdH0URYm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qT1HN/btqVzSf1qKv/sCkkDVDamGpBGWdH0URYm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqT1HN%2FbtqVzSf1qKv%2FsCkkDVDamGpBGWdH0URYm0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7.5 Boosting&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;부스팅(Boosting)&lt;/b&gt;은 약한 학습기를 여러 개 연결하여 강한 학습기를 만드는 앙상블 방법을 말합니다. 여기에는 &lt;b&gt;AdaBoost&lt;/b&gt;와 &lt;b&gt;Gradient Boosting&lt;/b&gt;이 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;7.5.1 &lt;span style=&quot;color: #333333;&quot;&gt;AdaBoost&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt; &lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;AdaBoost&lt;/b&gt;는 &lt;b&gt;이전 모델이 Underfitting했던 training data의 가중치를 더 높이며 새로운 모델을 만듭니다.&lt;/b&gt; 이렇게 하면 새로운 예측기는 학습하기 어려운 샘플에 점점 더 맞춰지게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHXzW1/btqVAIxuVlA/r0nNHyAjDRctj0DV9omkd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHXzW1/btqVAIxuVlA/r0nNHyAjDRctj0DV9omkd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHXzW1/btqVAIxuVlA/r0nNHyAjDRctj0DV9omkd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHXzW1%2FbtqVAIxuVlA%2Fr0nNHyAjDRctj0DV9omkd0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 &lt;span style=&quot;color: #333333;&quot;&gt;AdaBoost Classifier를 만들 때 먼저 Decision tree와 같은 첫 번째 Classifier를 Training set에서 훈련시키고 예측을 만듭니다. 그 다음 &lt;b&gt;알고리즘이 잘못 분류했던 Training data의 가중치를 높입니다.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;이것이 반영된 두번째 Classifier에서는 업데이트된 가중치로 Training set을 학습하고 예측하고, 나머지 과정은 반복되는 식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;다음은 &lt;span style=&quot;color: #333333;&quot;&gt;AdaBoost방식으로 갱신되어 가는 다섯개의 연속된 예측기의 결정 경계입니다. moons 데이터셋을 사용하였고, 모델은 규제를 강하게 한 RBF 커널 SVM Classifier입니다. Classifier의 성능이 가면 갈 수록 좋아지는 것을 확인할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PlvPn/btqVCcZpoRf/LeDCMcMpNKKDKHD9L5dnK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PlvPn/btqVCcZpoRf/LeDCMcMpNKKDKHD9L5dnK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PlvPn/btqVCcZpoRf/LeDCMcMpNKKDKHD9L5dnK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPlvPn%2FbtqVCcZpoRf%2FLeDCMcMpNKKDKHD9L5dnK1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p&gt;&amp;nbsp;AdaBoost 알고리즘을 좀 더 자세히 들여다보겠습니다. 각 데이터 가중치 $w^{(i)}$는 초기에 $\cfrac{1}{m}$으로 초기화 됩니다. 이후 첫 번째 예측기가 학습되고, 가중치가 적용된 에러율 $r_1$이 계산됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EORVJ/btqVCb0wCeH/lskkSm60UZ9gnH5sqgZcw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EORVJ/btqVCb0wCeH/lskkSm60UZ9gnH5sqgZcw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EORVJ/btqVCb0wCeH/lskkSm60UZ9gnH5sqgZcw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEORVJ%2FbtqVCb0wCeH%2FlskkSm60UZ9gnH5sqgZcw0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;두 번째 예측기의 가중치 $\alpha_j$는 다음 식으로 계산됩니다. 여기서 n처럼 생긴 저 기호는 learning rate입니다. 예측기가 정확할수록 에러율은 낮으므로 &lt;span style=&quot;color: #333333;&quot;&gt;$\alpha_j$은 높아지게 되고, 성능이 매우 안좋다면 음수까지도 갈 수 있습니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ndCwI/btqVJSlhi91/EaE7XKugfinQKJ2GHuJ4vK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ndCwI/btqVJSlhi91/EaE7XKugfinQKJ2GHuJ4vK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ndCwI/btqVJSlhi91/EaE7XKugfinQKJ2GHuJ4vK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FndCwI%2FbtqVJSlhi91%2FEaE7XKugfinQKJ2GHuJ4vK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그 다음 알고리즘은 다음 식을 사용해 잘못 예측한 경우에만 해당 데이터의 가중치를 &lt;span style=&quot;color: #333333;&quot;&gt;$\alpha_j$를 이용해 갱신합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5c9LU/btqVAHL9Go9/pYfjp9KOZ6ZTSAvKaIWsRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5c9LU/btqVAHL9Go9/pYfjp9KOZ6ZTSAvKaIWsRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5c9LU/btqVAHL9Go9/pYfjp9KOZ6ZTSAvKaIWsRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5c9LU%2FbtqVAHL9Go9%2FpYfjp9KOZ6ZTSAvKaIWsRK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그 후 모든 데이터의 가중치를 정규화하는 식으로 반복됩니다. 이 것은 정해진 예측기의 수에 도달하거나, 완벽한 예측기가 만들어지면 중지됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;AdaBoost는 단순히 모든 예측기의 예측을 계산하고, 예측기 가중치 &lt;span style=&quot;color: #333333;&quot;&gt;$\alpha_j$를 더해 예측 결과를 만듭니다. 그리고 가중치 합이 가장 큰 클래스가 예측 결과가 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2RPAx/btqVK7P2tzX/0ho6yyE6EOI13nfcgJ8P2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2RPAx/btqVK7P2tzX/0ho6yyE6EOI13nfcgJ8P2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2RPAx/btqVK7P2tzX/0ho6yyE6EOI13nfcgJ8P2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2RPAx%2FbtqVK7P2tzX%2F0ho6yyE6EOI13nfcgJ8P2K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 sklearn의 &lt;b&gt;AdaBoostClassifier&lt;/b&gt;를 사용하여 200개의 얕은 Decision tree를 기반으로 AdaBoost Classifier를 훈련시킵니다. 이때 Decision tree의 &lt;b&gt;max_depth = 1&lt;/b&gt;입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612366022162&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.ensemble import AdaBoostClassifier

ada_clf = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=1), n_estimators=200,
    algorithm=&quot;SAMME.R&quot;, learning_rate=0.5, random_state=42)
ada_clf.fit(X_train, y_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7.5.2 Gradient Boosting&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Gradient Boosting&lt;/b&gt;도 이전까지의 오차를 보정한 예측기가 순차적으로 앙상블에 추가됩니다. 다만 AdaBoost처럼 데이터의 가중치를 갱신하는 대신 &lt;b&gt;이전 예측기가 만든 잔여 오차(residual error)를 새로운 예측기에 학습시킵니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;간단한 회귀 문제를 풀어보겠습니다. 이때 사용되는 모델을 &lt;b&gt;Gradient tree boosting 혹은 GBRT&lt;/b&gt;라고 합니다. 우선 &lt;b&gt;DecisionTreeRegressor&lt;/b&gt;에 Training set을 학습시키겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612366183299&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.tree import DecisionTreeRegressor

tree_reg1 = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg1.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 &lt;b&gt;Residual Error&lt;/b&gt;를 두번째 &lt;span style=&quot;color: #333333;&quot;&gt;DecisionTreeRegressor에 훈련시킵니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1612366627935&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y2 = y - tree_reg1.predict(X)  # residual errors

tree_reg2 = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg2.fit(X, y2)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이번엔 세 번째입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612366650452&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y3 = y2 - tree_reg2.predict(X)  # residual error

tree_reg3 = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg3.fit(X, y3)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;새로운 데이터에 대한 예측은 모든 트리의 예측을 더하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612366730032&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_pred = sum(tree.predict(X_new) for tree in (tree_reg1, tree_reg2, tree_reg3))&lt;/code&gt;&lt;/pre&gt;
&lt;p&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;두번째 행의 앙상블은 첫 번째 트리의 잔여 오차를 학습하였습니다. 직관적으로 보면 앙상블의 예측이 $h_2(x_1)$와 잔여 오차를 더한 값임을 볼 수 있습니다.&lt;/li&gt;
&lt;li&gt;트리가 앙상블에 추가될 수록 앙상블의 예측은 더욱 좋아집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r41LL/btqVIJoB4AR/pAD6sH2lUqfc2FDZ8olv51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r41LL/btqVIJoB4AR/pAD6sH2lUqfc2FDZ8olv51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r41LL/btqVIJoB4AR/pAD6sH2lUqfc2FDZ8olv51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr41LL%2FbtqVIJoB4AR%2FpAD6sH2lUqfc2FDZ8olv51%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 sklearn에서 GBRT 앙상블을 간단하게 훈련시키는 코드입니다. &lt;b&gt;learning_rate&lt;/b&gt; 매개변수는 각 트리의 기여 정도를 조절합니다. 이것이 작을 수록 앙상블은 더욱 많은 트리를 필요로 하지만, 성능은 좋아지는데 이러한 규제 방법을 &lt;b&gt;축소(shrinkage)&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612367046220&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.ensemble import GradientBoostingRegressor

gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=3, learning_rate=1, random_state=42)
gbrt.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음 그래프에서 왼쪽은 트리가 너무 적어 Underfitting된 앙상블이고, 오른쪽은 반대로 너무 많아서 Overfitting된 앙상블입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o1a09/btqVyUSIgGf/mFeJ8OtZC6DvNyro35ero1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o1a09/btqVyUSIgGf/mFeJ8OtZC6DvNyro35ero1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o1a09/btqVyUSIgGf/mFeJ8OtZC6DvNyro35ero1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo1a09%2FbtqVyUSIgGf%2FmFeJ8OtZC6DvNyro35ero1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 최적의 트리 수를 찾기 위해 &lt;b&gt;조기 종료 기법&lt;/b&gt;을 적용한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612367212942&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

X_train, X_val, y_train, y_val = train_test_split(X, y, random_state=49)

gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=120, random_state=42)
gbrt.fit(X_train, y_train)

# 최적의 트리 개수 찾기
errors = [mean_squared_error(y_val, y_pred)
          for y_pred in gbrt.staged_predict(X_val)]
bst_n_estimators = np.argmin(errors)

# 최적의 트리개수로 그래디언트 부스팅 학습
gbrt_best = GradientBoostingRegressor(max_depth=2, n_estimators=bst_n_estimators, random_state=42)
gbrt_best.fit(X_train, y_train)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg8OMk/btqVyUrFPRj/ujwiRFkzxOqWQJGlvKOBEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg8OMk/btqVyUrFPRj/ujwiRFkzxOqWQJGlvKOBEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg8OMk/btqVyUrFPRj/ujwiRFkzxOqWQJGlvKOBEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg8OMk%2FbtqVyUrFPRj%2FujwiRFkzxOqWQJGlvKOBEK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위와 같이 많은 수의 트리를 먼저 훈련시키고 최적의 수를 찾는 대신 최적의 수라고 판단 시 실제로 훈련을 중도에 중지하는 방법으로도 구현될 수 있습니다. 다음 코드는 다섯 번의 반복 동안 Validation Error가 향상되지 않으면 훈련을 종료합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612367327502&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gbrt = GradientBoostingRegressor(max_depth=2, warm_start=True, random_state=42)

min_val_error = float(&quot;inf&quot;)
error_going_up = 0
for n_estimators in range(1, 120):
    gbrt.n_estimators = n_estimators
    gbrt.fit(X_train, y_train)
    y_pred = gbrt.predict(X_val)
    val_error = mean_squared_error(y_val, y_pred)
    if val_error &amp;lt; min_val_error:
        min_val_error = val_error
        error_going_up = 0
    else:
        error_going_up += 1
        if error_going_up == 5:
            break  # 조기 종료&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;GradientBoostingRegressor&lt;/b&gt;는 트리 훈련 시 사용할 Training subset의 크기를 subsample 매개변수로 지정할 수 있습니다. 이를 통해 편향은 높이고 분산은 줄일 수 있는데 이러한 기법을 &lt;b&gt;확률적 그레디언트 부스팅(Stochastic gradient boosting)&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;최적화된 Gradient Boosting 구현으로 가장 유명한 것은 &lt;b&gt;XGBoost&lt;/b&gt;입니다. 중요한 개념이니 꼭 한번 찾아보시길 바랍니다!!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음 포스팅에서는 고차원 데이터셋을 다룰 때 자주 사용하는 차원 축소에 대해서 다뤄보겠습니다. 긴 글 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>Ensemble</category>
      <category>PYTHON</category>
      <category>Random Forest</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>랜덤 포레스트</category>
      <category>머신러닝</category>
      <category>앙상블 학습</category>
      <category>인공지능</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/60</guid>
      <comments>https://box-world.tistory.com/60#entry60comment</comments>
      <pubDate>Thu, 4 Feb 2021 01:10:24 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈온 머신러닝 2 ] Decision Tree란?</title>
      <link>https://box-world.tistory.com/59</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;성공하려면 이미 했던 일을 제대로 활용하라&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;- 블레이크 로스 (파이어폭스 공동 개발자) -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시작하며&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;저번 포스팅에서는 SVM에 대해 다뤄보았습니다. 이번 포스팅에서 다룰 &lt;b&gt;Decision Tree&lt;/b&gt;은 SVM처럼 Classification, Regression 등 폭넓게 사용이 가능하며, 복잡한 데이터셋도 학습할 수 있는 강력한 알고리즘입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.1 Decision Tree 학습과 시각화&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;우선 Decision Tree를 이해하기 위해 모델 하나를 생성한 후 어떻게 예측하는지 살펴보겠습니다. 데이터는 &lt;b&gt;Iris(붓꽃의 종류를 클래스화한 데이터)&lt;/b&gt;를 사용하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612245560865&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier

iris = load_iris()
X = iris.data[:, 2:] # 꽃잎 길이와 너비
y = iris.target

tree_clf = DecisionTreeClassifier(max_depth=2, random_state=42)
tree_clf.fit(X, y)

//output
DecisionTreeClassifier(max_depth=2, random_state=42)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;export_graphviz()&lt;/b&gt; 함수는 Decision Tree를 시각화하여 .dot 파일의 형태로 출력합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612245692189&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from graphviz import Source
from sklearn.tree import export_graphviz

export_graphviz(
        tree_clf,
        out_file=os.path.join(IMAGES_PATH, &quot;iris_tree.dot&quot;),
        feature_names=iris.feature_names[2:],
        class_names=iris.target_names,
        rounded=True,
        filled=True
    )

Source.from_file(os.path.join(IMAGES_PATH, &quot;iris_tree.dot&quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bea4hW/btqVkKQp5yY/as6N5gSmE6QwVL2oI3VBCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bea4hW/btqVkKQp5yY/as6N5gSmE6QwVL2oI3VBCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bea4hW/btqVkKQp5yY/as6N5gSmE6QwVL2oI3VBCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbea4hW%2FbtqVkKQp5yY%2Fas6N5gSmE6QwVL2oI3VBCK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.2 예측하기&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;위 Decision Tree가 어떻게 예측을 하는지 살펴보면서 그래프를 분석해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7mg1X/btqVzQ8O5Ux/X4jVUU1TO5IhPLochyCatk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7mg1X/btqVzQ8O5Ux/X4jVUU1TO5IhPLochyCatk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7mg1X/btqVzQ8O5Ux/X4jVUU1TO5IhPLochyCatk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7mg1X%2FbtqVzQ8O5Ux%2FX4jVUU1TO5IhPLochyCatk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 먼저 데이터가 들어오면 &lt;b&gt;루트 노드(Depth = 0)&lt;/b&gt;를 가장 먼저 거치게 됩니다. 이 노드는 &lt;b&gt;꽃잎의 길이(petal length)&lt;/b&gt;가 2.45cm보다 짧은지 검사합니다. 만약 그렇다면(=True)왼쪽 자식 노드(Depth = 1)로 이동합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 이동한 자식 노드가 리프 노드(자식 노드를 가지지 않은 노드)라면 추가적인 검사를 하지않고 해당 노드에 적힌 class인 &lt;b&gt;&quot;senota&quot;&lt;/b&gt;라고 예측합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgulM7/btqVzRs7BsJ/8uZvPJSdo398FbzuJyRc00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgulM7/btqVzRs7BsJ/8uZvPJSdo398FbzuJyRc00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgulM7/btqVzRs7BsJ/8uZvPJSdo398FbzuJyRc00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgulM7%2FbtqVzRs7BsJ%2F8uZvPJSdo398FbzuJyRc00%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이번엔 꽃잎의 길이가 2.45cm보다 긴 데이터가 들어와 루트에서 오른쪽 자식 노드로 이동했다고 가정해보겠습니다. 그러면 해당 노드는 리프 노드가 아니기 때문에 꽃잎의 길이가 1.75cm보다 작은지 검사하게 됩니다. 검사 후 데이터는 어느 리프노드로 내려가냐에 따라 &lt;b&gt;&quot;versicolor&quot;&lt;/b&gt;혹은 &lt;b&gt;&quot;virginica&quot;&lt;/b&gt;가 될것입니다.&lt;/p&gt;
&lt;p&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&gt;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;&lt;b&gt;NOTE_&lt;/b&gt;&lt;/span&gt; Decision Tree의 장점 중 하나는 Data 전처리가 거의 필요하지 않다는 것입니다. 즉 feature의 Scale을 조정하구나 평균을 원점에 맞추는 작업을 요하지 않습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;이제 나머지 노드의 구성요소에 대해서 살펴보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;sample 속성&lt;/b&gt;은 해당 노드로 얼마나 많은 데이터가 내려왔는지를 헤아린 것입니다. 예를 들어 앞서 본 Tree의 보라색 노드의 sample = 46이므로 46개의 데이터가 이 노드로 내려왔다는 것을 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;value 속성&lt;/b&gt;은 어떤 클래스의 데이터가 해당 노드로 내려왔는지 알려줍니다. 보라색 노드의 value = [0, 1, 45]이므로 Setosa 클래스를 가지는 데이터는 0개, Versicolor는 1개, Virginica는 45개가 해당 노드로 내려왔다고 판단하게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;마지막으로 &lt;b&gt;gini&lt;/b&gt;는 &lt;b&gt;불순도(impurity)&lt;/b&gt;를 측정합니다. 보통 우리가 물에 이물질이나 흙이 많이 섞여있으면 불순도가 높다고 하는데 여기서도 비슷한 맥락을 가집니다. 예를 들어 한 노드를 지나간 데이터들이 모두 같은 클래스라면 이때의 gini = 0이라고 할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;불순도를 구하는 방법에는 여러가지가 있지만 가장 보편적인 것은 &lt;b&gt;'지니 불순도'&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzobVj/btqVkKCQIhS/vpG9AAKnncdlxaDAkoz0j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzobVj/btqVkKCQIhS/vpG9AAKnncdlxaDAkoz0j0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzobVj/btqVkKCQIhS/vpG9AAKnncdlxaDAkoz0j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzobVj%2FbtqVkKCQIhS%2FvpG9AAKnncdlxaDAkoz0j0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 식을 이용하면 그래프의 초록색 노드의 불순도는 다음처럼 구할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/M0biW/btqVtaAuGU4/n1Gzly0FHlKxUwV9r3ZKrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/M0biW/btqVtaAuGU4/n1Gzly0FHlKxUwV9r3ZKrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/M0biW/btqVtaAuGU4/n1Gzly0FHlKxUwV9r3ZKrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FM0biW%2FbtqVtaAuGU4%2Fn1Gzly0FHlKxUwV9r3ZKrK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPyz6D/btqVh8qr2oW/wCvcPK4gswgCLMFCKHz3rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPyz6D/btqVh8qr2oW/wCvcPK4gswgCLMFCKHz3rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPyz6D/btqVh8qr2oW/wCvcPK4gswgCLMFCKHz3rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPyz6D%2FbtqVh8qr2oW%2FwCvcPK4gswgCLMFCKHz3rk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위그림은 Decision Tree의 결정 경계를 보여줍니다. 굵은 수직선이 루트 노드의 결정 경계(꽃잎 길이 = 2.45cm)를 나타냅니다. 앞선 코드에서 max_depth를 2로 설정했었는데 만약 3으로 설정하면 점선으로 보이는 경계가 추가로 만들어집니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.2 클래스 확률 추정&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;Decision tree는 데이터가 특정 클래스 k에 속할 확률을 추정할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;1) 데이터가 속한 리프 노드를 찾기 위해 트리를 탐색합니다.&lt;/p&gt;
&lt;p&gt;2) 해당 노드를 지나간 데이터들 중에서 클래스 k의 비율을 반환합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예를 들어 length = 5cm이고, width = 1.5cm인 꽃잎은 초록색 노드입니다. 따라서 Setosa일 확률은 0%(0/54), Versicolor는 90.7%(49/54), Virginica는 9.3%(5/54)입니다. 다음 코드에서 방금 예시로 든 데이터를 예측했을 때 Versicolor(class = 1)이 나오는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612248539625&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tree_clf.predict_proba([[5, 1.5]])
&amp;gt;&amp;gt; array([[0.        , 0.90740741, 0.09259259]])

tree_clf.predict([[5, 1.5]])
&amp;gt;&amp;gt; array([1])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.4 CART 훈련 알고리즘&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Sklearn에서는 Decision Tree 학습을 위해 &lt;b&gt;CART 알고리즘&lt;/b&gt;을 사용합니다. 첫번째는 Training set에서 꽃잎의 길이와 같은 하나의 &lt;b&gt;feature&lt;/b&gt;를 고른 후, &amp;lt;= 2.45cm같이 노드를 가르는 &lt;b&gt;임곗값&lt;/b&gt; $t_k$를 사용하여 두 개의 subset으로 나눕니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이때의 feature는 Training set 내 클래스 비율을 고려하여 가장 순수하게 서브셋으로 나눌 수 있는 feature와 $t_k$를 찾습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;알고리즘이 최소화할 비용함수는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWs3Iy/btqVvORhDFc/Y2aZt3WBclFrUPfFbMBy3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWs3Iy/btqVvORhDFc/Y2aZt3WBclFrUPfFbMBy3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWs3Iy/btqVvORhDFc/Y2aZt3WBclFrUPfFbMBy3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWs3Iy%2FbtqVvORhDFc%2FY2aZt3WBclFrUPfFbMBy3K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Training set을 성공적으로 둘로 나눈 알고리즘은 max_depth까지 도달하거나, gini(불순도)를 줄이는 분할을 찾을 수 없을 때 멈추게 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.5 엔드로피 불순도&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 &lt;b&gt;criterion = &quot;entropy&quot;&lt;/b&gt;으로 지정하면 지니 불순도가 아닌 &lt;b&gt;엔트로피 불순도&lt;/b&gt;를 사용하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JVwOL/btqVyVJmRth/RG5y8UtDXU8EtsW1qzSzg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JVwOL/btqVyVJmRth/RG5y8UtDXU8EtsW1qzSzg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JVwOL/btqVyVJmRth/RG5y8UtDXU8EtsW1qzSzg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJVwOL%2FbtqVyVJmRth%2FRG5y8UtDXU8EtsW1qzSzg1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;지니 불순도가 좀 더 계산이 빠르기 때문에 기본적으로 좋지만, 엔트로피는 좀 더 균형 잡힌 트리를 만드는데 용이하다는 장점을 가지고 있습니다.&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.7 규제 파라미터&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Decision Tree는 Training data에 대한 제약이 거의 없습니다. 따라서 제한을 두지 않으면 트리는 데이터에 &lt;b&gt;Overfitting&lt;/b&gt;되기 쉽습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Decision tree는 학습 전 파라미터의 수가 결정되지 않아 &lt;b&gt;비파라미터 모델(nonparameter model)&lt;/b&gt;이라고 부르고, 모델의 구조가 자유롭습니다. 반대로 Linear model과 같은 &lt;b&gt;파라미터 모델(&lt;span style=&quot;color: #333333;&quot;&gt;parameter model&lt;/span&gt;)&lt;/b&gt;은 Overfitting될 위험이 줄어듭니다.&lt;/p&gt;
&lt;p&gt;이러한 Overfit을 막기 위해 &lt;b&gt;max_depth&lt;/b&gt;와 같은 규제 파라미터를 사용합니다. 이 외에도 sklearn의 &lt;b&gt;DecisionTreeClassifier&lt;/b&gt;에서는 다른 규제 파라미터가 있습니다.&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;min_samples_leaf&lt;/b&gt; : 리프 노드가 가져야할 최소 샘플 수&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;min_weight_graction_leaf&lt;/b&gt; : &lt;span style=&quot;color: #333333;&quot;&gt;min_samples_leaf와 같지만, 가중치가 부여된 전체 데이터 수에서의 ㅂ율&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- &lt;b&gt;max_leaf_nodes&lt;/b&gt; : 리프 노드의 최대 수&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- &lt;b&gt;max_features&lt;/b&gt; : 각 노드에서 분할에 사용할 특성의 최대 수&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 규제 파라미터의 효과를 관찰하기 위해 moons 데이터셋에 규제가 없는 것과 min_samples_leaf = 4로 설정한 것 두개의 Decision tree입니다. 확실히 왼쪽 그래프가 Overfitting되어있는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caVv0z/btqVkK31K56/6OE2diy4lbwh4kNNjYi1WK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caVv0z/btqVkK31K56/6OE2diy4lbwh4kNNjYi1WK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caVv0z/btqVkK31K56/6OE2diy4lbwh4kNNjYi1WK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaVv0z%2FbtqVkK31K56%2F6OE2diy4lbwh4kNNjYi1WK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.8 Regression&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이번엔 Decision Tree를 Regression에 활용하는 법을 공부해보습니다. sklearn의 &lt;b&gt;DecisiontreeRegressor&lt;/b&gt;를 이용해 feature가 2개인 데이터셋에 대해 &lt;b&gt;max_depth = 2&lt;/b&gt;로 설정하고 트리를 생성하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612250121347&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.tree import DecisionTreeRegressor

tree_reg = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg.fit(X, y)

&amp;gt;&amp;gt; DecisionTreeRegressor(max_depth=2, random_state=42)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zy141/btqVzSr6bLK/C9j8Rx2h8fMHOvpEcnMq80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zy141/btqVzSr6bLK/C9j8Rx2h8fMHOvpEcnMq80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zy141/btqVzSr6bLK/C9j8Rx2h8fMHOvpEcnMq80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzy141%2FbtqVzSr6bLK%2FC9j8Rx2h8fMHOvpEcnMq80%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;앞서 Classification을 위해 사용된 Decision Tree와 크게 차이가 있어보이진 않습니다. 다만 Regression에서는 들어온 데이터가 어느 클래스인지를 분류하는 대신 어떤 값을 예측한다는 점에서 차이가 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 $x_1 = 0.6$인 데이터의 타깃값을 예측한다면, 루트 노드에서부터 value가 0.111인 리프 노드에 도달하게 됩니다. 그리고 해당 리프 노드로 도달한 110개 데이터의 평균 타깃값이 예측값이 됩니다. 이를 이용하여 &lt;b&gt;MSE&lt;/b&gt;를 계산하면 0.015가 나오게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu28iu/btqVtb7lifM/CHjGbxPsYu8g5BBDlC9c6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu28iu/btqVtb7lifM/CHjGbxPsYu8g5BBDlC9c6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu28iu/btqVtb7lifM/CHjGbxPsYu8g5BBDlC9c6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu28iu%2FbtqVtb7lifM%2FCHjGbxPsYu8g5BBDlC9c6k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 그래프들은 서로 다른 max_depth에 대한 Decision Tree 모델이고, 빨간색 선이 데이터를 대표하는 회귀 그래프입니다. 각 영역의 예측값 $&lt;span style=&quot;color: #333333;&quot;&gt;\hat{y}&lt;/span&gt;$는 해당 영역에 있는 타깃값 $y$의 평균입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;CART 알고리즘&lt;/b&gt;은 불순도를 최소화하는 대신 다음과 같이 &lt;b&gt;MSE를 최소화&lt;/b&gt;하도록 분할합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvYcuw/btqVkMgueMk/IkUbgLotoRrTKGYoT7R0c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvYcuw/btqVkMgueMk/IkUbgLotoRrTKGYoT7R0c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvYcuw/btqVkMgueMk/IkUbgLotoRrTKGYoT7R0c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvYcuw%2FbtqVkMgueMk%2FIkUbgLotoRrTKGYoT7R0c0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Regression에서도 Decision Tree는 Overfitting되기 쉽기 때문에 규제 파라미터를 이용하면 다음과 같이 훨씬 그럴싸한 모델을 생성할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qvdOy/btqVAHqlYFN/k9U5tMz5hSDq3LMn7ja3Bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qvdOy/btqVAHqlYFN/k9U5tMz5hSDq3LMn7ja3Bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qvdOy/btqVAHqlYFN/k9U5tMz5hSDq3LMn7ja3Bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqvdOy%2FbtqVAHqlYFN%2Fk9U5tMz5hSDq3LMn7ja3Bk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&amp;nbsp;6.9 Decision Tree의 단점 : 불안정성&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Decision Tree의 결정 경계는 &lt;b&gt;계단 모양&lt;/b&gt;입니다. 이 말은 &lt;b&gt;Training set의 사소한 변화에도 민감하다는 의미입니다.&lt;/b&gt; 예를 들어 데이터셋을 45C&lt;span&gt;˚ 회전하게 되면 Decision Tree는 다음 오른쪽처럼 불필요하게 구불구불해집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbaydk/btqVvNSqP8q/GHZzwjc6CbEGsQsEn1HSe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbaydk/btqVvNSqP8q/GHZzwjc6CbEGsQsEn1HSe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbaydk/btqVvNSqP8q/GHZzwjc6CbEGsQsEn1HSe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbaydk%2FbtqVvNSqP8q%2FGHZzwjc6CbEGsQsEn1HSe1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;또 다른 예시는 앞서 본 Iris 데이터에서 Versicolor 클래스를 제거하고 훈련시켰을 때의 모델입니다. 분명 이전에 만든 Decision Tree와는 다른 모습을 보이는 문제가 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDLlSH/btqVvNSqXD5/WpXqsWL93qc8sWlK9Np2ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDLlSH/btqVvNSqXD5/WpXqsWL93qc8sWlK9Np2ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDLlSH/btqVvNSqXD5/WpXqsWL93qc8sWlK9Np2ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDLlSH%2FbtqVvNSqXD5%2FWpXqsWL93qc8sWlK9Np2ek%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;다음 포스팅에서는 앙상블 학습과 랜덤 포레스트에 대해서 공부해보겠습니다. 긴 글 읽어주셔서 감사합니다. 오늘도 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>Decision Tree</category>
      <category>Machine Learning</category>
      <category>PYTHON</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>결정 트리</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>인공지능</category>
      <category>핸즈온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/59</guid>
      <comments>https://box-world.tistory.com/59#entry59comment</comments>
      <pubDate>Tue, 2 Feb 2021 17:07:08 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈온 머신러닝 2판 ] SVM이란?</title>
      <link>https://box-world.tistory.com/58</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;인내는 어떤 실력보다 강하다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;- 벤 호건 (프로 골퍼) -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시작하며&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;SVM은 Classification, Regression 등 다양한 곳에서 활용됩니다. 특히 복잡한 데이터셋을 학습하기에 용이하다는 점도 SVM의 인기를 높이는 데 한 몫 하였습니다.&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.1 선형 SVM 분류&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJ94nS/btqVswQG566/PoG3gehEDlfxFkCi2ibpu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJ94nS/btqVswQG566/PoG3gehEDlfxFkCi2ibpu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJ94nS/btqVswQG566/PoG3gehEDlfxFkCi2ibpu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJ94nS%2FbtqVswQG566%2FPoG3gehEDlfxFkCi2ibpu0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 데이터셋은 서로 다른 종류의 붓꽃들을 모아놓은 데이터셋입니다. 이 둘을 직선 하나만 그어서 같은 클래스의 데이터들만 모여있도록 구역을 나눌 수 있을까요?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;당연히 가능합니다. 우리는 이것을 선형적으로 구분이 가능하다고 합니다. 그러나 왼쪽 그래프의 빨간색이나 자주색 선이 두 클래스를 잘 구분하는 듯 하지만 경계가 너무 데이터에 가깝기 때문에 좋은 성능을 보일거라곤 장담하지 못합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;결론은 오른쪽처럼 두 클래스를 나눌 때 최대한 큰 마진(margin)을 갖도록 경계를 정하면 그만큼 성능이 높아진다는 것입니다. 이렇게 마치 최대한 폭이 넓은 도로를 찾는 듯 분류하는 것이 Large Margin Classfication이라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;도로 밖에 data를 추가하더라도 경계는 변하지 않으며, 오른쪽 그래프의 두 점선처럼 도로의 경계에 영향을 미치는 데이터를 Suppor Vector라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 경계를 정하여 데이터를 분류하는데 사용하는 모델을 SVM(Support Vector Machine)이라고 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcxQ2Z/btqVug7FSjz/BpbOwqzqjwocQM3kKm1tC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcxQ2Z/btqVug7FSjz/BpbOwqzqjwocQM3kKm1tC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcxQ2Z/btqVug7FSjz/BpbOwqzqjwocQM3kKm1tC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcxQ2Z%2FbtqVug7FSjz%2FBpbOwqzqjwocQM3kKm1tC1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; SVM을 다룰 때 feature의 Scale(범위)을 조정하는 것이 중요합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;왼쪽 그래프는 $x_1$과 $x_0$의 Scale이 달라 Margin이 거의 없는 경계가 생성되었습니다. 반대로 이 feature들의 스케일을 조정하면 오른쪽처럼 경계가 훨씬 좋아집니다.&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&amp;nbsp;Margin Classification&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;Margin Classification에는 Hard와 Soft 두가지가 있습니다. Hard Margin Classification은 모든 데이터가 도로의 바깥쪽에 올바르게 분류되어야합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 이는 데이터가 선형적으로 분류가 가능해야하고, 변칙적으로 튀는 이상치(Anomaly data)에 민감합니다.(이상치마저도 완벽하게 분류하려하니 경계가 좋은 성능을 지닐 수가 없겠죠)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uvGbV/btqVdNT8d61/ikwKSUNa0TqxDY5tXJPjv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uvGbV/btqVdNT8d61/ikwKSUNa0TqxDY5tXJPjv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uvGbV/btqVdNT8d61/ikwKSUNa0TqxDY5tXJPjv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuvGbV%2FbtqVdNT8d61%2FikwKSUNa0TqxDY5tXJPjv0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;따라서 왼쪽 그래프처럼 이상치가 존재하는 경우 Hard하게 분류하는 것은 불가능합니다. 게다가 오른쪽처럼 분류할 수 있다하더라도 완벽하게 분류하기 위해선 margin이 거의 없는 경계를 만들어야하는 상황이 발생하게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그래서 우리는 분류가 조금 틀리더라도 성능 좋은 경계를 만들기 위해 Soft Margin Classification을 생각하게 되었습니다. 이는 도로의 Margin의 크기와 잘못 분류하는 Margin violation(마진 오류)에 대한 트레이드 오프 관계에서 균형을 잘 잡아야합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfbpsP/btqVvOpyHbV/NVIs0nm0K0RqLEKJMhXKFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfbpsP/btqVvOpyHbV/NVIs0nm0K0RqLEKJMhXKFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfbpsP/btqVvOpyHbV/NVIs0nm0K0RqLEKJMhXKFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfbpsP%2FbtqVvOpyHbV%2FNVIs0nm0K0RqLEKJMhXKFk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;sklearn의 SVM 모델의 하이퍼 파라미터중 하나인 $C$는 이러한 트레이드 오프를 정하는데 사용됩니다. 이 $C$가 높을 수록 모델은 Margin Violation을 허용하지 않으려 합니다. 반대로 $C$가 낮으면 Margin Violation은 높아지겠지만 일반화가 더 잘될 것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음은 앞서 본 붓꽃 데이터셋에 대해서 feature Scale을 조정한 후, 특정 품종을 감지하기 위해 선형 SVM 모델을 훈련시키는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612191726595&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np
from sklearn import datasets
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC

iris = datasets.load_iris()
X = iris[&quot;data&quot;][:, (2, 3)]  # 꽃잎 길이, 꽃잎 너비
y = (iris[&quot;target&quot;] == 2).astype(np.float64)  # Iris virginica

svm_clf = Pipeline([
        (&quot;scaler&quot;, StandardScaler()),
        (&quot;linear_svc&quot;, LinearSVC(C=1, loss=&quot;hinge&quot;, random_state=42)),
    ])

svm_clf.fit(X, y)

//output
Pipeline(steps=[('scaler', StandardScaler()),
                ('linear_svc', LinearSVC(C=1, loss='hinge', random_state=42))])&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1612191764217&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;svm_clf.predict([[5.5, 1.7]])

//output(예측 결과)
array([1.])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;sklearn의 SVM 모델을 최적화할 땐 보통 SGDClassifier같은 일반적인 Gradient Descent Algorithm을 이용합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.2 비선형 SVM 분류&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;선형 SVM 분류기가 많은 경우에 잘 작동하지만, 선형적으로 분류할 수 없는 데이터셋들 또한 많습니다. 이럴 때 Polynomial Feature과 같은 feature를 추가하는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n7ETO/btqVkLnB0AI/dK54MjR9JrlTOkqInwuaKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n7ETO/btqVkLnB0AI/dK54MjR9JrlTOkqInwuaKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n7ETO/btqVkLnB0AI/dK54MjR9JrlTOkqInwuaKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn7ETO%2FbtqVkLnB0AI%2FdK54MjR9JrlTOkqInwuaKk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;왼쪽 그래프는 $x_1$이라는 하나의 feature만 가지는 데이터셋으로 선형적으로 분류가 안되지만, $x_2=(x_1)^2$라는 새로운 특성을 추가하면 오른쪽처럼 완벽하게 선형적으로 분류가 가능합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 다음과 같이 적용해볼 수 있습니다 사용된 데이터는 Binary Classification의 예시를 들때 자주 사용되는 moon dataset입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612193255006&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.datasets import make_moons
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures

polynomial_svm_clf = Pipeline([
        (&quot;poly_features&quot;, PolynomialFeatures(degree=3)),
        (&quot;scaler&quot;, StandardScaler()),
        (&quot;svm_clf&quot;, LinearSVC(C=10, loss=&quot;hinge&quot;, random_state=42))
    ])

polynomial_svm_clf.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxRhnq/btqVqFUIuhw/lXVDC7xyjjwro5pWMJIKw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxRhnq/btqVqFUIuhw/lXVDC7xyjjwro5pWMJIKw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxRhnq/btqVqFUIuhw/lXVDC7xyjjwro5pWMJIKw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxRhnq%2FbtqVqFUIuhw%2FlXVDC7xyjjwro5pWMJIKw0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.2.1 Polynomial Kernel(다항식 커널)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp; Polynomial Feature를 추가하는 건 모든 머신러닝 알고리즘에서 사용가능한 보편적입니다. 그러나 이런식으로 변형된 높은 차수의 다항식은 모델을 느리게 만듭니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다행히 SVM은 Kernel Trick을 이용하여 실제로는 feature를 추가하지 않으면서 feature를 많이 추가한듯한 결과를 얻을 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp;커널 트릭에 대한 좀 더 자세한 부분은 아래의 이전 포스팅을 참고해주세요&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/27&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[AI/Coursera ( Machine Learning )] - [머신러닝 순한맛] SVM(Supprot Vector Machine)이란? - 3) Kernal&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1612193762965&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] SVM(Supprot Vector Machine)이란? - 3) Kernal&quot; data-og-description=&quot;시작하며 저번 포스팅에서는 SVM의 Margin에 대해 다루며, 선형으로 분리되는 데이터의 Decision Boundary를 어떻게 지정할 것인가에 대해 다뤄보았습니다. 하지만 이 세상의 대부분의 데이터는 대부분&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/27&quot; data-og-url=&quot;https://box-world.tistory.com/27&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/77P3m/hyI83ybHmS/porQdSVzECMQzI9zIrkV00/img.png?width=563&amp;amp;height=367&amp;amp;face=0_0_563_367,https://scrap.kakaocdn.net/dn/dKbK6q/hyI85bIO14/VNhEcpVQIvryST6XtuvZTk/img.png?width=563&amp;amp;height=367&amp;amp;face=0_0_563_367,https://scrap.kakaocdn.net/dn/cjq21y/hyI8XEJ1xK/cZbhINpVE2CXjiEkJ9npB1/img.png?width=1701&amp;amp;height=447&amp;amp;face=0_0_1701_447&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/27&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/27&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/77P3m/hyI83ybHmS/porQdSVzECMQzI9zIrkV00/img.png?width=563&amp;amp;height=367&amp;amp;face=0_0_563_367,https://scrap.kakaocdn.net/dn/dKbK6q/hyI85bIO14/VNhEcpVQIvryST6XtuvZTk/img.png?width=563&amp;amp;height=367&amp;amp;face=0_0_563_367,https://scrap.kakaocdn.net/dn/cjq21y/hyI8XEJ1xK/cZbhINpVE2CXjiEkJ9npB1/img.png?width=1701&amp;amp;height=447&amp;amp;face=0_0_1701_447');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] SVM(Supprot Vector Machine)이란? - 3) Kernal&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 저번 포스팅에서는 SVM의 Margin에 대해 다루며, 선형으로 분리되는 데이터의 Decision Boundary를 어떻게 지정할 것인가에 대해 다뤄보았습니다. 하지만 이 세상의 대부분의 데이터는 대부분&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음은 Polynomial Feature를 추가하여 SVM을 사용하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612193938231&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.svm import SVC

poly_kernel_svm_clf = Pipeline([
        (&quot;scaler&quot;, StandardScaler()),
        (&quot;svm_clf&quot;, SVC(kernel=&quot;poly&quot;, degree=3, coef0=1, C=5))
    ])
poly_kernel_svm_clf.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciJA2S/btqVvOb13wU/xhK3T8QcCggiofbwN6ihI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciJA2S/btqVvOb13wU/xhK3T8QcCggiofbwN6ihI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciJA2S/btqVvOb13wU/xhK3T8QcCggiofbwN6ihI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciJA2S%2FbtqVvOb13wU%2FxhK3T8QcCggiofbwN6ihI0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;왼쪽 그래프는 3차 Polynomial Kernel을, 오른쪽은 10차를 적용하였습니다. 추가하는 feature의 차수가 높아질수록 Margin Violation이 감소되게끔 경계가 변하는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;하이퍼파라미터 $C$는 높은 차수와 낮은 차수에 얼마나 영향을 받을지 결정합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.2.2 유사도 특성&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;유사도 특성은 각 data가 특정 랜드마크와 얼마나 닮았는지를 y값으로 두는 유사도 함수를 이용하는데, y값이 바로 추가된 feature가 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSJb5o/btqVswXvJBn/QIaVaQMkbngFcrFjpYklY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSJb5o/btqVswXvJBn/QIaVaQMkbngFcrFjpYklY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSJb5o/btqVswXvJBn/QIaVaQMkbngFcrFjpYklY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSJb5o%2FbtqVswXvJBn%2FQIaVaQMkbngFcrFjpYklY0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;287&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRIvhF/btqVnYtuCsX/Pz6arUEF1n8LRDNlcA3kKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRIvhF/btqVnYtuCsX/Pz6arUEF1n8LRDNlcA3kKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRIvhF/btqVnYtuCsX/Pz6arUEF1n8LRDNlcA3kKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRIvhF%2FbtqVnYtuCsX%2FPz6arUEF1n8LRDNlcA3kKK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;287&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 왼쪽 그래프처럼 $x_1 = -2$와 $x_1 = 1$를 중심축으로 가지는 $&lt;span&gt;&amp;gamma; = 3&lt;/span&gt;$인 Gaussian RBF를 유사도 함수로 정의합니다. 이때 &lt;span style=&quot;color: #333333;&quot;&gt;$x_1 = -2$와 $x_1 = 1$가 바로 랜드마크입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;쉽게 설명하자면 나머지 데이터들이 정해진 랜드마크와 얼마나 닮았느냐에 대한 수치가 y축인 유사도인것입니다. 예를 들어 랜드마크 $x_1 = -2$에 대해 $x_1 = -1$과 &lt;span style=&quot;color: #333333;&quot;&gt;$x_1 = 4$ 두개에 대해 -1이 -2와 더 가까우므로 유사도가 높은 것입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;이렇게 추가된 feature를 이용하면 오른쪽 그래프처럼 분류가 가능해집니다. 위 예시에서는 데이터들 중 2개만을 랜드마크로 지정했지만 모든 데이터를 랜드마크로 지정하면, 차원이 커지기 때문에 선형적으로 구분될 가능성이 커집니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;다만 n개의 feature를 가지던 m개의 데이터가 m개의 feature를 가지는 m개의 데이터로 변환된다는 것이 리스크로 작용합니다.(기존에 존재하던 feature는 제외한다고 가정합니다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.2.3 Gaussian RBF Kernel&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;앞서 우리는 유사도를 이용하여 feature를 추가하는 방법을 살펴보았습니다. 그런데 이렇게 유사도를 측정하여 feature를 추가하는 방식은 큰 연산 비용을 요구합니다. 여기서 Kernel Trick이 비용을 줄이는데 아주 중요한 작용을 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 다음은 &lt;span style=&quot;color: #333333;&quot;&gt;Gaussian RBF Kernel을 사용한 SVM 모델을 사용하는 코드입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1612195010212&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rbf_kernel_svm_clf = Pipeline([
        (&quot;scaler&quot;, StandardScaler()),
        (&quot;svm_clf&quot;, SVC(kernel=&quot;rbf&quot;, gamma=5, C=0.001))
    ])
rbf_kernel_svm_clf.fit(X, y)

//output
Pipeline(steps=[('scaler', StandardScaler()),
                ('svm_clf', SVC(C=0.001, gamma=5))])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lj7JE/btqVqG0lbiN/iXy87lAvzj1cFbQdFvW4f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lj7JE/btqVqG0lbiN/iXy87lAvzj1cFbQdFvW4f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lj7JE/btqVqG0lbiN/iXy87lAvzj1cFbQdFvW4f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flj7JE%2FbtqVqG0lbiN%2FiXy87lAvzj1cFbQdFvW4f1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 그래프에서 알 수 있듯이 $&lt;span style=&quot;color: #333333;&quot;&gt;&amp;gamma;&lt;/span&gt;$가 커질수록 앞서 봤던 종 모양의 그래프가 좁아지면서 각 데이터의 영향 범위가 줄어드는 효과를 가져옵니다. 이에 따라 경계는 좀더 구불구불해지고 불규칙해집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 밖에 다른 커널들도 많이 존재하지만 거의 쓰이지 않습니다. 대부분은 선형 커널(LinearSVC)와 Gaussian RBF Kernel에서 문제가 해결됩니다.&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.3 SVM을 이용한 Regression&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;SVM은 Classification 뿐 아니라 Regression에도 이용될 수 있습니다. 원리는 간단합니다. Regression에서는 도로 경계안에 최대한 많은 데이터들을 담아 데이터를 대표하려고 하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6m7io/btqVe8DM4WI/F4BRiML81390rKJQdKaeH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6m7io/btqVe8DM4WI/F4BRiML81390rKJQdKaeH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6m7io/btqVe8DM4WI/F4BRiML81390rKJQdKaeH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6m7io%2FbtqVe8DM4WI%2FF4BRiML81390rKJQdKaeH0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;즉 일정한 Margin Violation 아래에서 가능한 많은 데이터가 도로안에 들어가도록 학습니다. 이때 도로의 폭인 Margin은&amp;nbsp; 위와 같이 하이퍼파라미터로 조절 가능하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 sklearn의 LinearSVR을 이용한 선형 SVM Regression을 적용하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612195579480&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.svm import LinearSVR

svm_reg = LinearSVR(epsilon=1.5, random_state=42)
svm_reg.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 다음은 2차 Polynomial Kernel을 사용한 SVM Regression입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1612195732241&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.svm import SVR

svm_poly_reg = SVR(kernel=&quot;poly&quot;, degree=2, C=100, epsilon=0.1, gamma=&quot;scale&quot;)
svm_poly_reg.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/953Fs/btqVdNfrHev/Kv6jayi1xQy2nCKSzy0K60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/953Fs/btqVdNfrHev/Kv6jayi1xQy2nCKSzy0K60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/953Fs/btqVdNfrHev/Kv6jayi1xQy2nCKSzy0K60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F953Fs%2FbtqVdNfrHev%2FKv6jayi1xQy2nCKSzy0K60%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음 포스팅에서는 SVM만큼이나 보편적으로 사용되는 Decision Tree에 대해서 공부해보겠습니다. 긴글 읽어주셔서 감사합니다. 오늘도 행복한 하루 보내세요 :)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>deep learning</category>
      <category>kernel</category>
      <category>Machine Learning</category>
      <category>PYTHON</category>
      <category>regression</category>
      <category>sklearn</category>
      <category>SVM</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>핸즈온</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/58</guid>
      <comments>https://box-world.tistory.com/58#entry58comment</comments>
      <pubDate>Tue, 2 Feb 2021 01:11:53 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] ExpansionTile로 숨김 / 드러내기 기능 구현해보기!</title>
      <link>https://box-world.tistory.com/57</link>
      <description>&lt;p&gt;&amp;nbsp;안녕하세요 이번 포스팅에서는 Flutter의 ExpansionTile로 우리가 평소 여러 앱에서 보던 정보 숨기기 / 드러내기 기능을 구현해보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ExpansionTile&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우선 코드부터 보시겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1610443990644&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ExpansionTile(
                  title: new Text('기본 정보',
                    style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: screenWidth*(16 /360),
                        color: Colors.black
                    ),
                  ),
                  initiallyExpanded: true,
                  backgroundColor: Colors.white,
                  children: &amp;lt;Widget&amp;gt;[
                    Divider(height: 3,color: OptionDivideLineColor,),
                    Container(
                      height: screenHeight*0.05,
                      width: screenWidth,
                      child: Padding(
                        padding: EdgeInsets.symmetric(horizontal: screenWidth*0.0444444),
                        child: Row(
                          children: [
                            SizedBox(
                              width: screenWidth*0.24444,
                              child: Text('기존 월세',
                                style: TextStyle(
                                  color: hexToColor(&quot;#888888&quot;),
                                  fontSize: screenWidth*OptionFontSize,
                                ),),
                            ),
                            Text('234만원',
                              style: TextStyle(
                                color: Colors.black,
                                fontSize:screenWidth*OptionFontSize,
                              ),),
                          ],
                        ),
                      ),
                    ),
                    Divider(height: 3,color: OptionDivideLineColor,),
                    Container(
                      height: screenHeight*0.05,
                      width: screenWidth,
                      child: Padding(
                        padding: EdgeInsets.symmetric(horizontal: screenWidth*0.0444444),
                        child: Row(
                          children: [
                            SizedBox(
                              width: screenWidth*0.24444,
                              child: Text('기존 보증금',
                                style: TextStyle(
                                  color: hexToColor(&quot;#888888&quot;),
                                  fontSize: screenWidth*OptionFontSize,
                                ),),
                            ),
                            Text('234만원',
                              style: TextStyle(
                                color: Colors.black,
                                fontSize:screenWidth*OptionFontSize,
                              ),),
                          ],
                        ),
                      ),
                    ),
                    Divider(height: 3,color: OptionDivideLineColor,),
                    Container(
                      height: screenHeight*0.05,
                      width: screenWidth,
                      child: Padding(
                        padding: EdgeInsets.symmetric(horizontal: screenWidth*0.0444444),
                        child: Row(
                          children: [
                            SizedBox(
                              width: screenWidth*0.24444,
                              child: Text('평균 공과금',
                                style: TextStyle(
                                  color: hexToColor(&quot;#888888&quot;),
                                  fontSize: screenWidth*OptionFontSize,
                                ),),
                            ),
                            Text('234만원',
                              style: TextStyle(
                                color: Colors.black,
                                fontSize:screenWidth*OptionFontSize,
                              ),),
                          ],
                        ),
                      ),
                    ),
                  ]
              ),&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 실행한 결과입니다.&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/channel/3737436/cliplink/415723447&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/dof9Wy/hyIUy65bZK/dexqZZkI2RHXZbo5a3WG3k/img.jpg?width=368&amp;amp;height=156&amp;amp;face=0_0_368_156&quot; data-video-width=&quot;368&quot; data-video-height=&quot;156&quot; data-video-origin-width=&quot;368&quot; data-video-origin-height=&quot;156&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-play-service=&quot;daum_tistory&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/415723447?service=daum_tistory&quot; width=&quot;368&quot; height=&quot;156&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Option&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 여러 옵션에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- backgroundColor : ExpansionTile의 기본 색깔을 결정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- children [] : 펼쳤을 때 보이는 부분입니다. Container 등 자유롭게 넣으시면 됩니다. 일반적으로는 ListView는 많이 넣습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- title : ExpansionTile의 제목입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- initiallyExpanded : true로 설정 시 처음 들어왔을 때, 펼쳐져있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- onExpansionChanged : 펼쳐지거나 접혀지는 이벤트가 발생 시 실행할 액션을 담습니다. onTap이나 onPressed와 같은 맥락입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;읽어주셔서 감사합니다. 질문이 있다면 언제든 남겨주세요 :)&lt;/p&gt;</description>
      <category>개발/Flutter</category>
      <category>Android</category>
      <category>App</category>
      <category>DART</category>
      <category>ExpansionTile</category>
      <category>flutter</category>
      <category>google</category>
      <category>IOS</category>
      <category>Kotlin</category>
      <category>SWIFT</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/57</guid>
      <comments>https://box-world.tistory.com/57#entry57comment</comments>
      <pubDate>Tue, 12 Jan 2021 18:56:13 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] File Image 렌더링하기</title>
      <link>https://box-world.tistory.com/56</link>
      <description>&lt;p&gt;&amp;nbsp;이번 포스팅에서는 File 형식의 Image를 화면에 렌더링하는 코드를 소개해드리겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1609860879814&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;File f;//File 선언

Container(
	width: 100,
	height: 100,
	decoration: BoxDecoration(
	    image: DecorationImage(
	        image: FileImage(f),//File Image를 삽입
	        fit: BoxFit.cover)),
 )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yomC2/btqSDuozJV4/Q6EGJW87LH0ZlytOfRcMvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yomC2/btqSDuozJV4/Q6EGJW87LH0ZlytOfRcMvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yomC2/btqSDuozJV4/Q6EGJW87LH0ZlytOfRcMvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyomC2%2FbtqSDuozJV4%2FQ6EGJW87LH0ZlytOfRcMvK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;방금과 같이 File을 핸들링하면 위와 같이 정상적으로 화면에 이미지가 비춰지는 것을 보실 수 있습니다.&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>개발/Flutter</category>
      <category>Android</category>
      <category>Apple</category>
      <category>DART</category>
      <category>file</category>
      <category>flutter</category>
      <category>google</category>
      <category>image</category>
      <category>IOS</category>
      <category>안드로이드</category>
      <category>플러터</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/56</guid>
      <comments>https://box-world.tistory.com/56#entry56comment</comments>
      <pubDate>Wed, 6 Jan 2021 00:38:43 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter ] 갤러리 혹은 카메라에서 사진 가져오기</title>
      <link>https://box-world.tistory.com/55</link>
      <description>&lt;p&gt;&amp;nbsp;이번 포스팅에서는 Flutter에서 갤러리 혹은 카메라에서 사진을 'File'형식으로 가져오는 코드를 소개해드리겠습니다.&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1) 갤러리에서 가져오기&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1609859952567&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PickedFile f = await ImagePicker().getImage(source: ImageSource.gallery);//갤러리에서 사진을 가져옵니다.
File dummyFile = File(f.path);//가져온 사진의 Type을 File 형식으로 바꿔줍니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2) 카메라&lt;span style=&quot;color: #333333;&quot;&gt;에서 가져오기&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1609859994173&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PickedFile f = await ImagePicker().getImage(source: ImageSource.camera);//갤러리에서 사진을 가져옵니다.
File dummyFile = File(f.path);//가져온 사진의 Type을 File 형식으로 바꿔줍니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/channel/3737436/cliplink/415530049&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/AUkpa/hyIPFxRQT2/zkvHjAeNftY3TwSNgFWfR0/img.jpg?width=368&amp;amp;height=612&amp;amp;face=0_0_368_612&quot; data-video-width=&quot;368&quot; data-video-height=&quot;612&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-play-service=&quot;daum_tistory&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/415530049?service=daum_tistory&quot; width=&quot;368&quot; height=&quot;612&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;이렇게 해서 얻은 File 형식의 사진 파일은 위와 같이 활용될 수 있습니다.&lt;/p&gt;
&lt;p&gt;File 형식의 Image를 화면에 렌더링 하는법을 알고싶다면 다음 포스팅을 참고해주세요 :)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/56&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Flutter] - [ Flutter ] File Image 렌더링하기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1609861233701&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ Flutter ] File Image 렌더링하기&quot; data-og-description=&quot;&amp;nbsp;이번 포스팅에서는 File 형식의 Image를 화면에 렌더링하는 코드를 소개해드리겠습니다. File f;//File 선언 Container( width: 100, height: 100, decoration: BoxDecoration( image: DecorationImage( image:..&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/56&quot; data-og-url=&quot;https://box-world.tistory.com/56&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bWLeht/hyIPI9dQUE/AbuoYw5MJQWG5RnlOmWJl1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/vjlt2/hyIPx0VJHO/rCV9Ads5bV9LOpKgAs1BN1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/QuE5K/hyIPLSqmQs/A0SECdkJ5BtJCEFnVStJkk/img.png?width=368&amp;amp;height=607&amp;amp;face=0_0_368_607&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/56&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/56&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bWLeht/hyIPI9dQUE/AbuoYw5MJQWG5RnlOmWJl1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/vjlt2/hyIPx0VJHO/rCV9Ads5bV9LOpKgAs1BN1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/QuE5K/hyIPLSqmQs/A0SECdkJ5BtJCEFnVStJkk/img.png?width=368&amp;amp;height=607&amp;amp;face=0_0_368_607');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ Flutter ] File Image 렌더링하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;이번 포스팅에서는 File 형식의 Image를 화면에 렌더링하는 코드를 소개해드리겠습니다. File f;//File 선언 Container( width: 100, height: 100, decoration: BoxDecoration( image: DecorationImage( image:..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>개발/Flutter</category>
      <category>Android</category>
      <category>DART</category>
      <category>flutter</category>
      <category>google</category>
      <category>image</category>
      <category>IOS</category>
      <category>Kotlin</category>
      <category>picker</category>
      <category>안드로이드</category>
      <category>앱</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/55</guid>
      <comments>https://box-world.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 6 Jan 2021 00:30:00 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈온 머신러닝 2판 ] 로지스틱 회귀(Logistic Regression)이란?</title>
      <link>https://box-world.tistory.com/54</link>
      <description>&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;당신은 뭔가 더 대단한 것을 해낼 수 있다.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 칼로스&amp;nbsp;&lt;/span&gt;M.구티에레즈미국&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;상무장관 -&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/h4&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.6 로지스틱 회귀(Logistic Regression)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;본래 회귀(Regression)은 값을 예측할 때 쓰이지만, &lt;b&gt;Logistic Regression&lt;/b&gt;은 데이터가 어떤 클래스에 속하는지 &lt;b&gt;분류&lt;/b&gt;하는데 사용됩니다. 다시 말해서 Logistic Regression은 어떤 데이터가 특정 클래스일 확률을 결과값으로 도출하기 때문에 회귀에 속하는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 어떤 이메일이 스팸인지 아닌지를 분류할 때, 데이터를 Logistic Regression을 이용하여 추정할 때 결과값이 0.6이 나오면 해당 데이터가 스팸일 확률이 60%라는 것이고 이 경우 해당 메일을 스팸으로 분류하는 식입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.6.1 확률 추정&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Logistic Regression의 작동 방식에 대해 알아보겠습니다. 우선 처음엔 데이터를 집어넣으면 &lt;b&gt;각 feature의 가중치 합을 계산합니다.&lt;/b&gt; 여기까지가 일반적인 Linear Model의 결과값 도출방식입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;하지만 Logistic Regression에서는 이것을 &lt;b&gt;시그모이드 함수(sigmoid function)&lt;/b&gt;으로 감싸서 0과 1사이의 값이 나오도록 바꿔줍니다. 왜일까요? 당연히 데이터를 특정 클래스로 분류해야하기 때문에 &lt;b&gt;0~1사이의 확률값&lt;/b&gt;으로 변환해야하는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CPQDb/btqJVOPSqjb/7lHLGq2TBH8F1dr1k5utuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CPQDb/btqJVOPSqjb/7lHLGq2TBH8F1dr1k5utuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CPQDb/btqJVOPSqjb/7lHLGq2TBH8F1dr1k5utuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCPQDb%2FbtqJVOPSqjb%2F7lHLGq2TBH8F1dr1k5utuk%2Fimg.png&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 시그모이드 함수의 형태는 다음과 같으며, t에 대한 함수값이 0과 1 사이에서 존재하는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;293&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buKE8x/btqJXVN3WTD/gmTlq61dJdbCkNKVGUN2I1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buKE8x/btqJXVN3WTD/gmTlq61dJdbCkNKVGUN2I1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buKE8x/btqJXVN3WTD/gmTlq61dJdbCkNKVGUN2I1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuKE8x%2FbtqJXVN3WTD%2FgmTlq61dJdbCkNKVGUN2I1%2Fimg.png&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;293&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 함수를 거쳐나온 확률값으로 최종적으로 주어진 데이터가 어느 클래스에 속하는지 결정하게 됩니다. &lt;b&gt;보통 확률값이 0.5 이상이면 1 (양성 클래스), 이하면 0 (음성 클래스)라고 예측합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;b&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.6.2 훈련과 Cost 함수&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Logistic Regression에서 훈련의 목적은 &lt;b&gt;양성인 데이터 (y = 1)에 대해서는 높은 확률값을 도출하고 음성인 데이터(y=0)에 대해서는 낮은 확률값을 도출하는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Logistic Regression의 &lt;b&gt;Cost 함수&lt;/b&gt;는 이러한 아이디어를 잘 반영하고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxtBNo/btqJVPVAAXx/AWcH2H6KkGJhGNinyXgTJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxtBNo/btqJVPVAAXx/AWcH2H6KkGJhGNinyXgTJk/img.png&quot; data-alt=&quot;Cost 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxtBNo/btqJVPVAAXx/AWcH2H6KkGJhGNinyXgTJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxtBNo%2FbtqJVPVAAXx%2FAWcH2H6KkGJhGNinyXgTJk%2Fimg.png&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cost 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 예를 들어 데이터는 음성에 가까운데 ( 확률값인 t는 0에 가깝다 ) 이를 양성 클래스로 예측하면 - log(t)는 매우 커지므로 잘못된 예측이라는 것을 알 수 있습니다. 혹은 데이터는 양성에 가까운데 ( 확률값인 t는 1에 가깝다 ) 이를 음성 클래스로 예측하면 마찬가지로 -log(1-t)는 매우 커진다는 것을 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;반대로 데이터도 양성이고 예측도 양성이라면, -log(t)는 0에 가까워지고, 데이터도 음성이고 예측도 음성이 되면 -log(1-t)는 역시 0에 가까워집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;방금 우리가 한 것은 하나의 데이터에 대해 Cost를 계산하는 과정이었습니다. &lt;b&gt;전체 데이터에 대한 Cost&lt;/b&gt;는 모든 dataset의 Cost를 평균내는 것이고 이를 &lt;b&gt;로그 손실(log loss)&lt;/b&gt;라고 부르며 다음과 같은 식으로 표현합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XUDId/btqJ0ohUa3s/UTH80Ya8WKOqzgEZP5vqC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XUDId/btqJ0ohUa3s/UTH80Ya8WKOqzgEZP5vqC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XUDId/btqJ0ohUa3s/UTH80Ya8WKOqzgEZP5vqC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXUDId%2FbtqJ0ohUa3s%2FUTH80Ya8WKOqzgEZP5vqC1%2Fimg.png&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 Cost 함수는 &lt;b&gt;Gradient Descent Algorithm&lt;/b&gt;으로 최적화가 가능합니다. 특히 Cost 함수가 &lt;b&gt;볼록 함수&lt;/b&gt;이기 때문에 거의 &lt;b&gt;Global minimum(전역 최솟값)&lt;/b&gt;을 찾는 것을 보장합니다.&lt;/p&gt;
&lt;p&gt;다만 아쉽게도 Normal Equation( 정규 방정식 )과 같이 단번에 최적화하는 방법은 없습니다.&lt;/p&gt;
&lt;p&gt;다음은 최적화에 이용하는 &lt;b&gt;Cost 함수의 편도함수&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;123&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0QhN9/btqJWsMnJXk/NWffQctEa9hcqK4D0zqIyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0QhN9/btqJWsMnJXk/NWffQctEa9hcqK4D0zqIyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0QhN9/btqJWsMnJXk/NWffQctEa9hcqK4D0zqIyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0QhN9%2FbtqJWsMnJXk%2FNWffQctEa9hcqK4D0zqIyk%2Fimg.png&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;123&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.6.3 결정 경계&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이제 &lt;b&gt;세 가지의 서로 다른 꽃 품종을 Logistic Regression으로 분류하는 예시&lt;/b&gt;를 통해 설명을 계속 이어가보겠습니다. 우리가 사용할 데이터에는 &lt;b&gt;꽃의 꽃잎&lt;/b&gt;, &lt;b&gt;꽃받침의 너비&lt;/b&gt;와 &lt;b&gt;길이&lt;/b&gt;를 담고 있습니다. 여기서는&lt;b&gt; 꽃잎의 너비를 기반으로 Iris-Versicolor종을 감지하는 분류기&lt;/b&gt;를 만들어볼 것입니다. 우선 데이터를 로드해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601472771423&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn import datasets
iris = datasets.load_iris()
list(iris.keys())
&amp;gt;&amp;gt; 
['data',
 'target',
 'frame',
 'target_names',
 'DESCR',
 'feature_names',
 'filename']
 &lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1601472790791&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X = iris[&quot;data&quot;][:, 3:]  # 꽃잎 너비
y = (iris[&quot;target&quot;] == 2).astype(np.int)  # Iris virginica이면 1 아니면 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Logistic Regression 모델을 훈련시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601472833353&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression(solver=&quot;lbfgs&quot;, random_state=42)
log_reg.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 꽃잎의 너비가 0~3cm인 꽃들에 대해 &lt;b&gt;꽃잎의 너비&lt;/b&gt;에 따라 모델이 어떤것을 Iris-Versicolor종으로 분류하는 살펴보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601472928232&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X_new = np.linspace(0, 3, 1000).reshape(-1, 1)
y_proba = log_reg.predict_proba(X_new)
decision_boundary = X_new[y_proba[:, 1] &amp;gt;= 0.5][0]

plt.figure(figsize=(8, 3))
plt.plot(X[y==0], y[y==0], &quot;bs&quot;)
plt.plot(X[y==1], y[y==1], &quot;g^&quot;)
plt.plot([decision_boundary, decision_boundary], [-1, 2], &quot;k:&quot;, linewidth=2)
plt.plot(X_new, y_proba[:, 1], &quot;g-&quot;, linewidth=2, label=&quot;Iris virginica&quot;)
plt.plot(X_new, y_proba[:, 0], &quot;b--&quot;, linewidth=2, label=&quot;Not Iris virginica&quot;)
plt.text(decision_boundary+0.02, 0.15, &quot;Decision  boundary&quot;, fontsize=14, color=&quot;k&quot;, ha=&quot;center&quot;)
plt.arrow(decision_boundary, 0.08, -0.3, 0, head_width=0.05, head_length=0.1, fc='b', ec='b')
plt.arrow(decision_boundary, 0.92, 0.3, 0, head_width=0.05, head_length=0.1, fc='g', ec='g')
plt.xlabel(&quot;Petal width (cm)&quot;, fontsize=14)
plt.ylabel(&quot;Probability&quot;, fontsize=14)
plt.legend(loc=&quot;center left&quot;, fontsize=14)
plt.axis([0, 3, -0.02, 1.02])
save_fig(&quot;logistic_regression_plot&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qCFXc/btqJUMZxbVg/hOJEZtZXpKznPyzcggnUCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qCFXc/btqJUMZxbVg/hOJEZtZXpKznPyzcggnUCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qCFXc/btqJUMZxbVg/hOJEZtZXpKznPyzcggnUCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqCFXc%2FbtqJUMZxbVg%2FhOJEZtZXpKznPyzcggnUCk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&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;1) Iris-Verginica의 꽃잎 너비는 1.4cm~2.5cm 사이입니다. 반면 다른 꽃들의 꽃잎 너비는 0.1 ~ 1.8cm 사이로 약간 중첩됩니다.&lt;/li&gt;
&lt;li&gt;2) 꽃잎의 너비가 2cm가 넘어가면 &lt;span style=&quot;color: #333333;&quot;&gt;Iris-Verginica라고 강하게 확신합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3) 양쪽의 확률이 똑같이 50%가 되는 1.6cm 근방에서 결정 경계(decision boundary)가 생성됩니다. 바로 이 decision boundary를 기준으로 이것보다 꽃잎의 너비가 크면 &lt;span style=&quot;color: #333333;&quot;&gt;Iris-Verginica라고 예측할 것입니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1601473151399&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;log_reg.predict([[1.7], [1.5]]) #1.7은 양성, 1.5는 음성으로 분류하였습니다.
&amp;gt;&amp;gt; array([1, 0])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;이번에는 꽃잎의 너비에 꽃잎의 길이까지 더하여 &lt;b&gt;두개의 feature&lt;/b&gt;를 이용해 클래스를 예측해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601473240100&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import LogisticRegression

X = iris[&quot;data&quot;][:, (2, 3)]  # petal length, petal width
y = (iris[&quot;target&quot;] == 2).astype(np.int)

log_reg = LogisticRegression(solver=&quot;lbfgs&quot;, C=10**10, random_state=42)
log_reg.fit(X, y)

x0, x1 = np.meshgrid(
        np.linspace(2.9, 7, 500).reshape(-1, 1),
        np.linspace(0.8, 2.7, 200).reshape(-1, 1),
    )
X_new = np.c_[x0.ravel(), x1.ravel()]

y_proba = log_reg.predict_proba(X_new)

plt.figure(figsize=(10, 4))
plt.plot(X[y==0, 0], X[y==0, 1], &quot;bs&quot;)
plt.plot(X[y==1, 0], X[y==1, 1], &quot;g^&quot;)

zz = y_proba[:, 1].reshape(x0.shape)
contour = plt.contour(x0, x1, zz, cmap=plt.cm.brg)


left_right = np.array([2.9, 7])
boundary = -(log_reg.coef_[0][0] * left_right + log_reg.intercept_[0]) / log_reg.coef_[0][1]

plt.clabel(contour, inline=1, fontsize=12)
plt.plot(left_right, boundary, &quot;k--&quot;, linewidth=3)
plt.text(3.5, 1.5, &quot;Not Iris virginica&quot;, fontsize=14, color=&quot;b&quot;, ha=&quot;center&quot;)
plt.text(6.5, 2.3, &quot;Iris virginica&quot;, fontsize=14, color=&quot;g&quot;, ha=&quot;center&quot;)
plt.xlabel(&quot;Petal length&quot;, fontsize=14)
plt.ylabel(&quot;Petal width&quot;, fontsize=14)
plt.axis([2.9, 7, 0.8, 2.7])
save_fig(&quot;logistic_regression_contour_plot&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbHxwq/btqJVPnIEiC/LCsCBfsd64h1K6DqGaPyTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbHxwq/btqJVPnIEiC/LCsCBfsd64h1K6DqGaPyTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbHxwq/btqJVPnIEiC/LCsCBfsd64h1K6DqGaPyTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbHxwq%2FbtqJVPnIEiC%2FLCsCBfsd64h1K6DqGaPyTK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 위 그래프에서 &lt;b&gt;decision boundary&lt;/b&gt;는 검은색 점선입니다. 이외에 주목할 점으로는 0.900이라고 명시된 초록색 선 위에 있는 데이터는 90% 이상의 확률로 &lt;span style=&quot;color: #333333;&quot;&gt;Iris-Verginica로 분류된 데이입니다. 그리고 0.150이라고 명시된 파란색 선 아래에는 15% 미만으로 음성 클래스로 분류된 데이터들입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.6.4 소프트맥스 회귀(Softmax Regression)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;우리가 앞서 봤던 Logistic Regression은 &lt;b&gt;이진 분류(Binary Classification)&lt;/b&gt; 즉 1이냐 0이냐였습니다. &lt;b&gt;Softmax Regression&lt;/b&gt;은 두 가지 이상의 클래스를 분류하는데 사용하는 Logistic Regression입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpfiv4/btqJU5EAWYd/vQqtOGrlgmFpK9r4WI8E0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpfiv4/btqJU5EAWYd/vQqtOGrlgmFpK9r4WI8E0K/img.png&quot; data-alt=&quot;데이터 x가 클래스 k에 대한 softmax 점수를 산출하는 식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpfiv4/btqJU5EAWYd/vQqtOGrlgmFpK9r4WI8E0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcpfiv4%2FbtqJU5EAWYd%2FvQqtOGrlgmFpK9r4WI8E0K%2Fimg.png&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터 x가 클래스 k에 대한 softmax 점수를 산출하는 식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;데이터가 주어지면 Softmax Regression 모델은 해당 데이터가 각 클래스에 대한 &lt;b&gt;점수를 계산&lt;/b&gt;하고,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;138&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/doPvbs/btqJVPnIWIE/Epvet5o5vxkq5dlmhrw4K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doPvbs/btqJVPnIWIE/Epvet5o5vxkq5dlmhrw4K0/img.png&quot; data-alt=&quot;softmax 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doPvbs/btqJVPnIWIE/Epvet5o5vxkq5dlmhrw4K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoPvbs%2FbtqJVPnIWIE%2FEpvet5o5vxkq5dlmhrw4K0%2Fimg.png&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;138&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;softmax 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;softmax 함수를 이용하여 이 점수를 &lt;b&gt;확률값&lt;/b&gt;으로 바꾸게 됩니다. 그리고 가장 높은 확률값을 가진 클래스로 데이터 x를 분류하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5E5f1/btqJVoqqSvg/ebELu58xJIKDDjFhs9oJP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5E5f1/btqJVoqqSvg/ebELu58xJIKDDjFhs9oJP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5E5f1/btqJVoqqSvg/ebELu58xJIKDDjFhs9oJP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5E5f1%2FbtqJVoqqSvg%2FebELu58xJIKDDjFhs9oJP0%2Fimg.png&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;99&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이제 모델의 훈련 방법에 대해 알아보겠습니다. 우리의 목적은 타깃(정답) 클래스에 대해서는 높은 확률을, 나머지는 낮은 확률을 추정하도록 하는것이 목표입니다. 여기에 &lt;b&gt;Cross-Entropy Cost 함수&lt;/b&gt;를 사용합니다. 그리고 이를 최적화하기 위한 Gradient Vector는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;117&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tsmrq/btqJVoqqVdi/ccKhUuX64lVBcnhpRWOPhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tsmrq/btqJVoqqVdi/ccKhUuX64lVBcnhpRWOPhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tsmrq/btqJVoqqVdi/ccKhUuX64lVBcnhpRWOPhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftsmrq%2FbtqJVoqqVdi%2FccKhUuX64lVBcnhpRWOPhk%2Fimg.png&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;117&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음은 sklearn에서 Softmax Regression을 적용하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601474700401&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X = iris[&quot;data&quot;][:, (2, 3)]  # 꽃잎 길이, 꽃잎 너비
y = iris[&quot;target&quot;]

softmax_reg = LogisticRegression(multi_class=&quot;multinomial&quot;,solver=&quot;lbfgs&quot;, C=10, random_state=42)
softmax_reg.fit(X, y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 꽃잎의 길이가 5cm, 너비가 2cm인 꽃의 품종이 무엇인지 모델에 물어봤더니 94.2% 확률로 &lt;span style=&quot;color: #333333;&quot;&gt;Iris-Verginica라고 출력하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1601474792337&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;softmax_reg.predict([[5, 2]])
&amp;gt;&amp;gt; array([2])
&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1601474805775&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;softmax_reg.predict_proba([[5, 2]])
&amp;gt;&amp;gt; array([[6.38014896e-07, 5.74929995e-02, 9.42506362e-01]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;앞서 우리는 세개의 품종에 대해 &lt;span style=&quot;color: #333333;&quot;&gt;Iris-Verginica를 감지하는 분류기에 대해서 다뤄봤습니다. 그리고 다음에서 세 개의 클래스에 대해 decision boundary를 어떻게 형성하는지 살펴보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0cqKW/btqJZmxTeIG/mqXqrqFjAXbvmpvk35wRCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0cqKW/btqJZmxTeIG/mqXqrqFjAXbvmpvk35wRCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0cqKW/btqJZmxTeIG/mqXqrqFjAXbvmpvk35wRCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0cqKW%2FbtqJZmxTeIG%2FmqXqrqFjAXbvmpvk35wRCk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&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;1) class 사이의 decision boundary는 &lt;b&gt;선형&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li&gt;2) 모든 결정 경계가 만나는 지점에서는 클래스가 모두 동일하게 &lt;b&gt;33%의 추정 확률&lt;/b&gt;을 가집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음 포스팅에서는 Logistic Regression과 함께 Classification에 사용되는 대표적인 방법인 SVM (Support Vector Machine)에 대해 공부해보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;긴 글 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>hands on</category>
      <category>PYTHON</category>
      <category>regression</category>
      <category>sklearn</category>
      <category>softmax</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>핸즈 온 머신러닝</category>
      <category>회귀</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/54</guid>
      <comments>https://box-world.tistory.com/54#entry54comment</comments>
      <pubDate>Wed, 30 Sep 2020 23:24:41 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈온 머신러닝 2판 ] Linear Regression 속  Regularization이란?</title>
      <link>https://box-world.tistory.com/53</link>
      <description>&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;&quot;이끌거나, 따르거나, 비켜서라.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;&lt;b&gt;-&amp;nbsp;Ted Turner (CNN 설립자) -&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.5 선형 모델(Linear Model)에서의 규제(Regularization)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Regularization&lt;/b&gt;은 모델이 &lt;b&gt;Overfit&lt;/b&gt;되었을 때, 이를 감소시키는 대표적인 방법입니다. &lt;b&gt;다항 회귀(Polynomial Regression)&lt;/b&gt;에서는 단순히 차수를 감소시키는 것으로 Regularization이 가능합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;선형 회귀(Linear Regression)&lt;/b&gt;에서는 모델의 가중치를 제한하여 Regulariztion이 이뤄집니다. 여기에서 세 가지 방법이 있는데 이제부터 하나하나 살펴 보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.5.1 릿지 회귀(Ridge Regularization)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxIaG1/btqJVpChvFE/M1vRNJ3JD0vW3exPsFFKeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxIaG1/btqJVpChvFE/M1vRNJ3JD0vW3exPsFFKeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxIaG1/btqJVpChvFE/M1vRNJ3JD0vW3exPsFFKeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxIaG1%2FbtqJVpChvFE%2FM1vRNJ3JD0vW3exPsFFKeK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Linear Regression에 &lt;b&gt;Regularization 항&lt;/b&gt;이 추가된 것이 Ridge regression입니다. &lt;b&gt;Regularization 항은 훈련하는 동안에만 Cost 함수에 존재하고, 성능을 평가할 때는 포함하지 않습니다.&lt;/b&gt;&amp;nbsp;위 식이 어떻게 Overfit을 억제하는 것일까요?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 $&lt;span&gt;&amp;theta;&lt;/span&gt;$는 가중치입니다. 기본적으로 우리는 Cost가 최소가 되길 원합니다. 그런데 Regularization으로 인해 기존보다 $&lt;span&gt;&amp;theta;_i^2&lt;/span&gt;$들이 더해졌습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;그러면 모델을 학습시키는 입장에서는 Cost를 최소화하기 위해 $&lt;span&gt;&amp;theta;_i&lt;/span&gt;$를 기존보다 더 작게 설정해야할 것입니다.&lt;/b&gt; 그렇게 하면 보통 높은 차수에 곱해지는 가중치 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;theta;_i&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$는 0에 가까워져 없어지면서 차수가 내려가게 되면서 Overfit을 막게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;하이퍼파라미터 $&lt;span&gt;&amp;alpha;&lt;/span&gt;$는 &lt;b&gt;모델을 얼마나 Regularization할지 결정합니다.&lt;/b&gt; 이것이 커지면 커질수록 추가로 더해지는 가중치의 총합은 커지기 때문에 모델 학습이 이 가중치를 더욱 낮게 설정하려 하면서 차수가 더욱 낮아질 것입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;반대로 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;alpha;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$가 0이라면 기존에 우리가 알던 Cost함수와 동일해집니다. 다음은 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;alpha;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$의 변화에 따른 Ridge Regression의 훈련 결과입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1601394739716&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import Ridge

def plot_model(model_class, polynomial, alphas, **model_kargs):
    for alpha, style in zip(alphas, (&quot;b-&quot;, &quot;g--&quot;, &quot;r:&quot;)):
        model = model_class(alpha, **model_kargs) if alpha &amp;gt; 0 else LinearRegression()
        if polynomial:
            model = Pipeline([
                    (&quot;poly_features&quot;, PolynomialFeatures(degree=10, include_bias=False)),
                    (&quot;std_scaler&quot;, StandardScaler()),
                    (&quot;regul_reg&quot;, model),
                ])
        model.fit(X, y)
        y_new_regul = model.predict(X_new)
        lw = 2 if alpha &amp;gt; 0 else 1
        plt.plot(X_new, y_new_regul, style, linewidth=lw, label=r&quot;$\alpha = {}$&quot;.format(alpha))
    plt.plot(X, y, &quot;b.&quot;, linewidth=3)
    plt.legend(loc=&quot;upper left&quot;, fontsize=15)
    plt.xlabel(&quot;$x_1$&quot;, fontsize=18)
    plt.axis([0, 3, 0, 4])

plt.figure(figsize=(8,4))
plt.subplot(121)
plot_model(Ridge, polynomial=False, alphas=(0, 10, 100), random_state=42)
plt.ylabel(&quot;$y$&quot;, rotation=0, fontsize=18)
plt.subplot(122)
plot_model(Ridge, polynomial=True, alphas=(0, 10**-5, 1), random_state=42)

save_fig(&quot;ridge_regression_plot&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;아래 그래프에서 왼쪽은 일반적인 Linear model, 오른쪽은 Polynomial Regression으로 데이터를 10차로 확장한 후 Regularization을 적용하였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KtFrQ/btqJTGriT9E/qZNEoQnHJR1crMWjrDxkC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KtFrQ/btqJTGriT9E/qZNEoQnHJR1crMWjrDxkC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KtFrQ/btqJTGriT9E/qZNEoQnHJR1crMWjrDxkC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKtFrQ%2FbtqJTGriT9E%2FqZNEoQnHJR1crMWjrDxkC0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt; Ridge Regression의 최적화&lt;/b&gt;는 Linear Regression과 마찬가지로 &lt;b&gt;경사 하강법(Gradient Descent Algorithm)&lt;/b&gt;과 &lt;b&gt;정규 방정식(Normal Equation)&lt;/b&gt;이 모두 적용가능합니다. 다음은 Ridge Regression에서 Normal Equation을 적용하는 방법입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HhCAY/btqJWsZnlnu/BBudxSqzckVGD8vGhSHKKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HhCAY/btqJWsZnlnu/BBudxSqzckVGD8vGhSHKKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HhCAY/btqJWsZnlnu/BBudxSqzckVGD8vGhSHKKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHhCAY%2FbtqJWsZnlnu%2FBBudxSqzckVGD8vGhSHKKk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 sklearn에서 &lt;b&gt;Normal Equation&lt;/b&gt;을 이용하여 Ridge Regression을 최적화하는 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601395060175&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import Ridge
ridge_reg = Ridge(alpha=1, solver=&quot;cholesky&quot;, random_state=42)
ridge_reg.fit(X, y)
ridge_reg.predict([[1.5]])
&amp;gt;&amp;gt; array([[1.55071465]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;다음은 &lt;b&gt;SGD(확률적 경사 하강법)&lt;/b&gt;을 사용하여 최적화한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601395151400&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sgd_reg = SGDRegressor(penalty=&quot;l2&quot;, max_iter=1000, tol=1e-3, random_state=42)
sgd_reg.fit(X, y.ravel())
sgd_reg.predict([[1.5]])
&amp;gt;&amp;gt; array([1.47012588])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.5.2 라쏘 회귀(Lasso Regression)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;274&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tSyjR/btqJScqqz5h/kIJmKKXdKUGkklYLwmGgZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tSyjR/btqJScqqz5h/kIJmKKXdKUGkklYLwmGgZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tSyjR/btqJScqqz5h/kIJmKKXdKUGkklYLwmGgZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtSyjR%2FbtqJScqqz5h%2FkIJmKKXdKUGkklYLwmGgZ0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;274&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Lasso Regression과 Ridge Regression의 차이점은 &lt;b&gt;Regularization 항&lt;/b&gt;에서 나옵니다. 이것을 마찬가지로 Linear Regression과 Polynomial Regression에 적용해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601395332422&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import Lasso

plt.figure(figsize=(8,4))
plt.subplot(121)
plot_model(Lasso, polynomial=False, alphas=(0, 0.1, 1), random_state=42)
plt.ylabel(&quot;$y$&quot;, rotation=0, fontsize=18)
plt.subplot(122)
plot_model(Lasso, polynomial=True, alphas=(0, 10**-7, 1), random_state=42)

save_fig(&quot;lasso_regression_plot&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csrfmL/btqJUN4MXpE/JgaffBcWXrHqLlPQze66W1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csrfmL/btqJUN4MXpE/JgaffBcWXrHqLlPQze66W1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csrfmL/btqJUN4MXpE/JgaffBcWXrHqLlPQze66W1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsrfmL%2FbtqJUN4MXpE%2FJgaffBcWXrHqLlPQze66W1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Lasso Regression은 가장 큰 특징은 &lt;b&gt;중요하지 않은 feature는 제거해버린다는 것입니다.&lt;/b&gt; 위 그래프에서 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;alpha; = 1e - 07&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$일 때 그래프가 거의 선형적인 이유가 바로 중요하지 않은 feature의 가중치들이 모두 0이 되었기 때문입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;즉 Lasso Regression은 &lt;b&gt;자동으로 중요한 feature들을 선택하고 나머지 가중치들은 0으로 만들고,&lt;/b&gt; 선택된 feature의 가중치들도 상대적으로 적은 희소 모델(sparse model)을 만든다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;다음은 sklearn에서 Lasso Regression을 적용한 코드입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1601396812131&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import Lasso
lasso_reg = Lasso(alpha=0.1)
lasso_reg.fit(X, y)
lasso_reg.predict([[1.5]])
&amp;gt;&amp;gt; array([1.53788174])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.5.3 엘라스틱넷(elastic net)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;Elastic net은 Ridge와 Lasso를 섞은 모델입니다.&lt;/b&gt; 말 그대로 Ridge와 Lasso의 Regularization 항을 모두 더하고, 그 혼합 비율을 $r$을 사용해 조절합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;475&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWZTxa/btqJWs6a4co/KpYCxpd8NY7xm0ZRvShJdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWZTxa/btqJWs6a4co/KpYCxpd8NY7xm0ZRvShJdK/img.png&quot; data-alt=&quot;r = 0이면 Ridge, 1이면 Lasso와 같습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWZTxa/btqJWs6a4co/KpYCxpd8NY7xm0ZRvShJdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWZTxa%2FbtqJWs6a4co%2FKpYCxpd8NY7xm0ZRvShJdK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;475&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;r = 0이면 Ridge, 1이면 Lasso와 같습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;지금까지 Overfit을 막기 위해 사용하는 세가지 Regularization 방법에 대해 알아보았습니다. 대부분의 경우 약간의 Regularization은 무조건 필요하기 때문에 &lt;b&gt;Regularization이 없는 Linear Regression은 지양해야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;보통 Regularization이라고 하면 Ridge가 기본이 되지만, &lt;b&gt;많은 &lt;span style=&quot;color: #333333;&quot;&gt;feature&lt;/span&gt;들 중 일부 &lt;span style=&quot;color: #333333;&quot;&gt;feature&lt;/span&gt;만 중요하게 사용된다면 Lasso나 Elastic을 사용하는 것이 좋습니다.&lt;/b&gt; 왜냐하면 Lasso는 앞서 말한대로 중요하지 않은 feature의 가중치는 0으로 만들기 때문입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 &lt;b&gt;feature의 수가 data의 수보다 많거나, 특정 feature 몇개가 강하게 연관되어있다면,&lt;/b&gt; Lasso보다는 &lt;b&gt;Elastic&lt;/b&gt;을 사용하는 것이 좋습니다. 다음은 sklearn에서 Elastic net을 사용한 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601397195787&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import ElasticNet
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5, random_state=42)
elastic_net.fit(X, y)
elastic_net.predict([[1.5]])
&amp;gt;&amp;gt; array([1.54333232])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;2550748390&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.5.4 조기 종료(Early Stopping)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Gradient Descent Algorithm을 Regularizatin하는 방법은 Cost가 극솟값에 도달하면 훈련을 중지하는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GkR1E/btqJVOojPO7/NFLttRVNF0PNBJzwEMWZBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GkR1E/btqJVOojPO7/NFLttRVNF0PNBJzwEMWZBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GkR1E/btqJVOojPO7/NFLttRVNF0PNBJzwEMWZBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGkR1E%2FbtqJVOojPO7%2FNFLttRVNF0PNBJzwEMWZBK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Batch-Gradient Descent&lt;/b&gt;로 훈련시킨 위 모델은 &lt;b&gt;Epoch&lt;/b&gt;가 늘어날수록(훈련이 반복될수록) Cost가 점점 줄어들다가 다시 상승합니다. &lt;b&gt;즉 다시 상승하는 이 지점이 Overfit의 분기점입니다.&lt;/b&gt; 따라서 이 지점에서 멈추면 훈련 과정에서 Overfit되는 것을 막을 수 있습니다. 다음은 조기 종료를 위한 구현 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601397533796&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from copy import deepcopy

poly_scaler = Pipeline([
        (&quot;poly_features&quot;, PolynomialFeatures(degree=90, include_bias=False)),
        (&quot;std_scaler&quot;, StandardScaler())
    ])

X_train_poly_scaled = poly_scaler.fit_transform(X_train)
X_val_poly_scaled = poly_scaler.transform(X_val)

sgd_reg = SGDRegressor(max_iter=1, tol=-np.infty, warm_start=True,
                       penalty=None, learning_rate=&quot;constant&quot;, eta0=0.0005, random_state=42)

minimum_val_error = float(&quot;inf&quot;)
best_epoch = None
best_model = None
for epoch in range(1000):
    sgd_reg.fit(X_train_poly_scaled, y_train)  # 중지된 곳에서 다시 시작합니다
    y_val_predict = sgd_reg.predict(X_val_poly_scaled)
    val_error = mean_squared_error(y_val, y_val_predict)
    if val_error &amp;lt; minimum_val_error:
        minimum_val_error = val_error
        best_epoch = epoch
        best_model = deepcopy(sgd_reg)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;이번 포스팅은 여기서 마치겠습니다. 긴 글 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>PYTHON</category>
      <category>regression</category>
      <category>Regularization</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>규제</category>
      <category>머신러닝</category>
      <category>정규화</category>
      <category>핸즈 온 머신러닝</category>
      <category>회귀</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/53</guid>
      <comments>https://box-world.tistory.com/53#entry53comment</comments>
      <pubDate>Wed, 30 Sep 2020 01:45:38 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈 온 머신러닝 2판 ] Polynomial Regression과 Learning Curve란?</title>
      <link>https://box-world.tistory.com/52</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;&quot;먼저 행동으로 옮기고 나서 말하라&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;- 스티븐 스필버그 -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.3 Polynomial Regression(다항 회귀)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;Polynomial Regression은 &lt;b&gt;비선형(non-linear) 데이터를 학습하는데 선형 모델을 사용할 수 있게 해줍니다.&lt;/b&gt; 다시 말해서 모델이란 것은 데이터를 대표하는 것인데 어떻게 선형 모델이 비선형 데이터를 대표할 수 있게 되는 것일까요? 우선 간단한 이차방정식으로 데이터를 생성해보겠습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1601345357157&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;m = 100
X = 6 * np.random.rand(m, 1) - 3 // rand : 0~1의 균일분포 표준 정규분포 난수를 생성
y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1) // randn : 가우시안 표준정규분포 난수를 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;366&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HYyEE/btqJMvDfgAA/KocWqk6C6yQsPuLaxMYbvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HYyEE/btqJMvDfgAA/KocWqk6C6yQsPuLaxMYbvK/img.png&quot; data-alt=&quot;생성된 데이터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HYyEE/btqJMvDfgAA/KocWqk6C6yQsPuLaxMYbvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHYyEE%2FbtqJMvDfgAA%2FKocWqk6C6yQsPuLaxMYbvK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;366&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;생성된 데이터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;선형 모델은 분명 위 데이터에 적합하지 않을 것입니다. 하지만 &lt;b&gt;sklearn의 PolynomialFeatures&lt;/b&gt;를 사용하여 Training data를 변환시키면 적용이 가능합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1601345772979&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.preprocessing import PolynomialFeatures
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)
X[0]
&amp;gt;&amp;gt; array([-0.75275929])
X_poly[0]
&amp;gt;&amp;gt; array([-0.75275929,  0.56664654])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;그렇다면 Polynomial Regression은 &lt;b&gt;어떻게 데이터를 변환하는걸까요?&lt;/b&gt; 앞서 우리가 생성한 데이터를 기준으로 생각해보자면, feature가 하나이므로 결과값을 예측할 때는 다음과 같은 식을 사용해볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;$$Y = AX+b (A는 가중치입니다.)$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그런데 Polynomial Regression에서는 Input data $X$를 제곱하여 이것을 새로운 feature로 추가합니다. 즉 변환후 우리는 $X$ 그리고&amp;nbsp; $X^2$ 이렇게 두개의 feature를 지니는 셈이 되는 것이죠 그렇게 해서 우리가 학습시키게 될 모델은 다음과 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$$Y = A_1X + A_2X^2 + b$$&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;앞서 Polynomial Regression을 이용하면 선형 모델에 비선형 데이터를 학습 시킬 수 있음을 언급하였습니다. 머신러닝이 어려우신 분들의 이해를 돕기 위해 쉽게 설명드리자면, 아래 식을 보시면 차수가 올라간 것을 보실 수 있는데요 바로 이 차수가 높아지면서 비선형 데이터에 선형 모델이 fit할 수 있게 되는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이제 확장된 Training data에 Linear regression을 적용해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601346327128&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Linear Regression 적용
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)
lin_reg.intercept_, lin_reg.coef_

// 데이터 시각화
X_new=np.linspace(-3, 3, 100).reshape(100, 1) // -3~3 사이 100개의 수를 가지는 매트릭스 생성
X_new_poly = poly_features.transform(X_new) // 데이터 확장
y_new = lin_reg.predict(X_new_poly)
plt.plot(X, y, &quot;b.&quot;)
plt.plot(X_new, y_new, &quot;r-&quot;, linewidth=2, label=&quot;Predictions&quot;)
plt.xlabel(&quot;$x_1$&quot;, fontsize=18)
plt.ylabel(&quot;$y$&quot;, rotation=0, fontsize=18)
plt.legend(loc=&quot;upper left&quot;, fontsize=14)
plt.axis([-3, 3, 0, 10])
save_fig(&quot;quadratic_predictions_plot&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TZgKW/btqJP79uMto/f5E69mZHBRrjgCUOoVGG01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TZgKW/btqJP79uMto/f5E69mZHBRrjgCUOoVGG01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TZgKW/btqJP79uMto/f5E69mZHBRrjgCUOoVGG01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTZgKW%2FbtqJP79uMto%2Ff5E69mZHBRrjgCUOoVGG01%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Polynomial Regression의 또 다른 특징은 &lt;b&gt;기존 데이터의 feature가 여러개일 때 feature 간의 관계를 찾을 수 있습니다.&lt;/b&gt; 예를 들어 두개의 feature $a$,$b$가 있고, degree = 3으로 설정하여 PolynomialFeatures를 적용하면 $a^3, a^2, b^3, b^2$뿐 아니라 $ab,a^2b,ab^2$과 같은 항들도 feature로 추가하게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다만 이 과정에서 feature의 수가 엄청나게 증가할 수 있기 때문에 이 점은 주의하셔야 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4.4 학습곡선(Learning Curve)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;우선 Learning Curve가 무엇인지 배우기 전에, Polynomial Regression에 대한 얘기를 좀 더 해보면서 Learning Curve가 어떻게 사용될 수 있는지도 함께 배워보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Polynomial Regression을 통해 degree가 올라가게 되면 모델은 Training data에 더 fit해집니다.&lt;/b&gt; 다음 그래프는 300차와 2차 Polynomial Regression 그리고 단순 Linear Regression 모델 세 개를 비교하는데, 300차가 가장 구불구불하면서 fit한 모습을 보여주고 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;참고로 여기서 Polynomial Regression 모델이 300차라는 것은 &lt;span style=&quot;color: #333333;&quot;&gt;$Y = AX+b$이던 모델을 $Y = A_1X + ... + A_300X^300 + b$으로 확장한 것을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1601347221041&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

for style, width, degree in ((&quot;g-&quot;, 1, 300), (&quot;b--&quot;, 2, 2), (&quot;r-+&quot;, 2, 1)):
    polybig_features = PolynomialFeatures(degree=degree, include_bias=False)
    std_scaler = StandardScaler()
    lin_reg = LinearRegression()
    polynomial_regression = Pipeline([
            (&quot;poly_features&quot;, polybig_features),
            (&quot;std_scaler&quot;, std_scaler),
            (&quot;lin_reg&quot;, lin_reg),
        ])
    polynomial_regression.fit(X, y)
    y_newbig = polynomial_regression.predict(X_new)
    plt.plot(X_new, y_newbig, style, label=str(degree), linewidth=width)

plt.plot(X, y, &quot;b.&quot;, linewidth=3)
plt.legend(loc=&quot;upper left&quot;)
plt.xlabel(&quot;$x_1$&quot;, fontsize=18)
plt.ylabel(&quot;$y$&quot;, rotation=0, fontsize=18)
plt.axis([-3, 3, 0, 10])
save_fig(&quot;high_degree_polynomials_plot&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/npnEt/btqJMwvo0y9/kYPJW8gUjOUewlMETNlPE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/npnEt/btqJMwvo0y9/kYPJW8gUjOUewlMETNlPE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/npnEt/btqJMwvo0y9/kYPJW8gUjOUewlMETNlPE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnpnEt%2FbtqJMwvo0y9%2FkYPJW8gUjOUewlMETNlPE1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 위 300차 모델은 &lt;b&gt;Training data에 Overfit되어있습니다.&lt;/b&gt; 반면 1차 모델은 Underfit되어 있고, 가장 적합한 건 셋 중 2차 모델일 것입니다. 그렇다면 다른 데이터를 사용할 때 얼마나 복잡한 모델을 사용해야할지, 확장된 데이터가 Overfit 혹은 Underfit되어있는지 어떻게 알 수 있을까요? 여기서 &lt;b&gt;Learning Curve&lt;/b&gt;가 등장합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Learning Curve란 Training set 그리고 Validation set에 대한 모델의 성능을 함수로 나타냅니다.&lt;/b&gt; 다음은 단순한 Linear regression에 대한 Learning Curve입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601353256132&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

def plot_learning_curves(model, X, y):
    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=10)
    train_errors, val_errors = [], []
    for m in range(1, len(X_train)):
        model.fit(X_train[:m], y_train[:m])
        y_train_predict = model.predict(X_train[:m])
        y_val_predict = model.predict(X_val)
        train_errors.append(mean_squared_error(y_train[:m], y_train_predict))
        val_errors.append(mean_squared_error(y_val, y_val_predict))

    plt.plot(np.sqrt(train_errors), &quot;r-+&quot;, linewidth=2, label=&quot;train&quot;)
    plt.plot(np.sqrt(val_errors), &quot;b-&quot;, linewidth=3, label=&quot;val&quot;)
    plt.legend(loc=&quot;upper right&quot;, fontsize=14)   # 책에는 없음
    plt.xlabel(&quot;Training set size&quot;, fontsize=14) # 책에는 없음
    plt.ylabel(&quot;RMSE&quot;, fontsize=14)              # 책에는 없음&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1601353265586&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lin_reg = LinearRegression()
plot_learning_curves(lin_reg, X, y)
plt.axis([0, 80, 0, 3])                         # 책에는 없음
save_fig(&quot;underfitting_learning_curves_plot&quot;)   # 책에는 없음
plt.show()   &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfvcK7/btqJP7V8ToJ/RiNYUmm7FpoZcK9pHpGHM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfvcK7/btqJP7V8ToJ/RiNYUmm7FpoZcK9pHpGHM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfvcK7/btqJP7V8ToJ/RiNYUmm7FpoZcK9pHpGHM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfvcK7%2FbtqJP7V8ToJ%2FRiNYUmm7FpoZcK9pHpGHM1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;b&gt;X축은 Training set의 크기에 해당합니다.&lt;/b&gt; 즉 Training set의 개수가 0개일 때, 1개 일때, 2개일 때 ... 80개일때까지 반복적으로 학습하여 각 학습에 대한 Cost 값을 함수로 표현한 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그래프를 좀 더 구체적으로 살펴보자면, Training set에 대한 성능의 경우 처음에 데이터가 한 두개일 때는 Cost가 거의 0에 가까우므로 완벽하게 모델이 작동함을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 데이터가 커질 수록 Noise의 개입이나 데이터가 non-linear한 특성 때문에 모델이 Training set을 완벽하게 학습하는 것이 불가능해지면서 Cost가 점점 커지게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;이번엔 Validation set입니다.&lt;/b&gt; 이 경우엔 처음 0개부터 시작할 때는 적은 데이터로 모델을 일반화할 수 없기때문에 Cost가 높습니다. 그러나 데이터가 커질 수록 점점 학습해가면서 Cost가 줄어들면서 Training set의 그래프와 가까워집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이제 동일한 데이터를 10차 Polynomial Regression으로 확장한 후 이에 대한 Learning Curve를 그려보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1601353778676&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.pipeline import Pipeline

polynomial_regression = Pipeline([
        (&quot;poly_features&quot;, PolynomialFeatures(degree=10, include_bias=False)),
        (&quot;lin_reg&quot;, LinearRegression()),
    ])

plot_learning_curves(polynomial_regression, X, y)
plt.axis([0, 80, 0, 3])           # 책에는 없음
save_fig(&quot;learning_curves_plot&quot;)  # 책에는 없음
plt.show()                        # 책에는 없음&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkn8Oq/btqJKw3Lh1s/0Ne9QrDEYlIvTKhRvNYHi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkn8Oq/btqJKw3Lh1s/0Ne9QrDEYlIvTKhRvNYHi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkn8Oq/btqJKw3Lh1s/0Ne9QrDEYlIvTKhRvNYHi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdkn8Oq%2FbtqJKw3Lh1s%2F0Ne9QrDEYlIvTKhRvNYHi0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;6873136782&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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/bfvcK7/btqJP7V8ToJ/RiNYUmm7FpoZcK9pHpGHM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfvcK7/btqJP7V8ToJ/RiNYUmm7FpoZcK9pHpGHM1/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfvcK7/btqJP7V8ToJ/RiNYUmm7FpoZcK9pHpGHM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfvcK7%2FbtqJP7V8ToJ%2FRiNYUmm7FpoZcK9pHpGHM1%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkn8Oq/btqJKw3Lh1s/0Ne9QrDEYlIvTKhRvNYHi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkn8Oq/btqJKw3Lh1s/0Ne9QrDEYlIvTKhRvNYHi0/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 49.4186%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkn8Oq/btqJKw3Lh1s/0Ne9QrDEYlIvTKhRvNYHi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdkn8Oq%2FbtqJKw3Lh1s%2F0Ne9QrDEYlIvTKhRvNYHi0%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽은 Linear Regression, 오른쪽은 10차 Polynomial Regression&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 두 그래프의 차이점을 살펴보겠습니다.&lt;b&gt; Polynomial Regression은 Training set의 Cost가 Linear Regression에 비해 현저히 낮습니다.&lt;/b&gt; 왜 그럴까요?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Polynomial regression은 degree가 높아지기 때문에 당연히 주어진 데이터에 더 fit 해지기 때문입니다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;두번째는 Validation set과 Training set 사이에 공간이 있습니다.&lt;/b&gt; 이는 Training set에서의 모델 성능이 Validation set의 성능보다 낫다는 말인데,&amp;nbsp; 본래 좋은 모델이라면 Training set에서 뿐아니라 Validation set에서도 동일하게 성능이 좋아야할 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;결론을 짓자면 우리가 사용한 모델은 Overfit 되어있다는 뜻이 됩니다. &lt;b&gt;이러한 Overfit을 해결하기 위해서는 더 큰 Training set을 사용하면 두 곡선이 가까워지면서 해결되게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음 시간에는 regularization이 들어간 Linear Model에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;p&gt;긴 글 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>learning curve</category>
      <category>regression</category>
      <category>다항 회귀</category>
      <category>로지스틱 회귀</category>
      <category>머신러닝</category>
      <category>사이킷런</category>
      <category>텐서플로우</category>
      <category>파이썬</category>
      <category>핸즈 온 머신러닝</category>
      <category>회귀</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/52</guid>
      <comments>https://box-world.tistory.com/52#entry52comment</comments>
      <pubDate>Tue, 29 Sep 2020 14:01:00 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter] 앱 개발 입문자가 Flutter를 선택한 4가지 이유</title>
      <link>https://box-world.tistory.com/48</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #a6bc00;&quot;&gt;성공하려면 귀는 열고, 입은 닫아라&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #a6bc00;&quot;&gt;- 존 데이비슨 록펠러 -&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;438&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byPgER/btqJCTq10zX/GnPhq8pNO24SBpadjcCG50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byPgER/btqJCTq10zX/GnPhq8pNO24SBpadjcCG50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byPgER/btqJCTq10zX/GnPhq8pNO24SBpadjcCG50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyPgER%2FbtqJCTq10zX%2FGnPhq8pNO24SBpadjcCG50%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;438&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;안녕하세요 매번 머신러닝 관련 포스팅만 올렸지만, 이번에는 6개월 전 처음 입문하게 된 앱개발에서 제가 왜 Flutter를 선택하게 되었는지 그리고 왜 Flutter여야 했는지 입문자의 관점에서 풀어보고자 합니다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1) Flutter는 크로스 플랫폼!&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;456&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsoCr5/btqJCR7TEyT/K4fcl4e3k3Ef5ngKCKq7K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsoCr5/btqJCR7TEyT/K4fcl4e3k3Ef5ngKCKq7K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsoCr5/btqJCR7TEyT/K4fcl4e3k3Ef5ngKCKq7K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsoCr5%2FbtqJCR7TEyT%2FK4fcl4e3k3Ef5ngKCKq7K1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;456&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;크로스 플랫폼&lt;/b&gt;이란 하나의 코드로 안드로이드와 ios 개발이 동시에 가능한 프레임워크를 부르는 명칭입니다. 우리에게 알려진 크로스 플랫폼으로는&lt;b&gt; React Native&lt;/b&gt;와 &lt;b&gt;Flutter&lt;/b&gt;이 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;특히 크로스 플랫폼은 안드로이드와 ios개발에 투자되는 시간과 Cost를 반으로 줄일 수 있다는 점에서 많은 사람들에게 굉장히 매력적일 수 밖에 없습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;6개월 전 스타트업을 시작하게된 저도 최소한의 인력으로 앱 개발을 해야하는 상황에서 자연스럽게 Flutter로 눈이 갈 수 밖에 없었습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2) Flutter를 향한 Google의 적극적인 푸쉬!&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;389&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rRTNc/btqJCR06NCJ/WKKjXhIoY7yPesxjw6SA3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rRTNc/btqJCR06NCJ/WKKjXhIoY7yPesxjw6SA3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rRTNc/btqJCR06NCJ/WKKjXhIoY7yPesxjw6SA3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrRTNc%2FbtqJCR06NCJ%2FWKKjXhIoY7yPesxjw6SA3k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;389&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;어떤 프로그래머든 주력이 아닌 언어를 깊게 공부한다는 것은 쉬운 일이 아닙니다. 저 역시도 2017년 출시된 Flutter가 단기적인 인기만 끌다 금방 사라질 언어는 아닐지 많은 걱정이 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;398&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvl0MT/btqJF0WQwAf/X0NqYuqcX1EXdZnM9n68Z1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvl0MT/btqJF0WQwAf/X0NqYuqcX1EXdZnM9n68Z1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvl0MT/btqJF0WQwAf/X0NqYuqcX1EXdZnM9n68Z1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcvl0MT%2FbtqJF0WQwAf%2FX0NqYuqcX1EXdZnM9n68Z1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;398&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다행인것은 현재 Flutter는 구글이 확실하게 밀어주는 가운데 Google Ads, Cloud Platform 등이 Flutter로 개발되어있는 상태입니다. 특히 중국을 중심으로 텐센트, 알리바바 등이 Flutter를 적극적으로 활용하여 앱 개발이 이뤄지고 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇듯 이미 여러 곳이 Flutter를 이용하여 많은 것들을 개발하고 있고, 세계 최대의 소프트웨어 기업인 Google의 적극적인 푸쉬 아래 속에서 앞으로도 계속 성장하지 않을까 싶습니다.&lt;/p&gt;
&lt;p&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-2204003234852125&quot; data-ad-slot=&quot;5147145660&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3) Flutter는 웹 개발도 가능합니다.&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmrsuW/btqJIOaz1YA/5IQxjnFv2Tu2tCgFMqNmik/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmrsuW/btqJIOaz1YA/5IQxjnFv2Tu2tCgFMqNmik/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmrsuW/btqJIOaz1YA/5IQxjnFv2Tu2tCgFMqNmik/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmrsuW%2FbtqJIOaz1YA%2F5IQxjnFv2Tu2tCgFMqNmik%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;크로스 플랫폼인 Flutter는 심지어 웹 개발도 가능합니다. 물론 베타 버전이라 그 성능이 완벽하다고 할 순 없지만, 하나의 언어로 안드로이드, ios 그리고 웹까지 동시에 개발할 수 있다는건 무척 매력적입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;만약 정말 전문적으로 웹을 만들어야 하는게 아니라면, 저의 개인적인 포트폴리오를 소개하는 웹페이지 정도는 간단히 Flutter로 만들어 볼 것 같습니다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4) Flutter는 쉽습니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;제가 처음 앱 개발을 시작할 때 접했던 언어는 Flutter가 아닌 안드로이드 자바였습니다. 당시에 Constraint Layout을 기반으로 xml파일을 만지작거렸던 기억이 있습니다. 여차저차해서 앱을 만들긴 했으나, 레퍼런스가 많았음에도 불구하고 이해하기 어려운 부분이 한두가지가 아니었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이후에 접했던 Flutter는 구조적인 측면에서나 개발적인 측면에서나 모두 더 편하다고 느껴졌습니다. Flutter는 모든 것이 위젯으로 이루어져있어서 상대적으로 구조를 이해하기 쉬웠습니다. 위젯에 대해서는 다음 포스팅에서 구체적으로 설명하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;353&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7QxYU/btqJG9TyCGl/ykka8n2KqyqrGJHfTOuCF1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7QxYU/btqJG9TyCGl/ykka8n2KqyqrGJHfTOuCF1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7QxYU/btqJG9TyCGl/ykka8n2KqyqrGJHfTOuCF1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7QxYU%2FbtqJG9TyCGl%2Fykka8n2KqyqrGJHfTOuCF1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;353&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;게다가 Flutter를 개발해보신 분들이라면 &lt;b&gt;'alt + Enter'&lt;/b&gt;가 정말 유용하다는 생각을 많이 하셨을 것입니다. 이것 하나로 위젯을 쉽게 추가하고 지울 수 있어서 확장성 있는 코드를 써내려갈 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;422&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byjtML/btqJEyzv2Gr/V17E3rPaFNZjxeUkGQlc81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byjtML/btqJEyzv2Gr/V17E3rPaFNZjxeUkGQlc81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byjtML/btqJEyzv2Gr/V17E3rPaFNZjxeUkGQlc81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyjtML%2FbtqJEyzv2Gr%2FV17E3rPaFNZjxeUkGQlc81%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;422&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Flutter하면 &lt;b&gt;'Hot Reload'&lt;/b&gt; 기능을 빼놓을 수가 없겠죠! 이 기능은 우리가 코드를 변경하였을 때 재실행을 하는 대신에 사용하게 되면 0.1초만에 그 결과를 에뮬레이터에서 바로 확인하게 해주는 기능입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;덕분에 코드를 한줄한줄 써내려갈 때마다 Hot Reload 기능으로 결과물을 확인하며 코딩을 했습니다. 이렇게 결과를 바로바로 확인하면서 코딩을 하다보니 내가 써내려간 코드가 바로바로 적용된걸 확인하면서 초반에 신나게 코딩을 했던 기억이 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;이번 포스팅에서는 간단하게나마 제가 Flutter를 사용하며 느꼈던 점을 말씀드렸습니다. 물론 최적화나 적용할 수 있는 오픈소스 api 등의 측면에서는 오래전부터 사용되오던 React Native가 훨씬 유리할 수 있겠지만, Flutter만이 가지고 있는 장점이 저에겐 더 매력적으로 다가오는 것 같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음 포스팅에서는 본격적으로 Flutter가 무엇인지에 대해 알아보겠습니다. 긴 글 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>개발/Flutter</category>
      <category>App</category>
      <category>flutter</category>
      <category>google</category>
      <category>IOS</category>
      <category>React Native</category>
      <category>안드로이드</category>
      <category>앱</category>
      <category>앱 개발</category>
      <category>코틀린</category>
      <category>크로스 플랫폼</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/48</guid>
      <comments>https://box-world.tistory.com/48#entry48comment</comments>
      <pubDate>Sun, 27 Sep 2020 21:16:38 +0900</pubDate>
    </item>
    <item>
      <title>[ Tensorflow 2 / sklearn ]  Linear Regression과 Gradient Descent Algorithm의 종류</title>
      <link>https://box-world.tistory.com/47</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;이기는 것이 중요한 것은 아니지만,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;이기기를 원하는 것은 중요하다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- 에릭 슈미트(Google 전 Ceo) -&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이번 포스팅에서는 머신러닝의 가장 간단한 모델 중 하나인 회귀(Regression)에 속하는 &lt;b&gt;선형 회귀(Linear Regression)&lt;/b&gt;에 대해 알아보고, 이를 최적화하는 훈련 방식인 &lt;b&gt;경사 하강 알고리즘&lt;/b&gt;과 &lt;b&gt;Normal Equation&lt;/b&gt;에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;보통 우리가 Regression에서 모델을 훈련시킨다고 하면 &lt;b&gt;경사 하강 알고리즘(Gradient Descent algorithm)&lt;/b&gt;을 사용합니다. 좀 더 세부적으로는 Batch GD, Mini-Batch GD, SGD가 있는데, 이는 잠시 후에 다시 다뤄보겠습니다.&lt;/p&gt;
&lt;p&gt;또 다른 훈련 방식에는 &lt;b&gt;Normal Equation&lt;/b&gt;가 있습니다. 이 또한 Linear Regression을 다룬 후 다시 언급드리겠습니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;b&gt;4.1 Linear Regression&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;$$ 삶의 만족도 = &amp;theta;_0+&amp;theta;_1*(1인당 GDP) $$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;여기 1인당 GDP를 이용하여 삶의 만족도를 예측하고자 하는 Regression 모델이 있습니다. 이 모델은 &lt;b&gt;Linear model&lt;/b&gt;이고, $&amp;theta;_0$, $&amp;theta;_1$이 모델 파라미터입니다.&lt;/p&gt;
&lt;p&gt;$$y = &amp;theta;_0 + &amp;theta;_1*x_1 + &amp;theta;_2*x_2 + &amp;theta;_3*x_3 + ... + &amp;theta;_n*x_n$$&lt;/p&gt;
&lt;p&gt;&amp;nbsp;앞에서 본 것이 예시였다면 위 식은 좀 더 &lt;b&gt;일반적인 Linear model&lt;/b&gt;을 표현한 것입니다. Linear model은 Input의 &lt;b&gt;feature의 Weight 합&lt;/b&gt;과 &lt;b&gt;bias 혹은 intercept&lt;/b&gt;이라 부르는 상수를 더해 최종 예측값을 만들어 냅니다.&lt;/p&gt;
&lt;p&gt;$$y = h_&amp;theta;(x) = &amp;theta;*x$$&lt;/p&gt;
&lt;p&gt;앞에서 본 일반적인 식을 &lt;b&gt;벡터&lt;/b&gt;를 이용하여 위처럼 더욱 간단히 표현할 수 있습니다.&lt;/p&gt;
&lt;p&gt;- $&amp;theta;$는 $&amp;theta;_0 ... &amp;theta;_n$까지 Weight를 담은&lt;b&gt; Paraeter 벡터&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;- $x$는 $x_0 ... x_n$까지 Input의 feature를 담은 &lt;b&gt;feature 벡터&lt;/b&gt;입니다. 이때 $x_0$는 항상 0입니다.&lt;/p&gt;
&lt;p&gt;- $h_&amp;theta;(x)$는 &lt;b&gt;가설 함수&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;250&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctayrr/btqFZjUzc3d/1NKzWWkdvGH8VZ2bbkCK3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctayrr/btqFZjUzc3d/1NKzWWkdvGH8VZ2bbkCK3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctayrr/btqFZjUzc3d/1NKzWWkdvGH8VZ2bbkCK3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fctayrr%2FbtqFZjUzc3d%2F1NKzWWkdvGH8VZ2bbkCK3k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;250&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이제 Linear Regression 모델의 구조에 대해 알아보았으니 본격적으로 훈련을 시켜보겠습니다. 모델을 훈련시킨다는 것은&lt;b&gt; Training set에 최적화되게끔 parameter를 설정한다&lt;/b&gt;는 의미입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 이를 위해 필요한 것은 예측값과 실제값의 차이를 측정할 &lt;b&gt;loss function&lt;/b&gt;을 정의하는 것입니다. 보통 Linear Regression 모델에서 사용하는 loss function은 &lt;b&gt;MSE&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;b&gt;4.1.1 Normal Equation&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;Normal Equation&lt;/b&gt;은 앞서 언급했듯이 model parameter를 최적화하는 하나의 방식입니다. 우리가 보통 또 하나의 방법인 Gradient Descent Algorithm을 떠올리며 Gradient를 반복적으로 계산하며 조정하는 원리를 떠올립니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Normal Equation&lt;/b&gt;은 이러한 반복적인 연산없이 &lt;b&gt;공식을 이용해 한번의 최적의 parameter를 도출해냅니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;251&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RpaDT/btqFZOsYOol/tz9PrKKiyKcPMSTZLrpNLK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RpaDT/btqFZOsYOol/tz9PrKKiyKcPMSTZLrpNLK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RpaDT/btqFZOsYOol/tz9PrKKiyKcPMSTZLrpNLK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRpaDT%2FbtqFZOsYOol%2Ftz9PrKKiyKcPMSTZLrpNLK%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;251&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;- $&amp;theta;$ : loss function을 최소화하는 즉 &lt;b&gt;모델에 최적화된 parameter&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;- $X$ : Input입니다. 이떄 $X^T$는 $X$의 &lt;b&gt;전치 행렬&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;- $y$는 Input data에 대한 Label을 담고 있는 &lt;b&gt;벡터&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;우선 Normal Equation을 적용하기 위해 &lt;b&gt;랜덤으로 Linear한 데이터를 생성해보겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

X = 2 * np.random.rand(100,1)
y = 4+ 3*X + np.random.randn(100,1)

plt.plot(X, y, &quot;b.&quot;)
plt.xlabel(&quot;$x_1$&quot;, fontsize=18)
plt.ylabel(&quot;$y$&quot;, rotation=0, fontsize=18)
plt.axis([0, 2, 0, 15])

plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bERhOI/btqF1SHlEBu/zctkln0VeA5Ru9AnfvGyc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bERhOI/btqF1SHlEBu/zctkln0VeA5Ru9AnfvGyc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bERhOI/btqF1SHlEBu/zctkln0VeA5Ru9AnfvGyc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbERhOI%2FbtqF1SHlEBu%2Fzctkln0VeA5Ru9AnfvGyc0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이제 여기에서 생성된 $x_1$과 $y$를 Normal Equation에 대입하여 최적화된 $&amp;theta;$를 구해보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;아래 코드는 첫번째 줄에서 모든 데이터에 $x_0 = 1$을 추가한 후 &lt;b&gt;np.linalg의 inv()&lt;/b&gt; 함수를 이용하여 &lt;b&gt;역행렬(Inverse Matrix)&lt;/b&gt;를 만들고,&lt;b&gt; dot() 메서드&lt;/b&gt;를 이용하여 Matrix 곱셈을 진행하였습니다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;X_b = np.c_[np.ones((100,1)), X] # np.c_ : 배열 붙이기, np.ones : array 생성 함수
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y) #dot() : 행렬 곱셈&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Normal Equation에 의해 &lt;b&gt;최적화된 &amp;theta;&lt;/b&gt;를 확인해보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;lua&quot;&gt;&lt;code&gt;theta_best

##결과값##
&amp;gt;&amp;gt;
array([[3.93328217],
       [3.08032243]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;사실 $&amp;theta;_0 = 4$, $&amp;theta;_1 = 3$을 기대했기 때문에 완전히 정확하다고 할 순 없겠지만, 매우 비슷합니다. 이제 최적화된 $&amp;theta;$를 사용하여 예측을 해보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;X_new = np.array([[0], [2]]) # 2차원 열 벡터
X_new_b = np.c_[np.ones((2,1)), X_new] # 모든 샘플에 x0 = 1을 추가
y_predict = X_new_b.dot(theta_best)
y_predict

##결과값##
&amp;gt;&amp;gt;
array([[ 3.93328217],
       [10.09392703]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;모델의 예측을 그래프에 나타내보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;plt.plot(X_new, y_predict, &quot;r-&quot;)
plt.plot(X, y, &quot;b.&quot;)
plt.axis([0,2,0,15])
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RuZDz/btqFZ4vG6B5/qGn9eLGEKkYw10sEHtaaJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RuZDz/btqFZ4vG6B5/qGn9eLGEKkYw10sEHtaaJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RuZDz/btqFZ4vG6B5/qGn9eLGEKkYw10sEHtaaJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRuZDz%2FbtqFZ4vG6B5%2FqGn9eLGEKkYw10sEHtaaJk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;이번엔 잠시 Normal Equation은 접어두고, &lt;b&gt;sklearn에서 Lienar Regression&lt;/b&gt;을 사용해보겠습니다. 보시다시피 매우 간단합니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X, y)

lin_reg.intercept_, lin_reg.coef_ # .intercept_:추정된 상수항, .coef_ : 추정된 weight 벡터
&amp;gt;&amp;gt;
(array([4.27746389]), array([[2.91097464]]))

lin_reg.predict(X_new)
&amp;gt;&amp;gt;
array([[ 4.27746389],
       [10.09941316]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;sklearn의 LinearRegression 클래스는 &lt;b&gt;scipy.linalg.lstsq()&lt;/b&gt;함수를 기반으로 하고, 이를 직접 호출할 수도 있습니다.&lt;/p&gt;
&lt;pre class=&quot;perl&quot;&gt;&lt;code&gt;theta_best_svd, residuals, rank, s = np.linalg.lstsq(X_b, y, rcond=1e-6)
theta_best_svd

##결과값##
array([[4.27746389],
       [2.91097464]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위에서 사용한 np.linalg.lstsq는 $&amp;theta;=X^+*y$을 계산하여 최적화 된 $&amp;theta;$를 도출합니다. 이때 $X^+$는 $X$의 &lt;b&gt;유사 역행렬(pseudoinverse matrix)&lt;/b&gt;입니다. 이를 pseudoinverse matrix을 직접 구할 수도 있긴 합니다.&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;np.linalg.pinv(X_b).dot(y)

##결과값##
&amp;gt;&amp;gt;
array([[4.27746389],
       [2.91097464]])&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&amp;nbsp;여긴 수학적인 부분이므로 건너뛰어도 무방합니다.&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;pseudoinverse matrix&lt;/b&gt;는 &lt;b&gt;특이값 분해(SVD)&lt;/b&gt;라는 Matrix 분해 기법을 사용하여 계산됩니다. SVD는 아래와 같이 Training set를 담은 Matrix $X$를 분해합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cF8gGL/btqF1BMGEvF/rbdfVd5F602Fpgv7X8bXy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cF8gGL/btqF1BMGEvF/rbdfVd5F602Fpgv7X8bXy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cF8gGL/btqF1BMGEvF/rbdfVd5F602Fpgv7X8bXy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcF8gGL%2FbtqF1BMGEvF%2FrbdfVd5F602Fpgv7X8bXy0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Matrix A가 위로 길쭉한 직사각형 Matrix라면 아래와 같을 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgZp7b/btqFZx6aKir/KL5rGUPyGZJpjl1ZIAROYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgZp7b/btqFZx6aKir/KL5rGUPyGZJpjl1ZIAROYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgZp7b/btqFZx6aKir/KL5rGUPyGZJpjl1ZIAROYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgZp7b%2FbtqFZx6aKir%2FKL5rGUPyGZJpjl1ZIAROYK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;pseudoinverse matrix&lt;/b&gt;는 이 Matrix A를 아래와 같이 변형하여 도출되며, 그 형태는 아래와 같을 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/143Er/btqF1A1fFng/IQFDnSZDSMKODtsl2JyK20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/143Er/btqF1A1fFng/IQFDnSZDSMKODtsl2JyK20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/143Er/btqF1A1fFng/IQFDnSZDSMKODtsl2JyK20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F143Er%2FbtqF1A1fFng%2FIQFDnSZDSMKODtsl2JyK20%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rVtDn/btqF0RpmCRV/TAesHcbfwUVcSn1wlST1mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rVtDn/btqF0RpmCRV/TAesHcbfwUVcSn1wlST1mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rVtDn/btqF0RpmCRV/TAesHcbfwUVcSn1wlST1mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrVtDn%2FbtqF0RpmCRV%2FTAesHcbfwUVcSn1wlST1mk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;그렇다면 왜 &lt;b&gt;np.linalg.lstsq&lt;/b&gt;는Normal Equation이 아닌 &lt;b&gt;pseudoinverse matrix&lt;/b&gt;를 이용하여 parameter를 최적화하는 것일까요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;255&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RpaDT/btqFZOsYOol/tz9PrKKiyKcPMSTZLrpNLK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RpaDT/btqFZOsYOol/tz9PrKKiyKcPMSTZLrpNLK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RpaDT/btqFZOsYOol/tz9PrKKiyKcPMSTZLrpNLK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRpaDT%2FbtqFZOsYOol%2Ftz9PrKKiyKcPMSTZLrpNLK%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;255&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그 이유는 Normal Equation에서는 $X^T$를 필요로 하는데, Matrix의 행이 열보다 작거나(m &amp;lt; n), feature가 중복되는 &lt;b&gt;Matrix는 Inverse Matrix를 가지지 않는 것이 가장 큰 이유입니다.&lt;/b&gt; Inverse Matrix와 달리 &lt;b&gt;pseudoinverse matrix는 항상 구할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;&lt;b&gt;4.1.2 계산 복잡도&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;우리가 자료구조에서 빅오를 구하며, 메모리 사용의 효율성을 따지듯 &lt;b&gt;머신러닝에서도 계산 복잡도를 이용하여 모델의 성능을 비교하는 것 또한 매우 중요합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 &lt;b&gt;Normal Equation&lt;/b&gt;은 $X^T*X$를 계산하는데 이는 $(n+1) * (n+1)$의 크기를 가집니다. 이러한 Inverse Matrix를 구하는 계산 복잡도는 $O(n^2.4)$에서 $O(n^3)$ 사이입니다. 이를 다시 말하면 feature가 2배로 늘어나면 계산 시간이 5.3배에서 8배 정도 증가됨을 의미합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;sklearn의 LinearRegression 클래스가 사용하는 SVD 방법&lt;/b&gt;은 $O(n^2)$입니다. 다시 말해서 feature가 두배가 되면 계산 시간은 4배가 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;앞에서는 훈련 방식에 따른 계산 속도의 차이를 알아봤습니다. 이제 이와 별개로 &lt;b&gt;Linear Regression의 예측 속도는 데이터와 feature 수에 선형적입니다.&lt;/b&gt; 이는 매우 빠른 축에 속한다고 할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;&lt;b&gt;4.2 Gradient Descent Algorithm&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;우리는 현재 Linear Regression에서 &amp;theta;를 최적화하는 첫번째 방식인 Normal Equation에 대해 알아보았습니다. 이제 가장 보편적으로 쓰이는 &lt;b&gt;Gradient Descent Algorithm&lt;/b&gt;에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;Gradient Descent Algorithm의 아이디어는 loss function을 최소화하기 위해 반복적으로 &amp;theta;를 조정하는 것입니다.&lt;/p&gt;
&lt;p&gt;알고리즘을 단계화시켜 개념을 정립해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z9Guu/btqFZ4CrswO/n6aKSMWlw5HAkY3LbiiK4k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z9Guu/btqFZ4CrswO/n6aKSMWlw5HAkY3LbiiK4k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z9Guu/btqFZ4CrswO/n6aKSMWlw5HAkY3LbiiK4k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ9Guu%2FbtqFZ4CrswO%2Fn6aKSMWlw5HAkY3LbiiK4k%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;1) 랜덤으로 &amp;theta;를 정의하여&lt;b&gt; 초기 위치&lt;/b&gt;를 정합니다.&lt;/p&gt;
&lt;p&gt;2) &amp;theta;에 대한 loss function의 &lt;b&gt;기울기(gradient)&lt;/b&gt;를 계산하여 이 기울기가 감소하는 방향으로 &amp;theta;를 조정합니다.&lt;/p&gt;
&lt;p&gt;3) 기울기가 0이 되거나, 매우 가까울 때까지 2)를 반복합니다. 만약 &lt;b&gt;0에 도달했다면 cost를 최소로 하는 최적화된 &amp;theta;를 찾은 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;Gradient Descent Algorithm에서 중요한 하이퍼 파라미터는 &lt;b&gt;learning rate&lt;/b&gt;입니다. learning rate는 한번 이동할 때 얼마나 이동하냐를 결정짓습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;만약 learning rate가 너무 작다면&lt;/b&gt; 알고리즘이 수렴하기 위해 매우 많이 반복해야 하므로 시간이 오래 걸립니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;497&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkYo81/btqFZzbTVAn/kCePga4Gv0X0V0HFTQou21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkYo81/btqFZzbTVAn/kCePga4Gv0X0V0HFTQou21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkYo81/btqFZzbTVAn/kCePga4Gv0X0V0HFTQou21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkYo81%2FbtqFZzbTVAn%2FkCePga4Gv0X0V0HFTQou21%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;497&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;그렇다고 너무 크다면&lt;/b&gt; 오히려 알고리즘이 더 큰 값으로 발산하게 만들 수도 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;498&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGHxvh/btqFZzpsmUj/eUYqO5MqAtiUbBJp8nlgtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGHxvh/btqFZzpsmUj/eUYqO5MqAtiUbBJp8nlgtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGHxvh/btqFZzpsmUj/eUYqO5MqAtiUbBJp8nlgtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGHxvh%2FbtqFZzpsmUj%2FeUYqO5MqAtiUbBJp8nlgtK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;498&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;여기서 우리가 주목할 점은 &lt;b&gt;모든 loss function이 위에서 본 그래프들처럼 무난한 포물선의 형태를 그리지 않는다는 것입니다.&lt;/b&gt; 만약 loss function이 훨씬 더 꼬불꼬불하여 복잡하다면 부분적으로 극소를 가지는 &lt;b&gt;local minimum&lt;/b&gt; 그리고 전체에서 가장 최솟값을 가지는 지점인 &lt;b&gt;global minimum&lt;/b&gt; 두가지가 존재하게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;근데 만약 알고리즘이 왼쪽부터 시작하여 오른쪽으로 이동하는 과정에서 global minimum에 도달하기 전에 &lt;b&gt;local minimum을 만나면 이곳에서 수렴하게 된다는 문제점이 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;504&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9ZP3E/btqF1bgAkIG/oWS70kUkeebLdEhG0S9ROk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9ZP3E/btqF1bgAkIG/oWS70kUkeebLdEhG0S9ROk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9ZP3E/btqF1bgAkIG/oWS70kUkeebLdEhG0S9ROk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9ZP3E%2FbtqF1bgAkIG%2FoWS70kUkeebLdEhG0S9ROk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;504&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다행스러운건 우리가 지금까지 다뤘던 &lt;b&gt;Linear Regression에서 사용되는 loss function은 무난한 이차함수의 포물선 형태를 가지는 볼록 함수(convex function)입니다.&lt;/b&gt; 다시 말해서 local minimum 없이 global minimum만 존재한다는 뜻입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;179&quot; data-origin-height=&quot;141&quot; data-filename=&quot;blob&quot; width=&quot;306&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yuwNg/btqF1A1hith/zCL0wqQPNY378CyEHFXgy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yuwNg/btqF1A1hith/zCL0wqQPNY378CyEHFXgy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yuwNg/btqF1A1hith/zCL0wqQPNY378CyEHFXgy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyuwNg%2FbtqF1A1hith%2FzCL0wqQPNY378CyEHFXgy1%2Fimg.png&quot; data-origin-width=&quot;179&quot; data-origin-height=&quot;141&quot; data-filename=&quot;blob&quot; width=&quot;306&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;이제 feature의 범위(scale)에 따라 loss function의 형태는 어떤지, 어떤 결과를 불러오는지 알아보겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;보통 loss function은 위에서 내려다 봤을 때 원 모양이지만, &lt;b&gt;feature 간 scale이 매우 다르면 길쭉한 모양이 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5k7bb/btqF01eg2hz/MKSOAZg7ZjpPDkXqiLvZGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5k7bb/btqF01eg2hz/MKSOAZg7ZjpPDkXqiLvZGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5k7bb/btqF01eg2hz/MKSOAZg7ZjpPDkXqiLvZGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5k7bb%2FbtqF01eg2hz%2FMKSOAZg7ZjpPDkXqiLvZGk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;만약 일반적인 원 모양이라면&lt;/b&gt; 알고리즘이 global minimum으로 곧장 진행하고 있어 빠르게 수렴하게 됩니다. &lt;b&gt;그런데 오른쪽 그래프와 같이 길쭉할 경우&lt;/b&gt; 최솟값에는 수렴하겠으나, 시간이 오래 걸릴 것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;&lt;b&gt;4.2.1 Batch Gradient Descent&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;이제 Batch GD를 시작으로 몇가지 GD 알고리즘의 종류에 대해 알아보겠습니다. 그전에 우리가 앞에서 기울기를 줄이는 방향으로 이동한다는 말을 도식화하여 Gradient Descent Algorithm식을 확인하겠습니다.&lt;/p&gt;
&lt;p&gt;우리가 현재 &amp;theta; 지점에서의 loss function의 &lt;b&gt;기울기라는 것은 loss function의 편도 함수로 구합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;503&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l8JLl/btqFZNnvO9K/JjjTdksuZkE0bLleKRq1D0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l8JLl/btqFZNnvO9K/JjjTdksuZkE0bLleKRq1D0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l8JLl/btqFZNnvO9K/JjjTdksuZkE0bLleKRq1D0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl8JLl%2FbtqFZNnvO9K%2FJjjTdksuZkE0bLleKRq1D0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;503&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;만약 feature가 여러개라면 &lt;b&gt;벡터&lt;/b&gt;를 이용해 한번에 계산할 수도 있겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RQwIV/btqF1StSBCI/rr05wd2vRc8f3nKxCC2tH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RQwIV/btqF1StSBCI/rr05wd2vRc8f3nKxCC2tH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RQwIV/btqF1StSBCI/rr05wd2vRc8f3nKxCC2tH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRQwIV%2FbtqF1StSBCI%2Frr05wd2vRc8f3nKxCC2tH1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Batch GD는 &amp;theta;를 조정하기 위한 기울기를 구할 때 Training data 전체를 사용합니다.&lt;/b&gt; 즉 우리는 매 스텝마다 기울기를 구해서 &amp;theta;를 조정해나갈텐데, 만약&lt;b&gt; Training set이 매우 크다면 시간이 매우 오래 걸린다는 결론에 쉽게 도달할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우리가 알고리즘에서 minimum에 도달하기 위해서는 기울기가 구해지면 이것이 작아지는 방향으로 가야합니다. 여기서 각 스텝의 이동 속도를 결정하는 &lt;b&gt;learning rate&lt;/b&gt;가 사용됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;398&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6tO69/btqF1nHTdqn/5nZGzk6S6vsIqod3B1JzN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6tO69/btqF1nHTdqn/5nZGzk6S6vsIqod3B1JzN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6tO69/btqF1nHTdqn/5nZGzk6S6vsIqod3B1JzN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6tO69%2FbtqF1nHTdqn%2F5nZGzk6S6vsIqod3B1JzN0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;398&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이를 간단히 구현해보고 최적화된 &amp;theta;까지 바로 확인해보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;eta = 0.1
n_iterations = 1000
m = 100

theta = np.random.randn(2,1)

for iteration in range(n_iterations):
  gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
  theta = theta - eta * gradients

theta

##결과값##
&amp;gt;&amp;gt;
array([[4.27746389],
       [2.91097464]])&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;Normal Equation을 통해 도출했던 &amp;theta;와 정확히 같습니다. 그렇다면 learnin rate가 달라짐에 따라 경사 하강 알고리즘의 스텝은 어떻게 나아가는지 그래프를 관찰해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB2xgE/btqF1BFUt4C/p24kkn8XFKT4sT8LeHnXBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB2xgE/btqF1BFUt4C/p24kkn8XFKT4sT8LeHnXBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB2xgE/btqF1BFUt4C/p24kkn8XFKT4sT8LeHnXBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB2xgE%2FbtqF1BFUt4C%2Fp24kkn8XFKT4sT8LeHnXBK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;- learning rate가 작은 경우(왼쪽) : 최솟값엔 도달하겠지만 시간이 매우 오래걸릴 것입니다.&lt;/p&gt;
&lt;p&gt;- learning rate가 적당한 경우(가운데) : 몇번의 반복만에 최솟값에 수렴하였습니다.&lt;/p&gt;
&lt;p&gt;- learning rate가 클 경우(오른쪽) : 알고리즘이 이리저리 튀면서 스텝마다 최솟값에서 점점 멀어져 발산해갑니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;그렇다면 적당한 learning rate는 어떻게 찾을 수 있을까요?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;첫번재는 GridSearch를 사용합니다.&lt;/b&gt; 예를 들어, 0.000001부터 시작하여 10배로 불리며 각각의 결과를 관찰할 수 있겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;두번째는 반복 횟수를 크게 지정하고, 기울기 값이 어떤 &amp;epsilon;라는 매우 작은 값보다 작으면 거의 minimum에 도달한 것으로 간주하고 중지하는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;&lt;b&gt;4.2.2 SGD&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Batch GD&lt;/b&gt;의 가장 큰 문제는 매 스텝마다 전체 Training set을 계산해야 하기에 &lt;b&gt;데이터셋이 클 경우 매우 느리다는 점이었습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;SGD&lt;/b&gt;는 매 스텝마다 전체 데이터셋이 아닌 &lt;b&gt;하나의 데이터를 랜덤으로 선택하여 그 데이터에 대한 기울기를 계산합니다.&lt;/b&gt; 즉 매 스텝마다 사용하는 데이터가 작기 때문에 &lt;b&gt;알고리즘이 매우 빠릅니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 빠른만큼 &lt;b&gt;훨씬 불안정합니다.&lt;/b&gt; 다시 말해 최솟값으로 도달할 때 위아래로 튀면서 감소합니다. 그 결과 &lt;b&gt;완벽하게 global minimum에 도달하진 못합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;하지만 불안정하다는 의미는&lt;b&gt; local minimum을 건너뛸 수 있다는 의미이기도 합니다.&lt;/b&gt; 따라서 SGD가 Batch GD보다 global minimum에 도달할 확률이 더 큽니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;b&gt;그렇다면 SGD의 이러한 불안정성을 어떻게 해결할 수 있을까요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;첫번째 방식은 &lt;b&gt;learning rate를 점진적으로 감소기키는 것입니다.&lt;/b&gt; 다시 말해서 처음에는 큰 보폭으로 최솟값으로 다가가다가, 어느 순간부터 좁은 보폭으로 global minimum에 세심하게 다가가는 기법입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6MfEq/btqF1aovy8w/MeJSNDhIb0NOHCyzly1TjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6MfEq/btqF1aovy8w/MeJSNDhIb0NOHCyzly1TjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6MfEq/btqF1aovy8w/MeJSNDhIb0NOHCyzly1TjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6MfEq%2FbtqF1aovy8w%2FMeJSNDhIb0NOHCyzly1TjK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;SGD를 구현해보겠습니다. 각 반복을 epoch라 하는데 아래 코드의 경우 1000번을 반복하도록 하는데 50번만 반복하고도 최솟값에 근접하게 도달한 케이스입니다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;n_epochs = 50
t0, t1 = 5, 50  # 학습 스케줄 하이퍼파라미터

def learning_schedule(t):
    return t0 / (t + t1)

theta = np.random.randn(2,1)  # 랜덤 초기화

for epoch in range(n_epochs):
    for i in range(m):
        if epoch == 0 and i &amp;lt; 20:                    
            y_predict = X_new_b.dot(theta)           
            style = &quot;b-&quot; if i &amp;gt; 0 else &quot;r--&quot;         
            plt.plot(X_new, y_predict, style)        
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(epoch * m + i)
        theta = theta - eta * gradients
        theta_path_sgd.append(theta)              

plt.plot(X, y, &quot;b.&quot;)                             
plt.xlabel(&quot;$x_1$&quot;, fontsize=18)                     
plt.ylabel(&quot;$y$&quot;, rotation=0, fontsize=18)           
plt.axis([0, 2, 0, 15])                              
save_fig(&quot;sgd_plot&quot;)                                 
plt.show()

theta

##결과값##
&amp;gt;&amp;gt;
array([[4.21076011],
       [2.74856079]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;첫 20번의 훈련스텝을 보겠습니다. 매우 불안정하다는 것 그리고 learning rate가 점점 줄어든다는 것을 알 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;n_epochs = 50
t0, t1 = 5, 50  # 학습 스케줄 하이퍼파라미터

def learning_schedule(t):
    return t0 / (t + t1)

theta = np.random.randn(2,1)  # 랜덤 초기화

for epoch in range(n_epochs):
    for i in range(m):
        if epoch == 0 and i &amp;lt; 20:                    
            y_predict = X_new_b.dot(theta)          
            style = &quot;b-&quot; if i &amp;gt; 0 else &quot;r--&quot;         
            plt.plot(X_new, y_predict, style)        
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(epoch * m + i)
        theta = theta - eta * gradients
        theta_path_sgd.append(theta)                

plt.plot(X, y, &quot;b.&quot;)                                 
plt.xlabel(&quot;$x_1$&quot;, fontsize=18)                     
plt.ylabel(&quot;$y$&quot;, rotation=0, fontsize=18)           
plt.axis([0, 2, 0, 15])                              
plt.show()        &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcU4iT/btqF1R9Agc3/f1JWUgYzsrQLAWBXZ2Dni0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcU4iT/btqF1R9Agc3/f1JWUgYzsrQLAWBXZ2Dni0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcU4iT/btqF1R9Agc3/f1JWUgYzsrQLAWBXZ2Dni0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcU4iT%2FbtqF1R9Agc3%2Ff1JWUgYzsrQLAWBXZ2Dni0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;SGD의 경우 매 스텝마다 데이터를 랜덤으로 선택하기 때문에 어떤 데이터는 여러 번 선택되는 반면, 어떤 데이터는 한번도 반영되지 않을 수도 있습니다. &lt;b&gt;이를 방지하려면 epoch마다 데이터를 섞어주면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;sklearn에서 SGD를 구현해보았습니다.&lt;/b&gt; 반복 횟수는 1000번, 0.001보다 cost가 작을때까지 반복합니다.(tol=1e-3), learning rate는 0.1로 설정하였습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;from sklearn.linear_model import SGDRegressor

sgd_reg = SGDRegressor(max_iter = 1000, tol = 1e-3, penalty = None, eta0 = 0.1)
sgd_reg.fit(X, y.ravel())

sgd_reg.intercept_, sgd_reg.coef_
&amp;gt;&amp;gt;
(array([4.24365286]), array([2.8250878]))&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;4.2.3 Mini-Batch Gradient Algorithm&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;이제 마지막으로 알아볼 알고리즘은 &lt;b&gt;Mini-Batch Gradient Algorithm&lt;/b&gt;입니다. 이것은 Batch GD처럼 전체도 아니고, SGD처럼 하나도 아닌 mini-batch라 부르는 작은 데이터 세트에 대한 기울기를 계산합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 mini-batch를 크게하면, Batch GD에 가까워지므로 SGD에서 관찰됐던 불안정성이 조금씩 해결됩니다. 그러나 local minimum에 도달한 확률은 더욱 커집니다.&lt;/p&gt;
&lt;p&gt;다음은 세 가지 Gradient Descent Algorithm의 훈련 과정을 그래프로 표현한 것입니다.&lt;/p&gt;
&lt;p&gt;- Batch GD는 실제로 minimum에서 멈췄습니다. 그러나 SGD와 Mini-Batch GD는 근처에서 맴돕니다.&lt;/p&gt;
&lt;p&gt;- Batch GD가 학습에 가장 많은 시간이 소요됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB54kr/btqF1BeQpb0/ZP7qq9mDQOFk2f9cRI1yVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB54kr/btqF1BeQpb0/ZP7qq9mDQOFk2f9cRI1yVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB54kr/btqF1BeQpb0/ZP7qq9mDQOFk2f9cRI1yVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB54kr%2FbtqF1BeQpb0%2FZP7qq9mDQOFk2f9cRI1yVk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;여기까지 Linear Regression의 원리와 구현, 그리고 Gradient Descent Algorithm의 종류와 원리 그리고 구현까지 알아보았습니다.&lt;/p&gt;
&lt;p&gt;긴 글 읽어주셔서 감사합니다. 오늘도 행복한 하루 보내시길 바랍니다:)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>Keras</category>
      <category>pandas</category>
      <category>PYTHON</category>
      <category>pytorch</category>
      <category>regression</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/47</guid>
      <comments>https://box-world.tistory.com/47#entry47comment</comments>
      <pubDate>Fri, 24 Jul 2020 22:36:37 +0900</pubDate>
    </item>
    <item>
      <title>[핸즈온 머신러닝 2판 ] MNIST를 활용한 다중 분류(Multi Class Classification)은 어떻게 하는 것일까?</title>
      <link>https://box-world.tistory.com/46</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;나머지 인생을 설탕물이나 팔면서 보내고 싶습니까&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;아니면 세상을 바꿔 놓을 기회를 갖고 싶습니까?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;- 스티브 잡스 -&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;저번 포스팅에서는 MNIST 데이터셋을 활용하여 이진 분류(Bianry Classification)을 구현해보았습니다. 이번 포스팅에서는 같은 MNIST 데이터셋을 활용하여 둘 이상의 클래스를 구별할 수 있는 &lt;b&gt;다중 분류(Multiclass Classifier)&lt;/b&gt;에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;h2&gt;3.4 Multi-Class Classification&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;SGDClassifier, RandomClassifier, Naive Bayers 같은 일부 알고리즘들은 &lt;b&gt;Multi-class Classification&lt;/b&gt;이 가능합니다. 그러나 Logistic Regression, SVM과 같은 알고리즘은 &lt;b&gt;Binary Classification&lt;/b&gt;만 가능합니다. 그러나 &lt;b&gt;여러 개의 Binary Classifier를 사용하여 Multiclass Classifier 구현이 가능합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 특성 숫자 하나만을 구분하는 10개의 Bianry Classifier(0~9)를 훈련시켜 클래스가 10개인 숫자 이미지 분류 시스템을 만들 수 있습니다. 여기에 &lt;b&gt;이미지 분류 시 Decision score가 가장 높은 것을 클래스로 선택하게 됩니다.&lt;/b&gt; 이를 &lt;b&gt;OvR&lt;/b&gt;(one vs rest) 혹은 &lt;b&gt;OvA&lt;/b&gt;(one vs all)이라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;클래스가 10개인 숫자 이미지 분류 시스템을 구현하는 또 하나의 방법은 0과 1 구별, 0과 2구별, 1과 2 구별 등 &lt;b&gt;모든 숫자의 조합에 대해 Binary Classifier를 학습시키는 것입니다.&lt;/b&gt; 이를 &lt;b&gt;OvO&lt;/b&gt;(one vs one)이라고 합니다. 즉 클래스가 $N$개라면 Classifier는 $N * (N-1)/2$개가 필요합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;MNIST의 경우 10개의 클래스가 존재하므로 &lt;b&gt;45개의 Classifier&lt;/b&gt;를 훈련시켜야 할 것이고, 이미지 하나를 분류하기 위해선 이 45개의 Classifier를 모두 통과시킨 후 가장 높은 점수를 얻은 클래스를 선택하게 될것입니다. 이러한 OvO의 장점은 &lt;b&gt;각 Classifier를 훈련시킬 때 전체 데이터가 아닌 구별을 위한 두가지 클래스에 대한 데이터만 들어간다는 점입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이러한 OvO의 특징은 training set의 크기에 민감하여 작은 training set을 선호하는 &lt;b&gt;SVM&lt;/b&gt;에서 효과적입니다. 그러나 &lt;b&gt;대부분의 Binary Classification 알고리즘에서는 OvR을 선호합니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;sklearn으로 Multiclass Classification 구현 시 Binary Classifier를 선택하면 &lt;b&gt;알고리즘에 따라 자동으로 OvR 또는 OvO를 실행합니다.&lt;/b&gt; 이제 직접 &lt;b&gt;SVM&lt;/b&gt;을 테스트 해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595212707125&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.svm import SVC

svm_clf = SVC()
svm_clf.fit(X_train, y_train)
svm_clf.predict([some_digit])

###결과값###
&amp;gt;&amp;gt;
array([5], dtype=uint8)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 &lt;b&gt;sklearn이 실제로 OvO 방법을 사용하는지 확인해보겠습니다.&lt;/b&gt; &lt;b&gt;decision_function()&lt;/b&gt;을 사용하면 1개가 아니라, 데이터 당 10개의 점수를 반환합니다. 즉 이 10개의 점수는 각 클래스 마다의 점수라는 것을 의미합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595212961963&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;some_digit_scores = svm_clf.decision_function([some_digit])
some_digit_scores

###결과값###
&amp;gt;&amp;gt;
array([[ 2.81585438,  7.09167958,  3.82972099,  0.79365551,  5.8885703 ,
         9.29718395,  1.79862509,  8.10392157, -0.228207  ,  4.83753243]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이 10개 중 가장 높은 점수에 해당하는 것은 클래스 5입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595213114655&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;np.argmax(some_digit_scores)
&amp;gt;&amp;gt;
5

svm_clf.classes_
&amp;gt;&amp;gt;
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8)

svm_clf.classes_[5]
&amp;gt;&amp;gt;
5&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;만약 &lt;b&gt;sklearn에서 OvO나 OvR을 강제하고 싶다면 '&lt;/b&gt;&lt;span&gt;&lt;b&gt;OneVsRestClassifier'나 '&lt;/b&gt;&lt;span&gt;&lt;b&gt;OneVsOneClassifier'를 사용하면 됩니다.&lt;/b&gt; 사용 방법은 Binary 혹은 Multiclass Classifier 객체를 만들어 저 둘 중 하나에 인자로 던져주면 됩니다. 우선은 SVM부터 실행해보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595213266699&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.multiclass import OneVsRestClassifier

ovr_clf = OneVsRestClassifier(SVC())
ovr_clf.fit(X_train, y_train)
ovr_clf.predict([some_digit])

###결과값###
&amp;gt;&amp;gt;
array([5], dtype=uint8)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1595213312363&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;len(ovr_clf.estimators_)
&amp;gt;&amp;gt;
10&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;SGDClassifier나 RnadomForestClassifier를 훈련시키는 것도 마찬가지입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595213421409&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sgd_clf.fit(X_train, y_train)
sgd_clf.predict([some_digit])

###결과값###
&amp;gt;&amp;gt;
array([3], dtype=uint8)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;decision_function()으로 SGD가 클래스마다 부여한 점수를 확인해보겠습니다. &lt;b&gt;대부분의 점수가 큰 음수라는 것은 Classifier가 예측 결과에 대한 강한 확신을 보인다는 뜻입니다.&lt;/b&gt; 다만 클래스가 4의 점수가 1823이라는 것은 분류기가 의심하고 있다는 뜻입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595213767817&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sgd_clf.decision_function([some_digit])

###결과값###
&amp;gt;&amp;gt;
array([[-31893.03095419, -34419.69069632,  -9530.63950739,
          1823.73154031, -22320.14822878,  -1385.80478895,
        -26188.91070951, -16147.51323997,  -4604.35491274,
        -12050.767298  ]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 Classifier의 성능을 평가해보겠습니다. &lt;b&gt;평가에는 일반적으로 'cross validation'을 사용합니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595214065552&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cross_val_score(sgd_clf, X_train, y_train, cv=3, scoring=&quot;accuracy&quot;)

###결과값###
&amp;gt;&amp;gt;
array([0.87365, 0.85835, 0.8689 ])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;모든 fold가 84% 이상을 얻었습니다. 나쁘지는 않은 성능이지만 높일 여지는 있습니다. &lt;b&gt;Input의 scale을 조정하여 accuracy를 높여보고자 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595214164074&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
cross_val_score(sgd_clf, X_train_scaled, y_train, cv=3, scoring=&quot;accuracy&quot;)

###결과값###
&amp;gt;&amp;gt;
array([0.8983, 0.891 , 0.9018])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;3.5 에러 분석&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;보통은 가장 좋은 몇가지 모델을 골라 하이퍼파라미터를 튜닝하겠지만, 지금은 가능성 높은 모델 하나를 찾았다고 가정하고 성능을 향상시킬 방법을 찾아보겠습니다. 한 가지 방법은 &lt;b&gt;만들어진 에러의 종류를 분석하는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;먼저 &lt;b&gt;Confusion Matrix(오차 행렬)&lt;/b&gt;을 살펴보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1595222497883&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)
conf_mx = confusion_matrix(y_train, y_train_pred)
conf_mx

###결과값###
&amp;gt;&amp;gt;
array([[5577,    0,   22,    5,    8,   43,   36,    6,  225,    1],
       [   0, 6400,   37,   24,    4,   44,    4,    7,  212,   10],
       [  27,   27, 5220,   92,   73,   27,   67,   36,  378,   11],
       [  22,   17,  117, 5227,    2,  203,   27,   40,  403,   73],
       [  12,   14,   41,    9, 5182,   12,   34,   27,  347,  164],
       [  27,   15,   30,  168,   53, 4444,   75,   14,  535,   60],
       [  30,   15,   42,    3,   44,   97, 5552,    3,  131,    1],
       [  21,   10,   51,   30,   49,   12,    3, 5684,  195,  210],
       [  17,   63,   48,   86,    3,  126,   25,   10, 5429,   44],
       [  25,   18,   30,   64,  118,   36,    1,  179,  371, 5107]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;정상적으로 출력되긴 했지만, 가독성이 조금 떨어집니다. 따라서 이 숫자를 &lt;b&gt;이미지로 표현하여&lt;/b&gt; 가독성을 높이도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595222701165&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt.matshow(conf_mx, cmap = plt.cm.gray)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zUcO3/btqFQyWJ7BB/iUH6xiDVZLV41XMw898ibk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zUcO3/btqFQyWJ7BB/iUH6xiDVZLV41XMw898ibk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zUcO3/btqFQyWJ7BB/iUH6xiDVZLV41XMw898ibk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzUcO3%2FbtqFQyWJ7BB%2FiUH6xiDVZLV41XMw898ibk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 Confusion Matrix는 이미지들이 올바르게 분류되었음을 나타내는 주대각선에 있으므로 만족스러운 결과입니다. 그러나 &lt;b&gt;숫자 5는 상대적으로 어두워보이는데, 이는 다른 숫자들만큼 Classification이 잘 되지 않았기 때문입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그래프의 에러에 초점을 맞춰 Confusion Matrix의 각 값을 대응되는 클래스의 이미지 개수로 나누어 &lt;b&gt;에러 비&lt;/b&gt;율을 비교합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595222890466&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;row_sums = conf_mx.sum(axis=1, keepdims=True)
norm_conf_mx = conf_mx / row_sums&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 이미지로 표현할 건데 주대각선만 0으로 채우겠습니다. 행은 실제 클래스, 열은 예측한 클래스입니다. &lt;b&gt;클래스 8의 열이 밝다는 것은 많은 이미지들이 8로 잘못 분류되었음을 의미합니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595223409089&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;np.fill_diagonal(norm_conf_mx, 0)
plt.matshow(norm_conf_mx, cmap=plt.cm.gray)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbaVth/btqFOWYBsLT/GKt7zTWzXS9tWeaPsk18Pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbaVth/btqFOWYBsLT/GKt7zTWzXS9tWeaPsk18Pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbaVth/btqFOWYBsLT/GKt7zTWzXS9tWeaPsk18Pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbaVth%2FbtqFOWYBsLT%2FGKt7zTWzXS9tWeaPsk18Pk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Confusion Matrix 분석 시 Classifier의 성능을 향상시킬 키를 찾을 수도 있습니다. 앞서 말했던 것과 같이 위 그래프를 통해 8로 잘못 분류되는 것을 계산할 필요가 있습니다. 예를 들어 8에 대한 데이터를 더 학습하거나, 8과 다른 숫자의 차이를 구별하여 해결하는 등 그 방법은 다양하게 존재하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;좀 더 깊이 들어가 &lt;b&gt;개개의 에러를 분석해보면 Classifier가 무슨 일을 하고, 왜 잘못되었는지에 대해 통찰은 얻겠지만, 난이도는 훨씬 높고 시간도 오래 걸릴 것입니다.&lt;/b&gt; 예를 들어 3과 5의 데이터들을 비교해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595242074757&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cl_a, cl_b = 3, 5
X_aa = X_train[(y_train == cl_a) &amp;amp; (y_train_pred == cl_a)]
X_ab = X_train[(y_train == cl_a) &amp;amp; (y_train_pred == cl_b)]
X_ba = X_train[(y_train == cl_b) &amp;amp; (y_train_pred == cl_a)]
X_bb = X_train[(y_train == cl_b) &amp;amp; (y_train_pred == cl_b)]

plt.figure(figsize=(8,8))
plt.subplot(221); plot_digits(X_aa[:25], images_per_row=5)
plt.subplot(222); plot_digits(X_ab[:25], images_per_row=5)
plt.subplot(223); plot_digits(X_ba[:25], images_per_row=5)
plt.subplot(224); plot_digits(X_bb[:25], images_per_row=5)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;408&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqusM6/btqFPHmHNoM/o3Exkn2IySpQpBo5mD0Rak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqusM6/btqFPHmHNoM/o3Exkn2IySpQpBo5mD0Rak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqusM6/btqFPHmHNoM/o3Exkn2IySpQpBo5mD0Rak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqusM6%2FbtqFPHmHNoM%2Fo3Exkn2IySpQpBo5mD0Rak%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;408&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Classifier가 분류한 일부는 정말 사람도 분간하기 어려울만큼 모양이 애매합니다. 그러나 일부를 제외한 대부분의 잘못 분류된 이미지는 확실히 에러인 것 같고, Classifier가 실수한 이유를 이해하기 어렵습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;사실 그 원인은 선형(Linear) 모델은 SGDClassifier를 사용했기 때문입니다.&lt;/b&gt; Linear model은 조금 축약해서 말하자면 픽셀 강도에 대한 가중치의 합을 클래스의 점수로 계산합니다. 따라서 모양이 유사한 3과 5는 몇개의 픽셀만 다를 것이므로 모델이 쉽게 혼동할 수 밖에 없습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이러한 부분을 보완하기 위해서는 3과 5의 형태의 차이를 발견하여 데이터 전처리를 통해 혼동되지 않도록 해준다면 에러를 줄일 수 있을 것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;3.6 Multi-Label Classification&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;지금까지는 하나의 데이터가 하나의 클래스에만 할당되었습니다.&lt;/b&gt; 그러나 Classifier에 따라 &lt;b&gt;하나의 데이터가 여러 개의 클래스를 출력해야 할 때도 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 얼굴 인식 분류기를 생각해보겠습니다. 만약 하나의 사진에 여러 사람이 등장한다면 인식된 사람마다 하나의 클래스를 모두 지정하는게 맞을 것입니다. 구체적으로 Classifier가 앨리스, 밥, 찰리 세 얼굴을 인식하도록 훈련되어있을 때, 앨리스와 찰리가 있는 사진을 본다면 [1, 0, 1]을 출력해야 합니다. 이처럼 &lt;b&gt;여러 개의 Binary 클래스를 출력하는 Classifier를 'Multi-Label Classification'이라고 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이해를 위해 간단한 예시를 들어보겠습니다. 아래 코드는 &lt;b&gt;각 숫자 이미지에 두 개의 Label이 담긴 y_multilabel 배열&lt;/b&gt;을 만듭니다. 첫 번째 레이블은 숫자가 큰 값(7, 8, 9) 중 하나인지 나타내고, 두 번째는 홀수인지 나타냅니다. 그리고 그 다음줄에서 KNeighborsClassifier에 이 multilabel을 넣고 훈련시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595242841147&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.neighbors import KNeighborsClassifier

y_train_large = (y_train &amp;gt;= 7)
y_train_odd = (y_train % 2 == 1)
y_multilabel = np.c_[y_train_large, y_train_odd]

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_multilabel)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; 예측을 만들면 두개의 Label이 출력 됩니다. 5는 7, 8, 9에 속하지 않고(False) 홀수이므로(True) 아래 결과는 맞다고 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595243345306&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;knn_clf.predict([some_digit])

###결과값###
&amp;gt;&amp;gt;
array([[False,  True]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Multi-Label Classifier를 평가하는 방법은 많습니다.&lt;/b&gt; 다만 적절한 지표는 상황마다 다릅니다. 예를 들어 다음과 같이 모든 Label에 대한 F1 점수의 평균을 계산할 수 있겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595243454681&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3)
f1_score(y_multilabel, y_train_knn_pred, average=&quot;macro&quot;)
&amp;gt;&amp;gt;
0.976410265560605&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;위 코드는 모든 레이블의 가중치(Weight)가 같다고 가정한 것입니다.&lt;/b&gt; Weight를 주는 가장 간단한 방법은 Label에 클래스의 지지도(support) 즉 각 Label에 속한 데이터의 수를 Weight로 주는 것입니다. 이를 위해서는 &lt;b&gt;average=&quot;macro&quot;를 &quot;weighted&quot;로 설정하면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;3.7 Multi-output Classification&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;마지막으로 알아볼 Classification은 &lt;b&gt;Multi-output Classification&lt;/b&gt;입니다. Multi-Label Classification에서 &lt;b&gt;하나의 Label이 Multi-Class가 될 수 있도록 즉 두개 이상의 값을 가질 수 있도록 일반화한 것입니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이를 위해 &lt;b&gt;이미지에서 Noise를 제거하는 시스템&lt;/b&gt;을 만들어보겠습니다. &lt;b&gt;Noise가 많은 이미지를 Input&lt;/b&gt;으로 받고, &lt;b&gt;Noise를 제거한 숫자 이미지를 MNIST 이미지처럼 픽셀의 강도를 담은 배열로 출력하겠습니다.&lt;/b&gt; 특히 하나의 픽셀이 하나의 Label이기 때문에 &lt;b&gt;Classifier의 출력은 Multi-Label&lt;/b&gt;이고, 각 Label은 0~255사이의 값을 가집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 &lt;b&gt;Input으로 사용할 Noise 섞인 이미지를 만들기 위해&lt;/b&gt; MNIST에서 나눈 training set과 test set 각각에 &lt;b&gt;numpy의 randint() 함수&lt;/b&gt;를 사용하여 픽셀 강도에 잡음을 추가하겠습니다. 이에 대한 &lt;b&gt;Label은 Noise가 없는 원본 이미지가 되겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;164&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NMgkV/btqFP9chmel/FvLyFMaQ3zAl0flBwTWO20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NMgkV/btqFP9chmel/FvLyFMaQ3zAl0flBwTWO20/img.png&quot; data-alt=&quot;왼쪽이 Noise가 섞인 이미지(input), 오른쪽이 깨끗한 이미지(Label)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NMgkV/btqFP9chmel/FvLyFMaQ3zAl0flBwTWO20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNMgkV%2FbtqFP9chmel%2FFvLyFMaQ3zAl0flBwTWO20%2Fimg.png&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;164&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;왼쪽이 Noise가 섞인 이미지(input), 오른쪽이 깨끗한 이미지(Label)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp;이제 Classifier를 훈련시켜 위 이미지를 깨끗하게 만들어보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595246705712&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;knn_clf.fit(X_train_mode, y_train_mod)
clean_digit = knn_clf.predict([X_test_mod[some_index]])
plot_digit(clean_digit)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;177&quot; data-origin-height=&quot;170&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca5Snb/btqFQxKJspo/9w0DqXND2i53Kekxfilw11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca5Snb/btqFQxKJspo/9w0DqXND2i53Kekxfilw11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca5Snb/btqFQxKJspo/9w0DqXND2i53Kekxfilw11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca5Snb%2FbtqFQxKJspo%2F9w0DqXND2i53Kekxfilw11%2Fimg.png&quot; data-origin-width=&quot;177&quot; data-origin-height=&quot;170&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;이것으로 Classification에 대한 설명을 마쳤습니다. 다음 포스팅에서는 지금까지는 구체적인 이해없이 지나쳤던 모델의 훈련에 대해 알아보는 시간을 가져보겠습니다.&lt;/p&gt;
&lt;p&gt;긴 글 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>Classification</category>
      <category>Keras</category>
      <category>Machine Learning</category>
      <category>pandas</category>
      <category>PYTHON</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/46</guid>
      <comments>https://box-world.tistory.com/46#entry46comment</comments>
      <pubDate>Mon, 20 Jul 2020 14:34:22 +0900</pubDate>
    </item>
    <item>
      <title>[핸즈온 머신러닝 2판] MNIST를 활용한 이진 분류(Binary Classification)은 어떻게 하는 것일까?</title>
      <link>https://box-world.tistory.com/45</link>
      <description>&lt;p&gt;&amp;nbsp; 이번 포스팅에서는 머신러닝 공부의 Hello World! 라고 부르는 데이터셋인 MNIST를 사용하여 분류(Classification) 작업을 하는 모델을 만들어보고자 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이번 포스팅은 아래 포스팅을 공부하시고 보시면 더욱 효과적입니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/24&quot;&gt;https://box-world.tistory.com/24&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1595144279295&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝] 머신러닝 시스템 디자인 하기 : Precision, Recall, F score&quot; data-og-description=&quot;시작하며 머신러닝 시스템을 디자인하면서 적용해볼 수 있는 방법들은 다양하게 존재합니다. 이번 포스팅에서는 여러 방법들 중에 하나의 최선의 방법을 골라 적용할지 판단하는 체계적인 방��&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/24&quot; data-og-url=&quot;https://box-world.tistory.com/24&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OW3rL/hyGPfHNrwN/SjnfxYJhZYx7nxMboRGsGK/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/p8WcZ/hyGO4fbuA2/qN0BCPszGQqR2wHDWWaYE0/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/baUXJM/hyGO8hAtKo/tllrtiHfoyoPRvWg7WhQp1/img.png?width=683&amp;amp;height=382&amp;amp;face=0_0_683_382&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/24&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/24&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OW3rL/hyGPfHNrwN/SjnfxYJhZYx7nxMboRGsGK/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/p8WcZ/hyGO4fbuA2/qN0BCPszGQqR2wHDWWaYE0/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/baUXJM/hyGO8hAtKo/tllrtiHfoyoPRvWg7WhQp1/img.png?width=683&amp;amp;height=382&amp;amp;face=0_0_683_382');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝] 머신러닝 시스템 디자인 하기 : Precision, Recall, F score&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 머신러닝 시스템을 디자인하면서 적용해볼 수 있는 방법들은 다양하게 존재합니다. 이번 포스팅에서는 여러 방법들 중에 하나의 최선의 방법을 골라 적용할지 판단하는 체계적인 방��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;3.1 MNIST&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;MNIST 데이터셋&lt;/b&gt;은 고등학생과 미국 인구조사국 직원들이 손으로 쓴 70000개의 작은 숫자 이미지로 구성되어있습니다. 각 이미지에는 어떤 숫자를 나타내는지 Label은 붙어있지 않습니다. &lt;b&gt;sklearn&lt;/b&gt;에서는 MNIST 데이터셋 등 일반적으로 알려진 데이터셋을 내려받을 수 있는 함수를 제공합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595127304852&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.datasets import fetch_openml

mnist = fetch_openml('mnist_784', version = 1)
mnist.keys()

###결과값###
&amp;gt;&amp;gt;
dict_keys(['data', 'target', 'frame', 'feature_names', 'target_names', 'DESCR', 'details', 'categories', 'url'])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;sklearn이 읽어들인 데이터셋은 비슷한 딕셔너리 구조를 가지고 있습니다.&lt;/p&gt;
&lt;p&gt;- DESCR : 데이터셋을 설명함&lt;/p&gt;
&lt;p&gt;- data : 데이터가 하나의 행, feature가 하나의 열로 구성된 배열을 가짐&lt;/p&gt;
&lt;p&gt;- target : label을 담아놓은 배열&lt;/p&gt;
&lt;p&gt;&amp;nbsp;직접 살펴보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595127602854&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X, y = mnist[&quot;data&quot;], mnist[&quot;target&quot;]
X.shape

###결과값###
&amp;gt;&amp;gt;
(70000, 784)

y.shape
###결과값###
&amp;gt;&amp;gt;
(70000,)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;70000개의 이미지는 28 * 28 픽셀이기 때문에 &lt;b&gt;784개의 feature를 가지고 있습니다.&lt;/b&gt; 각 feature는 0~255사이의 픽셀 강도를 나타냅니다. 하나의 이미지를 확인하기 위해서는 &lt;b&gt;1)&lt;/b&gt; 이미지의 feature 벡터를 28 * 28 배열로 크기를 바꾸고, &lt;b&gt;2)&lt;/b&gt; matplotlib의 imshow() 함수를 사용해 그려줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595127882400&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import matplotlib as mpl
import matplotlib.pyplot as plt

some_digit = X[0]
some_digit_image = some_digit.reshape(28, 28)

plt.imshow(some_digit_image, cmap = &quot;binary&quot;)
plt.axis(&quot;off&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;256&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EmKln/btqFPtgBsnz/oLF03kyCtItY09jlYKRSjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EmKln/btqFPtgBsnz/oLF03kyCtItY09jlYKRSjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EmKln/btqFPtgBsnz/oLF03kyCtItY09jlYKRSjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEmKln%2FbtqFPtgBsnz%2FoLF03kyCtItY09jlYKRSjk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;256&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 이미지의 &lt;b&gt;label&lt;/b&gt;을 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595127966821&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y[0]

###결과값###
&amp;gt;&amp;gt;
'5'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이때 label은 문자열입니다. 그러나 머신러닝 알고리즘에서는 숫자를 사용해야하기 때문에 &lt;b&gt;y를 정수로 변환해줘야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595128041368&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np

y = y.astype(np.uint8)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;아래에 보이는 전체적인 MNIST 이미지 샘플들을 보면 분류 작업이 매우 어려울 것이란 것을 직감할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595128350727&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def plot_digits(instances, images_per_row=10, **options):
    size = 28
    images_per_row = min(len(instances), images_per_row)
    images = [instance.reshape(size,size) for instance in instances]
    n_rows = (len(instances) - 1) // images_per_row + 1
    row_images = []
    n_empty = n_rows * images_per_row - len(instances)
    images.append(np.zeros((size, size * n_empty)))
    for row in range(n_rows):
        rimages = images[row * images_per_row : (row + 1) * images_per_row]
        row_images.append(np.concatenate(rimages, axis=1))
    image = np.concatenate(row_images, axis=0)
    plt.imshow(image, cmap = mpl.cm.binary, **options)
    plt.axis(&quot;off&quot;)
    
plt.figure(figsize=(9,9))
example_images = X[:100]
plot_digits(example_images, images_per_row=10)
save_fig(&quot;more_digits_plot&quot;)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;300&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cry23s/btqFNQRxv58/PwS2yh4nr7YFKpx8pgGbDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cry23s/btqFNQRxv58/PwS2yh4nr7YFKpx8pgGbDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cry23s/btqFNQRxv58/PwS2yh4nr7YFKpx8pgGbDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcry23s%2FbtqFNQRxv58%2FPwS2yh4nr7YFKpx8pgGbDk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;300&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;이제 본격적인 훈련에 앞서 데이터셋을 6:1 비율의 training set과 test set으로 분리하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595128497648&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X_train, X_test, y_train, y_test = X[:60000], X[60000:],y[:60000],y[60000:]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;참고로 데이터셋은 웬만하면 섞는게 좋습니다.&lt;/b&gt; 왜냐하면 어떤 알고리즘은 순서에 민감하여 비슷한 데이터가 연속으로 들어오면 성능이 나빠질 수 있기 때문입니다. 우리가 사용할 training set의 경우 이미 섞여 있어 별도의 함수를 사용하지 않았습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;2.3. 이진 분류기 훈련&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;문제를 단순화해서 이미지가 5이냐 아니냐 두개의 클래스를 분류하는 &lt;b&gt;이진 분류기(Binary classifier)&lt;/b&gt;로 문제의 접근을 시작해보겟습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 분류 작업을 위한 &lt;b&gt;target vector&lt;/b&gt;를 만들어 보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595129087270&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_train_5 = (y_train == 5) # 5는 True, 다른 숫자는 모두 False
y_test_5 = (y_test == 5)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; 이제 &lt;b&gt;분류 모델&lt;/b&gt;을 만들어 훈련시켜보겠습니다. 우리가 첫 번째로 사용할 모델은 sklearn의&lt;b&gt; SGDClassifier&lt;/b&gt; 클래스의 &lt;b&gt;확률적 경사 하강법(Stochastic Gradient Descent)&lt;/b&gt;입니다. SGD는 Loss function 계산 시 전체가 아닌 일부 데이터셋을 이용하기 때문에 &lt;b&gt;속도가 빨라서 매우 큰 데이터셋을 다루는데 효과적입니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595129387344&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import SGDClassifier

sgd_clf  = SGDClassifier(random_state = 42)
sgd_clf.fit(X_train, y_train_5)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 훈련된 모델을 이용해 숫자 5의 이미지를 감지해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595129540593&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sgd_clf.predict([some_digit])

###결과값###
&amp;gt;&amp;gt;
array([ True])&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;3.3 성능 측정&lt;/h2&gt;
&lt;h3&gt;3.3.1 cross validation을 사용한 accuracy 측정&lt;/h3&gt;
&lt;p&gt;sklearn이 제공하는 기능보다 cross validation 과정을 더 많이 제어해야 한다면&lt;b&gt; 직접 함수를 정의하면 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- StratifiedFold는 클래스 비율이 유지되도록 &lt;b&gt;fold&lt;/b&gt;를 만들어 줍니다.&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;매 반복에서&lt;/b&gt; Classifier 객체를 복제하여 training fold로 훈련시키고, test fold로 예측을 만듭니다.&lt;/p&gt;
&lt;p&gt;- 그 다음 올바른 예측의 수를 세어 &lt;b&gt;정확한 예측의 비율&lt;/b&gt;을 출력 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595129816255&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone
skfolds = StratifiedKFold(n_splits=3,random_state = 42)

for train_index, test_index in skfolds.split(X_train, y_train_5):
  clone_clf = clone(sgd_clf)
  X_train_folds = X_train[train_index]
  y_train_folds = y_train_5[train_index]
  X_test_fold = X_train[test_index]
  y_test_fold = y_train_5[test_index]

  clone_clf.fit(X_train_folds, y_train_folds)
  y_pred = clone_clf.predict(X_test_fold)
  n_correct = sum(y_pred == y_test_fold)
  print(n_correct / len(y_pred))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;cross_val_score() 함수로 &lt;b&gt;fold가 3개인&lt;/b&gt; k-fold cross validation을 이용하여 SGDClassifier를 평가해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595130411435&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import cross_val_score

cross_val_score(sgd_clf, X_train, y_train_5, cv = 3, scoring = &quot;accuracy&quot;)

###결과값###
&amp;gt;&amp;gt;
array([0.95035, 0.96035, 0.9604 ])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;모든 fold에 대한 a&lt;b&gt;ccuracy가 95% 이상입니다.&lt;/b&gt; 성능이 매우 준수해보이는데 과연 그럴까요? Label에 상관없이 70000개의 &lt;b&gt;모든 데이터를 5가 아니라고 분류하는 더미 분류기&lt;/b&gt;를 만들어 accuracy를 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595130522535&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.base import BaseEstimator

class Never5Classifier(BaseEstimator):
  def fit(self, X, y=None):
    return self
  def predict(self, X):
    return np.zeros((len(X),1), dtype=bool) #0으로 초기화된 nparray 리턴&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1595130546392&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;never_5_clf = Never5Classifier()
cross_val_score(never_5_clf, X_train, y_train_5, cv = 3, scoring = &quot;accuracy&quot;)

###결과값###
&amp;gt;&amp;gt;
array([0.91125, 0.90855, 0.90915])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;모두 5가 아니라고 예측했음에도 정확도가 90%가 넘습니다.&lt;/b&gt; 이미지의 10%가 5에 해당하기 때문에 다 아니라고 예측해도 맞출 확률이 90%이기 때문입니다. 여기에서 왜 classification을 다룰 때, &lt;b&gt;accuracy를 성능 측정 지표로 사용하지 않는지 알려줍니다.&lt;/b&gt; 특히 클래스가 불균형한 데이터셋일수록 더욱 그렇습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;3.3.2 오차 행렬&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;Classification의 성능을 평가하는데 더 좋은 방법은 &lt;b&gt;오차 행렬(Confusion matrix)&lt;/b&gt;입니다. 기본적인 아이디어는 클래스 A의 샘플이 클래스 B로 분류된 횟수를 세는 것입니다. 예를 들어서 Classifier가 숫자 5를 3으로 잘못 분류한 횟수를 알고 싶다면, 행렬의 5행 3열을 보면 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Confusion matrix를 만드려면 실제 정답값과 비교할 수 있도록 예측값을 만들어야 합니다. &lt;b&gt;이때 주의할 점은 test set은 건드려선 안된다는 점입니다.&lt;/b&gt; 누차 강조하지만 test set는 프로젝트의 가장 마지막에 쓰입니다. 대신 &lt;b&gt;cross_val_predict()&lt;/b&gt;를 사용할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;cross_val_predict()는 cross_val_score()처럼 k-fold cross validation을 수행하지만, 점수 대신 &lt;b&gt;각 test fold에서 얻은 예측을 반환합니다.&lt;/b&gt; 이를 다시 말하면 모든 training set에 대해 &lt;b&gt;'깨끗한'&lt;/b&gt; 예측을 했다고 말할 수 있습니다. 즉 훈련 동안 보지 못했던 데이터에 대해 예측했다는 의미입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595143768476&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import  cross_val_predict

y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv = 3)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 실제 정답값과 예측값을 넣고 Confusion matrix를 호출해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595143940090&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import confusion_matrix

confusion_matrix(y_train_5, y_train_pred) #분류결과표

###결과값###
&amp;gt;&amp;gt;
array([[53892,   687],
       [ 1891,  3530]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; Confusion matrix는 네 가지 영역으로 구별됩니다. 행은 실제 클래스, 열은 예측한 클래스입니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;True Positive(3530)&lt;/b&gt;는 실제 이미지가 5인데(Positive), 예측도 5로 한것입니다(Positive).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;True Negative(53892)&lt;/b&gt;는 실제 이미지가 5가 아닌데(Negative), 예측값도 5가 아니라고 한것입니다.(Negative).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;False Positive(687)&lt;/b&gt;는 실제값은 5인데(Positive), 예측값은 5가 아닌 경우입니다(Negative).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;False Positive(1891)&lt;/b&gt;는 실제값은 5가 아닌데(Negative), 예측값은 5라고 한 경우입니다(Positive).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;만약 Classifier가 완벽하다면 True Positive와 True Negative를 제외하고 다음과 같이 나머지는 0일 것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595144782581&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_train_perfect_predictions = y_train_5
confusion_matrix(y_train_5, y_train_perfect_predictions)

###결과값###
&amp;gt;&amp;gt;
array([[54579,     0],
       [    0,  5421]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Confusion Matrix에 대한 정보를 요약해 표현하는 두가지 중요한 지표는 &lt;b&gt;Recall&lt;/b&gt;과&lt;b&gt; Precision&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;580&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L8MRb/btqFNbbp8At/MN1chNyo0Kan4N4Uz8hXuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L8MRb/btqFNbbp8At/MN1chNyo0Kan4N4Uz8hXuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L8MRb/btqFNbbp8At/MN1chNyo0Kan4N4Uz8hXuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL8MRb%2FbtqFNbbp8At%2FMN1chNyo0Kan4N4Uz8hXuK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;580&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;- &lt;b&gt;Recall&lt;/b&gt; : 5라고 예측한 데이터들 중 실제 5인 데이터는 얼마나 들어있느냐 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/luBUs/btqFOM172RG/LF6xzcIEWztcK5w4r6C880/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/luBUs/btqFOM172RG/LF6xzcIEWztcK5w4r6C880/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/luBUs/btqFOM172RG/LF6xzcIEWztcK5w4r6C880/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FluBUs%2FbtqFOM172RG%2FLF6xzcIEWztcK5w4r6C880%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;Precision&lt;/b&gt; : 실제로 5인 데이터들 중 예측값도 5라고 얼마나 잘 예측했느냐입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPgafd/btqFNPrHWMb/VQQEwKCjEOzQJ7NAejf3ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPgafd/btqFNPrHWMb/VQQEwKCjEOzQJ7NAejf3ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPgafd/btqFNPrHWMb/VQQEwKCjEOzQJ7NAejf3ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPgafd%2FbtqFNPrHWMb%2FVQQEwKCjEOzQJ7NAejf3ck%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;3.3.3 Precision과 Recall&lt;/h3&gt;
&lt;p&gt;sklearn은 Precision과 Recall을 포함하여 Classifier의 지표를 계산하는 여러 함수를 제공합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595145518594&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import precision_score, recall_score

precision_score(y_train_5, y_train_pred)

###결과값###
&amp;gt;&amp;gt;
0.8370879772350012&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1595145566183&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;recall_score(y_train_5,y_train_pred)

###결과값###
&amp;gt;&amp;gt;
0.6511713705958311&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;위 결과를 통해 우리의 모델은 전체 숫자 5에서 83%만 정확하게 5라고 예측했으며, 5라고 예측한 것중 65%만 실제 5였음을 알 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;여기에 한 단계 더 나아가 Precision과 Recall을 하나의 숫자로 표현한 지표인 &lt;b&gt;F1 score&lt;/b&gt;가 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z6A8K/btqFOh2mBcB/s1qzb3JgMXGAZ6RUia1Dd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z6A8K/btqFOh2mBcB/s1qzb3JgMXGAZ6RUia1Dd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z6A8K/btqFOh2mBcB/s1qzb3JgMXGAZ6RUia1Dd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz6A8K%2FbtqFOh2mBcB%2Fs1qzb3JgMXGAZ6RUia1Dd1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1595145912452&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import f1_score

f1_score(y_train_5, y_train_pred)

###결과값###
&amp;gt;&amp;gt;
0.7325171197343846&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;보통 Precision과 Recall이 비슷하다면 F1 score가 높습니다.&lt;/b&gt; 그러나 상황에 따라 Precision과 Recall 중 더 중요한 지표가 있을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 어린이에게 안전한 동영상을 걸러내는 Classifier를 만든다 한다면 Recall을 높여 나쁜 동영상이 몇개 노출되는 것보단 좋은 동영상이 제외되더라도(Low Recall) 안전한 것들만 노출시키는 것이 좋습니다(High Precision).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Precision과 Recall은 반비례 관계(trade-off)이므로 상황에 따라 충분히 고민하고 경중을 따지는게 좋습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;3.3.4 Precision/Recall trade-off&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;SGDClassifier가 어떻게 Classification하는지 보면서 Precision과 Recall의 &lt;b&gt;trade off 관계&lt;/b&gt;를 이해해보겠습니다. 우리의 Classifier는 Decision Function을 사용하여 각 데이터의 점수를 계산합니다. 이 점수가 &lt;b&gt;임곗값(threshold)&lt;/b&gt;보다 크면 Positive 클래스를 할당하고, 그렇지 않다면 Negative 클래스를 할당합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;688&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nGCvz/btqFNrdRxmV/F893tSzQhrwicMtYrqGrt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nGCvz/btqFNrdRxmV/F893tSzQhrwicMtYrqGrt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nGCvz/btqFNrdRxmV/F893tSzQhrwicMtYrqGrt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnGCvz%2FbtqFNrdRxmV%2FF893tSzQhrwicMtYrqGrt0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;688&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Decision Threshold가 위 그림에서 두개의 숫자 5 사이라고 가정해보겠습니다. 이 &lt;b&gt;기준선의 오른쪽&lt;/b&gt;에는 4개의 True Positive와 하나의 False Positive가 있습니다. 그러므로 &lt;b&gt;이 threshold에서 Precision은 80%라 할 수 있습니다.&lt;/b&gt; 하지만 실제 숫자 5는 6개이고 이중 Classifier는 4개만 감지했으므로 &lt;b&gt;Recall은 67%입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;Threshold를 높이면&lt;/b&gt;(오른쪽 방향으로 옮기면) False Positive였던 6이 True Negative가 되면서 Precision이 100%가 됩니다. 그러나 True Positive하나가 False Negatvie가 되면서 Recall은 50%로 줄어듭니다. &lt;b&gt;반대로 Threshold를 내리면&lt;/b&gt; Recall이 높아지는대신 Precision이 줄어들 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;sklearn에서는 Threshold를 직접 지정할 수는 없지만, 예측에 사용한 점수는 확인할 수 있습니다. decision_function() 메서드를 호출하면 각 데이터의 점수를 알 수 있습니다. 그리고 이 점수를 기반으로 원하는 Threshold를 정하여 예측을 만들 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595149940395&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_scores = sgd_clf.decision_function([some_digit])
y_scores

###결과값###
&amp;gt;&amp;gt;
array([2164.22030239])&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1595149961362&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#threshold가 0일때

threshold = 0
y_some_digit_pred = (y_scores &amp;gt; threshold)
y_some_digit_pred

###결과값###
&amp;gt;&amp;gt;
array([ True])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;이제 threshold를 높여보겠습니다.&lt;/b&gt; 보다시피 threshold가 0일 때는 감지되던 실제 5인 데이터가 threshold를 높이게 되면서 놓치게 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595150138976&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;threshold = 8000
y_some_digit_pred = (y_scores &amp;gt; threshold)
y_some_digit_pred

###결과값###
&amp;gt;&amp;gt;
array([False])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;그렇다면 적절한 threshold는 어떻게 정할 수 있을까요?&lt;/b&gt; 1) 우선 cross_val_predict() 메서드를 이용하여 training set 내 모든 데이터의 점수를 구해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595150357220&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method = &quot;decision_function&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 위의 결과를 precision_recall_curve() 함수에 넣으면 모든 threshold에 대한 Precision과 Recall의 변화 추이를 알 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595150412821&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import precision_recall_curve

precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1595150447769&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):
    plt.plot(thresholds, precisions[:-1], &quot;b--&quot;, label=&quot;Precision&quot;, linewidth=2)
    plt.plot(thresholds, recalls[:-1], &quot;g-&quot;, label=&quot;Recall&quot;, linewidth=2)
    plt.legend(loc=&quot;center right&quot;, fontsize=16) # Not shown in the book
    plt.xlabel(&quot;Threshold&quot;, fontsize=16)        # Not shown
    plt.grid(True)                              # Not shown
    plt.axis([-50000, 50000, 0, 1])             # Not shown



recall_90_precision = recalls[np.argmax(precisions &amp;gt;= 0.90)]
threshold_90_precision = thresholds[np.argmax(precisions &amp;gt;= 0.90)]


plt.figure(figsize=(8, 4))                                                                  # Not shown
plot_precision_recall_vs_threshold(precisions, recalls, thresholds)
plt.plot([threshold_90_precision, threshold_90_precision], [0., 0.9], &quot;r:&quot;)                 # Not shown
plt.plot([-50000, threshold_90_precision], [0.9, 0.9], &quot;r:&quot;)                                # Not shown
plt.plot([-50000, threshold_90_precision], [recall_90_precision, recall_90_precision], &quot;r:&quot;)# Not shown
plt.plot([threshold_90_precision], [0.9], &quot;ro&quot;)                                             # Not shown
plt.plot([threshold_90_precision], [recall_90_precision], &quot;ro&quot;)                             # Not shown                   
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(아래 그래프에서 Precision 곡선이 중간에 울퉁불퉁한 이유는 threshold를 올리더라도 Precision이 낮아질 때가 있기 때문입니다. 예를 들어 가운데 Threshold에서 오른쪽으로 숫자 하나만큼 이동하면 4/5(80%)에서 3/4(75%)로 줄어들게 됩니다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvTmP2/btqFNPSRjYU/Ftkf7okN8prLBTfEeSCCY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvTmP2/btqFNPSRjYU/Ftkf7okN8prLBTfEeSCCY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvTmP2/btqFNPSRjYU/Ftkf7okN8prLBTfEeSCCY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvTmP2%2FbtqFNPSRjYU%2FFtkf7okN8prLBTfEeSCCY1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;혹은 Recall에 대한 Precision 곡선(PR)을 그릴 수도 있습니다. 아래 그림을 보시면 &lt;b&gt;Recall이 80%인 부근에서 Precision이 급격하게 줄어들기 시작합니다.&lt;/b&gt; 이 부분 직전을 &lt;b&gt;trade off&lt;/b&gt;로 선택하는 것이 좋습니다. 예를 들면 60% 부근이 여기에 해당될 수 있겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qQ1EM/btqFPsa7gVE/OJokAuccXbQfHRklDYvHE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qQ1EM/btqFPsa7gVE/OJokAuccXbQfHRklDYvHE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qQ1EM/btqFPsa7gVE/OJokAuccXbQfHRklDYvHE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqQ1EM%2FbtqFPsa7gVE%2FOJokAuccXbQfHRklDYvHE1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;만약 Precision 90%가 목표라면 최댓값의 첫번째 인덱스를 반환하는 &lt;b&gt;np.argmax()&lt;/b&gt;를 이용하여 90%의 Precision을 만드는 가장 낮은 Threshold를 찾을 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595150985066&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;threshold_90_precision = thresholds[np.argmax(precisions &amp;gt;= 0.90)]
#~7816&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;training set에 대한 예측을 만듭니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595151078848&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_train_pred_90 = (y_scores &amp;gt;= threshold_90_precision)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이 예측에 대한 Precsion과 Recall을 확인하면, Precision 90%를 실제로 달성했음을 볼 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595151241873&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;precision_score(y_train_5, y_train_pred_90)
&amp;gt;&amp;gt;
0.9000345901072293

recall_score(y_train_5, y_train_pred_90)
&amp;gt;&amp;gt;
0.4799852425751706&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;3.3.5 ROC 곡선&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;ROC 곡선&lt;/b&gt;도 Binary Classification에서 많이 쓰이는 도구 중 하나입니다. ROC 곡선은 &lt;b&gt;False Positive 비율(FPR)에 대한 True Positive 비율&lt;/b&gt;(TPR, Recall의 다른 이름)의 곡선입니다. &lt;b&gt;FPR은 1 - True Positive 비율(TPR)&lt;/b&gt;입니다. &lt;b&gt;TPR&lt;/b&gt;은 특이도(specificity)라고도 합니다. 다시 말해서 ROC 곡선은 Recall에 대한 1 - specificity라고 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;ROC 곡선 사용을 위해서는 우선 &lt;b&gt;roc_curve()&lt;/b&gt; 함수를 사용하여 여러 threshold에 대한 TPR과 FPR을 계산해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595151784496&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(y_train_5, y_scores)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 &lt;b&gt;matplotlib&lt;/b&gt;을 이용하여 TPR에 대한 FPR 곡선을 나타냅니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595151871238&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def plot_roc_curve(fpr, tpr, label=None):
    plt.plot(fpr, tpr, linewidth=2, label=label)
    plt.plot([0, 1], [0, 1], 'k--') # dashed diagonal
    plt.axis([0, 1, 0, 1])                                    # Not shown in the book
    plt.xlabel('False Positive Rate (Fall-Out)', fontsize=16) # Not shown
    plt.ylabel('True Positive Rate (Recall)', fontsize=16)    # Not shown
    plt.grid(True)                                            # Not shown

plt.figure(figsize=(8, 6))                         # Not shown
plot_roc_curve(fpr, tpr)
plt.plot([4.837e-3, 4.837e-3], [0., 0.4368], &quot;r:&quot;) # Not shown
plt.plot([0.0, 4.837e-3], [0.4368, 0.4368], &quot;r:&quot;)  # Not shown
plt.plot([4.837e-3], [0.4368], &quot;ro&quot;)               # Not shown

plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crdsv7/btqFNPeiPKx/ubY7bk8HjWuAcIm4OZzJF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crdsv7/btqFNPeiPKx/ubY7bk8HjWuAcIm4OZzJF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crdsv7/btqFNPeiPKx/ubY7bk8HjWuAcIm4OZzJF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrdsv7%2FbtqFNPeiPKx%2FubY7bk8HjWuAcIm4OZzJF0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;TPR이 높을수록 Classifier가 만드는 FPR이 늘어납니다. 빨간색 점선은 데이터를 랜덤으로 분류하는 Classifier의 ROC 곡선입니다. &lt;b&gt;좋은 Classifier일수록 이 빨간색 점선에서 멀리 떨어져 있어야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;곡선 아래의 면적(AUC)&lt;/b&gt;를 측정하면 Classifier를 비교할 수 있습니다. 빨간 색 점선의 AUC는 0.5입니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1595152120428&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import roc_auc_score

roc_auc_score(y_train_5, y_scores)
&amp;gt;&amp;gt;
0.9604938554008616&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그렇다면 &lt;b&gt;어떨 때 ROC 곡선을 사용하고 어떨 때 Precision/Recall(PR) 곡선을 사용해야 할까요?&lt;/b&gt; 보통은 Positive 클래스가 드물거나, False Negative보다 False Positive가 더 중요할 때, 그러니까 예를 들어 보통 걸릴 확률이 아주 미비한 암 발병과 같은 것을 검출하는 상황에서는 PR 곡선을 씁니다. 그리고 그렇지 않으면 ROC 곡선을 사용합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;이제 &lt;b&gt;RandomForestClassifier&lt;/b&gt;를 훈련시켜 &lt;b&gt;SGDClassifier&lt;/b&gt;의 ROC 곡선과 ROC AUC 점수를 비교해보겠습니다. 우선 training set의 점수를 알아야 하는데 RandomForestClassifier에는 작동 방식의 차이로 decision_function() 대신 &lt;b&gt;predict_proba()&lt;/b&gt; 메서드가 있습니다. 이는 데이터가 행, 클래스가 열이고 데이터가 주어진 클래스에 속할 확률을 담은 배열을 반환합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595157023401&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.ensemble import RandomForestClassifier

forest_clf = RandomForestClassifier(random_state = 42)
y_probas_forest = cross_val_predict(forest_clf, X_train, y_train_5, cv=3, method = &quot;predict_proba&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;roc_curve() 함수 사용을 위해서는 Label과 점수가 필요합니다. 그러나 &lt;b&gt;점수 대신에 클래스 확률을 사용할 수 있기 때문에, Positive 클래스 확률을 점수로 사용해보겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1595157309017&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;y_scores_forest = y_probas_forest[:, 1]
fpr_forest, tpr_forest, thresholds_forest = roc_curve(y_train_5, y_scores_forest)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 ROC 곡선을 그려보고 SGDClassifier와 RandomeForest를 비교해보겠습니다. 아래 그래프 결과를 보면 RandomForest의 결과가 훨씬 좋은 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595157354616&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, &quot;b:&quot;, linewidth=2, label=&quot;SGD&quot;)
plot_roc_curve(fpr_forest, tpr_forest, &quot;Random Forest&quot;)
plt.plot([4.837e-3, 4.837e-3], [0., 0.4368], &quot;r:&quot;)
plt.plot([0.0, 4.837e-3], [0.4368, 0.4368], &quot;r:&quot;)
plt.plot([4.837e-3], [0.4368], &quot;ro&quot;)
plt.plot([4.837e-3, 4.837e-3], [0., 0.9487], &quot;r:&quot;)
plt.plot([4.837e-3], [0.9487], &quot;ro&quot;)
plt.grid(True)
plt.legend(loc=&quot;lower right&quot;, fontsize=16)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8IbYW/btqFNEKST2T/9MQTzKs87OtfO2X5DCxgk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8IbYW/btqFNEKST2T/9MQTzKs87OtfO2X5DCxgk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8IbYW/btqFNEKST2T/9MQTzKs87OtfO2X5DCxgk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8IbYW%2FbtqFNEKST2T%2F9MQTzKs87OtfO2X5DCxgk0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;ROC AUC 점수도 훨씬 높을 수 밖에 없습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1595157444583&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;roc_auc_score(y_train_5, y_scores_forest)
&amp;gt;&amp;gt;
0.9983436731328145&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;이번 포스팅에서는 Binary Classifier를 훈련ㅅ키는 것부터 다양한 지표를 이용하여 모델을 평가하는 법을 공부하였습니다. 다음 포스팅에서는 Multi Classifier에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;긴 글 읽어주셔서 감사합니다. 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>Keras</category>
      <category>Machine Learning</category>
      <category>mnist</category>
      <category>pandas</category>
      <category>PYTHON</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/45</guid>
      <comments>https://box-world.tistory.com/45#entry45comment</comments>
      <pubDate>Sun, 19 Jul 2020 12:51:33 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 모델 학습과 튜닝은 어떻게 하는 것일까? (3)</title>
      <link>https://box-world.tistory.com/44</link>
      <description>&lt;p&gt;&amp;nbsp;이전 2개의 포스팅에 결쳐 &lt;span style=&quot;color: #333333;&quot;&gt;우리는 지금까지 문제를 정의하고 데이터를 읽어들여 탐색하였습니다. 그리고 데이터를 training set과 test set으로 나누고 학습을 위한 머신러닝 알고리즘에 주입할 데이터를 자동으로 전처리하고 정제하는 파이프라인까지 만들어 보았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;이번 포스팅에서는 &lt;b&gt;머신러닝 모델을 선택하고 훈련시켜 세부적으로 튜닝하는 법&lt;/b&gt;까지 다뤄보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/42&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;box-world.tistory.com/42&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1595126986312&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (1)&quot; data-og-description=&quot;발견에는 항상 뜻밖의 재미가 있다 - 제프 베조스(Amazon CEO) - Chapter 2 이번 포스팅을 시작으로 3번에 걸쳐 하나의 머신러닝 프로젝트가 어떻게 구성되고 진행되는지 알아보겠습니다. 우선 주요 단&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/42&quot; data-og-url=&quot;https://box-world.tistory.com/42&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dBWYlE/hyGNSAupRK/x0kcIQSXcm3Em53ifbY4WK/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/b0A5Iy/hyGPehAh0q/124dvTUb46mQ3yC9tXpUmk/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/r41sI/hyGNFA844J/B0PFKlmuXB37zfcrcNAKq0/img.png?width=1018&amp;amp;height=540&amp;amp;face=0_0_1018_540&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/42&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/42&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dBWYlE/hyGNSAupRK/x0kcIQSXcm3Em53ifbY4WK/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/b0A5Iy/hyGPehAh0q/124dvTUb46mQ3yC9tXpUmk/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/r41sI/hyGNFA844J/B0PFKlmuXB37zfcrcNAKq0/img.png?width=1018&amp;amp;height=540&amp;amp;face=0_0_1018_540');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (1)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;발견에는 항상 뜻밖의 재미가 있다 - 제프 베조스(Amazon CEO) - Chapter 2 이번 포스팅을 시작으로 3번에 걸쳐 하나의 머신러닝 프로젝트가 어떻게 구성되고 진행되는지 알아보겠습니다. 우선 주요 단&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;box-world.tistory.com/43&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1595126995230&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (2)&quot; data-og-description=&quot;&amp;nbsp;저번 포스팅에서는 캘리포니아 주택 가격 데이터셋을 가지고 pandas, sklearn을 이용하여 데이터의 특성을 탐색하고, 모델 학습을 위해 test set을 분리하는 다양한 방법에 대해 알아보았습니다. &amp;nbsp;��&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/43&quot; data-og-url=&quot;https://box-world.tistory.com/43&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WvE3b/hyGPgfoRfM/LKgnGdBGoFIJ07ClDa66IK/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/pMU6h/hyGNPwYKXp/vBGEG4G4ccLOIQVQhc92e0/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/TraUH/hyGNMNMEKh/0Wmbxq9zFN7U3nXukYNHqK/img.png?width=923&amp;amp;height=383&amp;amp;face=0_0_923_383&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/43&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WvE3b/hyGPgfoRfM/LKgnGdBGoFIJ07ClDa66IK/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/pMU6h/hyGNPwYKXp/vBGEG4G4ccLOIQVQhc92e0/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/TraUH/hyGNMNMEKh/0Wmbxq9zFN7U3nXukYNHqK/img.png?width=923&amp;amp;height=383&amp;amp;face=0_0_923_383');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;저번 포스팅에서는 캘리포니아 주택 가격 데이터셋을 가지고 pandas, sklearn을 이용하여 데이터의 특성을 탐색하고, 모델 학습을 위해 test set을 분리하는 다양한 방법에 대해 알아보았습니다. &amp;nbsp;��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.6 모델 선택과 훈련&lt;/h2&gt;
&lt;h3&gt;2.6.1 training set에서의 훈련 및 평가&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;우선 가장 대표적인 모델인 &lt;b&gt;linear regression&lt;/b&gt;을 훈련시켜보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594875057898&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.linear_model import LinearRegression

lin_reg = LinearRegression()
lin_reg.fit(housing_prepared, housing_labels)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 우리는 linear regression 모델을 만들었으니, training set의 일부 샘플을 넣어보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594875178258&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;some_data = housing.iloc[:5]
some_labels = housing_labels.iloc[:5]
some_data_prepared = full_pipeline.transform(some_data)
print(&quot;예측: &quot;, lin_reg.predict(some_data_prepared))

###결과값###
&amp;gt;&amp;gt;
예측:  [210644.60459286 317768.80697211 210956.43331178  59218.98886849
 189747.55849879]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1594875340312&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(&quot;레이블: &quot;, list(some_labels))

###결과값###
&amp;gt;&amp;gt;
레이블:  [286600.0, 340600.0, 196900.0, 46300.0, 254500.0]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;아주 정확한 예측은 아니지만, 어느정도 작동하는 것을 볼 수 있습니다. 이제&lt;b&gt; sklearn의 mean_sqaure_error 함수&lt;/b&gt;를 이용하여 전체 training set에 대한 이 linear regression 모델의 &lt;b&gt;rmse&lt;/b&gt;를 측정해보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;대부분 구역의 median house value가 $120000~$265000 사이인 것을 감안하면, $68628의 오차는 그리 좋은 편은 아닌 것 같습니다. 이러한 결과는 모델이 &lt;b&gt;과소 적합(Underfit)&lt;/b&gt; 되었기 때문이며 이는 데이터가 부족하거나, 모델이 강력하지 못한 탓입니다. 우선 좀 더 복잡한 모델을 시도해서 어떻게 되는지 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594875425222&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.metrics import mean_squared_error

housing_predictions = lin_reg.predict(housing_prepared)
lin_mse = mean_squared_error(housing_labels,housing_predictions)
lin_rmse = np.sqrt(lin_mse)
lin_rmse

###결과값###
&amp;gt;&amp;gt;
68628.19819848923&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;DecisionTreeRegressor&lt;/b&gt;를 훈련시켜보겠습니다. 이 모델은 강력하며, 데이터에서 복잡한 &lt;b&gt;비선형관계&lt;/b&gt;를 찾을 수 있습니다.(DecisionTree에 대해서는 추후에 설명드리겠습니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1594875670561&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.tree import DecisionTreeRegressor

tree_reg = DecisionTreeRegressor()
tree_reg.fit(housing_prepared, housing_labels)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 모델을 평가해보겠습니다. 0.0이라는 것은 오차가 없다는 뜻인데, 모델이 완벽할 리는 없고 아마 데이터가 심각하게 &lt;b&gt;과대 적합(Overfit)&lt;/b&gt; 되었을 확률이 큽니다. 하지만 이 또한 확신할 수 없습니다. 따라서 우리는 training set에서 일부를 &lt;b&gt;교차 검증(cross-validation) 데이터&lt;/b&gt;로 분리시켜 모델을 평가하는데 사용해야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594875717470&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing_predictions = tree_reg.predict(housing_prepared)
tree_mse = mean_squared_error(housing_labels, housing_predictions)
tree_rmse = np.sqrt(tree_mse)
tree_rmse

###결과값###
&amp;gt;&amp;gt;
0.0&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.6.2 Cross-Validation을 사용한 평가&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;DecisionTreeRegressor&lt;/b&gt; 모델을 이어서 계속 보겠습니다. 우선 이전에 정의했던 train_test_split 함수를 사용하여 training set을 더 작은 traing set과 cv set으로 나누고, &lt;b&gt;training set&lt;/b&gt;에서는 모델 훈련을, &lt;b&gt;cv set&lt;/b&gt;에서는 모델 평가가 이루어지게 하면 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;혹은 훌륭한 대안으로 &lt;b&gt;sklearn의 k-fold cross-validation&lt;/b&gt; 기능을 사용할 수 있습니다. 이는 training set를 fold라 불리는 10개의 subset으로 무작위 분할합니다. 그 후 DecisionTree 모델을 10번 훈련하고 평가하는데, 이때 매번 다른 하나의 fold를 사용하여 평가하고 나머지 9개는 훈련에 사용됩니다. 그리고 10개의 평가 점수가 담긴 배열이 결과가 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;np.sqrt()에 -scores가 들어간 것&lt;/b&gt;은 cross_val_score() 메서드의 scoring 매개변수는 낮을수록 좋은 loss function이 아니라, 클수록 좋은 &lt;b&gt;utility function&lt;/b&gt;을 기대합니다. 따라서 MSE의 반대 즉 음숫값을 계산하는 &lt;b&gt;neg_mean_squared_error 함수&lt;/b&gt;를 사용합니다. 그래서 제곱근 계산을 위하여 -scores로 부호를 바꾼 것입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594876329398&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import cross_val_score

scores = cross_val_score(tree_reg, housing_prepared, housing_labels,
                         scoring = &quot;neg_mean_squared_error&quot;, cv=10)
tree_rmse_scores = np.sqrt(-scores)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;아래 결과를 살펴보면 DecisionTreeRegressor의 결과가 이전만큼 좋아보이지 않습니다. 심지어 linear regression 모델보다 안좋습니다. 이를 통해 Cross-validation으로는 모델의 성능 추정뿐 아니라 &lt;b&gt;이 추정이 얼마나 정확한지(표준편차)를 측정할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;DecisionTree 점수가 71407에서 &amp;plusmn;2439 사이입니다. cv set을 하나만 사용했다면 이를 알 수 없었을 것입니다. 그러나 모델을 여러 번 훈련시키는 것은 cost가 높으므로 이 점을 고려하며 사용해야겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594876593034&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def display_scores(scores):
  print(&quot;점수:&quot;,scores)
  print(&quot;평균:&quot;,scores.mean())
  print(&quot;표준편차:&quot;,scores.std())

display_scores(tree_rmse_scores)

###결과값###
&amp;gt;&amp;gt;
점수: [69649.64460859 66090.16419858 70329.66447084 69160.83207592
 70549.37962702 73640.27705273 70815.59582659 70998.36764945
 76652.63720653 68576.3158628 ]
평균: 70646.28785790454
표준편차: 2711.925409096817&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;비교를 위해 linear regression 모델의 점수를 계산해보겠습니다. 확실히 &lt;b&gt;DecisionTreeRegressor가 Overfit되어 성능이 나쁘다는 것을 알 수 있는 대목입니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594876919160&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lin_scores = cross_val_score(lin_reg, housing_prepared, housing_labels,
                             scoring=&quot;neg_mean_squared_error&quot;,cv=10)

lin_rmse_scores = np.sqrt(-lin_scores)
display_scores(lin_rmse_scores)

###결과값###
&amp;gt;&amp;gt;
점수: [66782.73843989 66960.118071   70347.95244419 74739.57052552
 68031.13388938 71193.84183426 64969.63056405 68281.61137997
 71552.91566558 67665.10082067]
평균: 69052.46136345083
표준편차: 2731.674001798344&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;마지막으로 &lt;b&gt;RandomForestRegressor&lt;/b&gt; 모델을 하나 더 시도해보겠습니다. 이는 feature를 무작위로 선택하여 많은 &lt;b&gt;DecisionTree&lt;/b&gt;를 만들고 그 예측들을 평균 내는 방식으로 작동합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 여러 모델을 만들어 하나의 모델을 만드는 것을 &lt;b&gt;앙상블 학습(Ensemble&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Learning&lt;/span&gt;)&lt;/b&gt;이라고 하며 머신러닝 알고리즘의 성능을 극대화하는 방식 중 하나입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594877108270&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.ensemble import RandomForestRegressor

forest_reg = RandomForestRegressor()
forest_reg.fit(housing_prepared, housing_labels)
housing_predictions = forest_reg.predict(housing_prepared)
forest_mse = mean_squared_error(housing_labels, housing_predictions)
forest_rmse = np.sqrt(forest_mse)
forest_rmse

###결과값###
&amp;gt;&amp;gt;
18790.050174547516&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;훨씬 훌륭해보입니다. 그러나 &lt;b&gt;training set에 대한 점수가 cv set에 대한 점수보다 훨씬 낮다는 것은 training set에 여전히 Overfit되어 잇따는 의미입니다.&lt;/b&gt; 이러한 &lt;b&gt;Overfit&lt;/b&gt;을 해결하려면 모델을 간단히 하거나, 더 많은 데이터를 모아야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594877201513&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;scores = cross_val_score(forest_reg, housing_prepared, housing_labels,
                         scoring = &quot;neg_mean_squared_error&quot;, cv=10)
forest_rmse_scores = np.sqrt(-scores)
display_scores(forest_rmse_scores)

###결과값###
&amp;gt;&amp;gt;
점수: [49621.96770814 47698.25757407 50071.21751987 52311.76799284
 49529.02895964 53216.72302009 48755.50575797 47792.20315641
 53017.97804452 49841.16154041]
평균: 50185.58112739592
표준편차: 1912.3687121407233&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;특히 모델 선정 시 중요한 것은 하나의 모델을 오래 붙잡고 하이퍼파라미터 튜닝에 시간을 소요하기 &lt;b&gt;전 2~5개 정도의 모델을 선정한 후 다양한 모델을 만들어보고 큰 그림을 그리는 것이 좋습니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p&gt;&amp;nbsp;다음은 실험한 sklearn 모델을 쉽게 저장할 수 있는 파이썬 패키지입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594877517664&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import joblib

##모델 저장 시
joblib.dump(모델명,&quot;my_model.pkl&quot;)

##모델 복원 시
my_model_loaded = joblib.load(&quot;my_model.pkl&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.7 모델 세부 튜닝&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이제 쓸만한 모델을 대충 추렸다고 가정하고, 이 모델들을 각각 세부 튜닝해보겠습니다.&lt;/p&gt;
&lt;h3&gt;2.7.1 그리드 탐색(Grid Search)&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;가장 단순한 방법은 &lt;b&gt;만족할 만한 하이퍼 파라미터 조합을 찾을 때까지 수동으로 조정하는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;sklearn의 GridSearchCV&lt;/b&gt;를 사용하면, 탐색하고자 하는 하이퍼파라미터와 시도해볼 값을 지정만 하면, 가능한 모든 하이퍼파라미터 조합에 대한 &lt;b&gt;Cross-Validation&lt;/b&gt;을 사용해 평가합니다. 다음은 &lt;b&gt;RandomForestRegressor&lt;/b&gt;에 대한 코드입니다.&amp;nbsp;(보통 어떤 하이퍼파라미터 값을 지정해야 할지 모르겠다면 연속된 10의 거듭제곱(10, 100, 1000...)을 시도해보는 것이 좋습니다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;b&gt;param_grid&lt;/b&gt;에 따라 sklearn이 n_estimators와 max_features의 3 * 4 조합을 평가한 후, 두 번째 dict에 있는 2 * 3 조합을 시도합니다. 이를 모두 합하면 총 18개 조합을 탐색하고 cv = 5에 의해 각각 5번 모델을 훈련시킵니다. 즉 &lt;b&gt;18 * 5 = 90번&lt;/b&gt;을 훈련시킵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594877888456&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import GridSearchCV

param_grid = [
              {'n_estimators' : [3, 10, 30], 'max_features': [2, 4, 6, 8]},
              {'bootstrap':[False],'n_estimators':[3,10], 'max_features':[2,3,4]},
]

forest_reg = RandomForestRegressor()

grid_search = GridSearchCV(forest_reg, param_grid, cv=5,
                           scoring = 'neg_mean_squared_error',
                           return_train_score=True)

grid_search.fit(housing_prepared, housing_labels)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;훈련을 시킨 후 다음과 같이 최적의 조합을 얻을 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594878113435&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;grid_search.best_params_

###결과값###
&amp;gt;&amp;gt;
{'max_features': 8, 'n_estimators': 30}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;최적의 estimator에 직접 접근할 수도 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594878153925&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;grid_search.best_estimator_

###결과값###
&amp;gt;&amp;gt;
RandomForestRegressor(bootstrap=True, ccp_alpha=0.0, criterion='mse',
                      max_depth=None, max_features=8, max_leaf_nodes=None,
                      max_samples=None, min_impurity_decrease=0.0,
                      min_impurity_split=None, min_samples_leaf=1,
                      min_samples_split=2, min_weight_fraction_leaf=0.0,
                      n_estimators=30, n_jobs=None, oob_score=False,
                      random_state=None, verbose=0, warm_start=False)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 18개의 조합에 대한 평가 점수도 확인할 수 있습니다. 어쨌든 우리는 이제 최적의 모델을 찾았습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594878231896&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cvres = grid_search.cv_results_
for mean_score, params in zip(cvres[&quot;mean_test_score&quot;],cvres[&quot;params&quot;]):
print(np.sqrt(-mean_score),params)
  
###결과값###
&amp;gt;&amp;gt;
62600.75458160353 {'max_features': 2, 'n_estimators': 3}
55591.35252026881 {'max_features': 2, 'n_estimators': 10}
52846.87575009015 {'max_features': 2, 'n_estimators': 30}
59730.917651981195 {'max_features': 4, 'n_estimators': 3}
52997.7576498801 {'max_features': 4, 'n_estimators': 10}
50563.70361731654 {'max_features': 4, 'n_estimators': 30}
59290.062986907295 {'max_features': 6, 'n_estimators': 3}
51769.540932619544 {'max_features': 6, 'n_estimators': 10}
50116.10761043424 {'max_features': 6, 'n_estimators': 30}
59543.28349500444 {'max_features': 8, 'n_estimators': 3}
51715.32187214485 {'max_features': 8, 'n_estimators': 10}
49920.36274608907 {'max_features': 8, 'n_estimators': 30}
62010.100776085696 {'bootstrap': False, 'max_features': 2, 'n_estimators': 3}
54309.058249698515 {'bootstrap': False, 'max_features': 2, 'n_estimators': 10}
59237.80817701035 {'bootstrap': False, 'max_features': 3, 'n_estimators': 3}
52482.66370840826 {'bootstrap': False, 'max_features': 3, 'n_estimators': 10}
58842.04223735213 {'bootstrap': False, 'max_features': 4, 'n_estimators': 3}
51687.84566902621 {'bootstrap': False, 'max_features': 4, 'n_estimators': 10}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.7.2 Random Search&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;Grid Search는 위에서 본 적은 수의 조합을 탐구할 때 괜찮습니다. 그러나 탐색의 조합 수가 커지면 &lt;b&gt;RandomizedSearchCV&lt;/b&gt;를 사용하는 편이 더 좋습니다. &lt;span style=&quot;color: #333333;&quot;&gt;RandomizedSearchCV는 GridSearchCV와 거의 같은 방식으로 사용하지만, 모든 조합을 시도하는 대신 각 반복마다 하이퍼파라미터에 임의의 수를 대입하여 지정한 횟수만큼 평가합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594878931184&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint

param_distribs = {
        'n_estimators': randint(low=1, high=200),
        'max_features': randint(low=1, high=8),
    }

forest_reg = RandomForestRegressor(random_state=42)
rnd_search = RandomizedSearchCV(forest_reg, param_distributions=param_distribs,
                                n_iter=10, cv=5, scoring='neg_mean_squared_error', random_state=42)
rnd_search.fit(housing_prepared, housing_labels)

###결과값###
&amp;gt;&amp;gt;
RandomizedSearchCV(cv=5, error_score=nan,
                   estimator=RandomForestRegressor(bootstrap=True,
                                                   ccp_alpha=0.0,
                                                   criterion='mse',
                                                   max_depth=None,
                                                   max_features='auto',
                                                   max_leaf_nodes=None,
                                                   max_samples=None,
                                                   min_impurity_decrease=0.0,
                                                   min_impurity_split=None,
                                                   min_samples_leaf=1,
                                                   min_samples_split=2,
                                                   min_weight_fraction_leaf=0.0,
                                                   n_estimators=100,
                                                   n_jobs=None, oob_score=Fals...
                                                   warm_start=False),
                   iid='deprecated', n_iter=10, n_jobs=None,
                   param_distributions={'max_features': &amp;lt;scipy.stats._distn_infrastructure.rv_frozen object at 0x7f20324dfeb8&amp;gt;,
                                        'n_estimators': &amp;lt;scipy.stats._distn_infrastructure.rv_frozen object at 0x7f20324df668&amp;gt;},
                   pre_dispatch='2*n_jobs', random_state=42, refit=True,
                   return_train_score=False, scoring='neg_mean_squared_error',
                   verbose=0)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1594878966048&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cvres = rnd_search.cv_results_
for mean_score, params in zip(cvres[&quot;mean_test_score&quot;], cvres[&quot;params&quot;]):
    print(np.sqrt(-mean_score), params)
    
###결과값###
&amp;gt;&amp;gt;
49150.70756927707 {'max_features': 7, 'n_estimators': 180}
51389.889203389284 {'max_features': 5, 'n_estimators': 15}
50796.155224308866 {'max_features': 3, 'n_estimators': 72}
50835.13360315349 {'max_features': 5, 'n_estimators': 21}
49280.9449827171 {'max_features': 7, 'n_estimators': 122}
50774.90662363929 {'max_features': 3, 'n_estimators': 75}
50682.78888164288 {'max_features': 3, 'n_estimators': 88}
49608.99608105296 {'max_features': 5, 'n_estimators': 100}
50473.61930350219 {'max_features': 3, 'n_estimators': 150}
64429.84143294435 {'max_features': 5, 'n_estimators': 2}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2.7.3 앙상블 방법&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;모델 튜닝의 또 다른 방법은 최상의 모델을 연결해보는 것입니다. 다시 말해서 DecisionTree의 앙상블 모델인 RandomForest가 성능이 더 좋은 것처럼 &lt;b&gt;모델의 그룹이 최상의 단일 모델보다 더 나은 성능을 발휘할 때가 많습니다.&lt;/b&gt; 특히 개개의 모델이 각기 다른 형태의 오차를 만들 때 더욱 그렇습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2.7.4 최상의 모델과 오차 분석&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;&amp;nbsp;최상의 모델을 분석하면 문제에 대한 좋은 통찰을 얻는 경우가 많습니다.&lt;/b&gt; 예를 들어 RandomForestregressor가 정확한 예측을 만들기 위한 &lt;b&gt;각 feature의 상대적인 중요도&lt;/b&gt;를 알려줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594879012343&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;feature_importances = grid_search.best_estimator_.feature_importances_
feature_importances

###결과값###
&amp;gt;&amp;gt;
array([7.08371932e-02, 6.56756347e-02, 4.27773453e-02, 1.52918532e-02,
       1.38124536e-02, 1.50121082e-02, 1.44797217e-02, 3.56732982e-01,
       5.52871544e-02, 1.15384814e-01, 6.37338038e-02, 6.96180139e-03,
       1.58719639e-01, 6.57055394e-05, 2.13890180e-03, 3.08888805e-03])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;가독성을 위해 각 중요도에 대응하는 feature를 함께 출력해보겠습니다. 아래 정보를 바탕으로 덜 중요한 특성들은 제외할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 시스템이 특정 오차를 만들었다면 feature를 추가하거나, 제거하거나, 이상치(Anomaly data)를 지우는 등 문제를 해결하는 방법을 찾으려 해야합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594879084355&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;extra_attribs = [&quot;rooms_per_hhold&quot;, &quot;pop_per_hhold&quot;, &quot;bedrooms_per_room&quot;]
cat_encoder = full_pipeline.named_transformers_[&quot;cat&quot;]
cat_one_hot_attribs = list(cat_encoder.categories_[0])
attributes = num_attribs + extra_attribs + cat_one_hot_attribs
sorted(zip(feature_importances,attributes),reverse=True)

###결과값###
&amp;gt;&amp;gt;
[(0.35673298193099007, 'median_income'),
 (0.1587196393569354, 'INLAND'),
 (0.11538481389295871, 'pop_per_hhold'),
 (0.07083719317436987, 'longitude'),
 (0.06567563468470206, 'latitude'),
 (0.06373380379050103, 'bedrooms_per_room'),
 (0.05528715436665197, 'rooms_per_hhold'),
 (0.04277734534225705, 'housing_median_age'),
 (0.015291853205156254, 'total_rooms'),
 (0.015012108190849801, 'population'),
 (0.014479721702475657, 'households'),
 (0.013812453588641672, 'total_bedrooms'),
 (0.006961801391129748, '&amp;lt;1H OCEAN'),
 (0.0030888880452384668, 'NEAR OCEAN'),
 (0.002138901797746015, 'NEAR BAY'),
 (6.570553939631248e-05, 'ISLAND')]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.7.5 Test set로 시스템 평가하기&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;어느 정도 모델 튜닝을 통해 만족할 만한 모델을 얻었으니 이제는 &lt;b&gt;test set을 이용하여 최종 모델을 평가해보겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 test set에서 예측 변수와 label을 얻은 후 이전에 만들었던 full_pipeline을 사용해 데이터를 변환합니다. 이때 test set에서 training하면 안되기 때문에 fit_transform()이 아닌 transform()입니다. 그리고 &lt;b&gt;test set에서 최종 모델을 평가합니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594879772329&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;final_model = grid_search.best_estimator_

X_test = strat_test_set.drop(&quot;median_house_value&quot;,axis=1)
y_test = strat_test_set[&quot;median_house_value&quot;].copy()

X_test_prepared = full_pipeline.transform(X_test)

final_predictions = final_model.predict(X_test_prepared)

final_mse = mean_squared_error(y_test, final_predictions)
final_rmse = np.sqrt(final_mse)

###결과값###
&amp;gt;&amp;gt;
47730.0&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&amp;nbsp;이렇게 우리는 3번의 포스팅에 걸쳐 하나의 머신러닝 프로젝트 안에서 데이터를 가져와 특징을 파악하고, 전처리하여 모델 훈련 후 튜닝까지 하는 법을 대략적으로 살펴보았습니다.&lt;/p&gt;
&lt;p&gt;긴 글 읽어주셔서 감사합니다. 오늘도 행복한 하루 보내시길 바랍니다:)&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>Keras</category>
      <category>Machine Learning</category>
      <category>pandas</category>
      <category>pytorch</category>
      <category>regression</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/44</guid>
      <comments>https://box-world.tistory.com/44#entry44comment</comments>
      <pubDate>Thu, 16 Jul 2020 14:35:09 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (2)</title>
      <link>https://box-world.tistory.com/43</link>
      <description>&lt;p&gt;&amp;nbsp;저번 포스팅에서는 캘리포니아 주택 가격 데이터셋을 가지고 pandas, sklearn을 이용하여 데이터의 특성을 탐색하고, 모델 학습을 위해 test set을 분리하는 다양한 방법에 대해 알아보았습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이번 포스팅에서는 &lt;b&gt;데이터를 탐색하고 시각화하는 것부터 데이터를 전처리 하는 과정&lt;/b&gt;까지 다뤄보도록 하겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/42&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;box-world.tistory.com/42&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1595126920887&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (1)&quot; data-og-description=&quot;발견에는 항상 뜻밖의 재미가 있다 - 제프 베조스(Amazon CEO) - Chapter 2 이번 포스팅을 시작으로 3번에 걸쳐 하나의 머신러닝 프로젝트가 어떻게 구성되고 진행되는지 알아보겠습니다. 우선 주요 단&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/42&quot; data-og-url=&quot;https://box-world.tistory.com/42&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dBWYlE/hyGNSAupRK/x0kcIQSXcm3Em53ifbY4WK/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/b0A5Iy/hyGPehAh0q/124dvTUb46mQ3yC9tXpUmk/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/r41sI/hyGNFA844J/B0PFKlmuXB37zfcrcNAKq0/img.png?width=1018&amp;amp;height=540&amp;amp;face=0_0_1018_540&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/42&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/42&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dBWYlE/hyGNSAupRK/x0kcIQSXcm3Em53ifbY4WK/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/b0A5Iy/hyGPehAh0q/124dvTUb46mQ3yC9tXpUmk/img.png?width=800&amp;amp;height=187&amp;amp;face=0_0_800_187,https://scrap.kakaocdn.net/dn/r41sI/hyGNFA844J/B0PFKlmuXB37zfcrcNAKq0/img.png?width=1018&amp;amp;height=540&amp;amp;face=0_0_1018_540');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (1)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;발견에는 항상 뜻밖의 재미가 있다 - 제프 베조스(Amazon CEO) - Chapter 2 이번 포스팅을 시작으로 3번에 걸쳐 하나의 머신러닝 프로젝트가 어떻게 구성되고 진행되는지 알아보겠습니다. 우선 주요 단&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.4 데이터 이해를 위한 탐색과 시각화&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;우선 데이터셋에서&lt;b&gt; training set&lt;/b&gt;만 떼서 &lt;b&gt;탐색&lt;/b&gt;을 진행하겠습니다. 보통 데이터가 크다면 training set 중에서도 일부를 떼어 탐색용 subset을 만들기도 하지만 우리는 전체 training set을 사용하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594793170414&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing = strat_train_set.copy()&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;&amp;nbsp;2.4.1&amp;nbsp; 지리적 데이터 시각화&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;데이터셋에 &lt;b&gt;위도(longitude)와 경도(latitude)&lt;/b&gt;에 해당하는 지리정보가 있으므로 이를 &lt;b&gt;산점도(Scatter)&lt;/b&gt;를 이용하여 시각화하겠습니다. 산점도란 두개 변수간의 관계를 직교 좌표계 위에 나타낸 그래프를 의미합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;383&quot; data-filename=&quot;blob&quot; width=&quot;829&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clwHWa/btqFEkzfla6/43ynkhJCfaGQXlMi6iZQwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clwHWa/btqFEkzfla6/43ynkhJCfaGQXlMi6iZQwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clwHWa/btqFEkzfla6/43ynkhJCfaGQXlMi6iZQwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclwHWa%2FbtqFEkzfla6%2F43ynkhJCfaGQXlMi6iZQwK%2Fimg.png&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;383&quot; data-filename=&quot;blob&quot; width=&quot;829&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;위 그림 자체로는 특별한 패턴을 찾기 어려울 것입니다. 여기에 &lt;b&gt;alpha 옵션&lt;/b&gt;을 주면 &lt;b&gt;군집도&lt;/b&gt;를 통해 패턴을 찾아낼 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;386&quot; data-filename=&quot;blob&quot; width=&quot;833&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/URsMa/btqFHbBkrRo/Ckr0cFsyGwkJrgIzWJohr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/URsMa/btqFHbBkrRo/Ckr0cFsyGwkJrgIzWJohr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/URsMa/btqFHbBkrRo/Ckr0cFsyGwkJrgIzWJohr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FURsMa%2FbtqFHbBkrRo%2FCkr0cFsyGwkJrgIzWJohr1%2Fimg.png&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;386&quot; data-filename=&quot;blob&quot; width=&quot;833&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp; 이제 여기에 주택 가격을 나타내보겠습니다. 원의 반지름은 구역의 인구, 그리고 파란색에서 빨간색으로 갈수록 높은 가격을 가지는데 이를 함수에서 cmpa = get_cmap(&quot;jet&quot;)로 표현합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그래프를 보면 &lt;b&gt;인구 밀도와 주택 가격이 밀접하게 관련되어 있다는 것을 알 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;639&quot; data-filename=&quot;blob&quot; width=&quot;827&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XPSXK/btqFD6BeHT4/hSWOUd2VVutcCEBQ873uRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XPSXK/btqFD6BeHT4/hSWOUd2VVutcCEBQ873uRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XPSXK/btqFD6BeHT4/hSWOUd2VVutcCEBQ873uRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXPSXK%2FbtqFD6BeHT4%2FhSWOUd2VVutcCEBQ873uRK%2Fimg.png&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;639&quot; data-filename=&quot;blob&quot; width=&quot;827&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;&amp;nbsp;2.4.2 상관관계 조사&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;데이터셋이 너무 크지 않기 때문에 feature 간의 &lt;b&gt;표준 상관계수(Standard correlation coefficient)&lt;/b&gt;를 &lt;b&gt;corr()&lt;/b&gt; 함수를 이용해 쉽게 계산할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594793878252&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;corr_matrix = housing.corr()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이제 &lt;b&gt;중간 주택 가격(median_house_value)와 다른 특성 간의 상관관계의 크기&lt;/b&gt;에 대해 알아보겠습니다. 상관관계의 범위는 (-1,1) 사이이며 1에 가까울수록 강한 양의 상관관계를 의미합니다. 그리고 0에 가까울수록 선형적인 상관관계가 없다고 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;- 중간 주택 관계와 위도는 약한 음의 상관관계를 보입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;257&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l1SH6/btqFINM09M4/AUiji3oeno3EwFzQ8NWDR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l1SH6/btqFINM09M4/AUiji3oeno3EwFzQ8NWDR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l1SH6/btqFINM09M4/AUiji3oeno3EwFzQ8NWDR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl1SH6%2FbtqFINM09M4%2FAUiji3oeno3EwFzQ8NWDR0%2Fimg.png&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;257&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음은 &lt;b&gt;두 변수간에 가질 수 있는 다양한 상관관계의 형태&lt;/b&gt;를 보여줍니다. 주의할 것은 &lt;b&gt;우리가 위에서 확인한 상관계수는 선형적인 상관관계만 측정합니다.&lt;/b&gt; 즉 아래 세번째 줄과 같은 비선형적인 상관관계는 잡지 못하고 0에 가까운 값으로 도출되게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxA9H9/btqFEl5ZJA7/9ZLKqqkB2dwIOqi0F0PNLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxA9H9/btqFEl5ZJA7/9ZLKqqkB2dwIOqi0F0PNLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxA9H9/btqFEl5ZJA7/9ZLKqqkB2dwIOqi0F0PNLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxA9H9%2FbtqFEl5ZJA7%2F9ZLKqqkB2dwIOqi0F0PNLK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp; feature간 상관관계를 확인하는 또 다른 방법은 &lt;b&gt;pandas의 scatter_matrix&lt;/b&gt;를 이용하여 숫자형 특성 사이에 산점도를 그리는 것입니다. 아래서 그 일부를 보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;왼쪽 위에서 오른쪽 아래로가는 대각선은 자기 자신에 대한 상관관계이므로 직선이 되는 것이기에 무시하셔도 됩니다. 아래에서 우리가 주목할 것은 첫번째 줄의 두번째 그래프인 &lt;b&gt;중간 소득(median_income)과 중간 주택 가격의 관계&lt;/b&gt;이니 이를 확대에서 다시 살펴보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594794368885&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from pandas.plotting import scatter_matrix

attributes = [&quot;median_house_value&quot;, &quot;median_income&quot;, &quot;total_rooms&quot;,
              &quot;housing_median_age&quot;]
              
scatter_matrix(housing[attributes], figsize=(12,8))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boxXFz/btqFHqdWFvh/RgItJlbzKrDDeEAE5kQHw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boxXFz/btqFHqdWFvh/RgItJlbzKrDDeEAE5kQHw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boxXFz/btqFHqdWFvh/RgItJlbzKrDDeEAE5kQHw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboxXFz%2FbtqFHqdWFvh%2FRgItJlbzKrDDeEAE5kQHw1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;- 중간 소득이 커질수록 중간 주택 가격이 상승하는 강한 상관관계를 보여주며, 포인트들이 너무 멀리 퍼져있지 않습니다.&lt;/p&gt;
&lt;p&gt;- 중간 주택 가격이 500000인 부분에서 수평선이 나타나는 이유는 가격 제한을 500000 이하로 두었기 때문입니다. 이 외에 350000, 280000에서 보이는 수평선은 면밀히 살펴보고 이상한 형태의 학습이 있었다면 이를 지워야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/enKX3e/btqFD5vwdLp/cgfTxrDmsKSyk913VWxG9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/enKX3e/btqFD5vwdLp/cgfTxrDmsKSyk913VWxG9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/enKX3e/btqFD5vwdLp/cgfTxrDmsKSyk913VWxG9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FenKX3e%2FbtqFD5vwdLp%2FcgfTxrDmsKSyk913VWxG9k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;2.4.3 feature 조합으로 실험&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;모델 학습을 위해 데이터를 준비하는 과정에서 마지막으로 해볼 수 잇는 것은 &lt;b&gt;여러 feature 조합을 시도해보는 것입니다.&lt;/b&gt; 이 부분에 대해서는 단순히 코딩이 아니라 feature간의 의미를 생각하며 어떤 features를 결합해야 유의미한 결과를 얻을 수 있을지 생각해야 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 특정 구역의 방 개수 자체는 해당 지역의 가구 수를 모른다면 의미가 없을 것입니다. 이렇나 맥락에서 가구당 방 개수를 도출해볼 수 있습니다. 다음에서 이런 특성들을 만들어 &lt;b&gt;corr_matrix&lt;/b&gt;를 확인해보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;- &lt;b&gt;새롭게 추가한 bedrooms_per_room&lt;/b&gt;은 total_bedrooms나 total_rooms보다 중간 주택 가격과의 상관관계가 훨씬 높습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594795213602&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing[&quot;rooms_per_household&quot;] = housing[&quot;total_rooms&quot;]/housing[&quot;households&quot;]
housing[&quot;bedrooms_per_room&quot;] = housing[&quot;total_bedrooms&quot;]/housing[&quot;total_rooms&quot;]
housing[&quot;population_per_household&quot;]=housing[&quot;population&quot;]/housing[&quot;households&quot;]

corr_matrix = housing.corr()
corr_matrix[&quot;median_house_value&quot;].sort_values(ascending=False)


###결과값###
&amp;gt;&amp;gt;
median_house_value 1.000000
median_income 0.687160
rooms_per_household 0.146285
total_rooms 0.135097
housing_median_age 0.114110
households 0.064506
total_bedrooms 0.047689
population_per_household -0.021985
population -0.026920
longitude -0.047432
latitude -0.142724
bedrooms_per_room -0.259984
Name: median_house_value, dtype: float64&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;지금까지 데이터를 탐색하는 몇 단계를 거쳐보았습니다. 하지만 머신러닝에서는 한번에 끝나는 일은 잘 없습니다. 최대한 빨리 이러한 프로토타입을 만들어 데이터에 대한 통찰을 얻고, 다시 이러한 과정을 반복하며 유의미한 결과를 계속해서 뽑아내는 과정을 거쳐야 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.5 머신러닝 알고리즘을 위한 데이터 준비&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이제 머신러닝 알고리즘을 위해 데이터를 만들어 보겠습니다. 중요한 것은 이러한 작업은 자동화되어야 하는데 다음은 그 이유입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;- 어떤 데이터셋이 주어져도 쉽게 데이터를 변환할 수 있습니다.&lt;/p&gt;
&lt;p&gt;- 프로젝트에서 앞으로 사용할 다양한 변환 라이브러리로 활용될 수 있습니다.&lt;/p&gt;
&lt;p&gt;- 여러 가지 데이터 변환을 쉽게 하며 어떤 조합이 가장 좋은지 확인하는데 편리합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 앞서서 생성한 strat_train_set에서 데이터 변형이 label에도 적용되는 것을 방지하기 위해 l&lt;b&gt;abel인 median_house_value를 training set에서 분리하겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594795851096&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing = strat_train_set.drop(&quot;median_house_value&quot;,axis=1)
housing_labels = strat_train_set[&quot;median_house_value&quot;].copy()&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2.5.1 데이터 정제&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;b&gt;데이터 정제&lt;/b&gt;란 전처리가 완료된 데이터에 대해 빈값(결측치)이나 정상 범위를 벗어난 값(이상치)들을 제거하거나 다른 값으로 대체하는 처리 과정을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;우선 앞서서 total_bedrooms에 누락된 값이 있었습니다. 누락된 값은 다음 세 가지 방식으로 처리할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;span&gt;- 해당 구역을 제거하기&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;- 전체 feature 삭제&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;- 특정 값을 채우기(0, median, mean etc...)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;이러한 작업은 &lt;b&gt;pandas의 2차원 테이블 구조인 DataFrame&lt;/b&gt;의 다양한 메서드를 이용하여 간단하게 처리가 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1594796297916&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing.dropna(subset=[&quot;total_bedrooms&quot;]) # 누락된 데이터가 들어있는 구역은 제거
housing.drop(&quot;total_bedrooms&quot;,axis=1) # feature 삭제

median = housing[&quot;total_bedrooms&quot;].median() # median으로 채우기
housing[&quot;total_bedrooms&quot;].fillna(median,inplace = True)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;혹은 &lt;b&gt;sklearn의 SimpleImputer&lt;/b&gt;로 누락된 값을 다룰 수 있습니다.&lt;b&gt; strategy = &quot;median&quot;&lt;/b&gt;으로 누락된 값을 중간값으로 대체할 것을 지정합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594796472018&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy=&quot;median&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;SimpleImputer를 적용하기 앞서 &lt;b&gt;수치형(categorical) 특성인 ocean_proximity를 제외한 복사본&lt;/b&gt;에 적용하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594796535480&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing_num = housing.drop(&quot;ocean_proximity&quot;,axis=1)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; 이제 imputer에 데이터셋을 인자로 주면 각 feature의 median을 &lt;b&gt;statistics_ 속성&lt;/b&gt;에 저장합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594796584906&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;imputer.fit(housing_num)

imputer.statistics_

###결과값###
&amp;gt;&amp;gt; array([ -118.51 , 34.26 , 29. , 2119.5 , 433. , 1164. , 408. , 3.5409])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; 마지막으로 &lt;b&gt;transform()&lt;/b&gt; 메서드로 데이터셋에 적용해주면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594796814021&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;X = imputer.transform(housing_num)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; X는 &lt;b&gt;numpy 배열&lt;/b&gt;입니다. 이를 다시 &lt;b&gt;pandas DataFrame&lt;/b&gt;으로 되돌릴 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594797060764&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing_tr = pd.DataFrame(X, columns=housing_num.columns,
                          index = housing_num.index)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p&gt;&amp;nbsp; 좀 더 공부하기에 앞서 &lt;b&gt;sklearn의 'estimator'와 'trasformer'&lt;/b&gt; 개념에 대해서 간단히 짚고 가겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;estimator&lt;/b&gt;는 input data에서 새롭게 추정된 데이터로 &lt;b&gt;fit()&lt;/b&gt; 메서드가 사용됩니다. &lt;b&gt;transformer&lt;/b&gt;는 input data를 변형하며 &lt;b&gt;transform()&lt;/b&gt; 메서드가 사용됩니다. 예를 들어 앞서 사용한 imputer 객체는 estimator, imputer 자체는 transformer라고 할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.5.2 텍스트와 범주형 특성 다루기&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;이제 수치형 feature가 아닌 &lt;b&gt;유일한 categorical feature인 ocean_proximity&lt;/b&gt;에 대해 다뤄보겠습니다. 우선 처음 10개 데이터에서 이 feature 값을 확인해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594797695674&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing_cat = housing[[&quot;ocean_proximity&quot;]]

housing_cat.head(10)

###결과값###
&amp;gt;&amp;gt;
17606 &amp;lt;1H OCEAN
18632 &amp;lt;1H OCEAN
14650 NEAR OCEAN
3230 INLAND
3555 &amp;lt;1H OCEAN
19480 INLAND
8879 &amp;lt;1H OCEAN
13685 INLAND
4937 &amp;lt;1H OCEAN
4861 &amp;lt;1H OCEAN&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;대부분의 머신러닝 알고리즘은 숫자를 다루기 때문에 이러한 categorical feature는 텍스트에서 숫자로 바꿔줄 필요가 있습니다. 이를 위해 &lt;b&gt;sklearn의 OridinalEncoder 클래스&lt;/b&gt;를 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594797821941&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.preprocessing import OrdinalEncoder

ordinal_encoder = OrdinalEncoder()
housing_cat_encoded = ordinal_encoder.fit_transform(housing_cat)
housing_cat_encoded[:10]

###결과값###
&amp;gt;&amp;gt;
array([[0.],
       [0.],
       [4.],
       [1.],
       [0.],
       [1.],
       [0.],
       [1.],
       [0.],
       [0.]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그리고 이렇게 변환된 array에서 &lt;b&gt;categories_ 인스턴스 변수&lt;/b&gt;를 이용하면 카테고리 목록 확인이 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594798099626&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ordinal_encoder.categories_

###결과값###
&amp;gt;&amp;gt;
[array(['&amp;lt;1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'],
       dtype=object)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;위 표현 방식의 문제점은 &lt;b&gt;알고리즘이 가까이 있는 두값이 떨어져있는 두 값보다 더 비슷하다고 생각한다는 점입니다&lt;/b&gt;(['bad', 'average', 'good', 'excellent']와 같은 경우).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그래서 대부분의 categorical feature에 대해 숫자로 변환할 때는 &lt;b&gt;one-hot encoding 방식&lt;/b&gt;을 사용합니다. 예를 들어 카테고리가 &amp;lt;1H OCEAN&amp;gt;이라면 이는 1을 가지고 나머지 feature는 모두 0을 가지는 벡터가 해당 데이터가 어느 카테고리에 속하는지 표현하는 방식이 되는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이때 출력은 numpy array가 아니라 &lt;b&gt;sparse matrix&lt;/b&gt;라는데 주목해야합니다. 즉 앞서 말했던 하나만 1이고 나머지는 0으로 채워져있는 벡터의 형태를 의미하는 것이빈다. 그러나 0을 모두 메모리에 저장하는 것은 비효율적이므로 sparse index는 0이 아닌 원소의 위치만을 저장합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594798421998&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.preprocessing import OneHotEncoder
cat_encoder = OneHotEncoder()
housing_cat_1hot = cat_encoder.fit_transform(housing_cat)
housing_cat_1hot

###결과값###
&amp;gt;&amp;gt;
&amp;lt;16512x5 sparse matrix of type '&amp;lt;class 'numpy.float64'&amp;gt;'
	with 16512 stored elements in Compressed Sparse Row format&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이를 &lt;b&gt;numpy 배열&lt;/b&gt;로 바꾸고 싶다면 다음과 같이 할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594798539570&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;housing_cat_1hot.toarray()

###결과값###
&amp;gt;&amp;gt;
array([[1., 0., 0., 0., 0.],
       [1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1.],
       ...,
       [0., 1., 0., 0., 0.],
       [1., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0.]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이렇게 변환한 numpy 배열에서도 &lt;b&gt;categories_ 인스턴스 변수&lt;/b&gt;가 적용됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594798631270&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat_encoder.categories_

###결과값###
&amp;gt;&amp;gt;
[array(['&amp;lt;1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'],
       dtype=object)]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.5.3 나만의 변환기&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;sklearn이 유용한 transformer를 제공하지만, 상황에 따라 특정 작업을 위해 &lt;b&gt;우리가 직접 transformer를 만들어야 할수도 있습니다.&lt;/b&gt; 이를 위해 내가 만든 transformer가 sklearn과 매끄럽게 연동되길 원한다면 fit(), transform(), fit_transform() 메서드가 구현된 클래스를 만들면 됩니다. 다음은 간단한 변환기입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;아래는 transformer가 add_bedrooms_per_room 하이퍼파라미터를 하나 가지며 기본값은 True입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594798801256&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.base import BaseEstimator, TransformerMixin

rooms_ix, bedrooms_ix, population_ix, households_ix = 3,4,5,6

class CombineAttirbutesAdder(BaseEstimator, TransformerMixin):
  def __init__(self, add_bedrooms_per_room = True):
    self.add_bedrooms_per_room = add_bedrooms_per_room
  def fit(self, X, y=None):
    return self
  def transform(self, X):
    rooms_per_household = X[:, rooms_ix] / X[:, households_ix]
    population_per_household = X[:, population_ix] / X[:, households_ix]
    if self.add_bedrooms_per_room:
      bedrooms_per_room = X[:,bedrooms_ix] / X[:, rooms_ix]
      return np.c_[X, rooms_per_household, population_per_household,
                   bedrooms_per_room]

    else:
      return np.c_[X, rooms_per_household, population_per_household]

attr_adder = CombineAttirbutesAdder(add_bedrooms_per_room=False)
housing_extra_attribs = attr_adder.transform(housing.values)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.5.4 특성 스케일링&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;가장 중요한 데이터 처리 과정 중 하나가 &lt;b&gt;feature scaling&lt;/b&gt;입니다. 왜냐면 머신러닝 알고리즘은 feature들의 input data의 범위(scale)이 다르면 잘 작동하지 않기 때문입니다. 우리의 데이터셋의 경우 전체 방 개수의 범위는 6~39320인 것에 비해 median_income은 0~15입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;scaling에는 보통 &lt;b&gt;min-max scaling(normalization)&lt;/b&gt;과 &lt;b&gt;표준화(standardization)&lt;/b&gt;이 사용됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;min-max scaling&lt;/b&gt;은 데이터가 0~1 범위에 들도록 스케일을 조정해줍니다. sklearn에서는 '&lt;b&gt;MinMaxScaler' transformer&lt;/b&gt;를 제공합니다. 다른 범위를 사용하고 싶다면 &lt;b&gt;feature_range 매개변수&lt;/b&gt;로 조정하면 되겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;표준화&lt;/b&gt;는 분산이 1이 되도록 합니다. 이는 min-max scaling에서의 0~1과 같은 범위은 상한, 하한이 없어 특정 알고리즘에서는 문제가 될 수 있습니다. 그러나 &lt;b&gt;표준화는 '이상치'에 영향을 덜 받습니다.&lt;/b&gt; sklearn에서는 '&lt;b&gt;StndardScaler' transformer&lt;/b&gt;를 표준화를 위해 제공합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.5.5. Transform 파이프라인&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;transform 단계가 여러개라면 그 순서는 더욱 중요할 수 밖에 없습니다. sklearn에서는 이러한 연속된 변환이 순서대로 안정적으로 이뤄지도록 &lt;b&gt;Pipeline 클래스&lt;/b&gt;를 통해 지원해줍니다. 다음은 &lt;b&gt;숫자형 feature를 처리하는 파이프라인&lt;/b&gt;입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1594802260793&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

num_pipeline = Pipeline([('imputer',SimpleImputer(strategy=&quot;median&quot;)),
                         ('attribs_adder', CombineAttirbutesAdder()),
                         ('std_scaler', StandardScaler()),
                         ])

housing_num_tr = num_pipeline.fit_transform(housing_num)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; Pipeline은 연속된 단계를 나타내는 &lt;b&gt;(이름 / estimator) 쌍의 목록&lt;/b&gt;을 입력으로 받습니다. 이때 &lt;b&gt;마지막 단계를 제외하고는 나머지 단계에서는 transformer만 사용이 가능합니다.&lt;/b&gt; 즉 fit_transform() 메서드를 가지고 있어야 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;파이프라인의 fit() 메서도를 호출하면 내부의 모든 transformer의 fit_transform() 메서드를 순서대로 호출하면서 한 단계의 출력을 다음 단계의 입력으로 전달합니다. 마지막 단계에서는 fit() 메서드만 호출합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;파이프라인 객체는 마지막 estimator와 동일한 메서드를 제공합니다.&lt;/b&gt; 위 예에서는 StandardScaler가 마지막 단계이므로 파이프라인은 transform() 메서드를 가지고 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;지금까지는 categorical feature와 수치형 feature를 따로 다뤘습니다. 그러나 &lt;b&gt;하나의 transformer로 categorical과 수치형을 동시에 처리할 수 있다면 훨씬 편할 것입니다.&lt;/b&gt; sklearn에서는 &lt;b&gt;ColumnTransformer&lt;/b&gt;를 통해 이를 지원합니다. 이는 pandas DataFrame과 잘 동작합니다.&lt;/p&gt;
&lt;p&gt;- 우선 수치형 열, 범주형 열 리스트를 각각 만들어줍니다.&lt;/p&gt;
&lt;p&gt;- 그 다음 ColumnTransformer의 생성자에서는 (이름, transformer, transformer에 적용될 리스트)를 각 튜플마다 받습니다.&lt;/p&gt;
&lt;p&gt;- 이때 OneHotEncoder는 대부분이 0으로 구성된 Sparse Matrix를, num_pipeline은 대부분이 0이 아닌 값으로 구성된 Dense Matrix를 반환합니다. 이렇게 &lt;b&gt;두가지가 섞여있을 때 ColumnTransformer는 최종 Matrix에서 0이 아닌 값에 대한 비율을 분석하여 30% 이하이면 Sparse를 그렇지 않으면 Dense를 반환합니다.&lt;/b&gt; (기본적으로 sparse_threshold = 0.3)&lt;/p&gt;
&lt;pre id=&quot;code_1594802767664&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sklearn.compose import ColumnTransformer

num_attribs = list(housing_num)
cat_attribs = [&quot;ocean_proximity&quot;]

full_pipeline = ColumnTransformer([(&quot;num&quot;, num_pipeline, num_attribs),
                                   (&quot;cat&quot;,OneHotEncoder(), cat_attribs),
                                   ])

housing_prepared = full_pipeline.fit_transform(housing)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이러헥 해서 우리는 전체 주택 데이터를 받아 적절한 변환을 적용하는 파이프라인을 만들었습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;다음 포스팅에서는 전처리한 데이터를 이용해 모델을 선택하고 훈련하여 튜닝하는 단계에 대해 다뤄보겠습니다. 오늘도 행복한 하루 보내시길 바랍니다 :)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/44&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;box-world.tistory.com/44&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1595126944688&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 모델 학습과 튜닝은 어떻게 하는 것일까? (3)&quot; data-og-description=&quot;&amp;nbsp;이전 2개의 포스팅에 결쳐 우리는 지금까지 문제를 정의하고 데이터를 읽어들여 탐색하였습니다. 그리고 데이터를 training set과 test set으로 나누고 학습을 위한 머신러닝 알고리즘에 주입할 데�&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/44&quot; data-og-url=&quot;https://box-world.tistory.com/44&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/trbGk/hyGNGtiewM/IMXGMbviDVJFqFxkGLfuMk/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/WEi0n/hyGO9N7ABg/IA02KtKocUsWSPWEXIlj71/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/b0uU5z/hyGO3NUG7k/F37UD5c7YKZg8YiryusqzK/img.png?width=264&amp;amp;height=200&amp;amp;face=0_0_264_200&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/44&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/44&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/trbGk/hyGNGtiewM/IMXGMbviDVJFqFxkGLfuMk/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/WEi0n/hyGO9N7ABg/IA02KtKocUsWSPWEXIlj71/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/b0uU5z/hyGO3NUG7k/F37UD5c7YKZg8YiryusqzK/img.png?width=264&amp;amp;height=200&amp;amp;face=0_0_264_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 모델 학습과 튜닝은 어떻게 하는 것일까? (3)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;이전 2개의 포스팅에 결쳐 우리는 지금까지 문제를 정의하고 데이터를 읽어들여 탐색하였습니다. 그리고 데이터를 training set과 test set으로 나누고 학습을 위한 머신러닝 알고리즘에 주입할 데�&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>AI</category>
      <category>Machine Learning</category>
      <category>pandas</category>
      <category>PYTHON</category>
      <category>sklearn</category>
      <category>TensorFlow</category>
      <category>데이터 사이언스</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/43</guid>
      <comments>https://box-world.tistory.com/43#entry43comment</comments>
      <pubDate>Wed, 15 Jul 2020 16:37:17 +0900</pubDate>
    </item>
    <item>
      <title>[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (1)</title>
      <link>https://box-world.tistory.com/42</link>
      <description>&lt;p&gt;&lt;b&gt;발견에는 항상 뜻밖의 재미가 있다&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;- 제프 베조스(Amazon CEO) -&lt;/b&gt;&lt;/p&gt;
&lt;h2&gt;Chapter 2&lt;/h2&gt;
&lt;p&gt;이번 포스팅을 시작으로 3번에 걸쳐 하나의 머신러닝 프로젝트가 어떻게 구성되고 진행되는지 알아보겠습니다. 우선 주요 단계는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;1) 큰 그림 보기&lt;/p&gt;
&lt;p&gt;2) 데이터 구하기&lt;/p&gt;
&lt;p&gt;3) 데이터 탐색 및 시각화&lt;/p&gt;
&lt;p&gt;4) 모델 학습을 위한 데이터 전처리&lt;/p&gt;
&lt;p&gt;5) 모델 선택 및 훈련&lt;/p&gt;
&lt;p&gt;6) 모델 튜닝&lt;/p&gt;
&lt;p&gt;7) 솔루션 제시&lt;/p&gt;
&lt;p&gt;8) 시스템 론칭, 모니터링 및 유지 보수&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2.1 실제 데이터로 작업하기&lt;/h2&gt;
&lt;p&gt;머신러닝을 적용하기 위해서 가장 먼저 필요한 것은 바로 데이터가 될텐데요. 특히 우리가 공부할 때는 인공적인 데이터셋이 아닌 실제 데이터셋을 직접 다뤄보는 것이 더욱 효과적입니다. 다음은 유명한 대표적인 데이터 저장소들입니다.&lt;/p&gt;
&lt;p&gt;- UC 얼바인 머신러닝 저장소(&lt;a href=&quot;https://archive.ics.uci.edu/ml/datasets.htm&quot;&gt;https://archive.ics.uci.edu/ml/datasets.htm&lt;/a&gt;l)&lt;/p&gt;
&lt;p&gt;- 캐글 (&lt;a href=&quot;https://www.kaggle.com/&quot;&gt;https://www.kaggle.com/&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;- 아마존 AWS 데이터셋 (&lt;a href=&quot;https://registry.opendata.aws/&quot;&gt;https://registry.opendata.aws/&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;설명을 위해 우리가 사용할 데이터셋은 &lt;b&gt;StarLib 저장소에 있는 캘리포니아 주택 가격&lt;/b&gt;입니다. 이제 데이터셋이 어떻게 구성되어 있는지 살펴보겠습니다.&lt;/p&gt;
&lt;h3&gt;2.2 큰 그림 보기&lt;/h3&gt;
&lt;p&gt;데이터는 인구(population), 중간 소득(median income), 중간 주택 가격(median housing price) 등으로 구성되어 있습니다. 우리는 이제부터 &lt;b&gt;주어진 데이터를 모델에 학습시킨 후 새로운 데이터가 주어졌을 때 해당 구역의 중간 주택 가격을 예측하게끔 해야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;h3&gt;2.2.1 문제 정의&lt;/h3&gt;
&lt;p&gt;머신러닝 모델은 'Tool' 말 그대로 도구입니다. 다시 말해서 머신러닝 자체가 목적이 아니기 때문에 머신러닝이 사용되는 &lt;b&gt;1)비즈니스의 목적이 무엇인지&lt;/b&gt;를 가장 먼저 파악하고 이에 따라 모델의 방향성을 결정해야 하는게 중요하겠습니다.&lt;/p&gt;
&lt;p&gt;우리가 만들 '중간 주택 가격 예측 모델'은 부동산 투자를 위하여 구역의 가격을 예측하여 이것이 다른 데이터들과 결합하여 투자를 결정하는데 사용됩니다. 수익과 바로 직결되기 때문에 올바른 예측은 더욱 중요할 수 밖에 없습니다.&lt;/p&gt;
&lt;p&gt;두번째로 파악해야할 것은 이러한 주택 가격을 예측하기 위해 &lt;b&gt;2)기존에는 어떤 솔루션을 사용했냐&lt;/b&gt;는 것입니다. 예를 들어 그 동안은 구역의 주택 가격을 전문가가 수동으로 측정했다면, 정보를 모으고 복잡한 규칙을 사용하여 추정을 하기까지 비용과 시간도 많이 들고 결과가 안좋았다면, 이러한 이유로 회사는 구역의 데이터를 기반으로 모델을 훈련시켜 예측하게 하는 것이 훨씬 합리적일 것입니다.&lt;/p&gt;
&lt;p&gt;그리고 최종적으로 &lt;b&gt;문제 정의&lt;/b&gt;를 하게 됩니다. 문제 정의에는 해결해야하는 문제 그리고 데이터에 기반하여 지도, 비지도, 강화 학습 중 무엇인지, 분류인지 회귀인지 혹은 배치 학습인지 온라인 학습인지 등을 결정해야 합니다. 우리가 해결할 문제는 다음과 같이 정의할 수 있습니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;- 캘리포니아 데이터셋은 Labeled Training set이므로 &lt;b&gt;지도 학습(Supervised Learning)&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;- 가격 즉 값을 예측하는 것이므로 &lt;b&gt;회귀(Regression)&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;- 예측을 위해 사용할 feature에는 인구, 중간 소득 등 여러 개 이므로 &lt;b&gt;다중 회귀(Multiple Regression)&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;- 구역 별로 하나의 값을 예측하므로 &lt;b&gt;단변량 회귀(Univariate Regression)&lt;/b&gt;입니다. 논외로 하나의 구역마다 여러 값을 예측해야 한다면 &lt;b&gt;다변량 회귀(Multivariate Regression)&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;- (데이터가 매우 크다면 &lt;b&gt;맵리듀스(MapReduce)&lt;/b&gt;를 이용하여 배치 학습을 여러 서버로 분할하거나 온라인 학습을 할 수 있습니다.)&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;2.2.2 성능 측정 지표 선택&lt;/h3&gt;
&lt;p&gt;다음 단계는 &lt;b&gt;성능 측정 지표&lt;/b&gt;를 선택하는 것인데, 대표적으로는 &lt;b&gt;평균 제곱근 오차(RMSE)&lt;/b&gt;가 있습니다. 이는 오차가 커질수록 값이 커지기 때문에 예측에 얼마나 많은 오류가 있는지 파악할 수 있습니다.&lt;/p&gt;
&lt;p&gt;$$RMSE(X,h) = \sqrt{\frac{1}{n}\Sigma_{i=1}^{n}{({h(x^i) -y^i})^2}}$$&lt;/p&gt;
&lt;p&gt;책의 내용과 별도로 제가 알아본 바로는 RMSE는 루트라는 무거운 연산에 비해 크게 메리트가 없어 다음과 같은 &lt;b&gt;MSE&lt;/b&gt;를 좀 더 보편적으로 쓴다고 합니다.&lt;/p&gt;
&lt;p&gt;$$MSE(X,h) = \frac{1}{n}\Sigma_{i=1}^{n}{({h(x^i) -y^i})^2}$$&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;2.3 데이터 가져오기&lt;/h2&gt;
&lt;p&gt;이제 본격적으로 실제 데이터를 가져와 직접 데이터를 다뤄보도록 하겠습니다. 저는 &lt;b&gt;Google의 Colab 환경&lt;/b&gt;에서 코드 작성을 진행하였습니다.&lt;/p&gt;
&lt;p&gt;2.3.1 데이터 다운로드&lt;/p&gt;
&lt;p&gt;다음 코드에서는 다운로드 링크를 통해 csv 파일 형식으로 데이터셋을 받아온 후 별도의 디렉토리에 넣어줍니다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import os
import tarfile
from six.moves import urllib

DOWNLOAD_ROOT = &quot;https://raw.githubusercontent.com/ageron/handson-ml2/master/&quot;
HOUSING_PATH = os.path.join(&quot;datasets&quot;, &quot;housing&quot;)
HOUSING_URL = DOWNLOAD_ROOT + &quot;datasets/housing/housing.tgz&quot;

def fetch_housing_data(housing_url=HOUSING_URL, housing_path=HOUSING_PATH):
    if not os.path.isdir(housing_path):
        os.makedirs(housing_path)
    tgz_path = os.path.join(housing_path, &quot;housing.tgz&quot;)
    urllib.request.urlretrieve(housing_url, tgz_path)
    housing_tgz = tarfile.open(tgz_path)
    housing_tgz.extractall(path=housing_path)
    housing_tgz.close()

fetch_housing_data()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그리고 pandas 라이브러리를 이용하여 데이터를 읽어들입니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;pandas&lt;/b&gt;란 python의 데이터 분석 라이브러리로써 행과 열로 이루어진 데이터 객체를 만들어 대용량의 데이터를 효과적으로 다루게 해줍니다. 이는 다른 포스팅에서 추후에 좀 더 구체적으로 다뤄보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import pandas as pd

def load_housing_data(housing_path=HOUSING_PATH):
  csv_path = os.path.join(housing_path, &quot;housing.csv&quot;)
  return pd.read_csv(csv_path)

load_housing_data()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1127&quot; data-origin-height=&quot;380&quot; data-filename=&quot;blob&quot; width=&quot;860&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHPG01/btqFDwFLgwP/P06BBDhTYxAOtyM5MFJjY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHPG01/btqFDwFLgwP/P06BBDhTYxAOtyM5MFJjY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHPG01/btqFDwFLgwP/P06BBDhTYxAOtyM5MFJjY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHPG01%2FbtqFDwFLgwP%2FP06BBDhTYxAOtyM5MFJjY1%2Fimg.png&quot; data-origin-width=&quot;1127&quot; data-origin-height=&quot;380&quot; data-filename=&quot;blob&quot; width=&quot;860&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3&gt;2.3.2 데이터 구조 훑어보기&lt;/h3&gt;
&lt;p&gt;이제 좀 더 구체적으로 데이터가 어떤 특성을 가지고 어떻게 구성되어있는지 알아보겠습니다. 우선 &lt;b&gt;head()&lt;/b&gt;를 사용하여 처음 다섯 행을 확인해보겠습니다. 여기서 하나의 행은 하나의 구역을 나타내며 특성은 longitude부터 ocean_proximity까지 총 10개입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;255&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NFYbR/btqFBYJIVw5/MpvERRIh62R6Od4zW07dok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NFYbR/btqFBYJIVw5/MpvERRIh62R6Od4zW07dok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NFYbR/btqFBYJIVw5/MpvERRIh62R6Od4zW07dok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNFYbR%2FbtqFBYJIVw5%2FMpvERRIh62R6Od4zW07dok%2Fimg.png&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;255&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;info()&lt;/b&gt; 메서드를 통해 데이터에 대한 간략한 설명 그 중에서도 전체 행 수, 각 feature의 데이터 타입과 Null이 아닌 값들의 개수 등을 확인할 때 유용합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;- 데이터셋에는 &lt;b&gt;20640개의 샘플&lt;/b&gt;로 상당히 적은 양에 속하지만, 초보자가 다루기엔 충분합니다.&lt;/p&gt;
&lt;p&gt;- 4번째 feature인 total_bedrooms만 20433개의 Null이 아닌 값을 가지는데, 이는 &lt;b&gt;나머지 207개의 구역이 이 feature를 가지고 있지 않기 때문입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;360&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uHPPU/btqFDbojcmS/mV5KthSkhm1i2GhCKOIaXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uHPPU/btqFDbojcmS/mV5KthSkhm1i2GhCKOIaXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uHPPU/btqFDbojcmS/mV5KthSkhm1i2GhCKOIaXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuHPPU%2FbtqFDbojcmS%2FmV5KthSkhm1i2GhCKOIaXk%2Fimg.png&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;360&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;- ocean_proximity를 제외한 &lt;b&gt;모든 feature의 데이터 타입은 숫자형입니다.&lt;/b&gt; ocean_proximity는 head()에서 데이터가 반복되는 것으로 보아서 범주형(categorical) 데이터이기 때문에 value_contents()를 통해 &lt;b&gt;각 카테고리별 속해있는 구역&lt;/b&gt;을 확인해봅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;152&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6zecK/btqFD52dNUW/WxbKeSyz4FsYSU0Gb5XQIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6zecK/btqFD52dNUW/WxbKeSyz4FsYSU0Gb5XQIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6zecK/btqFD52dNUW/WxbKeSyz4FsYSU0Gb5XQIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6zecK%2FbtqFD52dNUW%2FWxbKeSyz4FsYSU0Gb5XQIK%2Fimg.png&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;152&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;describe()&lt;/b&gt;를 통해 ocean_proximity 이외에 숫자형 feature의 요약 정보를 확인해보겠습니다. count, mean, std 등은 다들 통계를 공부해봤다면 알법한 쉬운 정보들로 구성되어있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;326&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bus8ci/btqFD6mvKm0/Za3TZYReCpwezhJk2eHZYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bus8ci/btqFD6mvKm0/Za3TZYReCpwezhJk2eHZYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bus8ci/btqFD6mvKm0/Za3TZYReCpwezhJk2eHZYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbus8ci%2FbtqFD6mvKm0%2FZa3TZYReCpwezhJk2eHZYk%2Fimg.png&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;326&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;데이터를 훑어보는데는 많은 방법들이 있겠지만, 직접 그래프로 시각화하여 보는 것만큼 효과적인 방법은 없다고 생각합니다. 다음은 숫자형 feature를 히스토그램으로 그려본 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;540&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blSFbe/btqFDxYYFeA/BLcrRE037OLZuv9L0400dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blSFbe/btqFDxYYFeA/BLcrRE037OLZuv9L0400dK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blSFbe/btqFDxYYFeA/BLcrRE037OLZuv9L0400dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblSFbe%2FbtqFDxYYFeA%2FBLcrRE037OLZuv9L0400dK%2Fimg.png&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;540&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;232&quot; data-filename=&quot;blob&quot; width=&quot;860&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SjRP4/btqFGxjq2AV/XTxd3LXY7ryEwNSkLppnw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SjRP4/btqFGxjq2AV/XTxd3LXY7ryEwNSkLppnw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SjRP4/btqFGxjq2AV/XTxd3LXY7ryEwNSkLppnw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSjRP4%2FbtqFGxjq2AV%2FXTxd3LXY7ryEwNSkLppnw0%2Fimg.png&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;232&quot; data-filename=&quot;blob&quot; width=&quot;860&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3&gt;2.3.4 테스트 세트 만들기&lt;/h3&gt;
&lt;p&gt;다음 코드를 통해 모델의 성능을 측정하기 위한 &lt;b&gt;테스트 데이터셋을 20% 정도 떼어 놓겠습니다.&lt;/b&gt; 우선 데이터를 쪼갤 함수를 만든 후 쪼갠 후, train set과 data set의 크기를 비교해보았습니다.&lt;/p&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;code&gt;import numpy as np

def split_train_test(data, test_ratio):
  shuffled_indices = np.random.permutation(len(data))
  test_set_size = int(len(data)*test_ratio)
  test_indices = shuffled_indices[:test_set_size]
  train_indices = shuffled_indices[test_set_size:]
  return data.iloc[train_indices], data.iloc[test_indices]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;173&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D3O72/btqFDwTo0dw/7H3rWV9s8G6evYZqZZTjSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D3O72/btqFDwTo0dw/7H3rWV9s8G6evYZqZZTjSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D3O72/btqFDwTo0dw/7H3rWV9s8G6evYZqZZTjSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD3O72%2FbtqFDwTo0dw%2F7H3rWV9s8G6evYZqZZTjSK%2Fimg.png&quot; data-origin-width=&quot;1059&quot; data-origin-height=&quot;173&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그런데 위와 같은 방식으로 했을 때의 문제점은 &lt;b&gt;함수를 실행할 때마다 다른 test set을 생성한다는 것입니다.&lt;/b&gt; 즉 모델이 전체 데이터셋을 보게 되는 것이죠. 이를 피하기 위해 &lt;b&gt;np.random.permutation(np.random.seed(42))&lt;/b&gt;와 같이 랜덤값 생성 시 초깃값을 지정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 이마저도 &lt;b&gt;업데이트 시 데이터는 바뀌었는데 초깃값은 그대로니 test set이 변경된다는 문제가 있습니다.&lt;/b&gt; 따라서 안정적인 데이터 분할을 위해선 각 샘플에 identifyer를 사용하여 test set에 보낼지 말지 결정하는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;예를 들어 identifyer의 해시값이 20%보다 작다면 test set으로 보내는 식입니다. 이를 통해 데이터셋이 업데이트 되더라도 기존에 training set에 있던 데이터가 test set에 들어가는 것을 방지할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;from zlib import crc32

def test_set_check(identifier, test_ratio):
  return crc32(np.int64(identifier)) &amp;amp; 0xffffffff &amp;lt; test_ratio * 2**32

def split_train_test_by_id(data, test_ratio, id_column):
  ids = data[id_column]
  in_test_set = ids.apply(lambda id : test_set_check(id, test_ratio))
  return data.loc[~in_test_set],data.loc[in_test_set]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;이때 원래 데이터셋에는 identifyer에 대한 column이 없기 때문에 &lt;b&gt;column의 인덱스를 ID로 사용하겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;housing_with_id = housing.reset_index()
train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, &quot;index&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;그러나 이렇게 행의 인덱스를 identifyer로 사용하기 위해서는 새로운 데이터셋은 끝에 추가되어야하며 어떤 행도 삭제가 되면 안됩니다. &lt;b&gt;좀 더 안정적인 identifyer를 사용하기 원한다면&lt;/b&gt; 구역의 longitude와 latitude처럼 몇백년이 지나도 변하지 않는 features를 연결하여 다음과 같이 ID를 만들 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;'사이킷런'도 데이터셋을 여러 서브셋으로 나누는 기능을 제공합니다.&lt;/b&gt; 가장 간단한 함수인 &lt;b&gt;train_test_split&lt;/b&gt;은 난수 초깃값을 지정할 random_state 매개변수가 있고, 행의 개수가 같은 여러 데이터셋을 동시에 넘겨 같은 인덱스를 기반으로 나누게 할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;from sklearn.model_selection import train_test_split

train_set, test_set = train_test_split(housing, test_size = 0.2, random_state = 42)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;지금까지 우리가 본 것은 &lt;b&gt;순수한 무작위 샘플링 방식&lt;/b&gt;입니다. 그러나 이러한 방식은 데이터의 대표성을 보장할 수 없습니다. 예를 들어 남자 400명, 여자 600명으로 구성된 1000개의 데이터셋에서 200개를 test set으로 분할할 때 200개 모두 남자일 수도 있다는 말이 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 우리 데이터셋의 소득 분포는 어떻게 되어있는지 보겠습니다. pd.cut() 함수를 이용하여 소득을 &lt;b&gt;5개의 카테고리로 구분한 후&lt;/b&gt; 이를 히스토그램으로 표현합니다.&lt;/p&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;housing[&quot;income_cat&quot;] = pd.cut(housing[&quot;median_income&quot;],
                               bins=[0,1.5,3.0,4.5,6,np.inf],
                               labels=[1,2,3,4,5])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;310&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WmoYA/btqFGxqG2KA/bkDlQZ3JVLOSkxkesWxpN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WmoYA/btqFGxqG2KA/bkDlQZ3JVLOSkxkesWxpN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WmoYA/btqFGxqG2KA/bkDlQZ3JVLOSkxkesWxpN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWmoYA%2FbtqFGxqG2KA%2FbkDlQZ3JVLOSkxkesWxpN1%2Fimg.png&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;310&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이제 사이킷런의 &lt;b&gt;StratifiedShuffleSplit&lt;/b&gt;을 사용하여 비율을 유지하여 샘플링을 하는 계층 샘플링을 하고 비율을 확인해보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;from sklearn.model_selection import StratifiedShuffleSplit

split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state = 42)
for train_index, test_index in split.split(housing,housing[&quot;income_cat&quot;]):
  strat_train_set = housing.loc[train_index]
  strat_test_set = housing.loc[test_index]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;153&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3hrhE/btqFGMHVLjw/VKdlx9fTQtkM5ssfxIx1fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3hrhE/btqFGMHVLjw/VKdlx9fTQtkM5ssfxIx1fK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3hrhE/btqFGMHVLjw/VKdlx9fTQtkM5ssfxIx1fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3hrhE%2FbtqFGMHVLjw%2FVKdlx9fTQtkM5ssfxIx1fK%2Fimg.png&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;153&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&amp;nbsp;여기까지가 프로젝트 진행을 위해 문제를 정의하고, pandas와 sklearn을 활용하여 데이터의 특성을 파악하는 법을 알아보았습니다. 다음 포스팅에 계속 이어서 데이터를 어떻게 탐색하고 시각화하는지 공부해보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;box-world.tistory.com/43&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1595126886249&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (2)&quot; data-og-description=&quot;&amp;nbsp;저번 포스팅에서는 캘리포니아 주택 가격 데이터셋을 가지고 pandas, sklearn을 이용하여 데이터의 특성을 탐색하고, 모델 학습을 위해 test set을 분리하는 다양한 방법에 대해 알아보았습니다. &amp;nbsp;��&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/43&quot; data-og-url=&quot;https://box-world.tistory.com/43&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WvE3b/hyGPgfoRfM/LKgnGdBGoFIJ07ClDa66IK/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/pMU6h/hyGNPwYKXp/vBGEG4G4ccLOIQVQhc92e0/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/TraUH/hyGNMNMEKh/0Wmbxq9zFN7U3nXukYNHqK/img.png?width=923&amp;amp;height=383&amp;amp;face=0_0_923_383&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/43&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WvE3b/hyGPgfoRfM/LKgnGdBGoFIJ07ClDa66IK/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/pMU6h/hyGNPwYKXp/vBGEG4G4ccLOIQVQhc92e0/img.png?width=800&amp;amp;height=331&amp;amp;face=0_0_800_331,https://scrap.kakaocdn.net/dn/TraUH/hyGNMNMEKh/0Wmbxq9zFN7U3nXukYNHqK/img.png?width=923&amp;amp;height=383&amp;amp;face=0_0_923_383');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈온 머신러닝 2판 ] pandas, sklearn을 통한 데이터 전처리는 어떻게 하는걸까? (2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;저번 포스팅에서는 캘리포니아 주택 가격 데이터셋을 가지고 pandas, sklearn을 이용하여 데이터의 특성을 탐색하고, 모델 학습을 위해 test set을 분리하는 다양한 방법에 대해 알아보았습니다. &amp;nbsp;��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/44&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;box-world.tistory.com/44&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1595126892651&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 모델 학습과 튜닝은 어떻게 하는 것일까? (3)&quot; data-og-description=&quot;&amp;nbsp;이전 2개의 포스팅에 결쳐 우리는 지금까지 문제를 정의하고 데이터를 읽어들여 탐색하였습니다. 그리고 데이터를 training set과 test set으로 나누고 학습을 위한 머신러닝 알고리즘에 주입할 데�&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/44&quot; data-og-url=&quot;https://box-world.tistory.com/44&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/trbGk/hyGNGtiewM/IMXGMbviDVJFqFxkGLfuMk/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/WEi0n/hyGO9N7ABg/IA02KtKocUsWSPWEXIlj71/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/b0uU5z/hyGO3NUG7k/F37UD5c7YKZg8YiryusqzK/img.png?width=264&amp;amp;height=200&amp;amp;face=0_0_264_200&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/44&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/44&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/trbGk/hyGNGtiewM/IMXGMbviDVJFqFxkGLfuMk/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/WEi0n/hyGO9N7ABg/IA02KtKocUsWSPWEXIlj71/img.jpg?width=300&amp;amp;height=386&amp;amp;face=0_0_300_386,https://scrap.kakaocdn.net/dn/b0uU5z/hyGO3NUG7k/F37UD5c7YKZg8YiryusqzK/img.png?width=264&amp;amp;height=200&amp;amp;face=0_0_264_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[ 핸즈 온 머신러닝 2판 ] pandas, sklearn을 통한 모델 학습과 튜닝은 어떻게 하는 것일까? (3)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;이전 2개의 포스팅에 결쳐 우리는 지금까지 문제를 정의하고 데이터를 읽어들여 탐색하였습니다. 그리고 데이터를 training set과 test set으로 나누고 학습을 위한 머신러닝 알고리즘에 주입할 데�&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>Machine Learning</category>
      <category>numpy</category>
      <category>pandas</category>
      <category>sklearn</category>
      <category>데이터 사이언스</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>빅데이터</category>
      <category>사이킷런</category>
      <category>핸즈 온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/42</guid>
      <comments>https://box-world.tistory.com/42#entry42comment</comments>
      <pubDate>Tue, 9 Jun 2020 20:37:49 +0900</pubDate>
    </item>
    <item>
      <title>[핸즈 온 머신러닝] 머신러닝(Machine Learning)의 종류와 유의할 점</title>
      <link>https://box-world.tistory.com/41</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;크게 실패할 용기있는 자만이 크게 이룰 수 있다&amp;rdquo; &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;-존 F. 케네디(35대 미국 대통령)-&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시작하며&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;497&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6zBec/btqEHxzGBPu/3rhhe84oufDIapBEZ7Vlk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6zBec/btqEHxzGBPu/3rhhe84oufDIapBEZ7Vlk1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6zBec/btqEHxzGBPu/3rhhe84oufDIapBEZ7Vlk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6zBec%2FbtqEHxzGBPu%2F3rhhe84oufDIapBEZ7Vlk1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;497&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;사실 우리 주변에 머신러닝은 이미 오래전부터 존재해왔습니다. 그 시작은 1990년대에 등장한 &lt;b&gt;스팸 필터(spam filter)&lt;/b&gt;입니다. 물론 성능이 완벽하진 않았겠지만, 기술적으로 머신러닝이 분명했고 시간이 흐르면서 이는 추천과 음성 검색으로 발전하였고, 현재는 더욱 다양한 분야에 머신러닝을 접목시키고자 많은 분들이 연구하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;그러면 이 머신러닝의 범주는 정확히 어디까지일까요? 기계가 학습한다는 것은 어떤 의미이며 머신러닝은 우리에게 왜 필요한 것일까요?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;이번 포스팅에서 전체적인 머신러닝의 그림을 조망하며 본격적으로 구체적인 개념을 공부하기 전 머신러닝을 거시적으로 바라보는 시간을 가져보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2&gt;머신러닝이란?&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;머신러닝&lt;/b&gt;은 데이터를 학습하도록 컴퓨터를 프로그래밍하는 과학입니다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;어떤 작업 T에 대한 컴퓨터 프로그램의 성능을 P로 측정했을 때, 경험 E로 인해 성능이 향상됐다면, 이 컴퓨터 프로그램은 작업 T와 성능 측정 P에 대한 경험 E로 학습한 것이다.&lt;/blockquote&gt;
&lt;p&gt;위는 인공지능의 대표적인 연구자인 '톰 미첼'이 내린 공학적인 정의로 머신러닝의 정의를 설명할 때 가장 일반적으로 인용되는 문구입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;389&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b16iAA/btqEJjmEWrT/ffB5uuGx2qyKEVH5xOIcbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b16iAA/btqEJjmEWrT/ffB5uuGx2qyKEVH5xOIcbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b16iAA/btqEJjmEWrT/ffB5uuGx2qyKEVH5xOIcbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb16iAA%2FbtqEJjmEWrT%2FffB5uuGx2qyKEVH5xOIcbK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;389&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;작업 T&lt;/b&gt;는 메일이 스팸인지를 판단하는 것이고, &lt;b&gt;경험 E&lt;/b&gt;는 시스템 학습에 사용되는 훈련 데이터(Training data)이며, &lt;b&gt;성능 측정 P&lt;/b&gt;는 우리가 직접 정의내려야 합니다. 예를 들어 전체 메일 중 정확히 분류된 메일의 비율을 P로 사용할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2&gt;머신러닝을 왜 사용해야할까?&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;머신러닝이 무엇인지를 알게 되었으니 &lt;b&gt;이제 왜 머신러닝이어야만 하는지&lt;/b&gt; 스팸 필터를 만드는 과정을 일반적인 프로그래밍과 머신러닝을 이용한 프로그래밍 둘로 나누어 비교하면서 생각해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;600&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWr7u4/btqEIUAEkKs/VrBFFBGOgK42E8WLypHYf1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWr7u4/btqEIUAEkKs/VrBFFBGOgK42E8WLypHYf1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWr7u4/btqEIUAEkKs/VrBFFBGOgK42E8WLypHYf1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWr7u4%2FbtqEIUAEkKs%2FVrBFFBGOgK42E8WLypHYf1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;600&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;'4U', '신용카드', '무료' 등 스팸 메일에 자주 등장하는 단어들이 있습니다. &lt;b&gt;일반적인 프로그래밍의 경우&lt;/b&gt;엔 이러한 단어의 패턴들을 찾아내는 알고리즘을 단어 하나당 하나씩 만들어 프로그램이 패턴을 발견 시 해당 메일을 스팸으로 분류하게 해야합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나&lt;b&gt; 머신러닝을 이용한다면,&lt;/b&gt; 스팸 메일에 자주 나타나는 패턴을 스스로 학습하기 때문에, 프로그램이 훨씬 짧아지고 유지보수도 훨씬 쉬워집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;만약 스팸 메일 발송자가 '4U' 단어가 포함된 메일은 모두 차단한다는 사실을 알게 되어 '4U' 대신 'For U'를 사용한다면 &lt;b&gt;일반적인 프로그래밍의 경우 또 다시 이것에 대한 알고리즘을 만들거나 계속해서 수정해야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;617&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QJNEc/btqEHNPMp9F/aLavNkOVIhR7p6i7dCVdi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QJNEc/btqEHNPMp9F/aLavNkOVIhR7p6i7dCVdi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QJNEc/btqEHNPMp9F/aLavNkOVIhR7p6i7dCVdi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQJNEc%2FbtqEHNPMp9F%2FaLavNkOVIhR7p6i7dCVdi0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;617&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그러나 &lt;b&gt;머신러닝을 이용한다면,&lt;/b&gt; 스팸 메일에 유독 'For U'가 자주 쓰인다는 것을 인식하여 &lt;b&gt;프로그래머가 별도의 작업을 하지 않아도 단어가 자동으로 스팸으로 분류됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;머신러닝을 통해 배울 수도 있습니다.&lt;/b&gt; 예를 들어 스펨 메일을 분류하는 머신러닝 모델이 있다면 이것을 분석하여 스팸 메일을 분류하는데 핵심이 되는 단어나 패턴이 무엇인지를 배울 수 있을 것입니다. 이렇게 머신러닝을 이용하여 빅데이터에서 보이지 않던 패턴을 발견하는 것을 데이터 마이닝이라고 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2&gt;머신러닝 시스템의 종류&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[ 지도학습 / 비지도학습 ]&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) 지도학습(Supervised Learning)&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;지도학습&lt;/b&gt;은 모델 학습에 사용되는 Training Data(훈련 데이터)에 &lt;b&gt;Label이 붙어있습니다.&lt;/b&gt; 대표적인 지도 학습의 종류에는 &lt;b&gt;분류&lt;/b&gt;와 &lt;b&gt;회귀&lt;/b&gt;가 있습니다. 스팸 메일이 분류의 예, 집의 사이즈를 보고 가격을 예측하는 것이 회귀의 대표적인 예가 되겠습니다.&lt;/p&gt;
&lt;p&gt;이외에 다음과 같은 알고리즘도 지도 학습에 포함됩니다.&lt;/p&gt;
&lt;p&gt;- K-nearest neighbors, Linear regression, Logistic Regression, &lt;span style=&quot;color: #333333;&quot;&gt;SVM(Support Vector Machine), &lt;span style=&quot;color: #333333;&quot;&gt;Decision Tree and Random Forest, &lt;span style=&quot;color: #333333;&quot;&gt;Neural Network&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b41H04/btqEIUAE3ue/nIjuCMhLNb1kvrUM2GyfR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b41H04/btqEIUAE3ue/nIjuCMhLNb1kvrUM2GyfR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b41H04/btqEIUAE3ue/nIjuCMhLNb1kvrUM2GyfR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb41H04%2FbtqEIUAE3ue%2FnIjuCMhLNb1kvrUM2GyfR1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2) 비지도학습(Non-Supervised Learning)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;비지도학습&lt;/b&gt;에 사용되는 Training set에는 &lt;b&gt;Label이 없습니다.&lt;/b&gt; 그렇기 때문에 학습 모델이 보통 알고리즘을 통해 직접 특성을 찾아내야합니다. 다음은 비지도학습에 포함되는 알고리즘들입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2 - 1) 군집(Clustering)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;군집&lt;/b&gt; : &lt;b&gt;비슷한 특성을 가지는 데이터끼리 묶어 특정한 패턴이나 규칙을 발견하기 위해 쓰입니다.&lt;/b&gt; 예를 들어 블로그 방문자에 대한 데이터가 있을 때, 이를 비슷한 특성을 가지는 데이터를 묶는 군집 알고리즘을 이용하여 60%의 방문자가 남성이며 저녁에 방문한다는 것을 알수도 있습니다.&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;이상치 탐지&lt;/b&gt; : &lt;b&gt;전체 데이터에 비해 매우 작은 비율의 데이터를 찾아낼 때 쓰입니다.&lt;/b&gt; 예를 들어, 10만건중 10번 꼴로 발견되는 신용 사기의 패턴을 분석하여 사전에 이를 발견하기 위해 쓰일 수 있습니다.&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;특이치 탐지&lt;/b&gt; : 이상치 탐지가 Training set에서 0.01%의 매우 작은 데이터를 발견하는데 쓰인다면, 특이치 탐지는 &lt;b&gt;Training set과 아예 다른 새롭고 특이한 데이터를 찾는데 쓰입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- K-means, DBSCAN, HCA, Anomaly Detection, novelty detection, one-SVM, isolation forest&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2 - 2) 시각화(visualization) 및 차원 축소(dimension reduction)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;시각화&lt;/b&gt; : 고차원의 데이터를 넣으면 그 구조를 가능한 한 유지하면서 도&lt;b&gt;식화가 가능한 2D나 3D로 표현해줍니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;차원 축소&lt;/b&gt; : 고차원의 데이터를 최대한 정보를 잃지 않으면서 &lt;b&gt;차원을 낮추는 것&lt;/b&gt;으로, 데이터를 가볍게 해주는 역할을 합니다.&lt;/p&gt;
&lt;p&gt;- PCA, Kernel-PCA, LLE, t-SNE&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2 - 3) 연관 규칙 학습(Association Rule Leraning)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;대량의 데이터에서 특성 간의 특별한 관계를 찾는데 유용하게 쓰입니다.&lt;/b&gt; 예를 들어, 슈퍼마켓 판매 기록 데이터를 연관 규칙 학습을 시켰더니 높은 비율로 스테이크를 살때 감자를 함께 산다는 것을 발견하여 이를 진열대 정리에 반영할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;- Apriori, Eclat&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3) 준지도 학습(Semisupervised Learning)&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;준지도 학습은&lt;b&gt; Traning set의 Label이 일부에만 붙어있는 데이터가 쓰입니다&lt;/b&gt;. 예를 들어, 저의 증명사진에 대해서, 저라는 정보를 기입하지 않고 갤러리에 올렸을 때는 갤러리 내에 제가 포함된 사진이 있는지 자동으로 찾아줄 수 있습니다. 이것은 &lt;b&gt;비지도학습&lt;/b&gt;입니다. 반대로 가족 사진을 갤러리에 올리며 사진 속 어떤 사람이 누군인지를 입력하면, 검색을 통해 해당 가족 인물이 포함된 사진을 쉽게 찾을 수 있습니다. 이는 &lt;b&gt;지도학습&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;대부분의 준지도 학습 알고리즘은 &lt;b&gt;지도 학습과 비지도 학습의 조합으로 이루어집니다.&lt;/b&gt; &lt;b&gt;심층 신뢰 신경망(DBN)&lt;/b&gt;은 비지도 학습 알고리즘인 &lt;b&gt;제한된 볼츠만 머신(RBM&lt;/b&gt;)에 기초합니다. 여러 겹(Layer)의 RBM으로 구성된 DBN은 각 Layer의 RBM에서 이뤄진 비지도 학습 방식을 이용하여 전체 시스템을 지도 학습으로 조정합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4)&amp;nbsp; 강화 학습(Reinforcement Learning)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v7WSh/btqEJhvIW4v/x417jXYZh3XbSI4wu0m14k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v7WSh/btqEJhvIW4v/x417jXYZh3XbSI4wu0m14k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v7WSh/btqEJhvIW4v/x417jXYZh3XbSI4wu0m14k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv7WSh%2FbtqEJhvIW4v%2Fx417jXYZh3XbSI4wu0m14k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;강화 학습&lt;/b&gt;은 &lt;b&gt;에이전트(Agent)&lt;/b&gt;라고 부르는 학습 시스템이&lt;b&gt; 환경&lt;/b&gt;을 관찰해서 행동을 실행하고 그에 따른 &lt;b&gt;보상이나 벌점&lt;/b&gt;을 받습니다. 이를 통해 &lt;b&gt;정책(Policy)&lt;/b&gt;라 부르는 최상의 전략을 스스로 학습하여 주어진 상황에서 에이전트가 어떻게 행동해야할지 정의합니다. 대표적인 예로, 알파고가 있습니다. 알파고는 별도의 바둑 규칙을 알려주지 않은 채 스스로 수없이 바둑을 두며 스스로 정책을 수립하였습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[ 배치 학습(오프라인 학습)과 온라인 학습 ]&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;배치 학습&lt;/b&gt;은 &lt;b&gt;데이터를 한번에 받아 학습하여 시스템을 만드는 것&lt;/b&gt;입니다. 즉 많은 양의 데이터를 한번에 학습해야 하기에 시간과 컴퓨팅 자원을 많이 소모하므로 오프라인에서 주로 수행되어 &lt;b&gt;오프라인 학습&lt;/b&gt;으로 불리기도 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;그리고 배치 학습은 새로운 데이터에 대해 학습하기 위해서는 새로운 데이터를 포함 시킨 전체 데이터를 다시 학습시킨 시스템과 기존 시스템을 교체하는 식으로 이뤄지기 때문에 굉장히 비효율적일 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이에 비해 &lt;b&gt;온라인 학습&lt;/b&gt;은 &lt;b&gt;미니 배치(mini batch)라는 작은 묶음 단위로 주입되는 데이터로 점진적으로 학습합니다.&lt;/b&gt; 그렇기 때문에 매 학습 단계가 빠르고 컴퓨팅 자원이 많이 소모되지 않습니다. 이것은 주식과 같이 연속적인 데이터를 받으며 빠른 변화가 필요한 시스템에 적합합니다. 혹은 데이터셋이 메모리크기보다 큰 경우 온라인 학습을 통해 데이터의 일부를 조금씩 메모리에 가져와 점진적으로 학습할 수도 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;온라인 학습에서 제일 중요한 요소 중 하나는 &lt;b&gt;학습률(Learning Rate)&lt;/b&gt;입니다. 이 학습률을 높게하면 시스템이 데이터에 빨리 적응하지만 예전 데이터는 금방 잊어버리게 됩니다. 반대로 학습률이 낮다면 새로운 데이터에 적응하는데 더 오랜 시간이 걸리게 되지만, 새로운 데이터의 잡음이나 이상한 데이터에 덜 민감해집니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;온라인 학습의 가장 큰 문제점은 &lt;b&gt;나쁜 데이터&lt;/b&gt;입니다. 예를 들어, 특정 음악 차트에 누군가 자신의 노래를 차트 상위권으로 올리기 위해 의도적으로 매크로를 돌리는 경우를 생각해볼 수 있습니다. 이 경우 관리자가 이를 걸러내는 시스템을 짜거나 지속적인 관리를 해야합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[ 모델 기반 학습과 사례 기반 학습 ]&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;1) 모델 기반 학습&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;596&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boIfMi/btqEKwllClC/OxcyTaFEdk2mxF05mXhTM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boIfMi/btqEKwllClC/OxcyTaFEdk2mxF05mXhTM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boIfMi/btqEKwllClC/OxcyTaFEdk2mxF05mXhTM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboIfMi%2FbtqEKwllClC%2FOxcyTaFEdk2mxF05mXhTM0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;596&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;모델 기반 학습&lt;/b&gt;은 데이터를 대표할 수 있는 모델을 생성하여 이를 예측에 이용하는 것입니다. 우리가 앞으로 머신러닝에서 공부할 대부분의 알고리즘들이 바로 여기에 속하게 됩니다. 이러한 모델 기반 학습은 &lt;b&gt;데이터 분석, 모델 선택, 모델 학습, 모델에 새로운 데이터를 적용하여 결과 평가하기&lt;/b&gt; 이렇게 보통 4단계로 이루어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;2) 사례 기반 학습&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;601&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FfKjB/btqEKxkijn9/kjZ6TFByzk6gcLDNsRbLWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FfKjB/btqEKxkijn9/kjZ6TFByzk6gcLDNsRbLWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FfKjB/btqEKxkijn9/kjZ6TFByzk6gcLDNsRbLWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFfKjB%2FbtqEKxkijn9%2FkjZ6TFByzk6gcLDNsRbLWK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;601&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;b&gt;사례 기반 학습&lt;/b&gt;은 &lt;b&gt;유사도&lt;/b&gt;라는 것을 이용하여 데이터를 분류합니다. 예를 들어 스팸 메일 분류의 경우, 일치하는 단어를 유사도의 척도로 사용하여 어떤 메일이 일정 유사도를 넘으면 스팸을 분류합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;머신러닝 적용 시 유의할 점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Training data의 수가 충분한가?&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;우리가 생각하는 좋은 머신러닝 알고리즘이 만들어지기 위해서는 수천개에서 수백만개의 데이터가 필요합니다. 문제는 실제로 우리가 몸담게될 산업현장에서는 우리가 공부할 때 사용하는 예제처럼 예쁘게 정제된 데이터가 대부분 없습니다. 따라서 현재 인공지능을 접목하고자 하는 산업 곳곳에서는 이러한 데이터를 구하기 위해 데이터 파이프라인을 구축하고, 학습에 이용할 수 있도록 데이터를 정제하는 기술을 개발하는데 힘쓰고 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Trainig data가 대표성을 지니고 있는가?&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;우리가 어떠한 머신러닝 알고리즘을 개발하여 특정 분야에 적용하고자 한다면 모델 학습에 사용되는 데이터는 대표성을 지녀야합니다. 예를 들어, 나라의 여러 특성을 이용하여 GDP를 예측하는 모델을 만들고자 할 때 특정 나라를 누락시킨다면 이러한 데이터를 학습한 알고리즘은 정확하다고 할 수 없을 것입니다. 이렇게 표본추출을 잘못하여 데이터가 대표성을 띄지 못하는 현상을 샘플링 편향(Sampling bias)라고 합니다. 이외에도 학습 데이터가 너무 작을 경우 샘플링 잡음(Sampling noise)라고 부르는 예외적인 데이터에 모델이 영향을 받을 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) Training data의 품질이 높은가?&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;Training data에 에러, 이상치(예외), 잡음(열악한 측정 장치로 인한)으로 가득찬다면 머신러닝 시스템이 잘 작동할리가 없습니다. 현재에도 다양한 산업군에서 '좋은' 데이터라는 것을 얻기 위해 데이터 사이언티스트의 역할이 더욱 중요해지고 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;데이터 사이언티스트는 데이터에 이상치가 들어있다면 이를 무시하거나 수동으로 뺄 수도 있고, 일부 데이터에 몇몇 특성이 빠져있다면 이를 그대로 진행할지 채울지를 고민해야합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) Training data에 필요없는 특성이 들어있진 않는가?&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;예를 들어 주어진 데이터를 통해 이 사람의 5년 후의 키를 예측하는 알고리즘을 짠다고 해보겠습니다. 그런데 뜬금없이 데이터의 특성으로 각 사람의 수학 점수가 들어간다면 당연히 좋은 알고리즘이 나올 수 없을 것입니다. 이처럼 Training set을 결정할 때는 알고리즘에 필요한 특성들로만 구성되어있는지 고민해야합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5) 모델의 과대적합(Overfitting) / 과소적합(Underfitting)&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;우리가 머신러닝 학습을 통해 만들어진 모델은 데이터를 대표합니다. 그런데 모델의 대표성이 지나치게 높거나 낮으면 알고리즘의 정확도에 큰 영향을 끼칠 수 있습니다. 예를 들어 암을 발견하는 알고리즘에서 모델이 데이터에 너무 꽉끼는 바람에 99.7% 이상의 확률을 가진 사람만 암으로 판단한다고 하면 실제로 암인데도 불구하고 98%나 99.1%의 확률로 암이 아니라는 끔찍한 오진을 내리게 될수도 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2&gt;요약&lt;/h2&gt;
&lt;p&gt;- 머신러닝은 프로그래머가 명시적으로 하나하나 구현하는 것이 아닌, 주어진 데이터를 가지고 스스로 학습하면서 성능을 강화시켜나간다.&lt;/p&gt;
&lt;p&gt;- 머신러닝 시스템에는 지도 학습과 비지도 학습, 배치 학습과 온라인 학습, 사례 기반 학습과 모델 기반 학습 등이 있다.&lt;/p&gt;
&lt;p&gt;- 머신러닝 알고리즘 자체도 중요하지만, 학습에 사용될 데이터를 여러 기준에 따라 알맞게 정제하는 것 또한 매우 중요하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Hands-On Machine Learning 2판</category>
      <category>cost 함수</category>
      <category>강화 학습</category>
      <category>경사 하강 알고리즘</category>
      <category>데이터</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>배치 학습</category>
      <category>온라인 학습</category>
      <category>지도 학습</category>
      <category>핸즈온 머신러닝</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/41</guid>
      <comments>https://box-world.tistory.com/41#entry41comment</comments>
      <pubDate>Tue, 2 Jun 2020 16:52:14 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 순환 신경망(RNN)이란?</title>
      <link>https://box-world.tistory.com/39</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;모든 경험에는 가르침이 있다&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 브라이언 트레이시 -&lt;/b&gt;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;시작하며&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;과거를 통해 미래를 예측하는 능력은 누구나 갖고 싶어하는 것입니다. 하지만 오늘날 딥러닝 분야에서는 이러한 예측 능력을 수학적으로 구현하여 미래에 한발짝 다가가고자 하는 알고리즘이 있습니다. 바로 &lt;b&gt;RNN&lt;span style=&quot;color: #333333;&quot;&gt;(Recurrent Neural Network)&lt;/span&gt;&lt;/b&gt;입니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이번 포스팅에서는 자연어 처리(NLP), 주가 예측 등 폭넓게 사용되는 기본적인 RNN에 대해 알아보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;RNN's Basic Idea&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;여기 네 개의 단어가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;326&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diph0V/btqEsXQ0L5x/huTskp5rZm5ndkTTu96Tx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diph0V/btqEsXQ0L5x/huTskp5rZm5ndkTTu96Tx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diph0V/btqEsXQ0L5x/huTskp5rZm5ndkTTu96Tx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdiph0V%2FbtqEsXQ0L5x%2FhuTskp5rZm5ndkTTu96Tx0%2Fimg.png&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;326&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; 'I'는 주어, 'work'는 동사, 'at'은 전치사, 'google'은 명사라는건 대부분 알고 있습니다. 좀 더 구체적으로 들여다보자면 &lt;b&gt;주어인 'I'가 왔기 때문에 그 뒤는 동사일 것이라고 자연스럽게 예측했고, 전치사 'at'이 왔기 때문에 그 뒤는 명사가 올것이라고 추론할 수 있었던 것입니다.&lt;/b&gt; 이러한 일련의 추론 과정을 수학적으로 모델링한 것이 바로 &lt;b&gt;'RNN'&lt;/b&gt;입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;RNN의 구조&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;426&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SfF2n/btqEpZJLZPt/eYl72YCAj1OPyMIuRKbZS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SfF2n/btqEpZJLZPt/eYl72YCAj1OPyMIuRKbZS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SfF2n/btqEpZJLZPt/eYl72YCAj1OPyMIuRKbZS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSfF2n%2FbtqEpZJLZPt%2FeYl72YCAj1OPyMIuRKbZS0%2Fimg.png&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;426&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;방금 보았던 예시를 4개의 단어를 Input으로 받아 품사가 무엇인지 Output으로 알려주는 RNN으로 다시 표현해보겠습니다. Input은 동시가 아닌 &lt;b&gt;순차적으로&lt;/b&gt; 들어오며, &lt;b&gt;'I'&lt;/b&gt;는&lt;b&gt; hidden state&lt;/b&gt;라는 것을 거쳐 '주어'라는 것을 미리 알고 있다고 가정합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;그러면 'I' 다음 &lt;b&gt;'work'&lt;/b&gt;를 Input으로 받는데, 이때 &lt;b&gt;hidden state&lt;/b&gt;는 'work' 뿐만 아니라 이전 'I'에 대한 데이터를 이전 hidden state를 통해 받아 &lt;b&gt;'동사'&lt;/b&gt;라고 판단하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;마지막으로 'google'이 들어왔을 때는 'google'과 함께 'I','work','at'에 대한 정보를 함께 &lt;b&gt;조합&lt;/b&gt;하여 'google'이 명사일 확률이 높다고 결론을 내리게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이처럼 &lt;b&gt;RNN&lt;/b&gt;은 Hidden state가 방향을 가진 Edge로 연결되어 순환구조를 이루는 인공신경망의 한 종류를 의미합니다. 그리고 이는 문장과 같은 &lt;b&gt;'Sequence Data'&lt;/b&gt;를 분석하는데 유용하며, Input과 Output의 길이에 제약받지 않고 &lt;b&gt;유연한 구조&lt;/b&gt;를 가질 수 있다는 점이 장점입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;이제 예시는 접어두고 Input은 $x_i$, Output은 $y_i$, hidden state는 $h_2$로 설정하고 구체적으로 구조를 살펴보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;431&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IWyo4/btqEsDkXo4h/qdJ3VTjnFUKkbyCDTFowek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IWyo4/btqEsDkXo4h/qdJ3VTjnFUKkbyCDTFowek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IWyo4/btqEsDkXo4h/qdJ3VTjnFUKkbyCDTFowek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIWyo4%2FbtqEsDkXo4h%2FqdJ3VTjnFUKkbyCDTFowek%2Fimg.png&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;431&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;갑자기 등장한 $W_{xh}$, $W_{hh}$때문에 놀랐셨을텐데, 이것은 우리가 그동안 자주 봐왔던 &lt;b&gt;가중치&lt;/b&gt;입니다. 결국 큰 맥락에서 &lt;b&gt;딥러닝의 일종인 'RNN'&lt;/b&gt;은 이전의 Input 데이터들을 반영하여 현재의 Input 데이터가 무엇인지 판단하는데, 이때 판단의 정확도를 높이기 위해 여타 딥러닝처럼 가중치인 $W$를 &lt;b&gt;최적화&lt;/b&gt;하는 매커니즘을 가지고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;427&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vCngl/btqEp0vaX9k/4Ii99sLJGpzZiVXSXLHK60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vCngl/btqEp0vaX9k/4Ii99sLJGpzZiVXSXLHK60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vCngl/btqEp0vaX9k/4Ii99sLJGpzZiVXSXLHK60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvCngl%2FbtqEp0vaX9k%2F4Ii99sLJGpzZiVXSXLHK60%2Fimg.png&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;427&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;RNN은 이전의 데이터를 반영한다는 것을 $+$를 이용해 수학적으로 표현합니다. 예를 들어 위 그림에서 Input으로 $x_2$가 들어왔을 때 hidden state는 $x_2$ 그리고 이전 hidden state를 통해 $x_1$를 받아 Output을 출력하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이때 각 $x_2$은 가중치 $W_{hh}$가, $x_1$은 가중치 $W_{xh}$가 곱해지고 여기에 &lt;b&gt;Bias term인 'b'&lt;/b&gt;까지 더해져 만들어진 $$W_{hh}*(x_2) + W_{xh}*(x_1) + b$$는&lt;b&gt; 활성 함수(activation function)&lt;/b&gt;인 $tanh$를 거쳐 최종적인 $y_2$를 도출하게 됩니다.&lt;b&gt;( 활성 함수 = 가설함수&lt;/b&gt; $h(x)$ &lt;b&gt;)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이때 $h(x)$의 형태가 우리가 일반적으로 써오던 $Wx + b$가 아닌 $tanh$인 이유가 중요합니다. 만약 위 그림에서 4개의 hidden state에 $tanh$ 대신 $Wx + b$가 들어있다면, $y(x) =h(h(h(h(x))))$인데 이는 $y(x) = c*c*c*c*x$로써 &lt;b&gt;사실상 결과값은 일차함수로 기존과 다를것이 없습니다.&lt;/b&gt; 따라서 딥러닝의 장점을 살려주기 위해서는 &lt;b&gt;활성함수로 &lt;/b&gt;선형 함수가 아닌&lt;b&gt; '비선형함수'를 사용해야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;440&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/trTqF/btqEsEjSP5N/PVh3wkJ7TwtcFe3J0xybwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/trTqF/btqEsEjSP5N/PVh3wkJ7TwtcFe3J0xybwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/trTqF/btqEsEjSP5N/PVh3wkJ7TwtcFe3J0xybwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtrTqF%2FbtqEsEjSP5N%2FPVh3wkJ7TwtcFe3J0xybwK%2Fimg.png&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;440&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이제 각각 도출한 $y$값을 &lt;b&gt;softmax&lt;/b&gt;에 넣으면 각 단어가 어떤 품사에 해당할지를 확률값으로 알려주고 &lt;b&gt;이중 제일 확률이 높은 값이 예측값이 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;502&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9R0NR/btqErMpsawH/D43B8z9YBc6qP3Qxm5KOl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9R0NR/btqErMpsawH/D43B8z9YBc6qP3Qxm5KOl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9R0NR/btqErMpsawH/D43B8z9YBc6qP3Qxm5KOl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9R0NR%2FbtqErMpsawH%2FD43B8z9YBc6qP3Qxm5KOl1%2Fimg.png&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;502&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이제 남은 것은 &lt;b&gt;'최적화(Optimization)'&lt;/b&gt;입니다. 최적화란 &lt;b&gt;예측값과 실제값의 Cost를 줄여나가는 과정&lt;/b&gt;을 의미합니다. 따라서 $W_{hh}$, $W_{xh}$, $b$ 총 세가지를 '&lt;b&gt;Gradient Descent Algorithm'&lt;/b&gt;을 이용하여 최적화하게 되고, 이 과정에서 &lt;b&gt;'Back Propagation'&lt;/b&gt;이 이용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;중요한 점은 위 그림에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$W_{hh}$, $W_{xh}$, $b$가 네 개있는 거처럼 보이지만 실제로는 12개의 값이 아닌 3개의 변수라는 점입니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Back Propagation에 대한 개념은 아래 포스팅에 자세히 설명되어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/19&quot;&gt;https://box-world.tistory.com/19&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590561563119&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝] Back Propagation(역전파) 정복하기&quot; data-og-description=&quot;시작하며 오늘은 머신러닝에서 가장 큰 고비 중 하나인 ' Back Propagation(역전파) 알고리즘' 에 대해 공부해보겠습니다. 알고리즘을 이해하기 어려울 수도 있고, 복잡한 수식이 나와 거부감이 드실 &quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/19&quot; data-og-url=&quot;https://box-world.tistory.com/19&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c3rRZk/hyGclV50gM/T0BNgNYO8VhgOGrhKksmqk/img.png?width=615&amp;amp;height=414&amp;amp;face=0_0_615_414,https://scrap.kakaocdn.net/dn/bnQ49d/hyGcwXDnWN/x3PNkVSF0ulE8hreAXvErk/img.png?width=615&amp;amp;height=414&amp;amp;face=0_0_615_414,https://scrap.kakaocdn.net/dn/c4Sn5C/hyGcmgoWzx/xOTPR2nKuLKjQUWeRlw3f0/img.png?width=717&amp;amp;height=506&amp;amp;face=0_0_717_506&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/19&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c3rRZk/hyGclV50gM/T0BNgNYO8VhgOGrhKksmqk/img.png?width=615&amp;amp;height=414&amp;amp;face=0_0_615_414,https://scrap.kakaocdn.net/dn/bnQ49d/hyGcwXDnWN/x3PNkVSF0ulE8hreAXvErk/img.png?width=615&amp;amp;height=414&amp;amp;face=0_0_615_414,https://scrap.kakaocdn.net/dn/c4Sn5C/hyGcmgoWzx/xOTPR2nKuLKjQUWeRlw3f0/img.png?width=717&amp;amp;height=506&amp;amp;face=0_0_717_506');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝] Back Propagation(역전파) 정복하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 오늘은 머신러닝에서 가장 큰 고비 중 하나인 ' Back Propagation(역전파) 알고리즘' 에 대해 공부해보겠습니다. 알고리즘을 이해하기 어려울 수도 있고, 복잡한 수식이 나와 거부감이 드실&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>AI</category>
      <category>cost</category>
      <category>LSTM</category>
      <category>nlp</category>
      <category>rnn</category>
      <category>경사 하강 알고리즘</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>인공지능</category>
      <category>자연어</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/39</guid>
      <comments>https://box-world.tistory.com/39#entry39comment</comments>
      <pubDate>Wed, 27 May 2020 11:45:36 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] CNN(Convolutional Neural Network)란?</title>
      <link>https://box-world.tistory.com/38</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;당신이 두려워하는 일을 매일 하라&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 엘리너 루즈벨트 -&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;시작하며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;10년 후에 우리의 삶을 송두리째 바꿀 단 하나의 기술을 꼽으라 하면 저는 &lt;b&gt;'자율주행'&lt;/b&gt;이라고 답할 것입니다. 현재 IT 산업 전반적으로 자율주행 자동차 상용화를 위해 천문학적인 금액을 투자중입니다. 그리고 이러한 자율주행 기술 구현을 위해 핵심이 되는 기술이 바로 &lt;b&gt;'컴퓨터 비전(Computer vision)'&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; 이번 포스팅에서는 이러한 컴퓨터 비전 분야에서 이미지 분석을 위해 가장 보편적으로 사용되는 &lt;b&gt;'CNN(Convolutional Neural Network)'&lt;/b&gt;에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 포스팅은 아래 포스팅을 통해 &lt;b&gt;딥러닝(Deep Learning)&lt;/b&gt;을 이해하고 공부하시면 더욱 효과적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/17&quot;&gt;https://box-world.tistory.com/17&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590388910617&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝] 딥러닝의 시작 Neural Network 정복하기 1&quot; data-og-description=&quot;시작하며 우리는 저번 포스팅에서 Overfitting을 다루며 배웠던 'non-linear classification' 에서, feature가 두개일 때 위와 같이 Decision Boundary를 표현해보았습니다.. Overfitting https://box-world.tist..&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/17&quot; data-og-url=&quot;https://box-world.tistory.com/17&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bfhUZ6/hyF98jsf29/PcjWnlX2Svc6eeNkf7Cdo1/img.png?width=231&amp;amp;height=174&amp;amp;face=0_0_231_174,https://scrap.kakaocdn.net/dn/eWSVk/hyGbm8duhc/BaCdKu087B1wae68B1pK41/img.png?width=231&amp;amp;height=174&amp;amp;face=0_0_231_174,https://scrap.kakaocdn.net/dn/bY3Ky1/hyGbtGgGcv/ZwOG3lGpuxu6QZdpWnW8k1/img.png?width=553&amp;amp;height=663&amp;amp;face=0_0_553_663&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/17&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/17&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bfhUZ6/hyF98jsf29/PcjWnlX2Svc6eeNkf7Cdo1/img.png?width=231&amp;amp;height=174&amp;amp;face=0_0_231_174,https://scrap.kakaocdn.net/dn/eWSVk/hyGbm8duhc/BaCdKu087B1wae68B1pK41/img.png?width=231&amp;amp;height=174&amp;amp;face=0_0_231_174,https://scrap.kakaocdn.net/dn/bY3Ky1/hyGbtGgGcv/ZwOG3lGpuxu6QZdpWnW8k1/img.png?width=553&amp;amp;height=663&amp;amp;face=0_0_553_663');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝] 딥러닝의 시작 Neural Network 정복하기 1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 우리는 저번 포스팅에서 Overfitting을 다루며 배웠던 'non-linear classification' 에서, feature가 두개일 때 위와 같이 Decision Boundary를 표현해보았습니다.. Overfitting https://box-world.tist..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;CNN : 등장 배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;b&gt;CNN&lt;/b&gt;이란 이미지 분석을 위해 사용되는 가장 유명한 딥러닝 알고리즘 중 하나이며, 핵심은 바로 &lt;b&gt;이미지의 패턴(pattern)&lt;/b&gt;을 분석하는 것입니다. &lt;span style=&quot;color: #333333;&quot;&gt;그 이유는 CNN의 시초를 이해하면 알 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAIdFZ/btqEnhctqr4/X6RtpEPW8w7n1I4ikXyK51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAIdFZ/btqEnhctqr4/X6RtpEPW8w7n1I4ikXyK51/img.png&quot; data-alt=&quot;CNN 의 시초가 된 고양이 실험&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAIdFZ/btqEnhctqr4/X6RtpEPW8w7n1I4ikXyK51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAIdFZ%2FbtqEnhctqr4%2FX6RtpEPW8w7n1I4ikXyK51%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;CNN 의 시초가 된 고양이 실험&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;1959년, 고양이가 어떻게 이미지를 인식하는지 알아보기 위해 한 실험을 진행하였습니다.&lt;span&gt; 보통 사람이&lt;/span&gt; 이미지를 볼 때는 각 뉴런들이 각 이미지의 서로 다른 부분적인 조각을 담당합니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;즉 하나의 이미지를 인지한다는 건 여러 개의 입력이 각 뉴런에 들어옴으로써 이루어진다고 할 수 있고,&lt;span&gt;&amp;nbsp;&lt;/span&gt;이것이 &lt;span&gt;CNN&lt;/span&gt;의 기본 아이디어입니다&lt;span&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2&gt;CNN : 작동 원리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 본격적으로 CNN의 작동 원리에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;654&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BFyyu/btqEoTu1ZXW/KzmCwRlvvoFIntmmtmypJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BFyyu/btqEoTu1ZXW/KzmCwRlvvoFIntmmtmypJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BFyyu/btqEoTu1ZXW/KzmCwRlvvoFIntmmtmypJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBFyyu%2FbtqEoTu1ZXW%2FKzmCwRlvvoFIntmmtmypJ1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;654&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 &lt;b&gt;2개의 Convolutional Layer로 이루어진 'Neural&lt;/b&gt;&lt;span&gt;&lt;b&gt; Network'&lt;/b&gt;가 있습니다. &lt;b&gt;Hidden Layer&lt;/b&gt;라고도 부르는 이 두개의 Convolutional Layer가 바로 CNN Neural Network의 핵심이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;Convolutional Layer가 바로 CNN 이미지 분석의 핵심인 &lt;b&gt;'패턴 분석'&lt;/b&gt;을 담당합니다. 그리고 이러한 패턴 분석을 위해 쓰이는 도구가 &lt;b&gt;'Filter'&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/23sXf/btqEnHvg4zr/PnbWhMHua3i0kV1Yq6Eoa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/23sXf/btqEnHvg4zr/PnbWhMHua3i0kV1Yq6Eoa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/23sXf/btqEnHvg4zr/PnbWhMHua3i0kV1Yq6Eoa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F23sXf%2FbtqEnHvg4zr%2FPnbWhMHua3i0kV1Yq6Eoa1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;여기 이미지를 보면 언덕,&lt;span&gt;&amp;nbsp;&lt;/span&gt;모양, 텍스쳐 등 &lt;b&gt;이미지를 구성하는 다양한 '오브젝트(object)'&lt;/b&gt;들이 있습니다. 이때 &lt;b&gt;'Filter'가 발견 하는 패턴&lt;/b&gt;은 Object를 구성하는 &lt;i&gt;Edge, Corner, Circle&lt;/i&gt; 등이 될 수 있습니다. 자세한 작동원리는 조금 있다 설명드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이때&amp;nbsp;&lt;b&gt;Neural Network가 깊어질수록&lt;/b&gt; Input으로 들어간 이미지는 더 많은 Convolutional Layer를 거치게 되면서, &lt;b&gt;Filter가 발견하는 패턴은 더욱 구체화됩니다.&lt;/b&gt; 즉 첫 Layer에서 Filter가 발견한 패턴이 Edge, Corner, Circle 등이었다면 이것이 점점 깊어질수록 &lt;i&gt;눈, 귀, 머리카락, 새들의 털, 부리&lt;/i&gt; 등 훨씬 구체적인 패턴을 발견할 수 있는 것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;CNN : Filter의 역할&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그러면 이제부터 Convolutinal Layer(Conv Layer)와 Filter가 네트워크안에서 어떤식으로 작동하는지 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;650&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brxYet/btqEpZVBQ9C/f9kYh3teTlZhtGEkYDxUu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brxYet/btqEpZVBQ9C/f9kYh3teTlZhtGEkYDxUu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brxYet/btqEpZVBQ9C/f9kYh3teTlZhtGEkYDxUu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrxYet%2FbtqEpZVBQ9C%2Ff9kYh3teTlZhtGEkYDxUu1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;650&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 Input Layer의 각 Unit에 &lt;b&gt;사람이 손으로 쓴 숫자 이미지&lt;/b&gt;를 넣어보겠습니다. 이렇게 Input Layer로 받아들인 이미지는 &lt;b&gt;다음 Conv Layer에 전달됩니다.&lt;/b&gt; 이때 각 Conv Layer에는 &lt;b&gt;Filter&lt;/b&gt;가 존재하게 되고, Filter의 개수는 &lt;b&gt;여러 개&lt;/b&gt;일 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;b&gt;Filter&lt;/b&gt;란 Input 이미지보다 훨씬 작은 행렬로써 사용자가 몇 개의 &lt;span&gt;row&lt;/span&gt;와 &lt;span&gt;column&lt;/span&gt;을 가질지 정할 수 있고, 그 안의 숫자값들은 &lt;span&gt;random&lt;/span&gt;으로 초기화되어 있습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;예를 들어 위 그림처럼 &lt;span&gt;3x3 Filter&lt;/span&gt;가 있다고 할 때, 이것은 I&lt;span&gt;nput&lt;/span&gt;으로 들어온 이미지를 &lt;span&gt;3x3 단위로&lt;/span&gt; 차례대로 돌아다니게 되며 이것을 &lt;b&gt;'C&lt;span&gt;onvolving'&lt;/span&gt;&lt;/b&gt;이라고 부릅니다&lt;span&gt;.&lt;/span&gt;&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/dRnF1a/btqEnIns6iJ/evfSKX0QEX9O22WDsJ1jK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRnF1a/btqEnIns6iJ/evfSKX0QEX9O22WDsJ1jK0/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;650&quot; height=&quot;NaN&quot; style=&quot;width: 51.8671%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRnF1a/btqEnIns6iJ/evfSKX0QEX9O22WDsJ1jK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRnF1a%2FbtqEnIns6iJ%2FevfSKX0QEX9O22WDsJ1jK0%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfrbfp/btqEm3liQSa/mwFHbgUy0KYri4LfvVENy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfrbfp/btqEm3liQSa/mwFHbgUy0KYri4LfvVENy1/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;649&quot; height=&quot;NaN&quot; style=&quot;width: 46.9701%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfrbfp/btqEm3liQSa/mwFHbgUy0KYri4LfvVENy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcfrbfp%2FbtqEm3liQSa%2FmwFHbgUy0KYri4LfvVENy1%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;예를 들어 왼쪽 그림처럼 Input으로 받은 이미지가 있을 때, &lt;/span&gt;이미지를 구성하는 행렬안의 숫자들은 이미지를 구성하는 &lt;b&gt;픽셀(Pixel)&lt;/b&gt;을 뜻합니다&lt;span&gt;. 그리고 오른쪽 그림에서 보이는 3x3 행렬이 우리가 사용할 Filter이고, 우선 갯수는 하나로 설정하겠습니다.&lt;/span&gt;&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/dutJV4/btqEoBaj2Us/6GeuQTp2ywG55pG19mRkL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dutJV4/btqEoBaj2Us/6GeuQTp2ywG55pG19mRkL1/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;649&quot; height=&quot;NaN&quot; style=&quot;width: 50.3758%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dutJV4/btqEoBaj2Us/6GeuQTp2ywG55pG19mRkL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdutJV4%2FbtqEoBaj2Us%2F6GeuQTp2ywG55pG19mRkL1%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oQQ8u/btqEn8e6VFQ/WZkwYSbHEic0BUvCzyUyq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oQQ8u/btqEn8e6VFQ/WZkwYSbHEic0BUvCzyUyq1/img.png&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;602&quot; data-filename=&quot;blob&quot; width=&quot;648&quot; height=&quot;NaN&quot; style=&quot;width: 48.4614%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oQQ8u/btqEn8e6VFQ/WZkwYSbHEic0BUvCzyUyq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoQQ8u%2FbtqEn8e6VFQ%2FWZkwYSbHEic0BUvCzyUyq1%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;1028&quot; height=&quot;602&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;그러면 맨 처음 이미지에&amp;nbsp;&lt;span&gt;3x3 Filter&lt;/span&gt;를 갖다댔을 떄 나온 &lt;b&gt;특정 값&lt;span&gt;(Dot)&lt;/span&gt;&lt;/b&gt;을 오른쪽 행렬 내 하나의 Element로 저장 합니다. 이때 이 픽셀이 &lt;b&gt;흑백일 경우&lt;/b&gt;, Dot은&amp;nbsp;&lt;b&gt;&lt;span&gt;2&lt;/span&gt;차원&lt;/b&gt;이지만,&lt;b&gt; 컬러일 경우&lt;/b&gt;는 &lt;span&gt;RGB&lt;/span&gt;가 고려되기 때문에 &lt;b&gt;&lt;span&gt;3&lt;/span&gt;차원&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;그 다음 Filter는 오른쪽 그림과 같이 한칸 단위로 반복적으로 이동하면서 Dot을 뽑아냅니다. 이렇게 우리가 지정한 Filter가 Input 이미지의 전 영역을 Convolving한 후 나타난 결과가 오른쪽 이미지인 것입니다. &lt;span&gt;즉 이것은 첫 Conv Layer가 Input layer에서 받은 이미지를 통해 출력한 Output으로 다음 Conv layer의 Input으로 넘어가게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;392&quot; width=&quot;650&quot; height=&quot;NaN&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu3sFi/btqEoBIdoKa/m2YD2waxkXuBgBrhj3hGt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu3sFi/btqEoBIdoKa/m2YD2waxkXuBgBrhj3hGt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu3sFi/btqEoBIdoKa/m2YD2waxkXuBgBrhj3hGt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu3sFi%2FbtqEoBIdoKa%2Fm2YD2waxkXuBgBrhj3hGt1%2Fimg.png&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;392&quot; width=&quot;650&quot; height=&quot;NaN&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;보통 Filter에서 나오는&amp;nbsp;&lt;b&gt;특정 값(Dot)&lt;/b&gt;은 Input 이미지의 3x3 행렬을 $Wx + b(=&lt;span&gt;&amp;theta;x + b&lt;/span&gt;)$에 대입하여 도출됩니다. 이때 &lt;span style=&quot;color: #333333;&quot;&gt;$Wx + b$을&lt;/span&gt;&amp;nbsp;&lt;b&gt;&lt;span&gt;Relu &lt;/span&gt;함수&lt;/b&gt;에 넣어줄 수도 있습니다&lt;span&gt;. (참고로 딥러닝에서는 $&lt;span style=&quot;color: #333333;&quot;&gt;&amp;theta;x + b&lt;/span&gt;$보단 &lt;span style=&quot;color: #333333;&quot;&gt;$Wx + b$이라고 일반적으로 표현합니다.&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;501&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6xsqm/btqEoTPqZYh/324WwoyFY1w2h1HRVo0abk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6xsqm/btqEoTPqZYh/324WwoyFY1w2h1HRVo0abk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6xsqm/btqEoTPqZYh/324WwoyFY1w2h1HRVo0abk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6xsqm%2FbtqEoTPqZYh%2F324WwoyFY1w2h1HRVo0abk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;501&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;b&gt;Relu &lt;/b&gt;&lt;/span&gt;&lt;b&gt;함수&lt;/b&gt;에 대해서 간단하게 설명드리자면, 우리가 Logistic Regression에서 사용하는 &lt;span&gt;sigmoid &lt;/span&gt;함수를 생각해보면 중간의 기울기는 &lt;span&gt;0&lt;/span&gt;보다 매우 크지만 &lt;b&gt;양옆으로 갈수록 &lt;span&gt;0&lt;/span&gt;에 가까워지는걸 알 수 있습니다&lt;/b&gt;&lt;span&gt;&lt;b&gt;.&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;이렇게 양 옆으로 갈수록 0에 가까워지는 특성은&lt;/span&gt; 네트워크가 깊어질수록 G&lt;span&gt;radient&lt;/span&gt;가 &lt;span&gt;0&lt;/span&gt;에 가까워져 데이터가 소멸이나 손실이 되어 우리가 원하는 학습을 못하는 결과가 일어납니다&lt;span&gt;. 따라서&lt;/span&gt;&amp;nbsp;&lt;span&gt;Relu &lt;/span&gt;함수를 통해 이러한 데이터의 손실을 막을 수 있습니다.&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/b4irIc/btqEm2s8nDq/rNkfW5H491ALZ4BVQ2T1k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4irIc/btqEm2s8nDq/rNkfW5H491ALZ4BVQ2T1k0/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;649&quot; height=&quot;NaN&quot; style=&quot;width: 48.1783%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4irIc/btqEm2s8nDq/rNkfW5H491ALZ4BVQ2T1k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4irIc%2FbtqEm2s8nDq%2FrNkfW5H491ALZ4BVQ2T1k0%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuMaJP/btqEpIT7G5d/4TaiuHLS8GTya09A74qFjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuMaJP/btqEpIT7G5d/4TaiuHLS8GTya09A74qFjk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 50.6589%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuMaJP/btqEpIT7G5d/4TaiuHLS8GTya09A74qFjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuMaJP%2FbtqEpIT7G5d%2F4TaiuHLS8GTya09A74qFjk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;왼쪽 그림처럼 7x7 이미지에 하나의 Filter를 Stride를 1로 설정하여 이미지 전체를 Convolving했을 경우, output 사이즈는 5x5가 됩니다. 이때 &lt;b&gt;Stride&lt;/b&gt;란 Filter를 한번 움직였을 때 이동하는 칸(Pixel)을 의미합니다. 오른쪽 그림에서는 Input 이미지와 Stride에 따른 Output Size의 크기를 공식으로 표현한 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T4Koe/btqEm1Ov4fu/ZluQMLTemeQUQEypjgDGC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T4Koe/btqEm1Ov4fu/ZluQMLTemeQUQEypjgDGC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T4Koe/btqEm1Ov4fu/ZluQMLTemeQUQEypjgDGC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT4Koe%2FbtqEm1Ov4fu%2FZluQMLTemeQUQEypjgDGC0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;근데 Filter를 Convolving할 때, Stride가 커질수록 Output Size가 작아지게 됩니다. &lt;/span&gt;&lt;b&gt;즉 정보가 손실된다는 뜻 입니다&lt;span&gt;. &lt;/span&gt;&lt;/b&gt;그래서 이러한 정보의 손실을 막기 위해 사용되는 것이 &lt;b&gt;패딩(Padding)&lt;/b&gt;입니다&lt;span&gt;. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;b&gt;'Padding'은 위 그림처럼 이미지를 &lt;span&gt;0&lt;/span&gt;으로 둘러싸줍니다&lt;/b&gt;&lt;span&gt;&lt;b&gt;.&lt;/b&gt; &lt;/span&gt;이렇게 하면 이미지가 지나치게 작아지는걸 막을 수 있고, 혹은 가장자리가 &lt;span&gt;0&lt;/span&gt;임을 이용하여 모서리라는 것을 알려줄 수도 잇습니다&lt;span&gt;. 또한 Padding을 적용하면 Output Size가 줄어들지 않고, &lt;b&gt;Input Size와 동일하게 유지됩니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FwZo6/btqEn8e7iT0/aCP8nlB33QK5VsPxyOnAV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FwZo6/btqEn8e7iT0/aCP8nlB33QK5VsPxyOnAV1/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&quot; style=&quot;width: 34.1657%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FwZo6/btqEn8e7iT0/aCP8nlB33QK5VsPxyOnAV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFwZo6%2FbtqEn8e7iT0%2FaCP8nlB33QK5VsPxyOnAV1%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2uX9o/btqEn78mTLM/GomNo5k2aKo3MbwxXXgbIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2uX9o/btqEn78mTLM/GomNo5k2aKo3MbwxXXgbIk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;654&quot; height=&quot;NaN&quot; style=&quot;width: 33.2556%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2uX9o/btqEn78mTLM/GomNo5k2aKo3MbwxXXgbIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2uX9o%2FbtqEn78mTLM%2FGomNo5k2aKo3MbwxXXgbIk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vPCqF/btqEoAiaU6B/vr0yj7iTn1HGZwUn6vBjAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vPCqF/btqEoAiaU6B/vr0yj7iTn1HGZwUn6vBjAk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 30.2531%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vPCqF/btqEoAiaU6B/vr0yj7iTn1HGZwUn6vBjAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvPCqF%2FbtqEoAiaU6B%2Fvr0yj7iTn1HGZwUn6vBjAk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이제&lt;span&gt; Conv Layer&lt;/span&gt;를 어떻게 만드는지 알아보겠습니다.&lt;span&gt; 오른쪽 그림같이&lt;/span&gt;&amp;nbsp;하나의 Filter를 거쳐 나온 &lt;span&gt;output&lt;/span&gt;을 &lt;span&gt;&lt;b&gt;activation map&lt;/b&gt;이라고 합니다. 이떄 Filter가 여러개 있으면 중앙 이미지와 같이 activation map도 여러개가 있을 것이고 오른쪽 그림같이 이를 합치면 &lt;b&gt;하나의 Conv Layer&lt;/b&gt;를 만들 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;420&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6aIIS/btqEm3MqkLw/g7uOx243qspqGEIWSCZVyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6aIIS/btqEm3MqkLw/g7uOx243qspqGEIWSCZVyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6aIIS/btqEm3MqkLw/g7uOx243qspqGEIWSCZVyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6aIIS%2FbtqEm3MqkLw%2Fg7uOx243qspqGEIWSCZVyk%2Fimg.png&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;420&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;또 하나의 개념인 &lt;b&gt;Pooling&lt;/b&gt;에 대해서 살펴보겠습니다. &lt;/span&gt;여기 &lt;span&gt;4x4&lt;/span&gt;의 이미지를&amp;nbsp;&lt;span&gt;2x2 filter를 이용하여&lt;/span&gt;&amp;nbsp;&lt;span&gt;stride 2&lt;/span&gt;로 C&lt;span&gt;onvoving &lt;/span&gt;했을때 색깔별로 영역을 나눌 수 있는데 &lt;span&gt;Pooling&lt;/span&gt;은 저 색깔로 구분된 &lt;b&gt;각 영역에서 특정값 하나를 그대로 뽑아 오는 것입니다&lt;span&gt;. &lt;/span&gt;&lt;/b&gt;가장 흔하게 쓰이는 것은 &lt;span&gt;Max Pooling&lt;/span&gt;으로서 최대값을 뽑아오는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;653&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mC8mf/btqEm3ljIRh/53ugRlizLJieHZPEJ7yGvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mC8mf/btqEm3ljIRh/53ugRlizLJieHZPEJ7yGvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mC8mf/btqEm3ljIRh/53ugRlizLJieHZPEJ7yGvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmC8mf%2FbtqEm3ljIRh%2F53ugRlizLJieHZPEJ7yGvk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;653&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;만약 하나의 Layer에 Filter가 여러 개라면 이런식으로 하나하나씩 &lt;span&gt;Pooling &lt;/span&gt;한다음 합치면 됩니다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;b&gt;Pooling&lt;/b&gt;&lt;/span&gt;&lt;b&gt;의 목적은 &lt;span&gt;overfitting&lt;/span&gt;을 막기 위함입니다&lt;/b&gt;&lt;span&gt;&lt;b&gt;.&lt;/b&gt; 하나의 Pixel은 하나의 Feature에 해당합니다.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;예를 들어 &lt;span&gt;96x96&lt;/span&gt;짜리 &lt;span&gt;image&lt;/span&gt;에 &lt;span&gt;8X8 400&lt;/span&gt;개의 &lt;span&gt;filter&lt;/span&gt;를 넣는다고 하면 한 필터당 &lt;span&gt;7921&lt;/span&gt;개의 &lt;span&gt;feature&lt;/span&gt;를 가지는 &lt;span&gt;output&lt;/span&gt;이 나오는데, 이런 것이 무려&amp;nbsp;&lt;span&gt;400&lt;/span&gt;개가 있는것입니다&lt;span&gt;. 따라서 너무 많은 Feature로 발생할 수 있는 Overfitting을 방지하고자 Pooling을 사용하는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;지금까지 우리가 본것은 하나의 Layer에서 Filter가 어떤 역할을 하는지 보여드린 것이고,&lt;span&gt; 이제 Filter가 Conv Layer를 통과하면서 어떻게 패턴을 분석하는가에 대해 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buocaU/btqEmKTOqG3/srPR04wOnmh8JDWn4Qt3yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buocaU/btqEmKTOqG3/srPR04wOnmh8JDWn4Qt3yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buocaU/btqEmKTOqG3/srPR04wOnmh8JDWn4Qt3yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuocaU%2FbtqEmKTOqG3%2FsrPR04wOnmh8JDWn4Qt3yk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;우선 사람이 손으로 쓴 숫자 7을 나타내는 이미지가 있고, 3x3 Filter 4개가 있습니다. 즉 기존 예시들과 다르게 &lt;b&gt;Filter가 여러개라는 것을 유의하셔야 합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;이 Filter안의 값에서 -1은 검은색, 1은 하얀색, 0은 회색을 뜻합니다. 그리고 아래 보이는 &lt;b&gt;4개의 이미지가 각 Filter를 Convoving한 Output입니다.&lt;/b&gt; 각 Filter가 발견한 패턴은 두가지로 구분할 수 있습니다. &lt;b&gt;첫번째&lt;/b&gt;는 4가지 Filter가 공통적으로 발견한 이미지의 가장자리 즉 Edge입니다. 그리고 &lt;b&gt;두번째&lt;/b&gt;가 밝게 보이는 하얀색 부분입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;b&gt;7을 3차원으로 바라보았을 때,&lt;/b&gt; 첫번째 Output의 경우 위에서 바라봤을 때 보이는 패턴을 &lt;span&gt;/ &lt;/span&gt;두번째는 왼쪽에서 &lt;span&gt;/ &lt;/span&gt;세번째는 아래에서 &lt;span&gt;/ &lt;/span&gt;네 번째는 오른쪽을 인식하고 있습니다&lt;span&gt;. &lt;/span&gt;이해하기 어렵다면 각 방향에서 손전등을 비췄다고 생각하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이것은 하나의 Conv Layer를 통과시켰을 때의 결과이고, 더 많은 Layer를 통과시킬수록 구체적인 패턴을 발견할 수 있습니다.&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/blm1tW/btqEmLLZdlW/vuMkDJw84HpbdPz7hFIAY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blm1tW/btqEmLLZdlW/vuMkDJw84HpbdPz7hFIAY0/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 50.9004%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blm1tW/btqEmLLZdlW/vuMkDJw84HpbdPz7hFIAY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fblm1tW%2FbtqEmLLZdlW%2FvuMkDJw84HpbdPz7hFIAY0%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chdgqz/btqEmKM4k4p/gHq14K0lmz9eamwIcaTPJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chdgqz/btqEmKM4k4p/gHq14K0lmz9eamwIcaTPJk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 47.9368%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chdgqz/btqEmKM4k4p/gHq14K0lmz9eamwIcaTPJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fchdgqz%2FbtqEmKM4k4p%2FgHq14K0lmz9eamwIcaTPJk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;예를 들어 위에서 여섯번째 3x3 Output은 원을 발견하였고, 마지막 Ouput은 &lt;span&gt;corner&lt;/span&gt;를 발견하였고, &lt;/span&gt;&lt;span&gt;이것보다 더 우리가 레이어를 통과시키면 동물 개와 같이 훨씬더 복잡한 모양의 패턴도 알아낼 수 있습니다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&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/Zez8M/btqEoACua0A/LBeVX3rvXCUYrBDqYpYJa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zez8M/btqEoACua0A/LBeVX3rvXCUYrBDqYpYJa0/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;649&quot; height=&quot;NaN&quot; style=&quot;width: 50.0188%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zez8M/btqEoACua0A/LBeVX3rvXCUYrBDqYpYJa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZez8M%2FbtqEoACua0A%2FLBeVX3rvXCUYrBDqYpYJa0%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D47qE/btqEoBH9MZ0/kQWnkIwIbAxHxYln3HqCKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D47qE/btqEoBH9MZ0/kQWnkIwIbAxHxYln3HqCKk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;750&quot; height=&quot;NaN&quot; style=&quot;width: 48.8184%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D47qE/btqEoBH9MZ0/kQWnkIwIbAxHxYln3HqCKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD47qE%2FbtqEoBH9MZ0%2FkQWnkIwIbAxHxYln3HqCKk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;이제 또 다른 예시를 보면서 최종적으로 CNN을 정리해보겠습니다. 우선 Layer는 패턴을 분석하기 위한 &lt;b&gt;Conv Layer&lt;/b&gt;, 데이터 손실을 방지하기 위한 &lt;b&gt;Relu Layer&lt;/b&gt;, overfitting을 방지하는 &lt;b&gt;Pooling Layer&lt;/b&gt; 등을 이용하여 네트워크를 구성합니다. 그리고 마지막에 FC Layer라는 것을 이용하여 최종적으로 Input 이미지가 무엇인지 &lt;b&gt;분류(Classification)&lt;/b&gt;를 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>CNN</category>
      <category>cost</category>
      <category>coursera</category>
      <category>경사 하강 알고리즘</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>인공지능</category>
      <category>인하대</category>
      <category>지도 학습</category>
      <category>코세라</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/38</guid>
      <comments>https://box-world.tistory.com/38#entry38comment</comments>
      <pubDate>Mon, 25 May 2020 16:49:44 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 다변량 정규분포(Multivariate Gaussian Distribution) in 이상 탐지(Anomaly Detection)</title>
      <link>https://box-world.tistory.com/37</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;혁신을 할 때는 모든 사람들이 당신을 미쳤다고 할 테니,&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;그들 말에 준비가 되어 있어야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 래리 앨리슨 (Oracle ceo) -&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;시작하며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리는 저번 포스팅을 통해 Anomaly Detection의 전반적인 이해를 마쳤습니다. 이번 포스팅에서는 Anomaly Detection에서 발생할 수 있는 문제를 살펴보며, 이에 대한 해결책인 &lt;b&gt;다변량 정규분포(Multivariate Gaussian Distribution)&lt;/b&gt;에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 포스팅은 아래 포스팅들을 통해 &lt;b&gt;Anomaly Detection&lt;/b&gt;을 이해하고 보시면 더욱 효과적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/35&quot;&gt;https://box-world.tistory.com/35&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590298827403&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] 이상 탐지(Anomaly Detection)이란?&quot; data-og-description=&quot;&amp;quot;기술에는 품위와 친절이 녹아있어야 한다.&amp;quot; - 팀 쿡 - 시작하며 여기 암을 조기에 발견할 수 있는 인공지능을 만드는 개발자가 있습니다. 그 개발자는 우여곡절끝에 정확도 99.00%를 자랑하는 머��&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/35&quot; data-og-url=&quot;https://box-world.tistory.com/35&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/YnqWH/hyF96LybRB/KSTshu4bjBDGE5j3pJp7PK/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/dohSEr/hyF93OOFzV/S9xpkJPHkWCkwiAYn7AoIk/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/bX96ia/hyF9Xui5ur/RMOXDoVoFXTyvzrGNwtKVk/img.png?width=683&amp;amp;height=395&amp;amp;face=0_0_683_395&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/35&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/35&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/YnqWH/hyF96LybRB/KSTshu4bjBDGE5j3pJp7PK/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/dohSEr/hyF93OOFzV/S9xpkJPHkWCkwiAYn7AoIk/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/bX96ia/hyF9Xui5ur/RMOXDoVoFXTyvzrGNwtKVk/img.png?width=683&amp;amp;height=395&amp;amp;face=0_0_683_395');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] 이상 탐지(Anomaly Detection)이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&quot;기술에는 품위와 친절이 녹아있어야 한다.&quot; - 팀 쿡 - 시작하며 여기 암을 조기에 발견할 수 있는 인공지능을 만드는 개발자가 있습니다. 그 개발자는 우여곡절끝에 정확도 99.00%를 자랑하는 머��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/36&quot;&gt;https://box-world.tistory.com/36&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590298829025&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] 이상 탐지(Anomaly Detection) vs Classification in Supervised Learning&quot; data-og-description=&quot;실패에 대해 걱정하지 마라. 한번만 제대로 하면 된다. - 드류 휴스턴(Dropbox 공동 창업자) 시작하며 우리는 저번 포스팅에서 Anomaly Detection이란 무엇이며,이를 위한 알고리즘의 작동 원리까지 공��&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/36&quot; data-og-url=&quot;https://box-world.tistory.com/36&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cDXGVF/hyF9Y7Re3b/IVG1pyQDLdp8Agf8I7LhZ1/img.png?width=683&amp;amp;height=369&amp;amp;face=0_0_683_369,https://scrap.kakaocdn.net/dn/Zww1c/hyF93OR29v/zq5zbZsnZTEpXoUsJ7uuw0/img.png?width=683&amp;amp;height=369&amp;amp;face=0_0_683_369,https://scrap.kakaocdn.net/dn/Vorxm/hyGablQaT0/N0nvUK0KV2Qe5aKyN0as3K/img.png?width=614&amp;amp;height=446&amp;amp;face=0_0_614_446&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/36&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cDXGVF/hyF9Y7Re3b/IVG1pyQDLdp8Agf8I7LhZ1/img.png?width=683&amp;amp;height=369&amp;amp;face=0_0_683_369,https://scrap.kakaocdn.net/dn/Zww1c/hyF93OR29v/zq5zbZsnZTEpXoUsJ7uuw0/img.png?width=683&amp;amp;height=369&amp;amp;face=0_0_683_369,https://scrap.kakaocdn.net/dn/Vorxm/hyGablQaT0/N0nvUK0KV2Qe5aKyN0as3K/img.png?width=614&amp;amp;height=446&amp;amp;face=0_0_614_446');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] 이상 탐지(Anomaly Detection) vs Classification in Supervised Learning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;실패에 대해 걱정하지 마라. 한번만 제대로 하면 된다. - 드류 휴스턴(Dropbox 공동 창업자) 시작하며 우리는 저번 포스팅에서 Anomaly Detection이란 무엇이며,이를 위한 알고리즘의 작동 원리까지 공��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;Multivariate Gaussian Distribution&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;286&quot; data-filename=&quot;blob&quot; width=&quot;696&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qJlC7/btqEm26Td7I/EQLZwq8QDDXsaKfhoGodk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qJlC7/btqEm26Td7I/EQLZwq8QDDXsaKfhoGodk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qJlC7/btqEm26Td7I/EQLZwq8QDDXsaKfhoGodk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqJlC7%2FbtqEm26Td7I%2FEQLZwq8QDDXsaKfhoGodk1%2Fimg.png&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;286&quot; data-filename=&quot;blob&quot; width=&quot;696&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위 그림은 &lt;b&gt;CPU 연산량&lt;/b&gt; $(x_1)$에 따라 &lt;b&gt;메모리 사용량&lt;/b&gt; $(x_2)$을 측정하는 Dataset입니다. 여기서 &lt;b&gt;Anomaly Detection&lt;/b&gt;을 사용하고자 각 feature를 &lt;b&gt;일반적인 가우시안 분포(Gaussian Distribution)&lt;/b&gt;으로 나타내자 문제가 발생하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보시다시피 녹색 데이터는 &lt;b&gt;Anomaly Data&lt;/b&gt;임이 분명한데, 이를 일반적인 &lt;b&gt;'2차원 가우시안 분포'&lt;/b&gt;로 나타낼 때는 $&amp;epsilon;$보다 큰 값을 가지게 되어 정상적인 데이터로 분류됩니다. 이를 해결하기 위해 나온 것이 &lt;b&gt;'다변량 정규분포(Multivariate Gaussian Distribution)'&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리가 지금까지 배운 Anomaly Detection 알고리즘은 가장 보편적으로 사용되는 &lt;b&gt;'Original Model'&lt;/b&gt;입니다. 사실 방금 문제를 'Multivariate Gaussian Distribution' 사용없이 '새로운 feature를 추가하여 해결하는 방법'도 있으나, &lt;b&gt;새로운 feature를 사용자가 직접 추가해야한다는 점에서 불편하고 정확도가 떨어지기에&lt;/b&gt; 좀 더 formal한 방법을 사용하여 해결하고자 하는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;460&quot; data-filename=&quot;blob&quot; width=&quot;549&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wc0bB/btqEnH824s1/WZFUeRm6vjWQsjn9EtkCj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wc0bB/btqEnH824s1/WZFUeRm6vjWQsjn9EtkCj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wc0bB/btqEnH824s1/WZFUeRm6vjWQsjn9EtkCj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWc0bB%2FbtqEnH824s1%2FWZFUeRm6vjWQsjn9EtkCj0%2Fimg.png&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;460&quot; data-filename=&quot;blob&quot; width=&quot;549&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;'Multivariate Gaussian Distribution'&lt;/b&gt;은 한마디로 &lt;b&gt;이차원&lt;/b&gt;에서 존재하던 정규분포를 &lt;b&gt;다차원 공간&lt;/b&gt;으로 확장한 것입니다. 문제가 되는 Dataset에서 &lt;b&gt;Anomaly 데이터를 검출하지 못했던 이유&lt;/b&gt;는 '&lt;b&gt;이차원 정규분포'&lt;/b&gt;에서 데이터를 바라보기 때문에 녹색 데이터 그리고 비슷한 위치에 존재하는 빨간색 데이터가 &lt;b&gt;사실상 동일한 위치에 있는걸로 보이기 때문입니다.&lt;/b&gt; 따라서 이를 &lt;b&gt;3차원&lt;/b&gt; 이상으로 확장하여 이를 보완하고자 하는 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;262&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfBWXj/btqEmpPg5Ev/fqom7UxJIBp9Hhdvt1NkZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfBWXj/btqEmpPg5Ev/fqom7UxJIBp9Hhdvt1NkZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfBWXj/btqEmpPg5Ev/fqom7UxJIBp9Hhdvt1NkZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfBWXj%2FbtqEmpPg5Ev%2Ffqom7UxJIBp9Hhdvt1NkZk%2Fimg.png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;262&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;'Multivariate Gaussian Distribution'&lt;/b&gt; 에 사용되는 공식&lt;b&gt;은 위와 같습니다. 여기에는 두가지 parameter가 등장하는데, $&amp;mu;$는 n 개의 feature&lt;/b&gt;를 나타내는 n차원 vector이고, $&amp;Sigma;$는 &lt;b&gt;공분산 행렬(covariance matrix)&lt;/b&gt;로 $n * n$차원 행렬입니다. 그리고 $|&amp;Sigma;|$은 &lt;b&gt;sigma의 절대값&lt;/b&gt;으로 뒤에 나올 sigma 값을 결정합니다. &lt;b&gt;한가지 주의할 점은 각 feature에 대한 가우시안 분포를 구하여 곱하는 구조가 아닌 공식에 parameter를 대입하여 한번에 $p(x)$를 도출합니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;PCA 알고리즘&lt;/b&gt;에서 이용되는 &lt;b&gt;'covariance matrix'는 간단히 말하자면 데이터가 어떻게 퍼져있는가&lt;/b&gt;에 대한 행렬입니다. PCA에서 이것이 이용됐던 이유는 &lt;b&gt;기존 데이터의 분포와 성질을 최대한 변화시키지 않으면서 낮은 차원에 mapping하기 위해서 였습니다.&lt;/b&gt; 따라서 '&lt;b&gt;Multivariate Gaussian Distribution&lt;/b&gt;'&lt;b&gt;에서도 2차원에서 나타나던 데이터의 분포를 최대한 변화시키지 않으면서 이를 다차원으로 확장시키기 위해 공분산 행렬&lt;/b&gt;을 이용하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;PCA 알고리즘&lt;/b&gt;이 궁금하신 분은 아래 포스팅을, &lt;b&gt;공분산 행렬&lt;/b&gt;에 대해 더 궁금하신 분은 아래 두번째 포스팅을 참고해주세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/33&quot;&gt;https://box-world.tistory.com/33&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590298834943&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&quot; data-og-description=&quot;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를..&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/33&quot; data-og-url=&quot;https://box-world.tistory.com/33&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dsmafU/hyF92oX5WG/EYK7OYjHZFNuzoR0MSe3C0/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/fJQC1/hyF98CIZ6f/HPnzjVAcUwNWMD1NQPFZBK/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/bhUOlr/hyF9Xuqy4J/hHkT92dz2QDiWimjs3oIN1/img.png?width=886&amp;amp;height=401&amp;amp;face=0_0_886_401&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/33&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/33&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dsmafU/hyF92oX5WG/EYK7OYjHZFNuzoR0MSe3C0/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/fJQC1/hyF98CIZ6f/HPnzjVAcUwNWMD1NQPFZBK/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/bhUOlr/hyF9Xuqy4J/hHkT92dz2QDiWimjs3oIN1/img.png?width=886&amp;amp;height=401&amp;amp;face=0_0_886_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를..&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://angeloyeo.github.io/2019/07/27/PCA.html&quot;&gt;https://angeloyeo.github.io/2019/07/27/PCA.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590298837145&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;주성분 분석(PCA) - 공돌이의 수학정리노트&quot; data-og-description=&quot;&quot; data-og-host=&quot;angeloyeo.github.io&quot; data-og-source-url=&quot;https://angeloyeo.github.io/2019/07/27/PCA.html&quot; data-og-url=&quot;https://angeloyeo.github.io/2019/07/27/PCA.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://angeloyeo.github.io/2019/07/27/PCA.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://angeloyeo.github.io/2019/07/27/PCA.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;주성분 분석(PCA) - 공돌이의 수학정리노트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;angeloyeo.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;702&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DMMRF/btqEnHOJqLR/VLawXk1yAwksAnYPyepUJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DMMRF/btqEnHOJqLR/VLawXk1yAwksAnYPyepUJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DMMRF/btqEnHOJqLR/VLawXk1yAwksAnYPyepUJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDMMRF%2FbtqEnHOJqLR%2FVLawXk1yAwksAnYPyepUJ1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;702&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 &lt;b&gt;'Multivariate Gaussian Distribution&lt;/b&gt;'을 기하학적으로 이해해보겠습니다. 위 그림은 두 개의 parameter $&amp;mu;$과 $&amp;Sigma;$에 따른 그래프의 변화입니다. $&amp;mu;$가 고정된 상태에서 $&amp;Sigma;$ &lt;b&gt;행렬의 값이 커질수록&lt;/b&gt; 원의 크기가 커지면서 데이터가 퍼지게 됩니다. 반대로 &lt;b&gt;값이 작아질수록&lt;/b&gt; 원의 크기가 작아지면서 데이터가 뭉치게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;701&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rNYhe/btqEmpobGUT/IyfGYhtiD1udz37ClJwaD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rNYhe/btqEmpobGUT/IyfGYhtiD1udz37ClJwaD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rNYhe/btqEmpobGUT/IyfGYhtiD1udz37ClJwaD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrNYhe%2FbtqEmpobGUT%2FIyfGYhtiD1udz37ClJwaD0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;701&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;$&amp;Sigma;$ 행렬에서 1행 1열의 element는 $x_1$의 &lt;b&gt;분산(퍼지는 정도)&lt;/b&gt;를 2행 2열은 $x_2$의 &lt;b&gt;분산&lt;/b&gt;을 결정합니다. 따라서 $x_2$의 분산을 고정시켜놓고 $x_1$&lt;b&gt;의 분산을 줄이면&lt;/b&gt; $x_1$ 관점에서 원이 홀쭉해지고, &lt;b&gt;분산을 늘리면&lt;/b&gt; 원이 뚱뚱해짐을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;703&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUzyZk/btqEmLdcAxY/Pasv0MnLJ2ub0bMpjUjmdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUzyZk/btqEmLdcAxY/Pasv0MnLJ2ub0bMpjUjmdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUzyZk/btqEmLdcAxY/Pasv0MnLJ2ub0bMpjUjmdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUzyZk%2FbtqEmLdcAxY%2FPasv0MnLJ2ub0bMpjUjmdK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;703&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;반대로 $x_1$의 분산을 고정하고 $x_2$의 분산을 변화시켰을 때 그래프의 변화입니다.&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/dzG1lu/btqEoz3LumO/UVxyfMJm4UE5wpVnAk8Ujk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzG1lu/btqEoz3LumO/UVxyfMJm4UE5wpVnAk8Ujk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;706&quot; height=&quot;NaN&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzG1lu/btqEoz3LumO/UVxyfMJm4UE5wpVnAk8Ujk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzG1lu%2FbtqEoz3LumO%2FUVxyfMJm4UE5wpVnAk8Ujk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OjHtN/btqEmKk6oVF/y0qe7MphxfXO5FLKItD1nK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OjHtN/btqEmKk6oVF/y0qe7MphxfXO5FLKItD1nK/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;705&quot; height=&quot;NaN&quot; style=&quot;width: 49.4186%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OjHtN/btqEmKk6oVF/y0qe7MphxfXO5FLKItD1nK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOjHtN%2FbtqEmKk6oVF%2Fy0qe7MphxfXO5FLKItD1nK%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;$&amp;Sigma;$ 행렬에서 1행 2열과 2행 1열의 element는 $x_1$과 $x_2$의 &lt;b&gt;상대적인 위치관계에 대한 분산&lt;/b&gt;을 조절합니다. 즉 &lt;b&gt;분산 값이 커질수록&lt;/b&gt; 데이터가 퍼지게 되니 원은 길게 홀쭉해지게 됩니다. 반대로 &lt;b&gt;분산이 작아질수록&lt;/b&gt; 원은 납작하게 홀쭉해집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;699&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Be5t1/btqEmKFnh6f/o78CVzBFKdt70ZgYmG5DhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Be5t1/btqEmKFnh6f/o78CVzBFKdt70ZgYmG5DhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Be5t1/btqEmKFnh6f/o78CVzBFKdt70ZgYmG5DhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBe5t1%2FbtqEmKFnh6f%2Fo78CVzBFKdt70ZgYmG5DhK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;699&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;$&amp;mu;$는 'Multivariate Gaussian Distribution'의 중심 위치를 결정합니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;701&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qB3Re/btqEnHHXnDn/dCaLfK2hXutkpGvKfcGTP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qB3Re/btqEnHHXnDn/dCaLfK2hXutkpGvKfcGTP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qB3Re/btqEnHHXnDn/dCaLfK2hXutkpGvKfcGTP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqB3Re%2FbtqEnHHXnDn%2FdCaLfK2hXutkpGvKfcGTP1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;701&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어쨌든 몇가지 예시를 통해 parameter 값을 조정하여 'Multivariate Gaussian Distribution'가 어떻게 변하는지를 보았고, 이것을 이용하여 Anomaly Data가 확실히 검출될 수 있도록 해야합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;359&quot; data-filename=&quot;blob&quot; width=&quot;643&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/en48mD/btqEm1NF1UN/kLlIt6kzr4ulMQKeIO3S50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/en48mD/btqEm1NF1UN/kLlIt6kzr4ulMQKeIO3S50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/en48mD/btqEm1NF1UN/kLlIt6kzr4ulMQKeIO3S50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fen48mD%2FbtqEm1NF1UN%2FkLlIt6kzr4ulMQKeIO3S50%2Fimg.png&quot; data-origin-width=&quot;622&quot; data-origin-height=&quot;359&quot; data-filename=&quot;blob&quot; width=&quot;643&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 Cpu / Memory Dataset에서 발생했던 문제를 해결해보겠습니다. 우선 Dataset의 평균과 분산을 이용하여 $&amp;mu;$와 $&amp;Sigma;$를 구하고, 이를&lt;b&gt;'Multivariate Gaussian Distribution&lt;/b&gt;' 공식에 대입하여 $p(x)$를 도출합니다. 이때 $&amp;epsilon;$보다 작은 데이터는 Anomaly 데이터가 될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 데이터의 분포를 살펴보면 정상적인 데이터들은 길쭉한 원의 형태로 분포되어 있고, 녹색 데이터만 동떨어져 확실히 분류가 됨을 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;287&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qGDoj/btqEn8L63ex/vzk98TKjPJa6QkAaJCxwJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qGDoj/btqEn8L63ex/vzk98TKjPJa6QkAaJCxwJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qGDoj/btqEn8L63ex/vzk98TKjPJa6QkAaJCxwJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqGDoj%2FbtqEn8L63ex%2Fvzk98TKjPJa6QkAaJCxwJ1%2Fimg.png&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;287&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리가 기존에 Original Model에서 사용했던 $p(x)$ 공식은 사실상 'Multivariate Gaussian Distribution'의 $p(x)$와 동일하다고 봐도 무방합니다. 왜냐하면 Original $p(x)$에서 각각의 feature에 대한 $&amp;sigma;^2$을 모두 모아 행렬로 표현하면 'Multivariate Gaussian Distribution'의 $p(x)$의 $&amp;Sigma;$가 되기 때문입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;696&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lg4vZ/btqEoA9rruI/JD481YxB0Pt2Or1MQmUdr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lg4vZ/btqEoA9rruI/JD481YxB0Pt2Or1MQmUdr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lg4vZ/btqEoA9rruI/JD481YxB0Pt2Or1MQmUdr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flg4vZ%2FbtqEoA9rruI%2FJD481YxB0Pt2Or1MQmUdr1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;696&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마지막으로 두 모델의 장단점을 비교해보겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;* Original Model&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- (단점) 문제가 발생했을 때, &lt;b&gt;사람이 직접&lt;/b&gt; 오류를 분석하고 feature를 추가해야 한다는 점에서 &lt;b&gt;리스크&lt;/b&gt;가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- (장점) &lt;b&gt;연산 Cost가 매우 저렴하기 때문에 보통 보편적으로 많이 사용합니다.&lt;/b&gt; 그래서 feature가 100000개라도 부담없이 사용하며, training set이 100개정도로 매우 작아도 Anomaly Detection이 가능합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;* Multivariate Gaussian Distribution&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;(단점)&lt;/b&gt; $&amp;Sigma;$는 $n*n$ 행렬입니다. 따라서 연산 과정에서 이것의 &lt;b&gt;inverse를 계산하는 cost&lt;/b&gt;는 매우 크기 때문에 dataset이 100000개 이상일 경우 사용하기 적절치 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- inverse를 계산해야하기 때문에 $&amp;Sigma;$가 &lt;b&gt;'non-invertible'이면 안됩니다.&lt;/b&gt; 따라서 이를 방지하기 위해 중복된 feature가 있다면 제거해야 합니다. 그리고 반드시 data의 개수가 feature의 수보다 10배 이상은 클때 사용이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;(장점)&lt;/b&gt; 특정 조건에서만 사용이 가능하지만, &lt;b&gt;문제 발생 시 사람이 직접 feature를 추가하지 않아도 됩니다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>cost 함수</category>
      <category>경사 하강 알고리즘</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>인공지능</category>
      <category>인하대</category>
      <category>정규분포</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/37</guid>
      <comments>https://box-world.tistory.com/37#entry37comment</comments>
      <pubDate>Sun, 24 May 2020 14:40:57 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 이상 탐지(Anomaly Detection) vs Classification in Supervised Learning</title>
      <link>https://box-world.tistory.com/36</link>
      <description>&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실패에 대해 걱정하지 마라. 한번만 제대로 하면 된다.&lt;/b&gt;&lt;/h4&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 드류 휴스턴(Dropbox 공동 창업자)&lt;/b&gt;&lt;/h4&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;시작하며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우리는 저번 포스팅에서 Anomaly Detection이란 무엇이며,이를 위한 알고리즘의 작동 원리까지 공부했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이번 포스팅에서는 &lt;b&gt;Anomaly Detection 알고리즘의 성능&lt;/b&gt;을 어떻게 평가할 수 있는지 그리고 &lt;b&gt;Anomaly Detection과 Supervised Learning의 차이점&lt;/b&gt;을 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이번 포스팅은 아래 포스팅들을 통해 &lt;b&gt;'Test / Cv data', 'Anomaly Detection'&lt;/b&gt;에 대해 이해하고 보시면 더욱 효과적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/23&quot;&gt;https://box-world.tistory.com/23&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590245176505&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝] 머신러닝 학습 시 고려해야할 것 : Test data와 Cv data란?&quot; data-og-description=&quot;시작하며 우리가 데이터를 모델에 학습시킬 때, 모델이 학습한 결과와 실제값이 달라 accuracy(정확도) 가 떨어지는 상황에서 무엇을 할 수 있을까요? 더 많은 데이터를 넣어본다? 데이터의 표본이&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/23&quot; data-og-url=&quot;https://box-world.tistory.com/23&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cHfUyo/hyF9WV707w/wU9CetYP52PjlO5tHI3YFK/img.png?width=499&amp;amp;height=277&amp;amp;face=0_0_499_277,https://scrap.kakaocdn.net/dn/Q4eSh/hyF93HIxFd/2Sf6CNBQwepv2BYB7EuM7K/img.png?width=499&amp;amp;height=277&amp;amp;face=0_0_499_277,https://scrap.kakaocdn.net/dn/bfzyXJ/hyF8M1Spmp/HIX3JhpjnGD8Ykaf4kkPK1/img.png?width=376&amp;amp;height=232&amp;amp;face=0_0_376_232&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/23&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/23&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cHfUyo/hyF9WV707w/wU9CetYP52PjlO5tHI3YFK/img.png?width=499&amp;amp;height=277&amp;amp;face=0_0_499_277,https://scrap.kakaocdn.net/dn/Q4eSh/hyF93HIxFd/2Sf6CNBQwepv2BYB7EuM7K/img.png?width=499&amp;amp;height=277&amp;amp;face=0_0_499_277,https://scrap.kakaocdn.net/dn/bfzyXJ/hyF8M1Spmp/HIX3JhpjnGD8Ykaf4kkPK1/img.png?width=376&amp;amp;height=232&amp;amp;face=0_0_376_232');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝] 머신러닝 학습 시 고려해야할 것 : Test data와 Cv data란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 우리가 데이터를 모델에 학습시킬 때, 모델이 학습한 결과와 실제값이 달라 accuracy(정확도) 가 떨어지는 상황에서 무엇을 할 수 있을까요? 더 많은 데이터를 넣어본다? 데이터의 표본이&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/35&quot;&gt;https://box-world.tistory.com/35&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590245178300&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] 이상 탐지(Anomaly Detection)이란?&quot; data-og-description=&quot;&amp;quot;기술에는 품위와 친절이 녹아있어야 한다.&amp;quot; - 팀 쿡 - 시작하며 여기 암을 조기에 발견할 수 있는 인공지능을 만드는 개발자가 있습니다. 그 개발자는 우여곡절끝에 정확도 99.00%를 자랑하는 머��&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/35&quot; data-og-url=&quot;https://box-world.tistory.com/35&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/be786W/hyF90xrm5f/RQc1t2pNSs2ndtGqZFjVek/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/MuKxR/hyF8N0OnvX/b6o5cZV3ZR23kOn3DUgUDk/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/RaFrK/hyF9YzDVce/9fJ6BWzP9kBLikdVJ1R0Ik/img.png?width=683&amp;amp;height=395&amp;amp;face=0_0_683_395&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/35&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/35&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/be786W/hyF90xrm5f/RQc1t2pNSs2ndtGqZFjVek/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/MuKxR/hyF8N0OnvX/b6o5cZV3ZR23kOn3DUgUDk/img.png?width=359&amp;amp;height=141&amp;amp;face=0_0_359_141,https://scrap.kakaocdn.net/dn/RaFrK/hyF9YzDVce/9fJ6BWzP9kBLikdVJ1R0Ik/img.png?width=683&amp;amp;height=395&amp;amp;face=0_0_683_395');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] 이상 탐지(Anomaly Detection)이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&quot;기술에는 품위와 친절이 녹아있어야 한다.&quot; - 팀 쿡 - 시작하며 여기 암을 조기에 발견할 수 있는 인공지능을 만드는 개발자가 있습니다. 그 개발자는 우여곡절끝에 정확도 99.00%를 자랑하는 머��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;Anomaly Detection 알고리즘 성능 측정하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 Anomaly Detection 알고리즘의 성능을 측정하는 방법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;259&quot; data-filename=&quot;blob&quot; width=&quot;603&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lUsOI/btqEn8E6ZP4/8EeGdrqCjnZXSHu99q0T8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lUsOI/btqEn8E6ZP4/8EeGdrqCjnZXSHu99q0T8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lUsOI/btqEn8E6ZP4/8EeGdrqCjnZXSHu99q0T8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlUsOI%2FbtqEn8E6ZP4%2F8EeGdrqCjnZXSHu99q0T8k%2Fimg.png&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;259&quot; data-filename=&quot;blob&quot; width=&quot;603&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;기본적으로 성능 측정을 위해서는 &lt;b&gt;학습에 사용될 데이터가 'Labeled Data'여야 합니다.&lt;/b&gt; 그래야 알고리즘이 데이터를 분류한 결과가 맞는지 틀린지 알 수 있기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;따라서 &lt;b&gt;우리에게 주어진 데이터가 'Unlabeled'일 경우,&lt;/b&gt; 보통 &lt;b&gt;Anomaly&lt;/b&gt; 데이터의 Label을 $y = 1$로 하고, 그렇지 않은 &lt;b&gt;정상적인&lt;/b&gt; 데이터의 Label은 $y=0$으로 설정하여 Labeled Data로 바꿔줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;446&quot; data-filename=&quot;blob&quot; width=&quot;654&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blG5Sm/btqEnh3EwGq/hZzU4kfNrlDSWP3bb40Mi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blG5Sm/btqEnh3EwGq/hZzU4kfNrlDSWP3bb40Mi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blG5Sm/btqEnh3EwGq/hZzU4kfNrlDSWP3bb40Mi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblG5Sm%2FbtqEnh3EwGq%2FhZzU4kfNrlDSWP3bb40Mi0%2Fimg.png&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;446&quot; data-filename=&quot;blob&quot; width=&quot;654&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; 저번 포스팅에서 다룬 비행기 엔진에 대한 Dataset을 예시로 들어보겠습니다. Dataset은 &lt;b&gt;10000개의 정상적인 엔진&lt;/b&gt;과 &lt;b&gt;20개의 비정상적인 엔진&lt;/b&gt;으로 구성되어 있습니다. 이때 비정상적인 엔진은 전체 데이터의 0.002%에 불과하기 때문에 이를 검출하기 위해서는 &lt;b&gt;Anomaly Detection 알고리즘&lt;/b&gt;이 필요합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 Dataset을 Training set : Test Set : Cv set = $6 : 2 : 2$로 나눕니다. 이때 Traing set에 들어가는 6000개의 데이터는 모두 &lt;b&gt;정상적인 데이터&lt;/b&gt; $(y=1)$로 구성하고, 20개의 비정상적인 데이터는 &lt;b&gt;10개씩 나눠 'Test Set'과 'Cv Set'에 들어가게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;데이터를 나눈 후, &lt;b&gt;Training set&lt;/b&gt;을 이용하여 $p(x)$ 함수를 만듭니다. 그리고 &lt;b&gt;Cv / Test set&lt;/b&gt;을 여기에 집어넣어 결과값 $y = 1 or 0$인지 확인합니다. 이때 이를 &lt;b&gt;구분짓는 경계(Threshold)를&lt;/b&gt;&amp;nbsp;$&lt;span&gt;&amp;epsilon;$으로 설정하여 이것보다 작으면 $y = 1$이라고 판단합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&amp;nbsp;여기에서 더 나아가 보통 Anomaly Detection 알고리즘을 평가할 때는, '&lt;b&gt;Precision / Recall'을 이용한 'F1 Score'를 이용합니다.&lt;/b&gt; 따라서 &lt;b&gt;Cv set&lt;/b&gt;을 이용하여 여러 &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;epsilon;$에 대한 각 알고리즘의 F1 score를 이용하여 &lt;b&gt;최적의&lt;/b&gt; &lt;span style=&quot;color: #333333;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;epsilon;$ &lt;b&gt;값을 찾아낼 수 있습니다.&lt;/b&gt; 그 후 최종적인 알고리즘을 평가할 때 &lt;b&gt;Test set&lt;/b&gt;을 이용하게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Anomaly Detection vs Classification in Supervised Learning&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;그런데 여기서 의문이 듭니다. 우리가 다루는 데이터가 &lt;b&gt;Labeled data&lt;/b&gt;라는 점에서 굳이 Anomaly를 사용하지 않고, &lt;b&gt;Supervised Learning의 Classification 알고리즘&lt;/b&gt;을 이용하여 비정상적인 데이터를 분류할 수는 없는 걸까요?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;349&quot; data-filename=&quot;blob&quot; width=&quot;647&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LcGCI/btqEnH8OU6s/B8Kk2BgKD4siusGS5ekzOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LcGCI/btqEnH8OU6s/B8Kk2BgKD4siusGS5ekzOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LcGCI/btqEnH8OU6s/B8Kk2BgKD4siusGS5ekzOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLcGCI%2FbtqEnH8OU6s%2FB8Kk2BgKD4siusGS5ekzOk%2Fimg.png&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;349&quot; data-filename=&quot;blob&quot; width=&quot;647&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;b&gt;결론은 Logistic Regression과 같은 알고리즘으로는 Anomaly한 데이터를 검출하는 것이 거의 불가능합니다.&lt;/b&gt; 왜냐하면 기본적으로 &lt;b&gt;Anomaly Detection 알고리즘&lt;/b&gt;은 데이터를 분류할 때 &lt;b&gt;'데이터의 밀도(Density)'를&lt;/b&gt; 이용합니다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;예를 들어 정상적인 비행기 엔진이라면 대부분 비슷한 성능을 보일 것이므로 &lt;b&gt;서로 뭉쳐있어 밀도가 높을 것입니다.&lt;/b&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그러나 비정상적인 비행기 엔진은 &lt;b&gt;정상적인 데이터들과는 동떨어져있기 때문에 밀도가 낮을 것입니다.&lt;/b&gt; 따라서 알고리즘은 이 밀도를 이용하여 밀도가 아주 낮은 데이터를 Anomaly하다고 판단하는 것입니다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp; 이에 반해 '&lt;span style=&quot;color: #333333;&quot;&gt;Logistic Regression'과 같은&lt;/span&gt; 알고리즘은 &lt;b&gt;정상적인 데이터와 비정상적인 데이터가 각각 학습되어야 합니다.&lt;/b&gt; 즉 알고리즘이 분류할 때 단순히 정상적인 데이터가 아니니 비정상적인 데이터겠지가 아니라, 정상적인 데이터에 대한 학습 그리고 비정상적인 데이터에 대한 학습이 모두 이루어져야 하는 것입니다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;그러니 우리가 비행기 엔진 Dataset의 경우, 비정상적인 데이터는 &lt;b&gt;20개&lt;/b&gt;로 학습에 턱없이 부족하기 때문에 일반적인 Classification 알고리즘을 적용할 수 없는 것입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;Non - Gaussian Features&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;709&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bah4IO/btqEmMbXGDf/ViVrF4Xm0TCWy550gOkYVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bah4IO/btqEmMbXGDf/ViVrF4Xm0TCWy550gOkYVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bah4IO/btqEmMbXGDf/ViVrF4Xm0TCWy550gOkYVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbah4IO%2FbtqEmMbXGDf%2FViVrF4Xm0TCWy550gOkYVk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;709&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우리는 Anomaly Detection 알고리즘에서 '&lt;b&gt;가우시안 분포(Gaussian Distribution)' 기반의 $p(x)$ 함수&lt;/b&gt;를 이용하였습니다. 그런데 만약 특정 feature의 확률 밀도 함수가 일반적인 가우시안 분포의 모양을 띄지 않는다면, 해당 feature의 모든 data에 $\log{x}$나 $\sqrt{x}$를 적용해주면 이를 해결할 수 있습니다.&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>anomaly</category>
      <category>cost 함수</category>
      <category>coursera</category>
      <category>가우시안 분포</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>이상 탐지</category>
      <category>인하대</category>
      <category>지도 학습</category>
      <category>코세라</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/36</guid>
      <comments>https://box-world.tistory.com/36#entry36comment</comments>
      <pubDate>Sun, 24 May 2020 00:37:22 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 이상 탐지(Anomaly Detection)이란?</title>
      <link>https://box-world.tistory.com/35</link>
      <description>&lt;h3 style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&quot;기술에는 품위와 친절이 녹아있어야 한다.&quot;&lt;/b&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: center;&quot;&gt;&lt;b&gt;- 팀 쿡 -&lt;/b&gt;&lt;/h3&gt;
&lt;h2&gt;시작하며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;여기 암을 조기에 발견할 수 있는 인공지능을 만드는 개발자가 있습니다. 그 개발자는 우여곡절끝에 &lt;b&gt;정확도 99.00%&lt;/b&gt;를 자랑하는 머신러닝 학습 모델을 만들어 냈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;하지만 우리나라 기준으로 연간 암 발병률은 &lt;b&gt;0.005%&lt;/b&gt;가 채 되지 않습니다. 열심히 만든 개발자에게는 99%도 겨우 만들어낸 훌륭한 모델이었으면 좋겠지만, 안타깝게도 이것으로 암을 조기에 발견하기에는 턱없이 부족한 정확도인것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이번 포스팅에서는 기존에 우리가 알던 분류(Classification)와는 다르게 100000개의 데이터 중에서 1개, 1000000000개 중에서 10개 꼴로 일어나는 것 같이 아주 극소수의 매우 작은 비율의 데이터 혹은 이상한(비정상적인) 데이터를 검출하는데 사용되는 &lt;b&gt;이상 탐지(Anomaly Detection)&lt;/b&gt;에 대해서 공부해보겠습니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Anomaly Detection&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;601&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOTP7P/btqEmLXUHux/lPPl1KAKv2q96wSx13d7E1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOTP7P/btqEmLXUHux/lPPl1KAKv2q96wSx13d7E1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOTP7P/btqEmLXUHux/lPPl1KAKv2q96wSx13d7E1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOTP7P%2FbtqEmLXUHux%2FlPPl1KAKv2q96wSx13d7E1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;601&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;여기 비행기 엔진을 만드는 공장이 있습니다. 정상적인 엔진이라면 &lt;b&gt;'열(heat)'이 높아질수록 '회전(vibration)' 또한 빨라져야 합니다.&lt;/b&gt; 이제 이것을 염두에 두고 데이터를 관찰해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;대부분의 데이터는 &lt;b&gt;열과 회전의 비례관계&lt;/b&gt;를 만족하며 정상적인 엔진들이라고 판단되지만, &lt;b&gt;녹색으로 표시된 데이터&lt;/b&gt;는 이 비례관계를 만족하다고 하기엔 애매하다고 할 수 있습니다. 바로 이 녹색 데이터가 비정상적인 데이터 &lt;b&gt;Anonmaly Data&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;이때 한가지 유의할 점은 'Anomaly Data Detection'이라는 것은 오류를 탐지하기 위한 알고리즘이 아니라, 전체 데이터 중 매우 작은 비율을 갖는 한쪽 데이터인 'skewed class'를 검출하는 알고리즘입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;598&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGjzGD/btqEmqmokWj/5fXX0msNncbaFJb7QfUZwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGjzGD/btqEmqmokWj/5fXX0msNncbaFJb7QfUZwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGjzGD/btqEmqmokWj/5fXX0msNncbaFJb7QfUZwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGjzGD%2FbtqEmqmokWj%2F5fXX0msNncbaFJb7QfUZwK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;598&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 m개의 dataset이 있을 때, &lt;b&gt;$x_{test}$가 anomaly한 데이터인지 어떻게 판단할 수 있을가요?&lt;/b&gt; 여기에 바로 &lt;b&gt;데이터의 밀도를 추정하는 함수(Density Estimation)인&lt;/b&gt; $p(x)$가 이용됩니다. 이것의 함수값은 우리가 넣은 데이터 $x$가 &lt;b&gt;정상적인 데이터일 가능성(probability)&lt;/b&gt;를 의미합니다. 그래서 이 함수값이 이따 살펴볼 &lt;b&gt;특정 경계값&lt;/b&gt; $(&amp;epsilon;)$ 보다 작다면 Anomaly하다고 판단하게 됩니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 구체적으로 &lt;b&gt;데이터의&lt;/b&gt; &lt;b&gt;밀도를 추정하는 함수&lt;/b&gt; $p(x)$가 어떤 형태를 띄는지 알기 위해서는 몇가지 수학적인 개념이 필요한데 겁먹을 필요 없습니다! 저 또한 수학을 잘하지 못하기 때문에 제가 이해한대로 최대한 쉽게 설명해드릴테니 믿고 따라와주시면 됩니다. :)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;507&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sM2TV/btqEj8TSDYg/i59QVXf0nSpkWEh10k21V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sM2TV/btqEj8TSDYg/i59QVXf0nSpkWEh10k21V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sM2TV/btqEj8TSDYg/i59QVXf0nSpkWEh10k21V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsM2TV%2FbtqEj8TSDYg%2Fi59QVXf0nSpkWEh10k21V0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;507&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 &lt;b&gt;확률 밀도 함수(Probability Density Function)&lt;/b&gt;라는 개념부터 살펴보겠습니다. $x = a$일 때 함수값이 $f(a)$라는 것은 &lt;b&gt;어떤 feature $x$가 $a$라는 값을 가질 상대적인 가능성을 의미합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;혹은 이 함수값은 &lt;b&gt;밀도&lt;/b&gt;를 의미하는데 내가 &lt;b&gt;input으로 넣은 데이터의 밀도가 크다는 것&lt;/b&gt;은 결국 나랑 비슷한 값을 갖는 데이터가 많다는 것이기 때문에 정상적인 데이터일 확률이 크다고 이해하셔도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;즉 상대적인 가능성을 뜻하는 $f(a)$가 낮을수록 feature $x$에서 $a$라는 값이 적게 나타나는 것이기 때문에 Anomaly할 확률은 그와 반대로 커지게 됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 확률 밀도 함수라는 개념을 기반으로 밀도를 추정하는 방법에는 'parametric'과 'non-parametric'이 있는데 이중 우리가 이용할 방법은 &lt;b&gt;'non-parametric'&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;492&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z3pR9/btqElFQ1is4/j84F62DY7N6kNqh4p3mGQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z3pR9/btqElFQ1is4/j84F62DY7N6kNqh4p3mGQ1/img.png&quot; data-alt=&quot;정규분포&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z3pR9/btqElFQ1is4/j84F62DY7N6kNqh4p3mGQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ3pR9%2FbtqElFQ1is4%2Fj84F62DY7N6kNqh4p3mGQ1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;492&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;정규분포&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;'parametric'&lt;/b&gt;은 우리가 사용할 dataset의 &lt;b&gt;모든 feature가 '정규분포'를 따른다고 가정하고 밀도를 추정합니다.&lt;/b&gt; 즉 위 이미지처럼 종 모양의 형태를 띄는 &lt;b&gt;정규분포&lt;/b&gt;는 feature $x$에 대해 &lt;b&gt;평균에 가까울수록 밀도가 커지기 때문에, 평균과 비슷한 데이터가 제일 많을 것이라고 가정하고 밀도를 추정하는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;그러나 우리가 일상 생활에서 발견하는 대부분의 데이터는 이런식의 예쁜 정규분포를 만족하지 않습니다. 따라서 &lt;b&gt;순수하게 관측된 데이터만으로 확률밀도함수를 만드는&lt;/b&gt; &lt;b&gt;'non-parametic'&lt;/b&gt;을 이용하여 우리는 밀도를 추정할 것입니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;머신러닝에서 사용하는 'non-parametic' 밀도 추정 방법 중 하나가 &lt;b&gt;'커널 밀도 추정(Kernel Density Estimation)'&lt;/b&gt;입니다. 즉 &lt;b&gt;커널&lt;/b&gt;이라는 것을 이용하여 확률 밀도 함수를 만들겠다는 것인데, 이것은&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1) 전 구간에서 함수값이 양수여야 하며 $K(x) &amp;gt;= 0$&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2) 대칭적이어야하고 $K(x) = K(-x)$&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3) 함수의 중앙에서 멀어질수록 함수값이 감소해야합니다. $K'(x) &amp;lt;= 0 for every x &amp;gt;0$&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8rmBB/btqElFKeQ2r/f6LmfoEknl5DJODUAmBCwK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8rmBB/btqElFKeQ2r/f6LmfoEknl5DJODUAmBCwK/img.jpg&quot; data-alt=&quot;커널의 4 종류&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8rmBB/btqElFKeQ2r/f6LmfoEknl5DJODUAmBCwK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8rmBB%2FbtqElFKeQ2r%2Ff6LmfoEknl5DJODUAmBCwK%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;커널의 4 종류&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이를 만족하는 커널에는 위와 같이 4종류가 있는데, 어떤 커널을 고르느냐는 중요한게 아니기 때문에 &lt;b&gt;이중 계산이 간편한 '가우시안 커널(Gaussian Kernel)&lt;/b&gt;'을 사용하겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;649&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/APqtE/btqEmoVAJYm/iM0T2RDTCnWA9nhAoOKtvK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/APqtE/btqEmoVAJYm/iM0T2RDTCnWA9nhAoOKtvK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/APqtE/btqEmoVAJYm/iM0T2RDTCnWA9nhAoOKtvK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAPqtE%2FbtqEmoVAJYm%2FiM0T2RDTCnWA9nhAoOKtvK%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;649&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 여기에 하나의 feature에 대한 dataset이 있습니다. 그리고 Kernel을 이용하여 특정 feature의 확률 밀도 함수인 '&lt;b&gt;KDE(Kernel Density Estimation)'를 구하는 법&lt;/b&gt; 은 다음과 같습니다.&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/7o1ha/btqEmoH24J2/r2l5M6jgULbrMeulRITTG1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7o1ha/btqEmoH24J2/r2l5M6jgULbrMeulRITTG1/img.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 49.3353%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7o1ha/btqEmoH24J2/r2l5M6jgULbrMeulRITTG1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7o1ha%2FbtqEmoH24J2%2Fr2l5M6jgULbrMeulRITTG1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nu2Zh/btqElFKfpKt/h67nlHEkDp5LfktrsSkhqK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nu2Zh/btqElFKfpKt/h67nlHEkDp5LfktrsSkhqK/img.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 49.5019%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nu2Zh/btqElFKfpKt/h67nlHEkDp5LfktrsSkhqK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnu2Zh%2FbtqElFKfpKt%2Fh67nlHEkDp5LfktrsSkhqK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 각 데이터 $x_{(i)}$ 하나 당 $x_{(i)}$를 중심으로 하는 &lt;b&gt;가우시안 커널을 하나씩 생성해줍니다.&lt;/b&gt; 그리고 더해주면 오른쪽 그림의 파란색 함수에 해당하는 &lt;b&gt;KDE&lt;/b&gt;를 구할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TWcz3/btqElWlCGqx/wkKGc0E4yiafXbBUUeVCz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TWcz3/btqElWlCGqx/wkKGc0E4yiafXbBUUeVCz1/img.png&quot; data-alt=&quot;공식 p(x, &amp;amp;amp;mu;, &amp;amp;amp;sigma;)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TWcz3/btqElWlCGqx/wkKGc0E4yiafXbBUUeVCz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTWcz3%2FbtqElWlCGqx%2FwkKGc0E4yiafXbBUUeVCz1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;공식 p(x, &amp;mu;, &amp;sigma;)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이해를 위해서 제가 단계를 나눠 KDE를 구하는 방식을 설명드렸지만, 각 feature의 $&amp;mu;$&lt;b&gt;(평균)&lt;/b&gt; 그리고 $&amp;sigma;$&lt;b&gt;(표준편차)&lt;/b&gt;를 구하여 위 공식에 대입하면 &lt;b&gt;별도의 단계없이 한번에 '해당 feature의 KDE'&lt;/b&gt;를 구할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsR12y/btqElV7crBn/q6kDAKWx0Znpw7tttYvZlk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsR12y/btqElV7crBn/q6kDAKWx0Znpw7tttYvZlk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsR12y/btqElV7crBn/q6kDAKWx0Znpw7tttYvZlk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bsR12y/btqElV7crBn/q6kDAKWx0Znpw7tttYvZlk/img.gif&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;500&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;여기서 중요한 것은 각 feature의 가우시안 커널 공식에서 &lt;b&gt;h에 해당하는 'bandwidth'&lt;/b&gt;입니다. 이 &lt;b&gt;bandwidth 가 너무 커지면&lt;/b&gt; KDE가 완만해져서 Anomaly를 찾기 어려워지고, &lt;b&gt;반대로 너무 작아지면&lt;/b&gt; KDE가 뾰족해져서 중심에서 조금만 멀어져도 Anomaly라고 판단하게 됩니다. &lt;b&gt;따라서 우리에게 중요한 것은 적절한 'bandwidth'를 찾는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이제 우리는 &lt;b&gt;하나의 feature에 대해 'KDE' 즉 확률 밀도 함수&lt;/b&gt;를 구하는 법을 알게 되었습니다. 이제 이것을 &lt;b&gt;Anomaly 데이터를 검출하는 알고리즘&lt;/b&gt;에 적용하기 위해서는 몇가지 단계를 거쳐야 합니다. 마지막에 총정리를 할테니 계속 따라와주세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 dataset에 각 feature마다 하나의 KDE를 모두 구해줍니다. 그 다음 &lt;b&gt;각 feature에서 나온 KDE를 모두 곱해주면&lt;/b&gt; 이것이 바로 $p(x)$가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이제 우리에게는 데이터가 Anomaly한지 검출할 수 있는 함수 $p(x)$가 있습니다. 이제 우리가 해야할 일은 dataset을 보았을 때, &lt;b&gt;Anomaly한 것으로 추정되는 데이터 $x_{(i)}$를 함수&lt;/b&gt; &lt;b&gt;$p(x)$에 집어넣으면 됩니다.&lt;/b&gt; 그리고 이렇게 해서 도출된 함수값 $p(x_{(i)})$가 양수이지만 매우 작은 $&amp;epsilon;$보다 작다면 &lt;b&gt;Anomaly&lt;/b&gt;하다고 판단하고, 크다면 &lt;b&gt;정상적&lt;/b&gt;인 데이터라고 판단하게 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;요약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1)&lt;/b&gt; 모든 Feature에 대해서, 각 Feature의 데이터들을 중심으로 하는 가우시안 커널을 생성하고 이들을 모두 더하여, 각 Feature에 대한 확률 밀도 함수 KDE를 만들어 냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2)&lt;/b&gt; 각 feature의 KDE를 모두 곱하여 $p(x)$를 구합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;*&lt;i&gt;3) *&lt;/i&gt; dataset에서 Anomaly하다고 생각되는 데이터를 추려낸 후, 이 데이터들을 $p(x)$의 input으로 넣어서 그 값이 $&amp;epsilon;$을 기준으로 작은지 큰지에 따라 Anomaly 데이터 여부를 판단하면 됩니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/basj9F/btqEnh267Pt/KoXVDYACablVgslDj8sI7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/basj9F/btqEnh267Pt/KoXVDYACablVgslDj8sI7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/basj9F/btqEnh267Pt/KoXVDYACablVgslDj8sI7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbasj9F%2FbtqEnh267Pt%2FKoXVDYACablVgslDj8sI7K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;652&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;마지막으로 예시를 보면서 개념을 복습해보겠습니다. 여기 $x1$, $x2$ &lt;b&gt;두개의 feature를 가지는 dataset&lt;/b&gt;이 있습니다. 따라서 각 feature마다 $&amp;mu;$(평균) 그리고 $&amp;sigma;$(표준편차)를 구하여 &lt;b&gt;공식에 대입하여 'KDE'를 구합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;보시다시피 feature $x2$의 $&amp;sigma;$가 더 작아서 분포가 뾰족한 것을 볼 수 있습니다. 이제 이 두개의 KDE를 곱하여 $p(x)$를 도출하고 &lt;b&gt;우리가 테스트해보고 싶은 데이터를 이 함수의 input으로 넣어주면 됩니다.&lt;/b&gt; 이때 $&amp;epsilon; = 0.02$라고 가정하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;우선 $x^{{1}}_{test}$의 경우는 함수에 넣었을 때 0.0426으로 0.02인 $&amp;epsilon;$보다 &lt;b&gt;크기 때문에 정상적인 데이터&lt;/b&gt;라고 판단합니다. 하지만 $x^{{2}}_{test}$의 경우 0.0021로 $&amp;epsilon;$보다 &lt;b&gt;작기 때문에 Anomaly한 데이터&lt;/b&gt;라고 판단하게 되고 실제 그래프를 보더라도 Anomaly한 데이터일 확률이 매우 커보입니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/24&quot;&gt;https://box-world.tistory.com/24&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1590159400861&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝] 머신러닝 시스템 디자인 하기 : Precision, Recall, F score&quot; data-og-description=&quot;시작하며 머신러닝 시스템을 디자인하면서 적용해볼 수 있는 방법들은 다양하게 존재합니다. 이번 포스팅에서는 여러 방법들 중에 하나의 최선의 방법을 골라 적용할지 판단하는 체계적인 방��&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/24&quot; data-og-url=&quot;https://box-world.tistory.com/24&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GBGsF/hyF8ORzTqj/k63TYspixmX4wVkZ88RWgK/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/Gz4Eo/hyF8MsHhQl/Ig808wLKtTb40R0jh0RXkK/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/dNTsLt/hyF8HkDj3E/iRKuDrb24Nk4nsKyGtGbCk/img.png?width=606&amp;amp;height=446&amp;amp;face=0_0_606_446&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/24&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/24&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GBGsF/hyF8ORzTqj/k63TYspixmX4wVkZ88RWgK/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/Gz4Eo/hyF8MsHhQl/Ig808wLKtTb40R0jh0RXkK/img.png?width=608&amp;amp;height=274&amp;amp;face=0_0_608_274,https://scrap.kakaocdn.net/dn/dNTsLt/hyF8HkDj3E/iRKuDrb24Nk4nsKyGtGbCk/img.png?width=606&amp;amp;height=446&amp;amp;face=0_0_606_446');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝] 머신러닝 시스템 디자인 하기 : Precision, Recall, F score&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 머신러닝 시스템을 디자인하면서 적용해볼 수 있는 방법들은 다양하게 존재합니다. 이번 포스팅에서는 여러 방법들 중에 하나의 최선의 방법을 골라 적용할지 판단하는 체계적인 방��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;제가 이전에 위 포스팅을 통해 &lt;b&gt;Skewed Class, Precision, Recall, F1 score&lt;/b&gt;의 개념에 대해서 다룬적이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;바로 이번 포스팅에서 배운 &lt;b&gt;Anomaly Detection을 위한 알고리즘의 성능을 측정하는데 쓰이는 대표적인 지표&lt;/b&gt;가 바로 이 &lt;b&gt;Precision, Recall, F1 score&lt;/b&gt;입니다. 따라서 이 포스팅을 완벽하게 공부하신 후 위 포스팅을 보신다면 큰 도움이 될거라고 생각합니다.&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>anomaly detection</category>
      <category>cost 함수</category>
      <category>경사 하강 알고리즘</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>이상 탐지</category>
      <category>인하대</category>
      <category>지도 학습</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/35</guid>
      <comments>https://box-world.tistory.com/35#entry35comment</comments>
      <pubDate>Fri, 22 May 2020 14:26:12 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란? (2)</title>
      <link>https://box-world.tistory.com/34</link>
      <description>&lt;h4&gt;&lt;b&gt;여기에서 실패는 하나의 옵션이다.&lt;/b&gt;&lt;/h4&gt;
&lt;h4&gt;&lt;b&gt;당신이 실패를 겪지 않았다면, 충분히 혁신하지 않았다는 것이다.&lt;/b&gt;&lt;/h4&gt;
&lt;h4&gt;&lt;b&gt;- 엘론 머스크 -&lt;/b&gt;&lt;/h4&gt;
&lt;h2&gt;시작하며&lt;/h2&gt;
&lt;p&gt;저번 포스팅에서 조금 어려울수도 있었던 &lt;b&gt;PCA 알고리즘의 원리&lt;/b&gt;에 대해 알아보았습니다. 이번 포스팅에서는 PCA 알고리즘으로 &lt;b&gt;차원을 감소시킨 데이터의 재복원&lt;/b&gt;, &lt;b&gt;알고리즘의 장단점&lt;/b&gt; 등을 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;이번 포스팅은 'PCA 알고리즘의 원리'를 이해하시고 공부하시면 더욱 효과적입니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/33&quot;&gt;https://box-world.tistory.com/33&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1594562149130&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&quot; data-og-description=&quot;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 &amp;nbsp;우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를 바탕으�&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/33&quot; data-og-url=&quot;https://box-world.tistory.com/33&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Ik5ZV/hyGJNrWErl/W409KSw8K35vHWMm1iu7LK/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/fd8xL/hyGJWJaMPd/xjQywTxlWY19tLoBT0bJBk/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/czKnQV/hyGJKIIRXx/Qtki3wV0MZAiKNB8hahTe0/img.png?width=850&amp;amp;height=401&amp;amp;face=0_0_850_401&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/33&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/33&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Ik5ZV/hyGJNrWErl/W409KSw8K35vHWMm1iu7LK/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/fd8xL/hyGJWJaMPd/xjQywTxlWY19tLoBT0bJBk/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/czKnQV/hyGJKIIRXx/Qtki3wV0MZAiKNB8hahTe0/img.png?width=850&amp;amp;height=401&amp;amp;face=0_0_850_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 &amp;nbsp;우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를 바탕으�&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;(&lt;a href=&quot;https://box-world.tistory.com/33&quot;&gt;https://box-world.tistory.com/33&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1594562150979&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&quot; data-og-description=&quot;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 &amp;nbsp;우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를 바탕으�&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/33&quot; data-og-url=&quot;https://box-world.tistory.com/33&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Ik5ZV/hyGJNrWErl/W409KSw8K35vHWMm1iu7LK/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/fd8xL/hyGJWJaMPd/xjQywTxlWY19tLoBT0bJBk/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/czKnQV/hyGJKIIRXx/Qtki3wV0MZAiKNB8hahTe0/img.png?width=850&amp;amp;height=401&amp;amp;face=0_0_850_401&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/33&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/33&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Ik5ZV/hyGJNrWErl/W409KSw8K35vHWMm1iu7LK/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/fd8xL/hyGJWJaMPd/xjQywTxlWY19tLoBT0bJBk/img.png?width=416&amp;amp;height=222&amp;amp;face=0_0_416_222,https://scrap.kakaocdn.net/dn/czKnQV/hyGJKIIRXx/Qtki3wV0MZAiKNB8hahTe0/img.png?width=850&amp;amp;height=401&amp;amp;face=0_0_850_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo; -Bill Gates- 시작하며 &amp;nbsp;우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를 바탕으�&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2&gt;재복원(Reconstruction)&lt;/h2&gt;
&lt;p&gt;먼저 감소시킨 차원의 데이터를 &lt;b&gt;어떻게 다시 원래의 차원의 데이터로 복원시킬 수 있는지&lt;/b&gt; 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;$$z = U^T_{reduce} * x$$&lt;/p&gt;
&lt;p&gt;예를 들어 n차원에서 k차원으로 데이터를 차원 감소시켰을 때, 차원 감소된 데이터 $z$는 &lt;b&gt;분산도가 가장 높은 k개의 PC들&lt;/b&gt;을 가지는 행렬 $U$와 기존 데이터 $x$를 곱함으로써 구할 수 있습니다.&lt;/p&gt;
&lt;p&gt;$$x = U_{reduce} * z$$&lt;/p&gt;
&lt;p&gt;우리가 다시 복원하려는 원래의 데이터는 $x$입니다. 따라서 $x$에 대해서 식을 정리하면, 위 식이 나오게 됩니다. 이때 $U_{reduce}$는 $n*k$차원, $z$는 $k * 1$차원이므로 원래의 데이터 $x$는 정상적으로 &lt;b&gt;n차원 vector&lt;/b&gt;가 되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;356&quot; data-origin-height=&quot;404&quot; data-filename=&quot;blob&quot; width=&quot;481&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAkKnL/btqEjDGrBbj/gvM6jcZJwcICRFFrrE7P9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAkKnL/btqEjDGrBbj/gvM6jcZJwcICRFFrrE7P9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAkKnL/btqEjDGrBbj/gvM6jcZJwcICRFFrrE7P9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAkKnL%2FbtqEjDGrBbj%2FgvM6jcZJwcICRFFrrE7P9K%2Fimg.png&quot; data-origin-width=&quot;356&quot; data-origin-height=&quot;404&quot; data-filename=&quot;blob&quot; width=&quot;481&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그러나 본래대로 복원된 n 차원의 데이터는 차원 감소되기 전 본래의 n 차원 데이터와 조금 다릅니다. &lt;b&gt;왜냐하면 차원이 감소되었다가 다시 복원되는 과정을 거치면서 데이터가 유실되었기 때문입니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Number of PC&lt;/h2&gt;
&lt;p&gt;** 그렇다면 n 차원의 데이터를 차원 감소시키고 싶다면 몇차원으로 감소시켜야할지 k값은 어떻게 선택해야할까요?**&lt;/p&gt;
&lt;p&gt;여기에는 두가지 방법이 있습니다. 첫번쨰 방법을 위한 공식에는 &lt;b&gt;'원래의 점과 PC1까지의 거리(Protection Error)'&lt;/b&gt;, 그리고 &lt;b&gt;'원점에서부터 원래의 점까지의 거리(Total Variation)'&lt;/b&gt; 두가지 요소가 필요합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;340&quot; data-filename=&quot;blob&quot; width=&quot;751&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ukja6/btqEkaqeXTK/u0n2W3oZPpCCxNmrOWkhBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ukja6/btqEkaqeXTK/u0n2W3oZPpCCxNmrOWkhBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ukja6/btqEkaqeXTK/u0n2W3oZPpCCxNmrOWkhBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fukja6%2FbtqEkaqeXTK%2Fu0n2W3oZPpCCxNmrOWkhBk%2Fimg.png&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;340&quot; data-filename=&quot;blob&quot; width=&quot;751&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이 둘의 비율은 &lt;b&gt;원래의 n차원 데이터 x와 k차원으로 감소된 점과의 오차율&lt;/b&gt;을 의미하며 &lt;b&gt;이 값이 작을 수록 둘의 차이가 적어지는 것입니다.&lt;/b&gt; 이때 &lt;b&gt;오차율&lt;/b&gt;이 1%라면, 반대로 99%의 &lt;b&gt;복원율&lt;/b&gt;을 갖는다고 생각할 수도 있습니다. 주로 이 오차율에 자주 사용되는 비율에는 &lt;b&gt;1%&lt;/b&gt;와 &lt;b&gt;5%&lt;/b&gt;가 있습니다.&lt;/p&gt;
&lt;p&gt;이 오차율을 이용하여 다음과 같이 활용하여 몇차원으로 줄일지 결정할 수 있습니다. 우선 우리가 알고리즘을 구현하였다면, &lt;b&gt;k 값&lt;/b&gt;을 &lt;b&gt;1&lt;/b&gt;부터 시작하여 1씩 늘려나가면서 &lt;b&gt;각 k 값에 대한 오차율&lt;/b&gt;을 구할 수 있을 것입니다. 이때 k값을 늘려나가다가 &lt;b&gt;오차율이 1% 이하가 되는 그떄의 k값&lt;/b&gt;을 선택하여 활용하면 되는 것입니다.&lt;/p&gt;
&lt;p&gt;예를 들어 k = 16 이었을 때 오차율이 1.18% 였다가, k = 17이 되면서 오차율이 0.99%가 되어서 1% 이하로 되었다면 우리가 감소시킬 차원은 17차원이 되는 것입니다.&lt;/p&gt;
&lt;p&gt;몇 차원으로 줄일지 정하는 또 하나의 방법은 &lt;b&gt;특이값 분해(SVD)&lt;/b&gt;를 이용하는 것입니다. 제가 이 부분에 대해서 깊이 이해하지는 못했지만 간단하게 SVD가 어떤 역할을 하는지에 대해 설명해보겠습니다.&lt;/p&gt;
&lt;p&gt;우리가 &lt;b&gt;PCA 알고리즘&lt;/b&gt;을 사용하는 것은 높은 차원에서 낮은 차원으로 데이터를 차원 감소시키기 위함입니다. 이 과정에서 '&lt;b&gt;SVD'는 차원을 낮출 때 데이터들 간의 상관관계를 그대로 유지시켜주는 수단입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;다시 말해서 우리가 n개의 PC 중 분산도가 가장 높은 k개의 PC 만을 골라 그곳에 데이터를 투영시켜주게 되는데 아시다시피 이 &lt;b&gt;PC들은 서로 직교 관계&lt;/b&gt;에 있습니다. 즉 &lt;b&gt;SVD&lt;/b&gt;는 n차원의 PC에서 k 차원의 PC로 줄일 떄 &lt;b&gt;PC들간의 직교 관계를 그대로 유지시켜 주는데 하나의 수단으로 쓰이는 것으로 보입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;230&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yuknM/btqEil7xWgF/I0PLDk2O8m1JDoceE9LZL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yuknM/btqEil7xWgF/I0PLDk2O8m1JDoceE9LZL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yuknM/btqEil7xWgF/I0PLDk2O8m1JDoceE9LZL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyuknM%2FbtqEil7xWgF%2FI0PLDk2O8m1JDoceE9LZL0%2Fimg.png&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;230&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;어쨌든 이 SVD를 이용하여 1에서 &lt;b&gt;K차원 SVD값(S)과 N차원 SVD값의 비율&lt;/b&gt;을 뺴서 0.01보다 작게 나오는 k값을 선택하는 것입니다. 이 식을 오른쪽 식처럼 SVD에 대한 항을 우변으로 옮기고 나머지를 좌변으로 옮기면 0.99 이상의 &lt;b&gt;복원율&lt;/b&gt;을 만족하게끔 한다는 것을 알 수 있습니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;PCA 알고리즘의 적용&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;PCA 알고리즘&lt;/b&gt;은 &lt;b&gt;비지도 학습(unsupervised Leaning)&lt;/b&gt;에서 쓰는 알고리즘이지만, 차원을 감소시켜 데이터를 가볍게 하여 머신러닝 학습의 속도를 높인다는 점에서 &lt;b&gt;Supervised Learning&lt;/b&gt;에서도 활용이 가능합니다.&lt;/p&gt;
&lt;p&gt;Supervised Learning에 대한 복습이 필요하신 분은 아래 포스팅을 참고해주시면 됩니다 :)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/6&quot;&gt;https://box-world.tistory.com/6&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1594562159847&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[머신러닝] 비용함수(Cost Function)란&quot; data-og-description=&quot;시작하며 오늘 포스팅에서는 머신러닝의 기본적인 모델과 함께 가설함수(hypothesis) 와 비용함수 (Cost Function) 를 알아보며 다음 포스팅에서 알아볼 경사 하강 알고리즘을 위한 기초를 다져보겠습�&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/6&quot; data-og-url=&quot;https://box-world.tistory.com/6&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UMQoi/hyGJQvri6C/qhkq9V4a80s5UDCP9gISpk/img.png?width=715&amp;amp;height=532&amp;amp;face=0_0_715_532,https://scrap.kakaocdn.net/dn/G13Ek/hyGK73oLsS/P6kq2opUGkKbZgMVCz4qLk/img.png?width=715&amp;amp;height=532&amp;amp;face=0_0_715_532,https://scrap.kakaocdn.net/dn/v4Bqb/hyGJMNkRgF/J82pEs1Gi5qayBnYigFkkK/img.png?width=813&amp;amp;height=362&amp;amp;face=0_0_813_362&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/6&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UMQoi/hyGJQvri6C/qhkq9V4a80s5UDCP9gISpk/img.png?width=715&amp;amp;height=532&amp;amp;face=0_0_715_532,https://scrap.kakaocdn.net/dn/G13Ek/hyGK73oLsS/P6kq2opUGkKbZgMVCz4qLk/img.png?width=715&amp;amp;height=532&amp;amp;face=0_0_715_532,https://scrap.kakaocdn.net/dn/v4Bqb/hyGJMNkRgF/J82pEs1Gi5qayBnYigFkkK/img.png?width=813&amp;amp;height=362&amp;amp;face=0_0_813_362');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;[머신러닝] 비용함수(Cost Function)란&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 오늘 포스팅에서는 머신러닝의 기본적인 모델과 함께 가설함수(hypothesis) 와 비용함수 (Cost Function) 를 알아보며 다음 포스팅에서 알아볼 경사 하강 알고리즘을 위한 기초를 다져보겠습�&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;454&quot; data-filename=&quot;blob&quot; width=&quot;751&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfDouw/btqEk2yt2Je/ESEV00WZQk0SrEdJYOqCgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfDouw/btqEk2yt2Je/ESEV00WZQk0SrEdJYOqCgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfDouw/btqEk2yt2Je/ESEV00WZQk0SrEdJYOqCgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfDouw%2FbtqEk2yt2Je%2FESEV00WZQk0SrEdJYOqCgk%2Fimg.png&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;454&quot; data-filename=&quot;blob&quot; width=&quot;751&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;우선 적용을 위하여 &lt;b&gt;Labeled된 dataset에서 x 값만 추출해냅니다.&lt;/b&gt; 즉 &lt;b&gt;Unlabeled Data&lt;/b&gt;로 바꾸는 것입니다. 그리고 이 x data에 &lt;b&gt;PCA 알고리즘을 적용&lt;/b&gt;하여 &lt;b&gt;차원이 감소된 데이터 'z'&lt;/b&gt;를 도출합니다. 그리고 이 z data와 차원이 감소되기 전 매칭되던 y data를 매칭시켜 &lt;b&gt;새로운 training dataset&lt;/b&gt;을 생성합니다. 그러면 가설함수나 cost 함수 또한 x 대신 z가 대신하는 것이 가능해집니다. 이렇게 PCA 알고리즘에 의해 새롭게 맵핑된 z data는 &lt;b&gt;test set&lt;/b&gt;과 &lt;b&gt;cv set&lt;/b&gt;에도 사용이 가능합니다.&lt;/p&gt;
&lt;p&gt;이렇게 PCA 알고리즘을 이용하면 데이터가 가벼워지기 때문에, &lt;b&gt;메모리나 디스크와 같은 HW 사용&lt;/b&gt;을 줄일 수 있으며, &lt;b&gt;머신러닝 학습속도&lt;/b&gt;를 향상시키고 &lt;b&gt;데이터를 시각화(visualization)&lt;/b&gt;시키는데에도 유용하게 사용됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;747&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcEaYH/btqEjqtJWmx/btnkElXlw4DyRqwdZkOkL1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcEaYH/btqEjqtJWmx/btnkElXlw4DyRqwdZkOkL1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcEaYH/btqEjqtJWmx/btnkElXlw4DyRqwdZkOkL1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcEaYH%2FbtqEjqtJWmx%2FbtnkElXlw4DyRqwdZkOkL1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;747&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이런 PCA 알고리즘 대표적으로 사용되는 분야가 &lt;b&gt;'얼굴 인식(Face Recognition)'&lt;/b&gt;입니다. 간단히 설명드리자면 얼굴 인식에서 사용되는 &lt;b&gt;20 개의 데이터가 45 x 40&lt;/b&gt; 이라고 해보겠습니다. 그러면 각 픽셀을 feature라고 생각하면 $45 * 40 = 1800$이므로 &lt;b&gt;데이터는 1800차원의 벡터라고 생각할 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;그러면 우리가 이전에 4차원의 데이터를 2차원으로 줄일 때, 4개의 PC에서 분산도가 높은 2개의 PC만을 걸러내서 데이터를 투영시켰을 때, 이때 &lt;b&gt;분산도가 높다는 것은 데이터에 많은 영향을 준다는 것이었습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;747&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Axlq6/btqElFpfcR9/aKxiyegowWlunYi4Pb9Ql1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Axlq6/btqElFpfcR9/aKxiyegowWlunYi4Pb9Ql1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Axlq6/btqElFpfcR9/aKxiyegowWlunYi4Pb9Ql1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAxlq6%2FbtqElFpfcR9%2FaKxiyegowWlunYi4Pb9Ql1%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;747&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그러니 얼굴 인식에서도 1800차원 데이터에 대해 &lt;b&gt;1800개의 PC를 생성하여 분산도가 높은 순으로 뽑아낸 20~30개의 PC에서 뽑아낸 이미지는 데이터에 공통된 요소를 잘 내포하고 있을 것입니다.&lt;/b&gt; 이를 &lt;b&gt;EigenFace&lt;/b&gt;라고도 합니다. 그리고 &lt;b&gt;분산도가 낮은 PC일수록 세부적인 정보 차이를 나타내게 되며 이를 '노이즈(noise)성 정보'라고 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;b&gt;그러나 PCA 알고리즘이 항상 좋은 것은 아닙니다.&lt;/b&gt; 원래의 데이터에서 차원을 낮춘다는 점에서 feature가 적은 데이터에서 자주 일어나는 &lt;b&gt;Overfit 발생의 여지&lt;/b&gt;가 있습니다. 혹은 Overfit이 발생하였을 때, 모델의 차수를 낮추고자 &lt;b&gt;PCA 알고리즘을 사용하는 것보다는 정규화(Normalization)의 람다를 이용하여 문제를 해결하는 것이 훨씬 효과적입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;따라서 Data가 복잡하다고 해서 무조건 PCA를 이용하기보다는, 우선 기존의 Data를 이용하여 학습해보고 메모리나 디스크의 부족 문제로 정상적인 수행이 어렵거나 데이터가 무거워 학습 시간이 오래 걸릴 경우 사용하는 것을 추천 드립니다.&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>cost 함수</category>
      <category>PCA</category>
      <category>svd</category>
      <category>경사 하강 알고리즘</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>인공지능</category>
      <category>인하대</category>
      <category>지도 학습</category>
      <category>차원 감소</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/34</guid>
      <comments>https://box-world.tistory.com/34#entry34comment</comments>
      <pubDate>Thu, 21 May 2020 19:08:28 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] PCA(Principal Component Analysis) 알고리즘이란?</title>
      <link>https://box-world.tistory.com/33</link>
      <description>&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f89009;&quot;&gt;&lt;b&gt;&amp;Prime;성공의 핵심 요소는 인내심이다.&amp;rdquo;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f89009;&quot;&gt;&lt;b&gt;-Bill Gates-&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;시작하며&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;우리 저번 포스팅에서 Data Compression 또는 Dimentianality Reduction의 기본적인 원리를 알아보았습니다. 이번 시간에는 이러한 원리를 바탕으로 효과적으로 차원을 줄이는 알고리즘인 &lt;b&gt;PCA(Principal Component Analysis) Algorithm&lt;/b&gt;에 대해 공부해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;한가지 유의할 점&lt;/b&gt;은 기존에 많은 분들이 PCA에 대해 다루실 때 수학적으로 접근하여 설명하는 부분이 저에게는 잘 와닿지 않았습니다. 그래서 저는 그보다는 쉽게 이해할 수 있도록, 빠지는 개념은 없지만 최대한 풀어서 설명하도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;이번 포스팅은 아래 포스팅을 공부하고 보시면 더욱 효과적입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/32&quot;&gt;https://box-world.tistory.com/32&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;PCA Algorithm&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;222&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btlwhk/btqEeYxFMB3/hdDkhNOaDYxvZzDibBRBR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btlwhk/btqEeYxFMB3/hdDkhNOaDYxvZzDibBRBR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btlwhk/btqEeYxFMB3/hdDkhNOaDYxvZzDibBRBR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbtlwhk%2FbtqEeYxFMB3%2FhdDkhNOaDYxvZzDibBRBR0%2Fimg.png&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;222&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기 &lt;b&gt;쥐와 유전에 대한 상관관계를 표현해놓은 Dataset&lt;/b&gt;이 있습니다. 2 개의 유전자는 Feature를 뜻하고, 6 마리의 쥐는 데이터를 의미합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;322&quot; data-filename=&quot;blob&quot; width=&quot;809&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAr1M8/btqEfqghj4v/r8qErkwvZjQ39T4NQEqkd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAr1M8/btqEfqghj4v/r8qErkwvZjQ39T4NQEqkd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAr1M8/btqEfqghj4v/r8qErkwvZjQ39T4NQEqkd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAr1M8%2FbtqEfqghj4v%2Fr8qErkwvZjQ39T4NQEqkd0%2Fimg.png&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;322&quot; data-filename=&quot;blob&quot; width=&quot;809&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;b&gt;만약 Feature가 하나라면,&lt;/b&gt; 우리는 데이터를 위와 같이 하나의 직선 위에 나타낼 수 있습니다. 특히 이때 'Mouse' 1, 2, 3번의 값은 낮고 4, 5, 6번의 값은 높다는 것을 알 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;401&quot; data-filename=&quot;blob&quot; width=&quot;810&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baV4Qk/btqEhPzbVFO/gExa7jHS7h2X9qskWXxLok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baV4Qk/btqEhPzbVFO/gExa7jHS7h2X9qskWXxLok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baV4Qk/btqEhPzbVFO/gExa7jHS7h2X9qskWXxLok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaV4Qk%2FbtqEhPzbVFO%2FgExa7jHS7h2X9qskWXxLok%2Fimg.png&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;401&quot; data-filename=&quot;blob&quot; width=&quot;810&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;만약 Feature가 두개라면,&lt;/b&gt; 우리는 하나의 축을 추가하여 데이터를 다음과 같이 표현할 수 있습니다. 이때도 역시 비슷한 데이터들끼리 모여있다는 것&lt;b&gt;(Cluster)&lt;/b&gt;을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;370&quot; data-filename=&quot;blob&quot; width=&quot;801&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJ2H2e/btqEfqm2QAX/SOPxkvDDhC2VGpKKsHbAEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJ2H2e/btqEfqm2QAX/SOPxkvDDhC2VGpKKsHbAEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJ2H2e/btqEfqm2QAX/SOPxkvDDhC2VGpKKsHbAEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJ2H2e%2FbtqEfqm2QAX%2FSOPxkvDDhC2VGpKKsHbAEK%2Fimg.png&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;370&quot; data-filename=&quot;blob&quot; width=&quot;801&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;만약 Feature가 세개라면,&lt;/b&gt; 다시 한번 축을 추가하여 데이터를 3차원 위에서 표현할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;317&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIRJxC/btqEepoCef1/kdtp0mSXRZzKGQSqROt5V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIRJxC/btqEepoCef1/kdtp0mSXRZzKGQSqROt5V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIRJxC/btqEepoCef1/kdtp0mSXRZzKGQSqROt5V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIRJxC%2FbtqEepoCef1%2Fkdtp0mSXRZzKGQSqROt5V0%2Fimg.png&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;317&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;하지만 4개의 유전자라면 즉 Feature가 4개라면,&lt;/b&gt; 4차원이기 때문에 더 이상 데이터를 표현할 수 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;401&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPvHA7/btqEfrlV6Yn/0A8wVuImxLJChXXvV7MHL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPvHA7/btqEfrlV6Yn/0A8wVuImxLJChXXvV7MHL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPvHA7/btqEfrlV6Yn/0A8wVuImxLJChXXvV7MHL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPvHA7%2FbtqEfrlV6Yn%2F0A8wVuImxLJChXXvV7MHL0%2Fimg.png&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;401&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;그래서 이제부터 우리는 PCA가 어떻게 4개 이상의 유전자를 측정할 수 있는지 알아볼 것입니다. 즉 &lt;b&gt;4개 이상의 차원에 존재하는 데이터를 PCA를 이용하여 2차원으로 감소시켜 표현할 것입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;그리고 위 그래프에서 쥐 1,2,3과 4,5,6은 여전히 군집해있다는 것을 확인할 수 있습니다. 그래서 우리는 &lt;b&gt;PCA가 어떻게 특정 Feature를 Data Clustering에 가장 중요한지 알려줄 수 있는지&lt;/b&gt;도 알아볼 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwMlNI/btqEfXL4G6E/GpRWmWYGGhVqkv2jiutADk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwMlNI/btqEfXL4G6E/GpRWmWYGGhVqkv2jiutADk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwMlNI/btqEfXL4G6E/GpRWmWYGGhVqkv2jiutADk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwMlNI%2FbtqEfXL4G6E%2FGpRWmWYGGhVqkv2jiutADk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우선 PCA가 무엇인지, 그리고 작동 원리가 무엇인지 알아보기 위해 다시 &lt;b&gt;데이터의 Feature를 두개로 줄여보겠습니다.&lt;/b&gt;&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/dtJaEh/btqEhPM1gDT/7SiJOLN6ckIXvBdt7Z8PKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtJaEh/btqEhPM1gDT/7SiJOLN6ckIXvBdt7Z8PKk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 50.0666%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtJaEh/btqEhPM1gDT/7SiJOLN6ckIXvBdt7Z8PKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtJaEh%2FbtqEhPM1gDT%2F7SiJOLN6ckIXvBdt7Z8PKk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A9vaa/btqEiM9VboW/3FJ6CUozeeFsoKA1VEauXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A9vaa/btqEiM9VboW/3FJ6CUozeeFsoKA1VEauXk/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 48.7706%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A9vaa/btqEiM9VboW/3FJ6CUozeeFsoKA1VEauXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA9vaa%2FbtqEiM9VboW%2F3FJ6CUozeeFsoKA1VEauXk%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;751&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbGaka/btqEimXZhnK/EOWMUxqLzIafuVI1YuCk30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbGaka/btqEimXZhnK/EOWMUxqLzIafuVI1YuCk30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbGaka/btqEimXZhnK/EOWMUxqLzIafuVI1YuCk30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbGaka%2FbtqEimXZhnK%2FEOWMUxqLzIafuVI1YuCk30%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;751&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그 다음 위 2개의 이미지처럼 Gene 1의 평균과 Gene 2의 평균을 도출하여 아래 이미지와 같이&amp;nbsp;&lt;b&gt;데이터의 중심&lt;/b&gt;이 어디인지를 파악합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;758&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FwzKA/btqEfrzQG5u/4CfiLwIOqWNSfNCi4zlOqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FwzKA/btqEfrzQG5u/4CfiLwIOqWNSfNCi4zlOqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FwzKA/btqEfrzQG5u/4CfiLwIOqWNSfNCi4zlOqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFwzKA%2FbtqEfrzQG5u%2F4CfiLwIOqWNSfNCi4zlOqK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;758&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 데이터의 상대적인 분포는 변화시키지 않고 그대로 &lt;b&gt;데이터의 중심을 원점으로 옮깁니다.&lt;/b&gt;&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/cZxhba/btqEg11ersU/Z4CEnU6CQWpCTtuLzk7870/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZxhba/btqEg11ersU/Z4CEnU6CQWpCTtuLzk7870/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 50.1931%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZxhba/btqEg11ersU/Z4CEnU6CQWpCTtuLzk7870/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZxhba%2FbtqEg11ersU%2FZ4CEnU6CQWpCTtuLzk7870%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yj5Zs/btqEfYdbo9i/yNLCkqdCcQZpNXo1t8raE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yj5Zs/btqEfYdbo9i/yNLCkqdCcQZpNXo1t8raE1/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 48.6441%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yj5Zs/btqEfYdbo9i/yNLCkqdCcQZpNXo1t8raE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyj5Zs%2FbtqEfYdbo9i%2FyNLCkqdCcQZpNXo1t8raE1%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제&lt;b&gt; 원점을 지나는 랜덤한 직선&lt;/b&gt;을 하나 생성합니다. 그리고 데이터에 &lt;b&gt;fit&lt;/b&gt;하도록 &lt;b&gt;직선을 회전&lt;/b&gt;시키면 오른쪽 그림의 결과가 나옵니다. 그런데 데이터에 fit하다는 것은 어떤 의미이며, 어떤 방법으로 데이터에 fit한 직선을 구하는지&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;477&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlXwuJ/btqEeYqS2Qf/CI1AHtGtqiuAhOqjIXxqmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlXwuJ/btqEeYqS2Qf/CI1AHtGtqiuAhOqjIXxqmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlXwuJ/btqEeYqS2Qf/CI1AHtGtqiuAhOqjIXxqmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlXwuJ%2FbtqEeYqS2Qf%2FCI1AHtGtqiuAhOqjIXxqmK%2Fimg.png&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;477&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리가 방금 랜덤하게 생성한 선에 &lt;b&gt;데이터를 투영&lt;/b&gt;합니다. 그리고 이 &lt;b&gt;선과 데이터의 거리&lt;/b&gt;를 측정하여 이 거리를 &lt;b&gt;최소화하는 직선&lt;/b&gt;을 찾습니다. &lt;b&gt;즉 PCA에게 데이터에 fit한 직선이라는 것은 데이터들과 거리가 가장 작은 직선을 의미합니다.&lt;/b&gt;&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/bi4ZT2/btqEg1tsinQ/httbYWweHkOF8uU0uCVs01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi4ZT2/btqEg1tsinQ/httbYWweHkOF8uU0uCVs01/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 52.2866%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi4ZT2/btqEg1tsinQ/httbYWweHkOF8uU0uCVs01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi4ZT2%2FbtqEg1tsinQ%2FhttbYWweHkOF8uU0uCVs01%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JWFd6/btqEg11eyM0/xBR5cjq0OAEMKyJPbzIy7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JWFd6/btqEg11eyM0/xBR5cjq0OAEMKyJPbzIy7k/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 46.5506%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JWFd6/btqEg11eyM0/xBR5cjq0OAEMKyJPbzIy7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJWFd6%2FbtqEg11eyM0%2FxBR5cjq0OAEMKyJPbzIy7k%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이렇게 '데이터와 직선의 거리를 최소화한다는 것'은 &lt;b&gt;원점에서 데이터가 투영된 점들까지의 거리를 최대화하는 선&lt;/b&gt;을 찾는다는 것을 의미합니다. 이 부분이 이해가 안될 수도 있는데 오른쪽 이미지처럼 데이터와 fit한 선을 찾았을 때 왼쪽의 이미지보다 원점에서 투영된 점들까지의 거리가 늘어나는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지금까지 우리는 데이터에 fit한 하나의 직선을 찾았습니다. 아직 긴가민가 하시겠지만 절 믿고 따라오시면 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nlZFF/btqEghwIKsz/t9QKcFSMmUXtTJs4OkXzHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nlZFF/btqEghwIKsz/t9QKcFSMmUXtTJs4OkXzHK/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 47.0089%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nlZFF/btqEghwIKsz/t9QKcFSMmUXtTJs4OkXzHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnlZFF%2FbtqEghwIKsz%2Ft9QKcFSMmUXtTJs4OkXzHK%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xVfWX/btqEghp6z2B/ZqkqJoeSF4C45s3G8iHc3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xVfWX/btqEghp6z2B/ZqkqJoeSF4C45s3G8iHc3K/img.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; style=&quot;width: 51.8283%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xVfWX/btqEghp6z2B/ZqkqJoeSF4C45s3G8iHc3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxVfWX%2FbtqEghp6z2B%2FZqkqJoeSF4C45s3G8iHc3K%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;0&quot; height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 보다 수학적으로 이해하기 위해 왼쪽 그림처럼&amp;nbsp;&lt;b&gt;하나의 점&lt;/b&gt;만 생각해보겠습니다. 우선 &lt;b&gt;데이터와 원점의 거리&lt;/b&gt;는 변하지 않습니다. 그리고 &lt;b&gt;점을 직선에 투영&lt;/b&gt;할 때 &lt;b&gt;직각&lt;/b&gt;을 이루게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이때 이를 오른쪽 그림처럼&amp;nbsp;&lt;b&gt;직각삼각형&lt;/b&gt;으로 보면 &lt;b&gt;점과 원점 사이의 거리 a&lt;/b&gt;는 변하지 않기 때문에 &lt;b&gt;b와 c는 반비례 관계&lt;/b&gt;를 가지게 됩니다. 눈치가 빠르신 분이라면 PCA 입장에서는 점과 직선 사이의 거리를 줄이려고 하기 때문에 &lt;b&gt;b를 줄이고 c를 늘리려할 것이라는 걸 알 수 있습니다.&lt;/b&gt; 다만 실제 구현에서는 b를 구해서 최소화 하는 것보단 &lt;b&gt;원점에서 투영된 점의 거리인 c를 구해서 이를 최대화하려는 것이 훨씬 쉽습니다.&lt;/b&gt;&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/Gjfoy/btqEfrGtApw/Qv2qAz43Zqlpi00YVX8S11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gjfoy/btqEfrGtApw/Qv2qAz43Zqlpi00YVX8S11/img.png&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;505&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&quot; style=&quot;width: 48.8435%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gjfoy/btqEfrGtApw/Qv2qAz43Zqlpi00YVX8S11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGjfoy%2FbtqEfrGtApw%2FQv2qAz43Zqlpi00YVX8S11%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;818&quot; height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/08EWR/btqEgQ6B1iu/fR88DLHU4zHJ38UYaVe6EK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/08EWR/btqEgQ6B1iu/fR88DLHU4zHJ38UYaVe6EK/img.png&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;497&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.9937%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/08EWR/btqEgQ6B1iu/fR88DLHU4zHJ38UYaVe6EK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F08EWR%2FbtqEgQ6B1iu%2FfR88DLHU4zHJ38UYaVe6EK%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;824&quot; height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이를 이제 왼쪽 그림처럼 여러개의 점들에 확장하여 적용해보겠습니다. 우선 데이터들을 직선에 &lt;b&gt;투영&lt;/b&gt;합니다. 그 다음 오른쪽 그림처럼 '6개의 점들' 각각과 '원점'과의 거리인 &lt;b&gt;d1부터 d6&lt;/b&gt;까지 계산합니다. 그 다음 이들을 &lt;b&gt;제곱&lt;/b&gt;하여 &lt;b&gt;음수와 양수가 상쇄되는 것&lt;/b&gt;을 방지합니다. 그리고 이 값들을 모두 더하게 되면 그림 위쪽과 같은 식이 나오게 되고, 우리는 이를 &lt;b&gt;거리 제곱의 합 'SS'&lt;/b&gt;라고 부릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;즉 다시 말해서 제가 아까 말했던 원점과 데이터가 직선에 투영된 점 사이의 거리를 최대화하는 직선을 찾아야 한다는 것은 결국 SS 값을 최대화하는 직선을 찾아야 한다는 것과 같은 의미입니다.&lt;/span&gt;&lt;/b&gt;&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/csG7Zj/btqEgQMe40U/MnmrW8DrnIKxQv1Gh7GZm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csG7Zj/btqEgQMe40U/MnmrW8DrnIKxQv1Gh7GZm0/img.png&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;453&quot; data-filename=&quot;blob&quot; style=&quot;width: 53.0071%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csG7Zj/btqEgQMe40U/MnmrW8DrnIKxQv1Gh7GZm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsG7Zj%2FbtqEgQMe40U%2FMnmrW8DrnIKxQv1Gh7GZm0%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;826&quot; height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EDf97/btqEg2eyhk3/GGNqkgDtyN6Go2Np8MlCz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EDf97/btqEg2eyhk3/GGNqkgDtyN6Go2Np8MlCz1/img.png&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;477&quot; data-filename=&quot;blob&quot; style=&quot;width: 45.8302%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EDf97/btqEg2eyhk3/GGNqkgDtyN6Go2Np8MlCz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEDf97%2FbtqEg2eyhk3%2FGGNqkgDtyN6Go2Np8MlCz1%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;752&quot; height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이러한 과정을 거쳐 &lt;b&gt;최대의 SS를 가지는 직선&lt;/b&gt;을 &lt;b&gt;PC1&lt;/b&gt;이라고 지정합니다. 이 PC1은 &lt;b&gt;0.25의 기울기&lt;/b&gt;를 가집니다. 이때 &lt;b&gt;기울기가 0.25&lt;/b&gt;라는 말은 &lt;b&gt;Gene 1이 4번의 단위&lt;/b&gt;만큼 증가할 때, &lt;b&gt;Gene 2는 1번의 단위&lt;/b&gt;만큼 증가하는 것을 의미합니다. 이것은 &lt;b&gt;대부분의 데이터가 Gene 1을 따라 분산되어 있고, 아주 적은 데이터가 Gene 2을 따라 분산되어 있다는 것을 의미합니다. &lt;/b&gt;아마 이 문장이 잘 이해가 안가실텐데 다음 문단에서 이해가기 쉽게 설명해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;472&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd12zo/btqEh7T2nfJ/5fq6jAELeqheleYQHKj34k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd12zo/btqEh7T2nfJ/5fq6jAELeqheleYQHKj34k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd12zo/btqEh7T2nfJ/5fq6jAELeqheleYQHKj34k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd12zo%2FbtqEh7T2nfJ%2F5fq6jAELeqheleYQHKj34k%2Fimg.png&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;472&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;방금 설명을 &lt;b&gt;'칵테일 레시피'&lt;/b&gt;라는 것으로 쉽게 비유해보겠습니다. Gene 1을 4 조각, Gene 2를 1조각 그리고 얼음을 넣고 섞었다고 생각해보겠습니다. 그러면 우리가 마실 칵테일에서는 Gene 1의 맛이 더 많이 느껴지겠죠? 이것이 &lt;b&gt;분산되어있는 데이터에서 Gene 1이 더 중요하다는 의미&lt;/b&gt;와 일맥상 통하게 됩니다. 수학자들은 이러한 칵테일 레시피를 &lt;b&gt;'선형 결합(Linear Combination)'&lt;/b&gt;이라고 부릅니다. 그리고 우리가 지금까지 본 이 PC1을 &lt;b&gt;변수들의 선형 결합&lt;/b&gt;이라고 부르기도 하지만 저는 이런 어려운 용어를 쓰지 않겠습니다 :(&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/t1MTa/btqEfrGuL2H/XPDRj6jF4YVu1gk5ZEDaLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t1MTa/btqEfrGuL2H/XPDRj6jF4YVu1gk5ZEDaLK/img.png&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;481&quot; data-filename=&quot;blob&quot; style=&quot;width: 44.8343%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t1MTa/btqEfrGuL2H/XPDRj6jF4YVu1gk5ZEDaLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft1MTa%2FbtqEfrGuL2H%2FXPDRj6jF4YVu1gk5ZEDaLK%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;760&quot; height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz7k0a/btqEhQyfeuw/xagUMZxh1FpnTnqqJ0xrP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz7k0a/btqEhQyfeuw/xagUMZxh1FpnTnqqJ0xrP0/img.png&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;475&quot; data-filename=&quot;blob&quot; style=&quot;width: 54.0029%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz7k0a/btqEhQyfeuw/xagUMZxh1FpnTnqqJ0xrP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz7k0a%2FbtqEhQyfeuw%2FxagUMZxh1FpnTnqqJ0xrP0%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;904&quot; height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 우린 &lt;b&gt;피타고라스의 정리&lt;/b&gt;를 이용해서 &lt;b&gt;빨간색 선의 길이&lt;/b&gt;를 계산할 수 있습니다. $1^2+4^2 = 17$이므로 결과값은 $\sqrt{17} = 4.12$가 됩니다. 그리고 &lt;b&gt;SVD(특이값 분해)&lt;/b&gt;라는 것을 통해&amp;nbsp;우리가 도출한 가장 적합한 &lt;b&gt;PC1의 단위벡터&lt;/b&gt;를 구해줄 것입니다. 이때 SVD 적용을 위해 빨간색 선의 길이는 1이 되어야 하기 때문에 세 변을 4.12로 모두 나누어줍니다. 하지만 &lt;b&gt;레시피에 들어가는 value값만 바뀌었을 뿐 비율은 여전히 동일합니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;475&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfjlzi/btqEgRqPFEc/nc27btcw6Kb9WAOXoeYxdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfjlzi/btqEgRqPFEc/nc27btcw6Kb9WAOXoeYxdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfjlzi/btqEgRqPFEc/nc27btcw6Kb9WAOXoeYxdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcfjlzi%2FbtqEgRqPFEc%2Fnc27btcw6Kb9WAOXoeYxdK%2Fimg.png&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;475&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다시 우리의 데이터로 돌아와보겠습니다. 현재 데이터와 방금 우리가 SVD를 통해 구한 &lt;b&gt;PC1에 대한 단위벡터&lt;/b&gt;가 있습니다. 이때 이 단위 벡터를 Gene 1의 0.97만큼과 Gene 2의 0.242 만큼으로 구성되어 있는 &lt;b&gt;Eigenvector(고유 벡터)&lt;/b&gt;라고 합니다. 그리고 이때 비율에 해당하는 0.97, 0.242는 &lt;b&gt;적재 점수(Loading score)&lt;/b&gt;라고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;478&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pWrmS/btqEepCf6aK/SrXFRBiGVhPgUBUawSl4Jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pWrmS/btqEepCf6aK/SrXFRBiGVhPgUBUawSl4Jk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pWrmS/btqEepCf6aK/SrXFRBiGVhPgUBUawSl4Jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpWrmS%2FbtqEepCf6aK%2FSrXFRBiGVhPgUBUawSl4Jk%2Fimg.png&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;478&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 우리가 위에서 구했던 원점과 투영된 점들의 거리 SS를 PC1을 위한 &lt;b&gt;Eigen value&lt;/b&gt;라고 합니다. 그리고 이것의 제곱근을 &lt;b&gt;PC1을 위한 Singular value&lt;/b&gt;라고 합니다.&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/HOzC9/btqEhQLM3I5/UUNoD6x9xN158KY3w8fBk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HOzC9/btqEhQLM3I5/UUNoD6x9xN158KY3w8fBk0/img.png&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;487&quot; data-filename=&quot;blob&quot; style=&quot;width: 48.9176%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HOzC9/btqEhQLM3I5/UUNoD6x9xN158KY3w8fBk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHOzC9%2FbtqEhQLM3I5%2FUUNoD6x9xN158KY3w8fBk0%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;860&quot; height=&quot;487&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpwQit/btqEepCgdLf/fZCi0wmFnAO6CwYMRFKVs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpwQit/btqEepCgdLf/fZCi0wmFnAO6CwYMRFKVs1/img.png&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;480&quot; data-filename=&quot;blob&quot; style=&quot;width: 49.9196%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpwQit/btqEepCgdLf/fZCi0wmFnAO6CwYMRFKVs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpwQit%2FbtqEepCgdLf%2FfZCi0wmFnAO6CwYMRFKVs1%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;865&quot; height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;501&quot; data-filename=&quot;blob&quot; width=&quot;676&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lhD1K/btqEepbcFyY/d1ViPYjTqKa6oXGCF0qwo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lhD1K/btqEepbcFyY/d1ViPYjTqKa6oXGCF0qwo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lhD1K/btqEepbcFyY/d1ViPYjTqKa6oXGCF0qwo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlhD1K%2FbtqEepbcFyY%2Fd1ViPYjTqKa6oXGCF0qwo0%2Fimg.png&quot; data-origin-width=&quot;905&quot; data-origin-height=&quot;501&quot; data-filename=&quot;blob&quot; width=&quot;676&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기에 왼쪽 위 그림처럼&amp;nbsp;&amp;nbsp;&lt;b&gt;PC2&lt;/b&gt;라는 것을 하나 더 그려봅시다. PC2는 그냥 원점을 지나면서 PC1과 직교하게끔 그으면 되기 때문에 복잡한 최적화 작업을 거칠 필요가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;다시 말해서 PC2의 레시피는 직교하기 때문에 Gene 1의 -1 단위, 그리고 Gene 2의 4 단위가 될 것이며, 그리고 이를 이용해 &lt;b&gt;PC2의 단위 벡터&lt;/b&gt;를 구하면 오른쪽과 같습니다. 그리고 우리가 PC1에 데이터를 투영했듯, PC2에도 데이터를 투영합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;476&quot; data-filename=&quot;blob&quot; width=&quot;751&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tKXBc/btqEg2r7TFH/rDp4EpGc8GfRFCSmoLeCck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tKXBc/btqEg2r7TFH/rDp4EpGc8GfRFCSmoLeCck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tKXBc/btqEg2r7TFH/rDp4EpGc8GfRFCSmoLeCck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtKXBc%2FbtqEg2r7TFH%2FrDp4EpGc8GfRFCSmoLeCck%2Fimg.png&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;476&quot; data-filename=&quot;blob&quot; width=&quot;751&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;최종적으로 구한 PC1과 PC2에 데이터를 투영한 결과입니다. 여기까지 읽는데 헷갈리시는 것도 많으실텐데 제가 마지막에 정리해드릴테니 따라와주시길 바랍니다! 이제 이제 마지막 단계를 위해 PC1을 &lt;b&gt;수평&lt;/b&gt;으로 회전시킵니다.&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/cjN7eJ/btqEfXSHqp9/6MoaKweiIBr2xFiD2KdtK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjN7eJ/btqEfXSHqp9/6MoaKweiIBr2xFiD2KdtK1/img.png&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;319&quot; data-filename=&quot;blob&quot; style=&quot;width: 42.1722%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjN7eJ/btqEfXSHqp9/6MoaKweiIBr2xFiD2KdtK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjN7eJ%2FbtqEfXSHqp9%2F6MoaKweiIBr2xFiD2KdtK1%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;450&quot; height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1fRL4/btqEh7Gvytq/krMFk6LB5pOzCH7pgQ8xJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1fRL4/btqEh7Gvytq/krMFk6LB5pOzCH7pgQ8xJ0/img.png&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;373&quot; data-filename=&quot;blob&quot; style=&quot;width: 56.665%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1fRL4/btqEh7Gvytq/krMFk6LB5pOzCH7pgQ8xJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1fRL4%2FbtqEh7Gvytq%2FkrMFk6LB5pOzCH7pgQ8xJ0%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;707&quot; height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;수평으로 회전시킨 후, 데이터가 어디있는지 찾기 위해 투영된 점들을 이용합니다. &lt;/span&gt;예를 들어, Sample 1의 경우 위와 같이 연결하여 맵핑되는 것이고 최종 결과는 오른쪽과 같이 됩니다.&lt;/span&gt;&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/kAR4U/btqEfrzFyVv/9OxBuk9pMouXKu4MS4julk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAR4U/btqEfrzFyVv/9OxBuk9pMouXKu4MS4julk/img.png&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;425&quot; data-filename=&quot;blob&quot; style=&quot;width: 53.5695%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAR4U/btqEfrzFyVv/9OxBuk9pMouXKu4MS4julk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAR4U%2FbtqEfrzFyVv%2F9OxBuk9pMouXKu4MS4julk%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;900&quot; height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvfHme/btqEh6OpCZF/UGKsJmBILkyaAGKyRkBtfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvfHme/btqEh6OpCZF/UGKsJmBILkyaAGKyRkBtfk/img.png&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;456&quot; data-filename=&quot;blob&quot; style=&quot;width: 45.2678%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvfHme/btqEh6OpCZF/UGKsJmBILkyaAGKyRkBtfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvfHme%2FbtqEh6OpCZF%2FUGKsJmBILkyaAGKyRkBtfk%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;816&quot; height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이제 마지막으로 한 가지 더 해야할 일이 있습니다. 우리가 이전에 &lt;b&gt;PC의 Eigenvalue&lt;/b&gt;로 부르던 &lt;b&gt;SS값&lt;/b&gt;을 왼쪽 그림처럼 샘플 사이즈 n -1으로 나눠 각각 &lt;b&gt;PC1, PC2의 분산(Variation)&lt;/b&gt;을 구합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;예를 들어 PC1의 분산도가 15, PC2의 분산도가 3이라면, 전체 분산도는 18일 경우 이중 PC1이 차지하는 비율은 83%이고, PC2는 17%가 됩니다. 이 분산도가 높을 수록 데이터에서 차지하는 비중이 높다는 것을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;오른쪽은 이를 보기 쉽게 &lt;b&gt;Scree plot&lt;/b&gt;이라는 것으로 나타낸 것입니다. 최종적으로 나온 이 결과 4개의 Feature를 가져 4차원으로 표현되던 데이터를 2차원으로 감소시킨 결과입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;요약&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1) 데이터에 fit한 직선 PC1을 구합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2) 기존에 데이터가 n차원이었다면, 원점을 지나며 기존 PC들과 직교하는 직선 n개를 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3) 각 PC의 분산도를 구하고 Scree plot을 이용하여 비교하기 쉽게 시각화합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4) 내가 만약 줄이려는 차원이 m차원이라면 분산도가 높은 순으로 m개 만큼의 PC만 남기고 나머지는 걷어냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;5) 이제 m개의 PC만 남았기 때문에 m차원이락 할 수 있고 여기에 데이터를 투영하면 끝입니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;415&quot; data-filename=&quot;blob&quot; width=&quot;753&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KXPkA/btqEil5OPuk/jfQM9tR3dol8IFyV6ePShk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KXPkA/btqEil5OPuk/jfQM9tR3dol8IFyV6ePShk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KXPkA/btqEil5OPuk/jfQM9tR3dol8IFyV6ePShk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKXPkA%2FbtqEil5OPuk%2FjfQM9tR3dol8IFyV6ePShk%2Fimg.png&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;415&quot; data-filename=&quot;blob&quot; width=&quot;753&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 좀더 복잡한 예시를 보겠습니다. 이번엔 Feature가 3개이고, 데이터는 오른쪽과 같이 3차원으로 표현됩니다. 우리는 이 데이터를 2차원으로 감소시킬 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;470&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1fCI3/btqEfrs4sbP/hWcl5JM36X2SLdk9tIeTJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1fCI3/btqEfrs4sbP/hWcl5JM36X2SLdk9tIeTJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1fCI3/btqEfrs4sbP/hWcl5JM36X2SLdk9tIeTJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1fCI3%2FbtqEfrs4sbP%2FhWcl5JM36X2SLdk9tIeTJk%2Fimg.png&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;470&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 데이터의 중심을 원점으로 옮긴 후 데이터가 가장 fit한 즉 SS값을 최대로 만드는 선을 찾아냅니다. 이 점선은 PC1을 위한 선입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;873&quot; data-origin-height=&quot;481&quot; data-filename=&quot;blob&quot; width=&quot;755&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKrCBT/btqEimXXWmN/iqciZ1xpndj2LkikaGKmK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKrCBT/btqEimXXWmN/iqciZ1xpndj2LkikaGKmK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKrCBT/btqEimXXWmN/iqciZ1xpndj2LkikaGKmK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKrCBT%2FbtqEimXXWmN%2FiqciZ1xpndj2LkikaGKmK0%2Fimg.png&quot; data-origin-width=&quot;873&quot; data-origin-height=&quot;481&quot; data-filename=&quot;blob&quot; width=&quot;755&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 우리가 구한 빨간색 점선의 기울기에 칵테일 레시피를 적용하면 위와 수치가 나오게 됩니다.(설명을 위해 수치를 구하는 과정은 생략하였습니다). 이 경우 Gene 3가 PC1에서 가장 중요하다고 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;467&quot; data-filename=&quot;blob&quot; width=&quot;750&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tu9sa/btqEeYkgnUG/yCrYAfWKkD1zk5n6v3v9aK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tu9sa/btqEeYkgnUG/yCrYAfWKkD1zk5n6v3v9aK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tu9sa/btqEeYkgnUG/yCrYAfWKkD1zk5n6v3v9aK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTu9sa%2FbtqEeYkgnUG%2FyCrYAfWKkD1zk5n6v3v9aK%2Fimg.png&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;467&quot; data-filename=&quot;blob&quot; width=&quot;750&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 빨간색 직선과 직교하면 원점을 통과하는 PC2를 생성합니다. 이때 Gene 1의 수치가 가장 크므로 PC2에서 제일 중요하다고 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;477&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ewBPFG/btqEh7fDLec/WjXTa6tFCIQG2L8VB2qLKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ewBPFG/btqEh7fDLec/WjXTa6tFCIQG2L8VB2qLKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ewBPFG/btqEh7fDLec/WjXTa6tFCIQG2L8VB2qLKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FewBPFG%2FbtqEh7fDLec%2FWjXTa6tFCIQG2L8VB2qLKk%2Fimg.png&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;477&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또 다시 PC1과 PC2와 직교하면서 원점을 지나는 PC3를 생성합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;496&quot; data-filename=&quot;blob&quot; width=&quot;745&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dk83JX/btqEeYq5IfU/2sXymhgT4ak8j3v1W2pHcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dk83JX/btqEeYq5IfU/2sXymhgT4ak8j3v1W2pHcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dk83JX/btqEeYq5IfU/2sXymhgT4ak8j3v1W2pHcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdk83JX%2FbtqEeYq5IfU%2F2sXymhgT4ak8j3v1W2pHcK%2Fimg.png&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;496&quot; data-filename=&quot;blob&quot; width=&quot;745&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 PC1, PC2, PC3의 Eigenvalue 즉 SS를 이용하여 각 PC가 차지하는 분산도의 비율을 위와 같이 결정할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;407&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHmkta/btqEfYYvlvQ/Oy2B7OYQUxk7ZEOGwfBBPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHmkta/btqEfYYvlvQ/Oy2B7OYQUxk7ZEOGwfBBPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHmkta/btqEfYYvlvQ/Oy2B7OYQUxk7ZEOGwfBBPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHmkta%2FbtqEfYYvlvQ%2FOy2B7OYQUxk7ZEOGwfBBPK%2Fimg.png&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;407&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리는 3차원에서 2차원으로 감소시키므로 저 PC들 중에서 분산도의 비율이 높은 순으로 PC1, PC2만 남겨놓고 나머지는 다 걷어냅니다.&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/baKtt9/btqEfqufo37/qhVWq3AEBKKF4Z2oyNlIp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baKtt9/btqEfqufo37/qhVWq3AEBKKF4Z2oyNlIp0/img.png&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;373&quot; data-filename=&quot;blob&quot; width=&quot;754&quot; height=&quot;NaN&quot; style=&quot;width: 53.4655%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baKtt9/btqEfqufo37/qhVWq3AEBKKF4Z2oyNlIp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaKtt9%2FbtqEfqufo37%2FqhVWq3AEBKKF4Z2oyNlIp0%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;781&quot; height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tNKJP/btqEggYSWZr/xcjNS4JgmqynIceWKeVnFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tNKJP/btqEggYSWZr/xcjNS4JgmqynIceWKeVnFk/img.png&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;363&quot; data-filename=&quot;blob&quot; style=&quot;width: 45.3717%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tNKJP/btqEggYSWZr/xcjNS4JgmqynIceWKeVnFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtNKJP%2FbtqEggYSWZr%2FxcjNS4JgmqynIceWKeVnFk%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;645&quot; height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 데이터를 PC1에 한번, PC2에 한번 투영 시킵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;408&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7tSED/btqEghp5kqr/uwhHs2EKzzQqINvsvWiogk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7tSED/btqEghp5kqr/uwhHs2EKzzQqINvsvWiogk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7tSED/btqEghp5kqr/uwhHs2EKzzQqINvsvWiogk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7tSED%2FbtqEghp5kqr%2FuwhHs2EKzzQqINvsvWiogk%2Fimg.png&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;408&quot; data-filename=&quot;blob&quot; width=&quot;748&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;투영 시킨 후 보기 편하도록 PC1의 기울기를 0이 되게끔 회전시켜줍니다.&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/csxyKP/btqEiNuc3zx/lYjmFO5t9hGBsd3oglKtmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csxyKP/btqEiNuc3zx/lYjmFO5t9hGBsd3oglKtmk/img.png&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;291&quot; data-filename=&quot;blob&quot; style=&quot;width: 62.7554%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csxyKP/btqEiNuc3zx/lYjmFO5t9hGBsd3oglKtmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsxyKP%2FbtqEiNuc3zx%2FlYjmFO5t9hGBsd3oglKtmk%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;848&quot; height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MxZx5/btqEg0VB3w2/TqpNEATFYDMzUX9Iqz4SL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MxZx5/btqEg0VB3w2/TqpNEATFYDMzUX9Iqz4SL1/img.png&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;416&quot; data-filename=&quot;blob&quot; style=&quot;width: 36.0818%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MxZx5/btqEg0VB3w2/TqpNEATFYDMzUX9Iqz4SL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMxZx5%2FbtqEg0VB3w2%2FTqpNEATFYDMzUX9Iqz4SL1%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;697&quot; height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 각 데이터가 PC1과 PC2에 투영했던 두개의 x를 이용하여 데이터를 다시 위치시키면 끝입니다.&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>cost</category>
      <category>PCA</category>
      <category>경사 하강 알고리즘</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>벡터</category>
      <category>인공지능</category>
      <category>인하대</category>
      <category>차원 감소</category>
      <category>행렬</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/33</guid>
      <comments>https://box-world.tistory.com/33#entry33comment</comments>
      <pubDate>Tue, 19 May 2020 22:46:59 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 데이터 압축(Data Compression), 차원 감소(Dimensionality Reduction) in 비지도 학습(Unsupervised Learning)</title>
      <link>https://box-world.tistory.com/32</link>
      <description>&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&quot;모두가 비슷한 생각을 한다는 것은 아무도 생각하고 있지 않다는 말이다&quot;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt; - 알버트 아인슈타인&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;시작하며&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;데이터 가공(Data Processing)&lt;/b&gt;은 머신러닝에서 가장 중요한 부분중 하나로 이를 어떻게 하느냐에 따라 머신러닝의 성능이 좌지우지되기도 합니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이번 포스팅은 연산 시간을 크게 줄이는 방법 중 하나로 &lt;b&gt;데이터 압축(Data Compression)&lt;/b&gt; 혹은 &lt;b&gt;차원 감소(Dimensionality Reduction)&lt;/b&gt;에 대해서 공부해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Data Compression&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;머신러닝에서 &lt;b&gt;데이터를 압축한다는 것&lt;/b&gt;은 &lt;b&gt;고차원의 데이터를 저차원의 데이터로 축소하는 방식&lt;/b&gt;을 의미하며, 이를 통해 전체 연산량을 줄여서 최종적으로 학습 시간을 단축하는 것입니다. &lt;b&gt;이것이 왜 필요한 것일까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1IJhy/btqEggC6fwm/pMUaSLspqXkkcMiMBzxgg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1IJhy/btqEggC6fwm/pMUaSLspqXkkcMiMBzxgg1/img.png&quot; data-alt=&quot;Dimension이 커질수록 알고리즘의 성능은 0에 수렴한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1IJhy/btqEggC6fwm/pMUaSLspqXkkcMiMBzxgg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1IJhy%2FbtqEggC6fwm%2FpMUaSLspqXkkcMiMBzxgg1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Dimension이 커질수록 알고리즘의 성능은 0에 수렴한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이는 바로 &lt;b&gt;'차원의 저주(Curse of dimensionality)'&lt;/b&gt;라는 것 때문입니다. 즉 차원이 증가하면 그것을 표현하기 위한 데이터의 양이 기하급수적으로 증가하기 때문에 데이터를 다루기 어려워지고 전체적인 알고리즘의 성능은 크게 감소하게 됩니다. 따라서 &lt;b&gt;우리는 차원을 감소시켜 데이터의 의미를 제대로 표현하는 특징만 추려 학습에 이용하겠다는 것입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGxQ2K/btqEd7AynTM/HWz4z7xvPBCK6QNeacUNMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGxQ2K/btqEd7AynTM/HWz4z7xvPBCK6QNeacUNMk/img.png&quot; data-alt=&quot;차원이 증가할수록 담겨진 데이터가 적어집니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGxQ2K/btqEd7AynTM/HWz4z7xvPBCK6QNeacUNMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGxQ2K%2FbtqEd7AynTM%2FHWz4z7xvPBCK6QNeacUNMk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;차원이 증가할수록 담겨진 데이터가 적어집니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;위는 데이터의 차원이 증가하면서 같은 공간에 데이터를 얼마나 담을 수 있는지 표현한 자료입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;359&quot; data-filename=&quot;blob&quot; width=&quot;601&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exm2Tt/btqEdxTNrMf/4waNoW53Tk6eSt4TjikPbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exm2Tt/btqEdxTNrMf/4waNoW53Tk6eSt4TjikPbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exm2Tt/btqEdxTNrMf/4waNoW53Tk6eSt4TjikPbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fexm2Tt%2FbtqEdxTNrMf%2F4waNoW53Tk6eSt4TjikPbK%2Fimg.png&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;359&quot; data-filename=&quot;blob&quot; width=&quot;601&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;예를 들어, 위에 보이는 그래프는 $$x1, x2$$로 구성된 2차원 데이터를 표현한 것인데, 이 점들은 모여서 선을 이루게 됩니다. 그리고 이 두가지의 데이터는 어떠한 관계를 가지고 있을 것입니다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;549&quot; data-origin-height=&quot;297&quot; data-filename=&quot;blob&quot; width=&quot;603&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K2vqb/btqEdjIiY8y/QdQ3TfUHRgAUH1aQ3PGobK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K2vqb/btqEdjIiY8y/QdQ3TfUHRgAUH1aQ3PGobK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K2vqb/btqEdjIiY8y/QdQ3TfUHRgAUH1aQ3PGobK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK2vqb%2FbtqEdjIiY8y%2FQdQ3TfUHRgAUH1aQ3PGobK%2Fimg.png&quot; data-origin-width=&quot;549&quot; data-origin-height=&quot;297&quot; data-filename=&quot;blob&quot; width=&quot;603&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;여기서 이 2차원의 데이터를 하나의 선에 투영하면, 1차원의 점들로 표현할 수 있습니다 다시 말해서 2차원의 점 $x^{(i)}$을 z라는 선에서 1차원으로 바라봐서 $z^{(i)}$이라는 1차원 데이터로 바라볼 수 있는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;결국 이렇게 데이터를 일렬로 표현하기 위해서는 &lt;b&gt;2차원의 데이터를 1차원인 하나의 실수로 나타내야한다는 것&lt;/b&gt;이며, 이는 &lt;b&gt;데이터가 반으로 줄어들게 되면서, 필요한 공간 또한 반으로 줄어든다는 것&lt;/b&gt;을 의미합니다. 그래서 결국 알고리즘의 성능이 향상되는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이것이 바로 데이터를 압축 또는 차원을 감소하는 기본 원리입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deSeBg/btqEeqs7sV4/pKhp9AGk5PXiWpCnqGCuU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deSeBg/btqEeqs7sV4/pKhp9AGk5PXiWpCnqGCuU0/img.png&quot; data-alt=&quot;3차원에서 2차원으로 차원 감소&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deSeBg/btqEeqs7sV4/pKhp9AGk5PXiWpCnqGCuU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdeSeBg%2FbtqEeqs7sV4%2FpKhp9AGk5PXiWpCnqGCuU0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;3차원에서 2차원으로 차원 감소&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번에는 &lt;b&gt;3차원의 데이터를 2차원으로 차원 감소시켜보겠습니다.&lt;/b&gt;&amp;nbsp; 이 경우 3차원 데이터를 &lt;b&gt;2차원의 사각형에 투영하는 형태&lt;/b&gt;를 생각해볼 수 있습니다. 다시 말해서 3차원 데이터로 $x_1, x_2, x_3$ 값을 가지던 vector $x^({i)}$은 $z_1, z_2$ 값을 가지는 vector $z^({i)}$로 다시 표현되는 것입니다.&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이러한 차원 감소는 1000차원, 2000차원같이 훨씬 더 높은 차원에서 100차원, 200차원으로 낮추는데도 사용할 수 있으며, 시스템의 성능에 긍정적인 영향을 줄것입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Data Visualization&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;697&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfHcjo/btqEd8GeI8Z/UJEcIFplksWVEnXO3kXktk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfHcjo/btqEd8GeI8Z/UJEcIFplksWVEnXO3kXktk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfHcjo/btqEd8GeI8Z/UJEcIFplksWVEnXO3kXktk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfHcjo%2FbtqEd8GeI8Z%2FUJEcIFplksWVEnXO3kXktk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;697&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이번엔 데이터를 이해하기 위한 하나의 방법인 &lt;b&gt;'Data Visulalization'&lt;/b&gt;입니다. 예를 들어 위와 같이 각 나라에 대한 데이터가 있습니다. 이 데이터에는 나라별로 50가지의 경제 관련 통계 자료가 들어있습니다. 즉 &lt;b&gt;50차원&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;697&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boIavm/btqEfqzphaE/dneZ6u95g0xnHU0LrBKsm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boIavm/btqEfqzphaE/dneZ6u95g0xnHU0LrBKsm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boIavm/btqEfqzphaE/dneZ6u95g0xnHU0LrBKsm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboIavm%2FbtqEfqzphaE%2FdneZ6u95g0xnHU0LrBKsm0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;697&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이 나라 별 50가지의 정보를 위와 같이 $z1, z2$로 구성된 &lt;b&gt;2차원의 데이터&lt;/b&gt;로 압축할 수 있습니다. 분명 50가지 데이터를 하나하나 살펴봐야 한다면 귀찮겠지만, 이를 2가지의 데이터로 압축하여 볼 수 있다면 나라를 분석하는데 훨씬 더 편할 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;700&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0M157/btqEcHixTAk/u2TiVakmivpA8Qkj0OzgFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0M157/btqEcHixTAk/u2TiVakmivpA8Qkj0OzgFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0M157/btqEcHixTAk/u2TiVakmivpA8Qkj0OzgFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0M157%2FbtqEcHixTAk%2Fu2TiVakmivpA8Qkj0OzgFK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;700&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이를 2차원의 그래프로 표현한 결과입니다. 각 점이 나라를 나타내며, 그래프를 이해하기 위해서는 $z_1, z_2$를 대략적으로 설정하면 어떤 의미일지 파악할 수 있습니다. 이렇게 차원을 줄이고 나니 그래프로 표현이 가능함에 따라 나라별 데이터간의 차이가 한눈에 보이기 때문에 많은 장점들이 있다고 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;결론적으로 차원을 줄이는 것은 데이터의 이해를 위한 것이라고 할 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;다음 포스팅에서는 이러한 원리를 기반으로 한 PCA 알고리즘에 대해 공부해보겠습니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>cost</category>
      <category>Data Compression</category>
      <category>Dimension Reduction</category>
      <category>neural network</category>
      <category>경사 하강 알고리즘</category>
      <category>데이터 압축</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>인하대</category>
      <category>차원 감소</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/32</guid>
      <comments>https://box-world.tistory.com/32#entry32comment</comments>
      <pubDate>Mon, 18 May 2020 14:47:55 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 비지도 학습(Unsupervised Learning)이란? : 최적화(Optimization)</title>
      <link>https://box-world.tistory.com/31</link>
      <description>&lt;h2&gt;시작하며&lt;/h2&gt;
&lt;p&gt;우리가 Supervised Learning에서 다양한 알고리즘을 다루면서 항상 했던 연산들 중 하나가 바로 &lt;b&gt;Cost 최소화&lt;/b&gt; 즉 &lt;b&gt;Cost 함수 최적화(optimization)&lt;/b&gt;였습니다.&lt;/p&gt;
&lt;p&gt;이번 포스팅에서는 &lt;b&gt;K-means 알고리즘의 Cost 함수&lt;/b&gt;에 대해 알아보고 이를 어떻게 &lt;b&gt;최적화&lt;/b&gt;하는지에 대해 공부해보겠습니다.&lt;/p&gt;
&lt;p&gt;이번 포스팅은 아래 포스팅들을 읽고 공부하시면 더욱 효과적입니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/29&quot;&gt;https://box-world.tistory.com/29&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1589692104224&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;비지도 학습(Unsupervised Learning)이란? : Clustering&quot; data-og-description=&quot;시작하며 우리가 그동안 이전 포스팅에서 배웠던 Linear Regression, Logistic Regression, Neural Network, SVM은 모두 지도학습(Supervised Learning) 즉 레이블(Label)이 있는 데이터에 대한 학습이었습니다...&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/29&quot; data-og-url=&quot;https://box-world.tistory.com/29&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bI2XMy/hyF48WHaBZ/QKGnBu1BipiWCILE64isu0/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/boFde6/hyF47DtRtC/7Nw6jyWOCTUK06B8macHYK/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/bScmyK/hyF4Woo2rT/QguIu8BcMwQaNqjsGGMG90/img.png?width=683&amp;amp;height=382&amp;amp;face=0_0_683_382&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/29&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/29&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bI2XMy/hyF48WHaBZ/QKGnBu1BipiWCILE64isu0/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/boFde6/hyF47DtRtC/7Nw6jyWOCTUK06B8macHYK/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/bScmyK/hyF4Woo2rT/QguIu8BcMwQaNqjsGGMG90/img.png?width=683&amp;amp;height=382&amp;amp;face=0_0_683_382');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;비지도 학습(Unsupervised Learning)이란? : Clustering&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 우리가 그동안 이전 포스팅에서 배웠던 Linear Regression, Logistic Regression, Neural Network, SVM은 모두 지도학습(Supervised Learning) 즉 레이블(Label)이 있는 데이터에 대한 학습이었습니다...&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://box-world.tistory.com/30&quot;&gt;https://box-world.tistory.com/30&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1589692104281&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;비지도 학습(Unsupervised Learning)이란? : K-means algorithm&quot; data-og-description=&quot;시작하며 저번 포스팅에서는 비지도학습(Unsupervised Learning)의 기초 개념을 다뤄보았습니다. 이번 포스팅에서는 Unsupervised Learning의 원리를 알아보고 이것의 대표적인 알고리즘인 'K-means algorithm'에&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/30&quot; data-og-url=&quot;https://box-world.tistory.com/30&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/excig/hyF37d4k2Y/nif9hSep011VZhQQNKhsAk/img.png?width=683&amp;amp;height=379&amp;amp;face=0_0_683_379,https://scrap.kakaocdn.net/dn/cV4NHd/hyF35HjJXq/8qS89qFNLJFaQS7W3nM8A0/img.png?width=683&amp;amp;height=379&amp;amp;face=0_0_683_379,https://scrap.kakaocdn.net/dn/9FZB3/hyF300jou4/VBWKViUJLKSklFzrnsFwLk/img.png?width=683&amp;amp;height=379&amp;amp;face=0_0_683_379&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/30&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/excig/hyF37d4k2Y/nif9hSep011VZhQQNKhsAk/img.png?width=683&amp;amp;height=379&amp;amp;face=0_0_683_379,https://scrap.kakaocdn.net/dn/cV4NHd/hyF35HjJXq/8qS89qFNLJFaQS7W3nM8A0/img.png?width=683&amp;amp;height=379&amp;amp;face=0_0_683_379,https://scrap.kakaocdn.net/dn/9FZB3/hyF300jou4/VBWKViUJLKSklFzrnsFwLk/img.png?width=683&amp;amp;height=379&amp;amp;face=0_0_683_379');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;비지도 학습(Unsupervised Learning)이란? : K-means algorithm&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 저번 포스팅에서는 비지도학습(Unsupervised Learning)의 기초 개념을 다뤄보았습니다. 이번 포스팅에서는 Unsupervised Learning의 원리를 알아보고 이것의 대표적인 알고리즘인 'K-means algorithm'에&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2&gt;K-means Algorithm : Cost 함수&lt;/h2&gt;
&lt;p&gt;우선 &lt;b&gt;K-means 알고리즘의 Cost 함수를 구성하는 요소&lt;/b&gt;에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;349&quot; data-filename=&quot;blob&quot; width=&quot;690&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSIFNr/btqEcHWqOPS/ZZnZ07UF0d45baS1u0xPw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSIFNr/btqEcHWqOPS/ZZnZ07UF0d45baS1u0xPw1/img.png&quot; data-alt=&quot;K-means 알고리즘의 Cost 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSIFNr/btqEcHWqOPS/ZZnZ07UF0d45baS1u0xPw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSIFNr%2FbtqEcHWqOPS%2FZZnZ07UF0d45baS1u0xPw1%2Fimg.png&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;349&quot; data-filename=&quot;blob&quot; width=&quot;690&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;K-means 알고리즘의 Cost 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;우리는 $c^{(i)}$가 i 번째 데이터 $x^{(i)}$가 속한 Cluster 값을 의미하고, $&amp;mu;_k$ 는 K번쨰 Cluster의 Cluster Centroid를 의미함을 저번 포스팅에서 배웠습니다. 그리고 새롭게 등장한 $&amp;mu;_c^{(i)}$는 $x^{(i)}$가 속한 Cluster의 Cluster Centroid를 의미합니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;K-means 알고리즘의 Cost 함수 J&lt;/b&gt;는 위와 같습니다. 이는 &lt;b&gt;DIstortion Cost 함수&lt;/b&gt;라고도 불립니다. 이 함수의 Cost 값을 &lt;b&gt;최소화(minimize)&lt;/b&gt;하기 위해서는 i 번째 데이터 $x^{(i)}$와 이 데이터가 속한 Cluster의 Centroid인 $&amp;mu;_c^{(i)}$ 사이의 &lt;b&gt;거리를 최소화&lt;/b&gt; 시켜야합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;228&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hv5fq/btqEbP1Hkuy/lvrygJYbvrrbFf8wI1fKTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hv5fq/btqEbP1Hkuy/lvrygJYbvrrbFf8wI1fKTK/img.png&quot; data-alt=&quot;K-means Algorithm&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hv5fq/btqEbP1Hkuy/lvrygJYbvrrbFf8wI1fKTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHv5fq%2FbtqEbP1Hkuy%2FlvrygJYbvrrbFf8wI1fKTK%2Fimg.png&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;228&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;K-means Algorithm&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이제 방금 배운 Cost 함수를 이용하여 알고리즘을 어떻게 동작시키는지 알아보겠습니다. 우선 Cluster가 k개라고 할때, &lt;b&gt;K개의 Cluster Centroids를 랜덤으로 지정합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;여기서 첫번째 단계인 &lt;b&gt;Cluster assignment step&lt;/b&gt;에 의하여, 데이터들을 &lt;b&gt;자기와 가까운 Cluster Centroids의 Cluster로 구분&lt;/b&gt;시킵니다. 그리고 두번쨰 단계인 &lt;b&gt;Move Centoirds&lt;/b&gt;에 의하여, 그렇게 할당된 각 &lt;b&gt;Cluster의 데이터들의 평균값&lt;/b&gt;의 위치로 &lt;b&gt;각 Cluster의 Centroid들을 이동&lt;/b&gt;시킵니다. 이 두 가지 단계를 반복적으로 실행하여 최적의 Clustering을 하게 됩니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Random Initialization&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IxBld/btqEbvJbLCV/VlqOkf5kCLem0W1y78SpCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IxBld/btqEbvJbLCV/VlqOkf5kCLem0W1y78SpCK/img.png&quot; data-alt=&quot;Local Optima&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IxBld/btqEbvJbLCV/VlqOkf5kCLem0W1y78SpCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIxBld%2FbtqEbvJbLCV%2FVlqOkf5kCLem0W1y78SpCK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Local Optima&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;우리는 저번 시간에 알고리즘의 시작 부분에서 &lt;b&gt;랜덤으로 설정되는 Cluster Centroids의 위치에 따라 결과값이 바뀔 수 있음&lt;/b&gt;을 배웠습니다. 구체적으로 이렇게 초기에 위치가 잘못 설정되어 정상적인 Clustering이 되지 못한 결과를 &lt;b&gt;Local optima&lt;/b&gt;이라고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;307&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nvQtX/btqEeXQ3LED/VXMZ4X8gnH53SFXruG0k80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nvQtX/btqEeXQ3LED/VXMZ4X8gnH53SFXruG0k80/img.png&quot; data-alt=&quot;Multiple Random Initialization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nvQtX/btqEeXQ3LED/VXMZ4X8gnH53SFXruG0k80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnvQtX%2FbtqEeXQ3LED%2FVXMZ4X8gnH53SFXruG0k80%2Fimg.png&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;307&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Multiple Random Initialization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이러한 문제를 해결하고자 나온 방법이 바로 &lt;b&gt;Multiple Random Initialization&lt;/b&gt;입니다. 말 그대로 여&lt;b&gt;러 번 알고리즘을 수행하여 이중 Cost가 가장 작은 값이 나온 Case를 채택하는 것입니다.&lt;/b&gt; 예를 들어 알고리즘으 100번 돌리게 되면, 각기 다른 랜덤한 Cluster Centroid에서 출발한 K-means 알고리즘의 100개의 Cost 값들은 각각 다를 것인데, 우리는 이중 가장 작은 Cost 값을 가지는 Case를 취하는 것입니다.&lt;/p&gt;
&lt;p&gt;보통 이렇게 반복하는 횟수는 &lt;b&gt;50 ~ 1000회&lt;/b&gt;가 적당하고, 이러한 방법은 &lt;b&gt;Cluster의 갯수&lt;/b&gt;가 &lt;b&gt;10개 이하&lt;/b&gt;일 때 잘 적용됩니다. 만약 그 이상의 Cluster를 가지는 dataset에 사용할 경우 Local optima가 발생할 가능성이 상대적으로 높아 좋지 않은 결과가 나올 수 있습니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Choosing the Number of Clusters&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdY5ru/btqEcmZhh82/pZ14DSKSBneU0BqaLZX0rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdY5ru/btqEcmZhh82/pZ14DSKSBneU0BqaLZX0rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdY5ru/btqEcmZhh82/pZ14DSKSBneU0BqaLZX0rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdY5ru%2FbtqEcmZhh82%2FpZ14DSKSBneU0BqaLZX0rk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;dataset를 구분하는 Cluster의 수&lt;/b&gt;는 어떻게 결정해야하는지 알아보겠습니다. 결론은 정답은 없고, 따라서 다 해봐야 한다는 것입니다. 그래서 가장 많이 사용되는 것이 &lt;b&gt;Elbow Method&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;283&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clWYTc/btqEeXXPitw/6QJF6K8zKKlg7vHkJ3bcwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clWYTc/btqEeXXPitw/6QJF6K8zKKlg7vHkJ3bcwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clWYTc/btqEeXXPitw/6QJF6K8zKKlg7vHkJ3bcwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclWYTc%2FbtqEeXXPitw%2F6QJF6K8zKKlg7vHkJ3bcwK%2Fimg.png&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;283&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;간단하게 Cluster 개수가 1개일 때부터 시작하여 &lt;b&gt;계속 K를 늘려가며 각 K에 대한 Cost 값을 비교&lt;/b&gt;하는 것입니다. 이때 위와 같은 그래프를 보았을 때, 그 모양이 마치 우리가 팔을 구부린 것과 같으며, 저 중 그래프가 꺾이는 지점 즉 &lt;b&gt;팔꿈치&lt;/b&gt;에 해당하는 K = 3를 가장 적절한 갯수로 결정하게 됩니다. 그러나 &lt;b&gt;오른쪽처럼 모든 그래프에 이러한 Elbow가 나타나는 것은 아니므로 유의해야합니다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>cost 함수</category>
      <category>k-means</category>
      <category>경사 하강 알고리즘</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>앤드류 응</category>
      <category>인공지능</category>
      <category>인하대</category>
      <category>지도학습</category>
      <category>코세라</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/31</guid>
      <comments>https://box-world.tistory.com/31#entry31comment</comments>
      <pubDate>Sun, 17 May 2020 14:08:26 +0900</pubDate>
    </item>
    <item>
      <title>[머신러닝 순한맛] 비지도 학습(Unsupervised Learning)이란? : K-means algorithm</title>
      <link>https://box-world.tistory.com/30</link>
      <description>&lt;h2 data-ke-size=&quot;size18&quot;&gt;시작하며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;저번 포스팅에서는 비지도학습(Unsupervised Learning)의 기초 개념을 다뤄보았습니다. 이번 포스팅에서는 Unsupervised Learning의 원리를 알아보고 이것의 대표적인 알고리즘인 &lt;b&gt;'K-means algorithm'&lt;/b&gt;에 대해 다뤄보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 포스팅은 아래 포스팅을 보시고 공부하시면 더욱 효과적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/29&quot;&gt;box-world.tistory.com/29&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1589638449567&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;비지도 학습(Unsupervised Learning)이란? : Clustering&quot; data-og-description=&quot;시작하며 우리가 그동안 이전 포스팅에서 배웠던 Linear Regression, Logistic Regression, Neural Network, SVM은 모두 지도학습(Supervised Learning) 즉 레이블(Label)이 있는 데이터에 대한 학습이었습니다...&quot; data-og-host=&quot;box-world.tistory.com&quot; data-og-source-url=&quot;https://box-world.tistory.com/29&quot; data-og-url=&quot;https://box-world.tistory.com/29&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DGcJH/hyF47iVKfc/rxnUznaZj1cFUEf961kw90/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/tu9i1/hyF34VCL7B/Y7tepxHrYBTNn0vl4pERe1/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/bocosh/hyF45MbDxG/CeTNY1dxWOkxTDmXcTVGKk/img.png?width=683&amp;amp;height=382&amp;amp;face=0_0_683_382&quot;&gt;&lt;a href=&quot;https://box-world.tistory.com/29&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://box-world.tistory.com/29&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DGcJH/hyF47iVKfc/rxnUznaZj1cFUEf961kw90/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/tu9i1/hyF34VCL7B/Y7tepxHrYBTNn0vl4pERe1/img.png?width=300&amp;amp;height=168&amp;amp;face=0_0_300_168,https://scrap.kakaocdn.net/dn/bocosh/hyF45MbDxG/CeTNY1dxWOkxTDmXcTVGKk/img.png?width=683&amp;amp;height=382&amp;amp;face=0_0_683_382');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;비지도 학습(Unsupervised Learning)이란? : Clustering&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;시작하며 우리가 그동안 이전 포스팅에서 배웠던 Linear Regression, Logistic Regression, Neural Network, SVM은 모두 지도학습(Supervised Learning) 즉 레이블(Label)이 있는 데이터에 대한 학습이었습니다...&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;box-world.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;Unsupervised Learning의 작동 원리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;697&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FSz1G/btqEcGJG6VP/82KzC8qNYWOFxuhO7hgRi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FSz1G/btqEcGJG6VP/82KzC8qNYWOFxuhO7hgRi0/img.png&quot; data-alt=&quot;랜덤으로 Cluster Centroids를 설정합니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FSz1G/btqEcGJG6VP/82KzC8qNYWOFxuhO7hgRi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFSz1G%2FbtqEcGJG6VP%2F82KzC8qNYWOFxuhO7hgRi0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;697&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;랜덤으로 Cluster Centroids를 설정합니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;** Cluster&lt;b&gt;란 하나의 **군집화된 데이터 그룹&lt;/b&gt;을 의미합니다. 우선 위와 같은 데이터를 두 개의 Cluster로 나눠보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때 Cluster의 갯수가 정해지면 &lt;b&gt;동일한 갯수의 Cluster Centroids(중심점)&lt;/b&gt;가 동시에 랜덤으로 지정됩니다. 이는 각 Cluster의 일종의 대표 역할을 하게 됩니다. 이렇게 Cluster의 갯수만큼 Centroids를 생성하여 위치시키는 것이 Unsupervised Learning의 첫번째 단계가 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lwbkh/btqEbRkF2hy/tKaXfh2NqFETlck7wQIag1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lwbkh/btqEbRkF2hy/tKaXfh2NqFETlck7wQIag1/img.png&quot; data-alt=&quot;Cluster Centroids에 따라 데이터를 구분합니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lwbkh/btqEbRkF2hy/tKaXfh2NqFETlck7wQIag1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLwbkh%2FbtqEbRkF2hy%2FtKaXfh2NqFETlck7wQIag1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;698&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cluster Centroids에 따라 데이터를 구분합니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 두번째 단계로 위치시킨 두개의 Cluster Centroids을 기준으로 &lt;b&gt;나머지 데이터들을 두 개의 Cluster 중 하나로 구분합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIxiGG/btqEbQlKE2M/WrL7gPPu1csVZ9vuKiLEZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIxiGG/btqEbQlKE2M/WrL7gPPu1csVZ9vuKiLEZ0/img.png&quot; data-alt=&quot;Cluster Centroids를 갱신하고 데이터를 이에 따라 새롭게 구분합니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIxiGG/btqEbQlKE2M/WrL7gPPu1csVZ9vuKiLEZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIxiGG%2FbtqEbQlKE2M%2FWrL7gPPu1csVZ9vuKiLEZ0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cluster Centroids를 갱신하고 데이터를 이에 따라 새롭게 구분합니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다시 첫번째 돌아와서 Cluster Centroid의 위치를 조정하게 되는데, &lt;b&gt;이때는 나름의 기준을 가지고 조정하게 됩니다.&lt;/b&gt; 그 다음 마찬가지로 나머지 데이터들도 다시 새롭게 구분됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;688&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wKStk/btqEcoidFhE/IHysc89t5XYqvGk58mz6d0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wKStk/btqEcoidFhE/IHysc89t5XYqvGk58mz6d0/img.png&quot; data-alt=&quot;단계를 반복적으로 거칠수록 데이터가 안정적으로 구분됩니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wKStk/btqEcoidFhE/IHysc89t5XYqvGk58mz6d0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwKStk%2FbtqEcoidFhE%2FIHysc89t5XYqvGk58mz6d0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;688&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;단계를 반복적으로 거칠수록 데이터가 안정적으로 구분됩니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;첫번째로 Cluster Centroid를 설정하여 데이터를 나누고, 두번째로 Cluster Centroid를 조정하는 단계를 반복적으로 거치면서 점점 데이터들을 적절하게 구분이 되어갑니다. 이를 통해 학습 모델이 형성되고 적절하게 Cluster된 결과를 얻을 수 있습니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 data-ke-size=&quot;size18&quot;&gt;K-means Algorithm&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;306&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cn6qbD/btqEeo2fh6R/zZsNGoZTeNDEhv5uLzTwh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cn6qbD/btqEeo2fh6R/zZsNGoZTeNDEhv5uLzTwh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cn6qbD/btqEeo2fh6R/zZsNGoZTeNDEhv5uLzTwh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcn6qbD%2FbtqEeo2fh6R%2FzZsNGoZTeNDEhv5uLzTwh1%2Fimg.png&quot; data-origin-width=&quot;585&quot; data-origin-height=&quot;306&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;K-means Algorithm&lt;/b&gt;은 위에서 봤던 내용과 비교했을 때, 기본적인 작동 원리는 동일하며, &lt;b&gt;어떻게 매 단계마다 Cluster Centroids를 갱신하는지 주목하면 좋습니다.&lt;/b&gt; 알고리즘은 &lt;b&gt;두개의 입력값&lt;/b&gt;을 가집니다. 하나&lt;b&gt;(K)&lt;/b&gt;는 &lt;b&gt;데이터를 몇 개의 Cluster로 구분할 것인가&lt;/b&gt;, 다른 하나는 &lt;b&gt;구분할 dataset&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;K-means Algorithm&lt;/b&gt;은 Unsupervised Learning을 다루므로 &lt;b&gt;데이터의 Label을 존재하지 않습니다.&lt;/b&gt; 따라서 dataset은 $(x_1,y_1), (x_2, y_2)... $의 형태가 아닌 &lt;b&gt;$x_1, x_2...$의 형태가 됩니다.&lt;/b&gt; 이어서 data가 n개라면 $x_0$를 포함하여 &lt;b&gt;dataset은 $n+1$차원의 vector로 표현 가능합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;292&quot; data-filename=&quot;blob&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPufZh/btqEcS4gDN6/RH9zeglkZDIelhKWVkSSsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPufZh/btqEcS4gDN6/RH9zeglkZDIelhKWVkSSsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPufZh/btqEcS4gDN6/RH9zeglkZDIelhKWVkSSsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPufZh%2FbtqEcS4gDN6%2FRH9zeglkZDIelhKWVkSSsk%2Fimg.png&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;292&quot; data-filename=&quot;blob&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;만약 데이터를 k개의 Cluster로 분류하게 되면, 마찬가지로 주어진 데이터 중 &lt;b&gt;k개의 Clsuter Centroid를 랜덤으로 지정&lt;/b&gt;하게 되고 이것들은 $&amp;mu;_k$로 표기합니다. 작동원리는 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1) Cluster assignment&lt;/b&gt; : 초기에 랜덤으로 지정된 k개의 Cluster Centroids를 기준으로 &lt;b&gt;나머지 데이터들이 어느 $&amp;mu;_k$에 가까운지 체크하여 구분하게 되며 이 결과를 $c(i)$로 표기합니다.&lt;/b&gt; 예를 들어 $c(24) = 2$라면 24번째 데이터가 2번째 Cluster로 구분된 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2) Move centroid&lt;/b&gt; : 이 단계에서는 &lt;b&gt;K개의 Cluster Centroids를 새로운 위치로 갱신하게 됩니다.&lt;/b&gt; 구체적으로 $&amp;mu;_k$는 k번째 Cluster는 &lt;b&gt;k 번째 Cluster에 포함된 데이터의 평균 값을 구하여 그 위치로 이동하게 됩니다.&lt;/b&gt; 예를 들어 $x(1), x(5), x(6), x(7)$이 2번째 Cluster에 포함된다면, $c(1), c(5), c(6), c(7)$은 모두 2일 것이며 $&amp;mu;_2$는 이 이들의 평균값인 $\frac{1}{4}(x(1) + x(5) + x(6) + x(7)$의 위치로 갱신됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;알고리즘은 단계를 반복하면서, 반복해도 &lt;b&gt;결과가 바뀌지 않거나(수렴)&lt;/b&gt;, &lt;b&gt;사용자가 지정한 roop를 수행&lt;/b&gt;하게 되면 종료됩니다.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;702&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIg38P/btqEbva4Si8/3dwcXyF1gTGBXa6aysBdp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIg38P/btqEbva4Si8/3dwcXyF1gTGBXa6aysBdp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIg38P/btqEbva4Si8/3dwcXyF1gTGBXa6aysBdp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIg38P%2FbtqEbva4Si8%2F3dwcXyF1gTGBXa6aysBdp1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;702&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;육안으로 보기에 분리가 쉽게 되는 경우도 있지만, &lt;b&gt;오른쪽 그래프처럼 불규칙하여 쉽게 분리할 수 없을거 같이 보이는 그래프도 Clustering이 가능합니다.&lt;/b&gt; 오른쪽 그래프는 T-shirt의 Size를 small, medium, large 3개의 cluster로 구분한 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;701&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8u6Ux/btqEcnjhDEl/RwchCk1qidih0odzTW5b2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8u6Ux/btqEcnjhDEl/RwchCk1qidih0odzTW5b2K/img.png&quot; data-alt=&quot;초기값 위치에 다라 달라지는 결과값&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8u6Ux/btqEcnjhDEl/RwchCk1qidih0odzTW5b2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8u6Ux%2FbtqEcnjhDEl%2FRwchCk1qidih0odzTW5b2K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;701&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;초기값 위치에 다라 달라지는 결과값&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 K-means Algorithm의 특징과 단점에 대해 알아보겠습니다. 우선 첫 단계에서 Cluster Centroids를 랜덤으로 설정하게 되는데 &lt;b&gt;이 초기 랜덤값인 Cluster Centroids에 따라 결과값이 달라질 수 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;699&quot; height=&quot;NaN&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cewt4s/btqEbPAn7I2/9xN7zZTScaFkbbMkqYmkEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cewt4s/btqEbPAn7I2/9xN7zZTScaFkbbMkqYmkEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cewt4s/btqEbPAn7I2/9xN7zZTScaFkbbMkqYmkEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcewt4s%2FbtqEbPAn7I2%2F9xN7zZTScaFkbbMkqYmkEk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;699&quot; height=&quot;NaN&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또한 &lt;b&gt;군집의 밀도가 서로 다를 때&lt;/b&gt; 작동하지 않을 수 있습니다.&lt;/p&gt;</description>
      <category>AI/Coursera ( Machine Learning )</category>
      <category>cluster</category>
      <category>cost</category>
      <category>k-means</category>
      <category>supervised</category>
      <category>딥러닝</category>
      <category>머신러닝</category>
      <category>비용 함수</category>
      <category>인공지능</category>
      <category>인하대</category>
      <category>지도 학습</category>
      <author>Box형</author>
      <guid isPermaLink="true">https://box-world.tistory.com/30</guid>
      <comments>https://box-world.tistory.com/30#entry30comment</comments>
      <pubDate>Sat, 16 May 2020 20:13:23 +0900</pubDate>
    </item>
  </channel>
</rss>