<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>해야지11 님의 블로그</title>
    <link>https://dmdkdk0129.tistory.com/</link>
    <description>해야지11 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Thu, 25 Jun 2026 21:16:13 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>해야지11</managingEditor>
    <item>
      <title>토익 벌크업 팩!!</title>
      <link>https://dmdkdk0129.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;안녕하세요! 이제 슬슬 취업을 준비해야 할 나이가 되니, 마음도 급박해지고 걱정이 앞서네요. ㅠㅠ 하지만 이럴 때일수록 조급해하지 않고, 차근차근 하나씩 준비하며 성장해 나가려고 굳게 다짐했습니다!&lt;br&gt;취준의 기본은 역시 어학 점수 확보인 것 같아서 일단 영어 공부부터 제대로 파보려고 하는데요. 마침 공부 자료를 찾다가 토익 벌크업팩을 무료로 배포한다는 꿀정보를 알게 되어 여러분께도 공유해 드립니다!&lt;br&gt;&lt;br&gt;&lt;a href=&quot;http://hackers.ac/contents/?m=landing&amp;amp;v=toeic/toeic_bulkuppack_free&amp;amp;_C_=689481&amp;amp;keywd=ac_toeic_bulkup_somun_250430&amp;amp;logger_kw=ac_toeic_bulkup_somun_250430&amp;amp;source=logger_kw&amp;amp;source=logger_kw&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;http://hackers.ac/contents/?m=landing&amp;amp;v=toeic/toeic_bulkuppack_free&amp;amp;_C_=689481&amp;amp;keywd=ac_toeic_bulkup_somun_250430&amp;amp;logger_kw=ac_toeic_bulkup_somun_250430&amp;amp;source=logger_kw&amp;amp;source=logger_kw&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;해커스어학원 :: 토익 벌크업팩 무료배포(점수상승8종세트)&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;토익 점수상승 8종세트 선착순 무료배포!&quot; data-og-host=&quot;www.hackers.ac&quot; data-og-source-url=&quot;https://www.hackers.ac/contents/?m=landing&amp;amp;v=toeic/toeic_bulkuppack_free&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/JBLOp/dJMb8VNppTl/KIBTh6KVSjCOezvMmqXmqK/img.jpg?width=500&amp;amp;height=250&amp;amp;face=0_0_500_250&quot; data-og-url=&quot;https://www.hackers.ac/contents/?m=landing&amp;amp;v=toeic/toeic_bulkuppack_free&quot;&gt;&lt;a href=&quot;https://www.hackers.ac/contents/?m=landing&amp;amp;v=toeic/toeic_bulkuppack_free&quot; target=&quot;_blank&quot; data-source-url=&quot;https://www.hackers.ac/contents/?m=landing&amp;amp;v=toeic/toeic_bulkuppack_free&quot;&gt;&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/JBLOp/dJMb8VNppTl/KIBTh6KVSjCOezvMmqXmqK/img.jpg?width=500&amp;amp;height=250&amp;amp;face=0_0_500_250')&quot;&gt; &lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;해커스어학원 :: 토익 벌크업팩 무료배포(점수상승8종세트)&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;토익 점수상승 8종세트 선착순 무료배포!&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;www.hackers.ac&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;br&gt;혼자만 알고 있기엔 너무 유용한 자료라 가져왔어요. 자료 구성도 알차고 실전 감각 익히기에 딱 좋아 보입니다. 저도 이거 풀면서 열공 모드 들어가려고요! 우리 모두 이 자료로 영어 점수 확실하게 잡고, 스펙 업그레이드해서 꼭 원하는 곳에 취뽀 성공합시다! 저도 열심히 활동하며 좋은 결과 만들겠습니다. 다들 지치지 말고 파이팅하세요!!&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhMptO/dJMcadHw4dC/zM4wZMSJVMWfcGz8lwxhh0/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhMptO/dJMcadHw4dC/zM4wZMSJVMWfcGz8lwxhh0/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhMptO/dJMcadHw4dC/zM4wZMSJVMWfcGz8lwxhh0/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhMptO%2FdJMcadHw4dC%2FzM4wZMSJVMWfcGz8lwxhh0%2Ftfile.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;1200&quot; height=&quot;1200&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djoH8a/dJMcadHw4dH/HikTJQBpya9uxLe1ac5Gwk/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djoH8a/dJMcadHw4dH/HikTJQBpya9uxLe1ac5Gwk/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djoH8a/dJMcadHw4dH/HikTJQBpya9uxLe1ac5Gwk/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjoH8a%2FdJMcadHw4dH%2FHikTJQBpya9uxLe1ac5Gwk%2Ftfile.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;1200&quot; height=&quot;1200&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0b5kZ/dJMcaaD4BgN/KW6ZPX4hKMmEfotuKkSsjK/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0b5kZ/dJMcaaD4BgN/KW6ZPX4hKMmEfotuKkSsjK/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0b5kZ/dJMcaaD4BgN/KW6ZPX4hKMmEfotuKkSsjK/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0b5kZ%2FdJMcaaD4BgN%2FKW6ZPX4hKMmEfotuKkSsjK%2Ftfile.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;1200&quot; height=&quot;1200&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wh91c/dJMcadHw4dS/kk8hGBVWlq6oHpkHFIXGKK/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wh91c/dJMcadHw4dS/kk8hGBVWlq6oHpkHFIXGKK/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wh91c/dJMcadHw4dS/kk8hGBVWlq6oHpkHFIXGKK/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwh91c%2FdJMcadHw4dS%2Fkk8hGBVWlq6oHpkHFIXGKK%2Ftfile.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;1200&quot; height=&quot;1200&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkmvGG/dJMcaaD4BgP/lxm9kCsx2UlHoWhN2H5kbk/tfile.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkmvGG/dJMcaaD4BgP/lxm9kCsx2UlHoWhN2H5kbk/tfile.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkmvGG/dJMcaaD4BgP/lxm9kCsx2UlHoWhN2H5kbk/tfile.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkmvGG%2FdJMcaaD4BgP%2Flxm9kCsx2UlHoWhN2H5kbk%2Ftfile.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;1200&quot; height=&quot;1200&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;</description>
      <category>토익</category>
      <category>토익공부</category>
      <category>토익시험</category>
      <category>해커스토익</category>
      <category>해커스토익점수벌크업</category>
      <author>해야지11</author>
      <guid isPermaLink="true">https://dmdkdk0129.tistory.com/7</guid>
      <comments>https://dmdkdk0129.tistory.com/7#entry7comment</comments>
      <pubDate>Thu, 22 Jan 2026 15:24:30 +0900</pubDate>
    </item>
    <item>
      <title>[혼공머신] 5주차</title>
      <link>https://dmdkdk0129.tistory.com/6</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;06-1 (&lt;/b&gt;&lt;b&gt;군집 알고리즘)&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;타깃이 없을 때 사용하는 머신러닝 알고리즘을 &lt;b&gt;비지도 학습&lt;/b&gt;이라고 한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;먼저 과일 사진 데이터를 준비했고 넘파이 배열을 통해 크기를 확인했다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import numpy as np
import matplotlib.pyplot as plt

fruits = np.load('fruits_300.npy')

print(fruits.shape)&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;140&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8QLzp/btsPLGkFtGO/TbrQN1tuH9UcxZKC2Dsqr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8QLzp/btsPLGkFtGO/TbrQN1tuH9UcxZKC2Dsqr1/img.png&quot; data-alt=&quot;배열 크기 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8QLzp/btsPLGkFtGO/TbrQN1tuH9UcxZKC2Dsqr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8QLzp%2FbtsPLGkFtGO%2FTbrQN1tuH9UcxZKC2Dsqr1%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;170&quot; height=&quot;68&quot; data-origin-width=&quot;140&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배열 크기 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;그 다음엔 픽셀 100개에 들어있는 값을 출력했다. 이 넘파이 배열은 흑백 사진을 담고 있고 0~255까지의 정수값을 가진다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dq3oOP/btsPLXsYew2/VfuyMU1j9PSqMFxz9ryiOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dq3oOP/btsPLXsYew2/VfuyMU1j9PSqMFxz9ryiOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dq3oOP/btsPLXsYew2/VfuyMU1j9PSqMFxz9ryiOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdq3oOP%2FbtsPLXsYew2%2FVfuyMU1j9PSqMFxz9ryiOk%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;520&quot; height=&quot;155&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;matplotlib의 &lt;b&gt;imshow() 함수&lt;/b&gt;를 사용하면 넘파이 배열로 저장된 이미지를 쉽게 그릴 수 있다. 흑백 이미지이므로 cmap 매개변수를 'gray'로 지정했다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dg8yWW/btsPPleIGnG/GZAhEMKMnbfSoo8DKyU7u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dg8yWW/btsPPleIGnG/GZAhEMKMnbfSoo8DKyU7u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dg8yWW/btsPPleIGnG/GZAhEMKMnbfSoo8DKyU7u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdg8yWW%2FbtsPPleIGnG%2FGZAhEMKMnbfSoo8DKyU7u1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;432&quot; height=&quot;478&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드를 통해 첫 번째 이미지는 사과라고 알 수 있다. 또한 0에 가까울수록 검게 나타나고 높은 값은 밝게 표시된다.&lt;br&gt;우리의 관심을 바탕이 아니라 사과이기에 흑백이미지를 반전 시킬 것이다. 이는 &lt;b&gt;cmap 매개변수&lt;/b&gt;를 '&lt;b&gt;gray_r&lt;/b&gt;'로 지정하면 된다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o5HWC/btsPLkPJsjm/qjxsqg8qEzFt3uAbqchQy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o5HWC/btsPLkPJsjm/qjxsqg8qEzFt3uAbqchQy0/img.png&quot; data-alt=&quot;흑백이 반전된 사과 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o5HWC/btsPLkPJsjm/qjxsqg8qEzFt3uAbqchQy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo5HWC%2FbtsPLkPJsjm%2Fqjxsqg8qEzFt3uAbqchQy0%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;433&quot; height=&quot;481&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;흑백이 반전된 사과 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;픽셀값을 분석하기 위해서 100 X 100 2차원 배열을 길이가 10,000인 1차원 배열로 만들 것이다. 이렇게 펼치면 이미지로 출력하긴 어렵지만 배열을 계산할 때 편리하다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;apple = fruits[0:100].reshape(-1, 100*100)
pineapple = fruits[100:200].reshape(-1, 100*100)
banana = fruits[200:300].reshape(-1, 100*100)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;사과, 파인애플, 바나나 중 하나의 크기를 확인해보면 아래와 같다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;133&quot; data-origin-height=&quot;57&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YbmKD/btsPM19trml/lTVz7RLJaWbokHHVoV6hC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YbmKD/btsPM19trml/lTVz7RLJaWbokHHVoV6hC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YbmKD/btsPM19trml/lTVz7RLJaWbokHHVoV6hC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYbmKD%2FbtsPM19trml%2FlTVz7RLJaWbokHHVoV6hC1%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;133&quot; height=&quot;57&quot; data-origin-width=&quot;133&quot; data-origin-height=&quot;57&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;사과 샘플 100개에 대한 픽셀 평균값을 계산하고 이를 히스토그램으로 표현해 볼 것이다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y9OHf/btsPNN3XcWt/QKylQJpCIaaIdsmVDW2Xe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y9OHf/btsPNN3XcWt/QKylQJpCIaaIdsmVDW2Xe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y9OHf/btsPNN3XcWt/QKylQJpCIaaIdsmVDW2Xe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy9OHf%2FbtsPNN3XcWt%2FQKylQJpCIaaIdsmVDW2Xe1%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;517&quot; height=&quot;267&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8EYTO/btsPNegoWop/mxkC1fCntRmkbfyAlqBKp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8EYTO/btsPNegoWop/mxkC1fCntRmkbfyAlqBKp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8EYTO/btsPNegoWop/mxkC1fCntRmkbfyAlqBKp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8EYTO%2FbtsPNegoWop%2FmxkC1fCntRmkbfyAlqBKp1%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;541&quot; height=&quot;526&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사과와 파인애플은 90~100 사이에 많이 모여있고 바나나 사진의 평균값은 40 아래에 집중되어 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;이번에는 각 픽셀의 평균을 구해볼 것이다. axis=0으로 지정하면 쉽게 계산할 수 있다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;fig, axs = plt.subplots(1, 3, figsize=(20,5))
axs[0].bar(range(10000), apple.mean(axis=0))
axs[1].bar(range(10000), pineapple.mean(axis=0))
axs[2].bar(range(10000), banana.mean(axis=0))
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjiOLQ/btsPLjXxVrw/gYnGfkfy95RblztxdEv0Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjiOLQ/btsPLjXxVrw/gYnGfkfy95RblztxdEv0Kk/img.png&quot; data-alt=&quot;각 픽셀의 평균을 막대그래프로 표현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjiOLQ/btsPLjXxVrw/gYnGfkfy95RblztxdEv0Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjiOLQ%2FbtsPLjXxVrw%2FgYnGfkfy95RblztxdEv0Kk%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;847&quot; height=&quot;237&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;각 픽셀의 평균을 막대그래프로 표현&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서대로 사과, 파인애플, 바나나 그래프이다. 각각 값이 높은 구간이 다르다. 사과는 사진 중앙에 상대적으로 값이 작은 영역이 보이고 파인애플 그래프는 비교적 고르면서 높다. 바나나는 확실히 중앙의 픽셀값이 높다.&lt;br&gt;&amp;nbsp;&lt;br&gt;픽셀 평균값을 100 X 100 크기로 바꿔서 이미지 처럼 출력하여 위 그래프와 비교해 봤다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;apple_mean = apple.mean(axis=0).reshape(100,100)
pineapple_mean = pineapple.mean(axis=0).reshape(100,100)
banana_mean = banana.mean(axis=0).reshape(100,100)
fig, axs = plt.subplots(1, 3, figsize=(20,5))
axs[0].imshow(apple_mean, cmap='gray_r')
axs[1].imshow(pineapple_mean, cmap='gray_r')
axs[2].imshow(banana_mean, cmap='gray_r')
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SqKfz/btsPO5wdo7e/BkVFKWFB6qdcEMSWL3EMJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SqKfz/btsPO5wdo7e/BkVFKWFB6qdcEMSWL3EMJk/img.png&quot; data-alt=&quot;각 픽셀의 평균을 이미지로 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SqKfz/btsPO5wdo7e/BkVFKWFB6qdcEMSWL3EMJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSqKfz%2FbtsPO5wdo7e%2FBkVFKWFB6qdcEMSWL3EMJk%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;849&quot; height=&quot;247&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;각 픽셀의 평균을 이미지로 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;이번에는 사과 사진의 평균값과 가까운 사진을 고를 것이다. 그러기 위해서는 모든 샘플에서 apple_mean으 뺀 절댓값을 평균을 계산하면 된다. 이때 &lt;b&gt;넘파이 abs() 함수&lt;/b&gt;라는 절댓값을 계산하는 함수를 이용할 것이다. 이 함수는&lt;b&gt; np.absolute() 함수&lt;/b&gt;의 다른 이름이다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;abs_diff = np.abs(fruits - apple_mean)
abs_mean = np.mean(abs_diff, axis=(1,2))
print(abs_mean.shape)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;여기서 abs_diff는 (300, 100, 100) 크기의 배열이다. 따라서 각 샘플에 대한 평균을 구하기 위해 axis 두 번째, 세 번째 차원을 모두 지정했다. 이렇게 계산한 abs_mean은 각 샘플의 오차 평균이므로 크기가 (300,)인 1차원 배열이다.&lt;br&gt;그러고나서 이 값이 가장 작은 순서대로 100개를 고른다. 이것은 apple_mean과 오차가 가장 작은 샘플 100개를 고르는 것이다. np.argsort() 함수는 작은 것에서 큰 순서대로 나열한 abs_mean 배열의 인덱스를 반환한다. 이 인덱스 중에서 처음 100개를 선택해 10 X 10 격자로 이루어진 그래프를 그렸다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;apple_index = np.argsort(abs_mean)[:100]
apple_index = apple_index.reshape(10,10)
fig, axs = plt.subplots(10, 10, figsize=(10,10))
for i in range(10):
&amp;nbsp;&amp;nbsp;for j in range(10):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axs[i,j].imshow(fruits[apple_index[i,j]],cmap='gray_r')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axs[i,j].axis('off')
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MGKWw/btsPODs9J83/soilkOTTvnIlbA2MDPaseK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MGKWw/btsPODs9J83/soilkOTTvnIlbA2MDPaseK/img.png&quot; data-alt=&quot;위 코드 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MGKWw/btsPODs9J83/soilkOTTvnIlbA2MDPaseK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMGKWw%2FbtsPODs9J83%2FsoilkOTTvnIlbA2MDPaseK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;782&quot; height=&quot;778&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;778&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 코드 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;apple_mean과 가장 가까운 사진 100개를 골랐더니 모두 사과이다. 위 코드를 좀 더 설명하자면 subplots() 함수로 10 X 10, chd 100개의 서브 그래프를 만든다. 그래프가 많기에 figsize = (10, 10)으로 조금 크게 지정하고 2중 for문을 통해 10개의 행과 열에 이미지를 출력한다. i,j 두 첨자를 사용하여 서브 그래프 위치를 지정하였고 axis('off')를 사용하여 좌표축을 그리지 않았다.&lt;br&gt;&amp;nbsp;&lt;br&gt;흑백 사진에 있는 픽셀값을 사용해 과일 사진을 모으는 작업을 하는 것과 같이 비슷한 샘플끼리 그룹으로 모으는 작업을 군집이라 한다. 군집은 대표적인 비지도 학습 작업 중 하나이고 군집 알고리즘에서 만든 그룹을 클러스터라고 한다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr 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;06-2 (k-평균&lt;/b&gt;&lt;b&gt;)&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;1절에서는 사과, 파인애플, 바나나 사진임을 미리 알고 있었기에 각 과일을 평균을 구했다. 하지만 진짜 비지도 학습에서는 사진에 어던 과일이 들어있는지 알지 못한다. 이럴 경우에는 &lt;b&gt;k-평균 군집 알고리즘&lt;/b&gt;이 평균값을 자동으로 찾아준다. 이 평균값이 클러스터의 중심에 위치하기 때문에 &lt;b&gt;클러스터 중심&lt;/b&gt; 또는 &lt;b&gt;센트로이드&lt;/b&gt;라고 부른다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;k-평균 알고리즘의 작동 방식은 다음과 같다.&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;&lt;li&gt;무작위로 k개의 클러스터 중심을 정한다.&lt;/li&gt;&lt;li&gt;각 샘플에서 가장 가까운 클러스터 중심을 찾아 해당 클러스터의 샘플로 지정한다.&lt;/li&gt;&lt;li&gt;클러스터에 속한 샘플의 평균값으로 클러스터 중심을 변경한다.&lt;/li&gt;&lt;li&gt;클러스터 중심에 변화가 없을 때까지 2번으로 돌아가 반복한다.&lt;/li&gt;&lt;/ol&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;사이킷런의 k-평균 알고리즘은 sklearn.cluster 모듈 아래 KMeans 클래스에 구현되어 있다.&lt;br&gt;클러스터 개수를 정정하는 매개변수는 n_clusrers이다. 비지도 학습이기에 fit() 메서드에서 타깃 데이터를 사용하지 않는다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import numpy as np
fruits = np.load('fruits_300.npy')
fruits_2d = fruits.reshape(-1, 100*100)

from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, random_state=42)
km.fit(fruits_2d)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;label_ 배열의 값은 0, 1, 2 중 하나이다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JAWf6/btsPNlT5dU8/EJFtUXnZZfWDsGEG8nyxu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JAWf6/btsPNlT5dU8/EJFtUXnZZfWDsGEG8nyxu1/img.png&quot; data-alt=&quot;각 샘플이 어떤 레이블에 해당되는지 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JAWf6/btsPNlT5dU8/EJFtUXnZZfWDsGEG8nyxu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJAWf6%2FbtsPNlT5dU8%2FEJFtUXnZZfWDsGEG8nyxu1%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;527&quot; height=&quot;199&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;각 샘플이 어떤 레이블에 해당되는지 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;레이블값 0, 1, 2와 레이블 순서에는 어떤 의미도 없고, 실제 레이블 0, 1, 2가 어떤 과일 사진을 주로 모았는지 알아보려면 직접 이미지를 출력하는 것이 최선이다. 그 전에 레이블 0, 1, 2로 모은 샘플의 개수를 확인해봤다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kTTnj/btsPOnKEusc/SBSKfsSHCEqk2XxiMARXDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kTTnj/btsPOnKEusc/SBSKfsSHCEqk2XxiMARXDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kTTnj/btsPOnKEusc/SBSKfsSHCEqk2XxiMARXDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkTTnj%2FbtsPOnKEusc%2FSBSKfsSHCEqk2XxiMARXDk%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;395&quot; height=&quot;60&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;draw_fruits() 함수는 (샘플 개수, 너비, 높이)의 3차원 배열을 입력받아 가롤로 10개씩 이미지를 출력한다. 또한 아래 코드에서&amp;nbsp;&lt;b&gt;불리언 인덱싱&lt;/b&gt;을 사용한다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt
def draw_fruits(arr, ratio=1):
&amp;nbsp;&amp;nbsp;n = len(arr)
&amp;nbsp;&amp;nbsp;rows = int(np.ceil(n/10))
&amp;nbsp;&amp;nbsp;cols = n if rows &amp;lt; 2 else 10
&amp;nbsp;&amp;nbsp;fig, axs = plt.subplots(rows, cols,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;figsize=(cols*ratio, rows*ratio), squeeze=False)
&amp;nbsp;&amp;nbsp;for i in range(rows):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for j in range(cols):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if i*10 + j &amp;lt; n:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axs[i, j ].imshow(arr[i*10 + j], cmap='gray_r')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axs[i,j].axis('off')
&amp;nbsp;&amp;nbsp;plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;위 코드를 통해 각 라벨이 어떤 과일을 나타내는지 알아봤다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;draw_fruits(fruits[km.labels_==0])&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPqdH5/btsPL4FBrb6/f3b2rRnhddxBs6UGKgyalk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPqdH5/btsPL4FBrb6/f3b2rRnhddxBs6UGKgyalk/img.png&quot; data-alt=&quot;레이블이 0일때의 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPqdH5/btsPL4FBrb6/f3b2rRnhddxBs6UGKgyalk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPqdH5%2FbtsPL4FBrb6%2Ff3b2rRnhddxBs6UGKgyalk%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;631&quot; height=&quot;757&quot; data-origin-width=&quot;631&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;레이블이 0일때의 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;draw_fruits(fruits[km.labels_==1])&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;643&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhjg6W/btsPNMDVcHE/Debvf2h0hoGrR9WSpQLK0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhjg6W/btsPNMDVcHE/Debvf2h0hoGrR9WSpQLK0k/img.png&quot; data-alt=&quot;레이블이 1일 때의 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhjg6W/btsPNMDVcHE/Debvf2h0hoGrR9WSpQLK0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhjg6W%2FbtsPNMDVcHE%2FDebvf2h0hoGrR9WSpQLK0k%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;635&quot; height=&quot;643&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;643&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;레이블이 1일 때의 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;draw_fruits(fruits[km.labels_==2])&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;563&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zjqsW/btsPLfAVbBs/6DppJD8sSQr7gKHh874thK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zjqsW/btsPLfAVbBs/6DppJD8sSQr7gKHh874thK/img.png&quot; data-alt=&quot;레이블이 2일 때 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zjqsW/btsPLfAVbBs/6DppJD8sSQr7gKHh874thK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzjqsW%2FbtsPLfAVbBs%2F6DppJD8sSQr7gKHh874thK%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;632&quot; height=&quot;563&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;563&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;레이블이 2일 때 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;위 출력들을 통해 레이블이 0은 대부분 파인애플, 1은 바나나, 2는 사과가 출력되었음을 알 수 있다. 샘플들을 완벽하게 구별하지는 못했어도 비슷한 샘플들을 잘 모았다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;KMeans 클래스가 최종적으로 찾은 클러스터 중심은 &lt;b&gt;cluster_centers_ 속성&lt;/b&gt;에 저장되어 있다. 이 배열은 fruits_2d 샘플의 클러스터 중심이기 때문에 각 중심을 이미지로 출력하려면 100 X 100 크기의 2차원 배열로 바꿔야 한다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsIQqU/btsPN4xNfvu/qbbqvEO9g0lfDeMxcKrQB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsIQqU/btsPN4xNfvu/qbbqvEO9g0lfDeMxcKrQB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsIQqU/btsPN4xNfvu/qbbqvEO9g0lfDeMxcKrQB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsIQqU%2FbtsPN4xNfvu%2FqbbqvEO9g0lfDeMxcKrQB0%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;727&quot; height=&quot;273&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;KMeans 클래스는 훈련 데이터 샘플에서 클러스터 중심까지 거리로 변환해 주는&lt;b&gt; transform() 메서드&lt;/b&gt;를 가지고 있다. 이 메서는 마치 StandardScaler 클래스처럼 특성값을 변환하는 도구로 사용할 수 있다는 의미이다.&lt;br&gt;transform() 메서드를 적용할 때, fit() 메서드와 마찬가지로 2차원 배열을 기대한다. fruits_2d[100]처럼 쓰면 (10000,) 크기의 배열이 되므로 에러가 발생한다. 그러므로 슬라이싱 연산자를 사용해서 (1, 10000) 크기의 배열을 전달했다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uBflC/btsPOkNWq2W/cGBzlzjdtUshyIMuCq0Re1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uBflC/btsPOkNWq2W/cGBzlzjdtUshyIMuCq0Re1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uBflC/btsPOkNWq2W/cGBzlzjdtUshyIMuCq0Re1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuBflC%2FbtsPOkNWq2W%2FcGBzlzjdtUshyIMuCq0Re1%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;321&quot; height=&quot;63&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 클러스터(레이블 0), 두 번째 클러스터(레이블 1), 세 번째 클러스터(레이블 2)가 각각 첫 번째 원소, 두 번째 원소, 세 번째 원소의 값이다. 이중 첫 번째 클러스터까지의 거리가 가장 작기에 이 샘플을 레이블 0에 속했다.&lt;br&gt;&amp;nbsp;&lt;br&gt;KMeans 클래스는 가장 가까운 클러스터 중심을 예측 클래스로 출력하는 &lt;b&gt;predict() 메서드&lt;/b&gt;도 제공한다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;263&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mfsO9/btsPOD7L6ZT/FNNvkcvp2jEHME6euD0JH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mfsO9/btsPOD7L6ZT/FNNvkcvp2jEHME6euD0JH1/img.png&quot; data-alt=&quot;몇 번째 레이블과 가장 가까운지 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mfsO9/btsPOD7L6ZT/FNNvkcvp2jEHME6euD0JH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmfsO9%2FbtsPOD7L6ZT%2FFNNvkcvp2jEHME6euD0JH1%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;263&quot; height=&quot;56&quot; data-origin-width=&quot;263&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;몇 번째 레이블과 가장 가까운지 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;208&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lrvIu/btsPObp8JzT/paCJDXf8RgeARZDUlJJ7Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lrvIu/btsPObp8JzT/paCJDXf8RgeARZDUlJJ7Ok/img.png&quot; data-alt=&quot;샘플 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lrvIu/btsPObp8JzT/paCJDXf8RgeARZDUlJJ7Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlrvIu%2FbtsPObp8JzT%2FpaCJDXf8RgeARZDUlJJ7Ok%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;208&quot; height=&quot;142&quot; data-origin-width=&quot;208&quot; data-origin-height=&quot;142&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;샘플 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;transform()의 결과에서 짐작했듯이 이 샘플은 파인애플이 맞았다.&lt;br&gt;&amp;nbsp;&lt;br&gt;k-평균 알고리즘은 앞에서 설명햇들이 반복적으로 클러스터 중심을 옮기면서 최적의 클러스터를 찾는다. 알고리즘이 반복한 횟수는 KMeans 클래스의 &lt;b&gt;n_iter_ 속성&lt;/b&gt;에 저장된다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;127&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L9S3Z/btsPOFYRtYr/pYQFXKbznkrzWZDoKlao0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L9S3Z/btsPOFYRtYr/pYQFXKbznkrzWZDoKlao0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L9S3Z/btsPOFYRtYr/pYQFXKbznkrzWZDoKlao0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL9S3Z%2FbtsPOFYRtYr%2FpYQFXKbznkrzWZDoKlao0K%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;127&quot; height=&quot;58&quot; data-origin-width=&quot;127&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;만약 우리가 n_cluster를 지정할 수 없을 때 최적의 클러스터를 어떻게 구해야할지 고민될 것이다. 적절한 k 값을 찾기 위한 완벽한 방법은 없다. 몇 가지 도구가 있지만 저마다의 장단점이 있다. 그 중 우린 대표적인 방법은 &lt;b&gt;엘보우 방법&lt;/b&gt;에 대해서 알아볼 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;k-평균 알고리즘은 클러스터 중심과 클러스터에 속한 샘플 사이의 거리를 잴 수 있다. 이 거리의 제곱 합을 &lt;b&gt;이너셔&lt;/b&gt;라고 부르고 이너셔는 클러스터에 속한 샘플이 얼마나 가깝게 모여 있는지를 나타내는 값으로 생각할 수 있다. 일반적으로 클러스터 개수가 늘어나면 클러스터 개개의 크기는 줄어들기에 이너셔도 줄어든다. 엘보우 방법은 클러스터 개수를 늘려가면서 이너셔의 변화를 관찰하여 최적의 클러스터 개수를 찾는 방법이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;클러스터 개수를 증가시키면서 이너셔를 그래프로 그리면 감소하는 속도가 꺾이는 지점이 있다. 이 지접부터는 클러스터 개수를 늘려도 클러스터에 잘 밀집된 정도가 크게 개선되지 않기에 이 지점을 k로 사용한다. 이 지점이 마치 팔꿈치 모양이어서 엘보우 방법이라 부른다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;741&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ekRmVv/btsPMKmBS5W/WDDS8GfxBAiF5aE8VRMCD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ekRmVv/btsPMKmBS5W/WDDS8GfxBAiF5aE8VRMCD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ekRmVv/btsPMKmBS5W/WDDS8GfxBAiF5aE8VRMCD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FekRmVv%2FbtsPMKmBS5W%2FWDDS8GfxBAiF5aE8VRMCD0%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;727&quot; height=&quot;741&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;741&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 위 그래프는 그래프의 기울기가 조금 바뀌었지만 지점이 명확하지 않다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;06-3 (주성분 분석&lt;/b&gt;&lt;b&gt;)&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;너무 많은 사진이 등록되어 저장 공간이 부족해질 수가 있다. 이때 차원을 축소하면 된다. 이때 머신러닝에서의 차원은 예를 들어 과일 사진의 경우 10,000개의 픽셀이 있기 때문에 10,000개의 특성이 있는 셈이고 이러한 특성을 &lt;b&gt;차원&lt;/b&gt;이라고 한다. 10,000개의 차원을 줄이기 위한 비지도 학습 작업 중 하나인 &lt;b&gt;차원 축소 알고리즘&lt;/b&gt;을 다룰 것이다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;특성이 많으면 선형 모델의 성능이 높아지고 훈련 데이터에 과대적합된다. 차원 축소는 데이터를 가장 잘 나타내는 일부 특성을 선택하여 데이터 크기를 줄이고 지도 학습 모델의 성능을 향상시킬 수 있는 방법이다. 또한 줄어든 차원에서 다시 원본 차원으로 손실을 최대한 출이면서 복원할 수도 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;대표적인 차원 축소 알고리즘인 &lt;b&gt;주성분 분석&lt;/b&gt;에 대해 배우 것이며 주성분 분석을 간단히 &lt;b&gt;PCA&lt;/b&gt;라고도 부른다.&lt;br&gt;&amp;nbsp;&lt;br&gt;주성분 분석에 대해서 소개하자면 주성분 분석은 데이터에 있는 분산이 큰 방향을 찾는 것으로 이해할 수 있다. 분산은 데이터가 널리 퍼져있는 정도를 말하며 분산이 큰 방향은 데이터를 잘 표현하는 어떤 벡터라고 생각할 수 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;2차원 데이터를 생각해보면 데이터의 분포를 가장 잘 표현하는 길게 늘어진 대각선을 생각할 수 있고 이 대각선 방향이 분산이 가장 크다고 말할 수 있다. 화살표의 위치는 중요하지 않고 분산이 큰 방향을 찾는 것이 중요하다. 이 직선이 원점에서 출발한다면 두 원소로 이루어진 벡터를 쓸 수 있다. 이 벡터를 &lt;b&gt;주성분&lt;/b&gt;이라고 부른다. 샘플 데이터를 주성분에 직각으로 투영하면 1차원 데이터를 만들 수 있다.&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;주성분이 가장 분산이 큰 방향이기에 주성분에 투영하여 바꾼 데이터는 원본이 가지고 있는 특성을 가장 잘 나타내고 있을 것이다.&lt;br&gt;첫 번째 주성분을 찾은 다음 이 벡터에 수직이고 분산이 가장 큰 다음 방향을 찾는다. 이 벡터가 두 번째 주성분이다. 여기서는 2차원이기 때문에 두 번째 주성분의 방향은 하나뿐이다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import numpy as np
fruits = np.load('fruits_300.npy')
fruits_2d = fruits.reshape(-1, 100*100)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;사이킷런은 sklearn.decomposition 모듈 아래 PCA 클래스로 주성분 분석 알고리즘을 제공한다. PCA 클래스의 객체를 만들 때 &lt;b&gt;n_components 매개변수&lt;/b&gt;에 주성분의 개수를 지정해야한다. k-평균과 마찬가지로 비지도 학습이기에 fit() 메서드에 타깃값을 제공하지 않는다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from sklearn.decomposition import PCA
pca = PCA(n_components = 50)
pca.fit(fruits_2d)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YGgnS/btsPLk3dKRa/zsMRemL8BP3MnqTXbnva61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YGgnS/btsPLk3dKRa/zsMRemL8BP3MnqTXbnva61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YGgnS/btsPLk3dKRa/zsMRemL8BP3MnqTXbnva61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYGgnS%2FbtsPLk3dKRa%2FzsMRemL8BP3MnqTXbnva61%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;201&quot; height=&quot;59&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진과 같이 n_components를 50으로 지정했기에 첫 번째 차원은 50개, 즉 40개의 주성분을 찾았고 두 번째 차원은 항상 원본 데이터의 특성 개수와 같은 10,000이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;또한 주성분을 그림으로 그려보았다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt

def draw_fruits(arr, ratio=1):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n = len(arr)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# n은 샘플 개수입니다
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# 한 줄에 10개씩 이미지를 그립니다. 샘플 개수를 10으로 나누어 전체 행 개수를 계산합니다.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rows = int(np.ceil(n/10))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# 행이 1개 이면 열 개수는 샘플 개수입니다. 그렇지 않으면 10개입니다.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cols = n if rows &amp;lt; 2 else 10
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fig, axs = plt.subplots(rows, cols,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;figsize=(cols*ratio, rows*ratio), squeeze=False)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for i in range(rows):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for j in range(cols):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if i*10 + j &amp;lt; n:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# n 개까지만 그립니다.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axs[i, j].imshow(arr[i*10 + j], cmap='gray_r')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axs[i, j].axis('off')
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;plt.show()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
draw_fruits(pca.components_.reshape(-1, 100, 100))&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGPUC9/btsPPnXVbQV/GWb3usBOZsBDGQKZQ6Jk5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGPUC9/btsPPnXVbQV/GWb3usBOZsBDGQKZQ6Jk5K/img.png&quot; data-alt=&quot;주성분을 그림으로 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGPUC9/btsPPnXVbQV/GWb3usBOZsBDGQKZQ6Jk5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGPUC9%2FbtsPPnXVbQV%2FGWb3usBOZsBDGQKZQ6Jk5K%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;793&quot; height=&quot;399&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주성분을 그림으로 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;원본 데이터를 주성분에 투영하여&amp;nbsp; 특성 개수를 10,000개에서 50개로 줄일 것이다. PCA의 &lt;b&gt;transform() 메서드&lt;/b&gt;를 사용해서 원본 데이터의 차원을 50으로 줄였다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;print(fruits_2d.shape)

fruits_pca = pca.transform(fruits_2d)
print(fruits_pca.shape)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;앞에서 특성을 50개로 줄였다. 어느 정도 손실이 발생할 수밖에 없지만 최대한 분산이 큰 방향으로 데이터를 투영했기에 원본 데이터를 상당 부분 재구성할 수 있다. PCA 클래스는 이를 위해 i&lt;b&gt;nverse_transform() 메서드&lt;/b&gt;를 제공한다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;fruits_inverse = pca.inverse_transform(fruits_pca)
print(fruits_inverse.shape)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;주성분이 원본 데이터의 분산을 얼마나 잘 나타내는지 기록한 값을 &lt;b&gt;설명된 분산&lt;/b&gt;이라고 한다. PCA 클래스의&amp;nbsp;&lt;b&gt;explained_variance_ratio_&lt;/b&gt;에 각 주성분의 설명된 분산 비율이 기록되어있다. 당연히 첫 번째 주성분의 설명된 분산ㅇ ㅣ가장 크다.&lt;br&gt;&amp;nbsp;&lt;br&gt;분산 비율을 모두 더하면 50개의 주성분으로 표현하고 있는 총 분산 비율을 얻을 수 있다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;print(np.sum(pca.explained_variance_ratio_))&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;또한 적절한 주성분의 개수를 찾기 위해 설명된 분산의 비율을 그래프로 그려보았다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;plt.plot(pca.explained_variance_ratio_)
plt.show()&lt;/code&gt;&lt;/pre&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mFZCw/btsPLmfLjcH/nLwtZ2UbkrE4kgh7UTIze0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mFZCw/btsPLmfLjcH/nLwtZ2UbkrE4kgh7UTIze0/img.png&quot; data-alt=&quot;설명된 분산의 비율 그래프&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mFZCw/btsPLmfLjcH/nLwtZ2UbkrE4kgh7UTIze0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFZCw%2FbtsPLmfLjcH%2FnLwtZ2UbkrE4kgh7UTIze0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;543&quot; height=&quot;406&quot; data-origin-width=&quot;543&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설명된 분산의 비율 그래프&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프를 통해 처음 10개의 주성분이 대부분의 분산을 표현함을 을 수 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;원본 데이터와 축소한 데이터를 지도 학습에 적용해보고 어던 차이가 있는지 알아보기 위해 로지스틱 회귀 분석을 사용하였다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()

target = np.array([0]*100 + [1]*100 + [2]*100)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;cross_validate()로 교차 검증을 수행하였다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vYgnw/btsPLOJKo7B/g6IHiF2Aybah5yoNa7ZFSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vYgnw/btsPLOJKo7B/g6IHiF2Aybah5yoNa7ZFSk/img.png&quot; data-alt=&quot;원본 데이터 및 PCA로 축소한 데이터를 통한 교차검증 수행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vYgnw/btsPLOJKo7B/g6IHiF2Aybah5yoNa7ZFSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvYgnw%2FbtsPLOJKo7B%2Fg6IHiF2Aybah5yoNa7ZFSk%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;360&quot; height=&quot;272&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;원본 데이터 및 PCA로 축소한 데이터를 통한 교차검증 수행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;정확도가 동일하지만 훈련시간은 줄어들었다.&lt;br&gt;&amp;nbsp;&lt;br&gt;설명된 분산의 50%에 달하는 주성분을 찾도록 PCA 모델을 만들어보았다. 주성분 개수 대신 0~1 사이의 비율을 실수로 입력하면된다.&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;pca = PCA(n_components=0.5)
pca.fit(fruits_2d)

print(pca.n_components_)&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;이 결과 2개의 특성만으로 원본 데이터에 있는 분산의 50%를 표현할 수 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;이 모델로 원본 데이터를 변환하고 교차 검증을 확인해 보았다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;219&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U17CJ/btsPLmNzdJh/YmETgwCOt7vuiRzsVT8E5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U17CJ/btsPLmNzdJh/YmETgwCOt7vuiRzsVT8E5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U17CJ/btsPLmNzdJh/YmETgwCOt7vuiRzsVT8E5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU17CJ%2FbtsPLmNzdJh%2FYmETgwCOt7vuiRzsVT8E5k%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;353&quot; height=&quot;219&quot; data-origin-width=&quot;353&quot; data-origin-height=&quot;219&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;2개의 특성만으로도 정확도가 높은 것을 알 수 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;이번에는 차원 축소된 데이터를 사용해 k-평균 알고리즘으로 클러스터를 찾아볼 것이다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bo2YAS/btsPOrM30AS/wg7PizAYkSeI4KkgGierkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bo2YAS/btsPOrM30AS/wg7PizAYkSeI4KkgGierkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bo2YAS/btsPOrM30AS/wg7PizAYkSeI4KkgGierkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbo2YAS%2FbtsPOrM30AS%2Fwg7PizAYkSeI4KkgGierkK%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;399&quot; height=&quot;116&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;116&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 데이터와 거의 비슷한 결과이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;훈련 데이터의 차원을 줄이면 얻을 수 있는 장점은 시각화이다. 3개 이하로 차원을 줄이면 화면에 출력하기 비교적 쉽다. fruits_pca 데이터는 2개의 특성이 있기 때문에 2차원으로 표현할 수 있다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dn78h/btsPN5jaWNS/mfXVTpF4jnsX76rm8oZIHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dn78h/btsPN5jaWNS/mfXVTpF4jnsX76rm8oZIHK/img.png&quot; data-alt=&quot;시각화 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dn78h/btsPN5jaWNS/mfXVTpF4jnsX76rm8oZIHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDn78h%2FbtsPN5jaWNS%2FmfXVTpF4jnsX76rm8oZIHK%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;582&quot; height=&quot;532&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시각화 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;숙제&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;k-평균 알고리즘의 작동 방식은 다음과 같다.&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;&lt;li&gt;무작위로 k개의 클러스터 중심을 정한다.&lt;/li&gt;&lt;li&gt;각 샘플에서 가장 가까운 클러스터 중심을 찾아 해당 클러스터의 샘플로 지정한다.&lt;/li&gt;&lt;li&gt;클러스터에 속한 샘플의 평균값으로 클러스터 중심을 변경한다.&lt;/li&gt;&lt;li&gt;클러스터 중심에 변화가 없을 때까지 2번으로 돌아가 반복한다.&lt;/li&gt;&lt;/ol&gt;</description>
      <category>[혼공머신]</category>
      <category>k-평균</category>
      <category>pca</category>
      <category>군집 알고리즘</category>
      <category>주성분 분석</category>
      <category>혼공머신</category>
      <author>해야지11</author>
      <guid isPermaLink="true">https://dmdkdk0129.tistory.com/6</guid>
      <comments>https://dmdkdk0129.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 10 Aug 2025 19:29:53 +0900</pubDate>
    </item>
    <item>
      <title>[혼공머신] 4주차</title>
      <link>https://dmdkdk0129.tistory.com/5</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;05-1 (결정 트리)&lt;/b&gt;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결정 트리 모델은 스무고개와 같기에 이유를 설명하기 쉽고 fit() 메서드를 호출해서 모델을 훌녈하고 score()메서드로 정확도를 평가한다.&lt;/p&gt;
&lt;pre id=&quot;code_1753620282482&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 DecisionTreeClassifier
dt = DecisionTreeClassifier(random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target))
print(dt.score(test_scaled, test_target))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훈련 세트에 대한 점수가 엄청 높고 테스트 세트의 성능은 그에 비해 조금 낮으므로 과적합된 모델이라 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;이 모델을 그림으로 표현한다면 사이킷런의 plot_tree() 함수를 사용하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1753620371386&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(10,7))
plot_tree(dt)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crGcOW/btsPAYyo0y0/RATjLFTOIl5k77PnPbHb8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crGcOW/btsPAYyo0y0/RATjLFTOIl5k77PnPbHb8k/img.png&quot; data-alt=&quot;모델을 그림으로 표현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crGcOW/btsPAYyo0y0/RATjLFTOIl5k77PnPbHb8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrGcOW%2FbtsPAYyo0y0%2FRATjLFTOIl5k77PnPbHb8k%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;380&quot; height=&quot;265&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모델을 그림으로 표현&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;max_depth 매개변수&lt;/b&gt;를 1로 주면 루트 노드를 제외하고 하나의 노드를 더 확장하여 그릴 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;filled 매개변수&lt;/b&gt;에서 클래스에 맞게 노드의 색을 칠할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;feature_names 매개변수&lt;/b&gt;에는 특성의 이름을 전달할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1753620578235&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt.figure(figsize=(10,7))
plot_tree(dt, max_depth=1, filled=True,
          feature_names=['alcohol','sugar','pH'])
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wQVm2/btsPCqAE5AU/g0UhPrIzMQ2QJZwitqNyU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wQVm2/btsPCqAE5AU/g0UhPrIzMQ2QJZwitqNyU0/img.png&quot; data-alt=&quot;위 코드를 실행한 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wQVm2/btsPCqAE5AU/g0UhPrIzMQ2QJZwitqNyU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwQVm2%2FbtsPCqAE5AU%2Fg0UhPrIzMQ2QJZwitqNyU0%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;379&quot; height=&quot;265&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 코드를 실행한 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드 상자 안 gini는 지니 불순도를 의미한다. DecisionTreeClassifier 클래스의 criterion 매개변수의 기본값이 'gini'이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지니 불순도는 클래스의 비율을 제곱해서 더한 다음 1에서 빼면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지니 불순도 = 1 - {(음성 클래스 비율)&amp;sup2; + (양성 클래스 비율)&amp;sup2;}&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결정 트리 모델은 부모 노드와 자식 노드의 불순도 차이가 가능한 크도록 트리를 성장시킨다. 부모 노드와 자식 노드의 불순도 차이를 계산하는 방법은 자식 노드의 불순도를 샘플 개수에 비례하여 모두 더한다. 그다음 부모 노드의 불순도에서 빼면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정보 이득 = 부모의 불순도 - (왼쪽 노드 샘플 수 / 부모의 샘플 수) &amp;times; 왼쪽 노드 불순도&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- (오른쪽 노드 샘플 수 / 부모의 샘플수) &amp;times; 오른쪽 노드 불순도&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;criterion = 'entropy'를 지정하여 엔트로피 불순도를 사용할 수 있다. 엔트로피 불손도도 노드의 클래스 비율을 사용하지만 지니 불손도처럼 제곱이 아니라 밑이 2인 로그를 사용하여 곱한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결정 트리도 가지치기를 해야 무작정 끝까지 자라나는 트리가 만들어지지 않는다. 무작정 자라나면 훈련 세트에는 아주 잘 맞겠지만 테스트 세트에서 점수는 그에 못 치지기 때문이다. 그 중 가장 간단한 방법은 트리의 최대 깊이를 지정하는 것이다. DecisionTreeClassifier 클래스의 max_depth 매개변수를 3으로 지정하여 모델을 만들 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1753624644858&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target))
print(dt.score(test_scaled, test_target))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 실행하면 훈련 세트의 성능은 낮아졌지만 테스트 세트의 성능은 거의 그대로이다. plot_tree() 함수로 그려보면 아래와 같이 나온다.&lt;/p&gt;
&lt;pre id=&quot;code_1753624700209&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt.figure(figsize=(20,15))
plot_tree(dt,filled=True, feature_names=['alcohol','sugar','pH'])
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2YxLX/btsPBl7VmMN/7fPFm9x79KpJNAvtF2CJW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2YxLX/btsPBl7VmMN/7fPFm9x79KpJNAvtF2CJW1/img.png&quot; data-alt=&quot;위 코드 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2YxLX/btsPBl7VmMN/7fPFm9x79KpJNAvtF2CJW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2YxLX%2FbtsPBl7VmMN%2F7fPFm9x79KpJNAvtF2CJW1%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;373&quot; height=&quot;273&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 코드 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;05-2 (교차 검증과 그리드 서치)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 세트를 사용하지 않으면 모델이 과대적합인지 과소적합인지 판단하기 어렵다. 테스트 세트를 사용하지 않고 이를 측정하는 간단한 방법은 훈련 세트를 나는 것이다. 이 데이터를 검증 세트라고 한다. 아래 코드는 훈련 세트와 테스트 세트를 나눈 후 훈련 세트에서 훈련 세트와 검증 세트로 나누는 과정이다.&lt;/p&gt;
&lt;pre id=&quot;code_1753624956001&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
train_input, test_input, train_target, test_target = train_test_split(
    data, target, test_size=0.2, random_state=42)
    
sub_input, val_input, sub_target, val_target = train_test_split(
    train_input, train_target, test_size=0.2, random_state=42
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;교차 검증&lt;/b&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;k-폴드 교차 검증은 훈련 세트를 몇 부분으로 나누냐에 따라 다르게 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이킷런에는 &lt;b&gt;cross_validate()&lt;/b&gt;라는 교차 검증 함수가 있다. 사용법은 먼저 평가할 모델 객체를 첫 번째 매개변수로 전달하고 그다음 앞에서처럼 직접 검증 세트를 떼어 내지 않고 훈련 세트 전체를 cross_validate() 함수에 전달하는 것이다. 이 함수는 fit_time, score_time, test_score 키를 가진 딕셔너리를 반환한다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753625247777&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 DecisionTreeClassifier
dt = DecisionTreeClassifier(random_state=42)
dt.fit(sub_input, sub_target)
print(dt.score(sub_input, sub_target))
print(dt.score(val_input, val_target))

from sklearn.model_selection import cross_validate
scores = cross_validate(dt, train_input, train_target)
print(scores)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교차 검증의 최종 점수는 test_score 키에 담긴 점수를 평균하여 얻을 수 있다. 이름은 test_score지만 검증 폴드의 점수이다.&lt;/p&gt;
&lt;pre id=&quot;code_1753625375041&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
print(np.mean(scores['test_score']))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cross_validate() 함수는 기본적으로 회귀 모델일 경우 KFold 분할기를 사용하고 분류 모델일 경우 타깃 클래스를 골고루 나누기 위해 StratifiedKFold를 사용한다. 앞서 수행한 교차 검증은 다음 코드와 동일하다.&lt;/p&gt;
&lt;pre id=&quot;code_1753625475417&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
scores = cross_validate(dt, train_input, train_target, cv=StratifiedKFold())
print(np.mean(scores['test_score']))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 훈련 세트를 섞은 후 10-폴드 교차 검증을 수행하려면 다음과 같이 작성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1753625504777&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;splitter = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
scores = cross_validate(dt, train_input, train_target, cv=splitter)
print(np.mean(scores['test_score']))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모델 파라미터&lt;/b&gt;는 머신러닝 모델이 학습하는 파라미터이고 모델이 학습할 수 없어서 사용자가 지정해야만 하는 파라미터를 &lt;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;결정 트리 모델에서 최적의 max_depth와 min_samples_split 매개변수를 동시에 바꿔가면 최적의 값을 찾아야 한다. 게다가 매개변수가 많아지면 더욱 복잡해지므로 사이킷런에서 제공하는 &lt;b&gt;그리드 서치&lt;/b&gt;를 사용할 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1753625690345&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
# 탐색할 매개변수와 탐색할 값의 리스트를 딕셔너리로 만든다.
params = {'min_impurity_decrease': [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]} 

gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)

gs.fit(train_input, train_target)

dt = gs.best_estimator_
print(dt.score(train_input, train_target))

# 0.0001이 가장 좋은 값으로 선택됨
print(gs.best_params_)

print(gs.cv_results_['mean_test_score'])

print(gs.cv_results_['params'][gs.best_index_])

# 교차 검증하기 위해 매개변수의 값을 다르게 지정 총 9 X 15 X 10 = 1,350번의 교차 검증이 일어난다.
params = {'min_impurity_decrease': np.arange(0.0001, 0.001, 0.0001),
          'max_depth': range(5, 20, 1),
          'min_samples_split': range(2,100,10)
          }
          
gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)
gs.fit(train_input, train_target)

# 최상의 매개변수 조합을 확인
print(gs.best_params_)

print(np.max(gs.cv_results_['mean_test_score']))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;랜덤 서치&lt;/b&gt;는 매개변수의 값이 수치일 때 값의 범위나 간격을 미리 정하기 어려울 때 또 너무 많은 매개변수 조건이 있어 그리드 서치 수행 시간이 오래 걸릴 때 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1753626035137&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from scipy.stats import uniform,randint

rgen = randint(0,10)
rgen.rvs(10)

# 1,000개를 샘플링 후 각 숫자의 개수를 셈
np.unique(rgen.rvs(1000), return_counts=True)

ugen = uniform(0,1)
ugen.rvs(10)

# 0.0001에서 0.001 사이의 실숫값을 샘플링, 20에서 50사이의 정수를 샘플링, 
# 2에서 25 사이의 정수, 1에서 25 사이의 정수를 샘플링한다.
params = {'min_impurity_decrease': uniform(0.0001, 0.001),
          'max_depth': randint(20,50),
          'min_samples_split': randint(2,25),
          'min_samples_leaf': randint(1,25),
          }

# n_iter = 100을 통해 100번을 샘플링하여 교차 검증을 수행
from sklearn.model_selection import RandomizedSearchCV
rs = RandomizedSearchCV(DecisionTreeClassifier(random_state=42), params,
                        n_iter=100, n_jobs=-1, random_state=42)
rs.fit(train_input, train_target)

print(rs.best_params_)

print(np.max(rs.cv_results_['mean_test_score']))

dt = rs.best_estimator_
print(dt.score(test_input, test_target))&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;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;05-3 (트리의 앙상블)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;CSV, 데이터베이스, 엑셀과 같이 어떤 구조로 되어있는 데이터를 &lt;b&gt;정형 데이터&lt;/b&gt;라 하고 이와 반대되는 데이터를 &lt;b&gt;비정형 데이터&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정형 데이터를 다루는 데 가장 뛰어난 성과를 내는 알고리즘이 앙상블 학습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;랜덤 포레스트&lt;/b&gt;는 앙상블 학습의 대표 주자로 안정적인 성능 덕분에 널리 사용되고 있다. 랜덤 포레스트는 부트스트랩 샘플을 사용한다. 예를 든다면 1,000개의 샘플이 들어있는 가방에서 100개의 샘플을 뽑는다면 먼저 1개를 뽁고, 뽑았던 1개를 다시 가방에 넣는 식으로 중복된 샘플을 뽑을 수 있는 복원 추출을 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1753626581785&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_validate
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target,
                        return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))

# n_jobs 매개변수를 -1로 지정하여 모든 CPU 코어를 사용
# return_train_score 매개변수를 True로 지정하면 검증 점수뿐만 아니라
# 훈련 세트에 대한 점수도 반한됨 ( 기본값은 False)

rf.fit(train_input, train_target)
print(rf.feature_importances_)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부트스트랩 샘플에 포함되지 않고 남는 샘플이 있다. 이를 OOB(out of bag) 샘플이라 한다. 이 남는 샘ㅁ플을 사용하여 부트스트랩 샘플로 훈련한 결정 트리를 검증 세트의 역할로 평가할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1753626800937&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print(rf.oob_score_)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;엑스트라 트리&lt;/b&gt;는 랜덤 포레스트와 매우 비슷하지만 부트스트랩 샘플을 사용하지 않는다. 즉각 결정 트리를 만들 때 전체 훈련 세트를 사용한다. 대신 노드를 분할할 때 가장 좋은 분할을 찾는 것이 아니라 무작위로 분할한다. 무작위로 분할 하면 성능이 낮아지겠지만 많은 트리를 앙상블 하기 때문에 과대적합을 막고 검증 세트의 점수를 높이는 효과가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1753626932177&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 ExtraTreesClassifier
et = ExtraTreesClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(et, train_input, train_target,
                        return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))

et.fit(train_input, train_target)
print(et.feature_importances_)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그레이디언트 부스팅&lt;/b&gt;은 깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법이다. 깊이가 얕은 결정 트리를 사용하기 때문에 과대적합이 강하고 일반적으로 높은 일반화 성능을 기대할 수 있다. 그레이디언트 부스팅은 경사 하강법을 사용하여 트리를 앙상블에 추가한 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1753627180817&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 GradientBoostingClassifier
gb = GradientBoostingClassifier(random_state=42)
score = cross_validate(gb, train_input, train_target,
                       return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))


gb = GradientBoostingClassifier(n_estimators=500, learning_rate=0.2,
                                random_state=42)
scores = cross_validate(gb, train_input, train_target,
                        return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))


gb.fit(train_input, train_target)
print(gb.feature_importances_)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;히스토그램 기반 그레이디언트&lt;/b&gt;&amp;nbsp;&lt;b&gt;부스팅&lt;/b&gt;은 정형 데이터를 다루는 머신러닝 알고리즘 중에 가장 인기가 높은 알고리즘이다. 히스토그램 기반 그레이디언트 부스팅은 먼저 입력 특성을 256개의 구간으로 나누기에 노드를 분할할 때 최적의 분할을 매우 빠르게 찾을 수 있다. 256개의 구간 중에서 하나를 떼어 놓고 누락된 값을 위해서 사용한다. 그렇기에 입력에 누락된 특성이 있더라도 따로 전처리할 필요가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n_estimators 대신에 부스팅&amp;nbsp; 반복 횟수를 지정하는 &lt;b&gt;max_iter&lt;/b&gt;를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;permutation_importance() 함수&lt;/b&gt;를 사용하여 특성 중요도를 계산한다.&lt;/p&gt;
&lt;pre id=&quot;code_1753627378777&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 HistGradientBoostingClassifier
hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target,
                        return_train_score=True)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))

from sklearn.inspection import permutation_importance
hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target,
                               n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean)

result = permutation_importance(hgb, test_input, test_target,
                                n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean)

hgb.score(test_input, test_target)

# 중요도를 내림차순 정렬해서 보기 쉽게 출력
feature_names = data.columns
for i in result.importances_mean.argsort()[::-1]:
    print(f&quot;{feature_names[i]:&amp;lt;10}: 중요도 평균 = {result.importances_mean[i]:.4f}, &quot;
          f&quot;표준편차 = {result.importances_std[i]:.4f}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히스토그램 기반 그레이디언트 부스팅 말고도 그레이디언트 부스팅 알고리즘을 구현한 라이브러리가 있는데 가장 대표적인 라이브러리는 &lt;b&gt;XGBoost&lt;/b&gt;이다. cross_validate() 함수와 함께 사용할 수 있다. tree_method 매개변수를 'hist'로 지정하면 히스토그램 기반 그레이디언트 부스팅을 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1753627545913&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from xgboost import XGBClassifier
xgb = XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target,
                        return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;널리 사용하는 또 다른 히스토그램 기반 그레이디언트 부스팅 라이브러리는 마이크로소프트에서 만든 LightGBM이 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1753627587209&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from lightgbm import LGBMClassifier
lgb = LGBMClassifier(random_state=42)
scores = cross_validate(lgb, train_input, train_target,
                        return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))&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;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;숙제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교차 검증은 검증 세트를 떼어 내어 평가하는 과정을 여러 번 반복한다. 그다음 이 점수를 평균하여 최종 검증 점수를 얻는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d41vLU/btsPCj2DSoc/YGGoeeXKkaFDVZ1zhElxY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d41vLU/btsPCj2DSoc/YGGoeeXKkaFDVZ1zhElxY1/img.png&quot; data-alt=&quot;3 - 폴드 교차 검증&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d41vLU/btsPCj2DSoc/YGGoeeXKkaFDVZ1zhElxY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd41vLU%2FbtsPCj2DSoc%2FYGGoeeXKkaFDVZ1zhElxY1%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;361&quot; height=&quot;234&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;3 - 폴드 교차 검증&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3 - 폴드 교차 검증은 훈련 세트를 세 부분으로 나눠서 교차 검증을 수행하는 것이다. 3번의 교차 검증을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>[혼공머신]</category>
      <category>결정 트리</category>
      <category>교차 검증</category>
      <category>그리드 서치</category>
      <category>머신러닝</category>
      <category>앙상블</category>
      <category>트리</category>
      <category>혼공머신</category>
      <author>해야지11</author>
      <guid isPermaLink="true">https://dmdkdk0129.tistory.com/5</guid>
      <comments>https://dmdkdk0129.tistory.com/5#entry5comment</comments>
      <pubDate>Sun, 27 Jul 2025 23:52:32 +0900</pubDate>
    </item>
    <item>
      <title>[혼공머신] 3주차</title>
      <link>https://dmdkdk0129.tistory.com/3</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;04-1 (로지스틱 회귀)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;k-최근접 이웃 분류를 통해 어떤 생선으로 분류될지 파악하는 단원&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터를 준비하고 pd.unique()함수를 통해 어떤 종류의 생선이 있는지 파악&lt;/p&gt;
&lt;pre id=&quot;code_1753014051239&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
print(fish.head())

print(pd.unique(fish['Species']))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Species 열을 제외한 나머지 5개의 열을 입력데이터로 사용하고 Species 열을 타깃 데이터로 사용&lt;/p&gt;
&lt;pre id=&quot;code_1753014163303&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fish_input = fish[['Weight','Length','Diagonal','Height','Width']]
print(fish_input.head())

fish_target = fish['Species']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 훈련세트와 테스트 세트로 나누고 사이킷런의 StandardScaler 클래스를 사용하여 훈련 세트와 테스트 세트를 표준화 전처리&lt;/p&gt;
&lt;pre id=&quot;code_1753014279728&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
train_input, test_input, train_target, test_target = train_test_split(
fish_input, fish_target, random_state=42)

from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;k-최근접 이웃 분류기의 확률 예측을 통해 점수 확인&lt;/p&gt;
&lt;pre id=&quot;code_1753014330399&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
kn = KNeighborsClassifier(n_neighbors=3)
kn.fit(train_scaled, train_target)
print(kn.score(train_scaled, train_target))
print(kn.score(test_scaled, test_target))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타깃값을 그대로 사이킷런 모델에 전달하면 순서가 자동으로 알파벳 순으로 매겨진다. 그렇기에 pd.unique(fish['Species'])로 출력했던 순서와 다르다.&lt;/p&gt;
&lt;pre id=&quot;code_1753014457223&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(pd.unique(fish['Species']))
print(kn.classes_)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 세트에 있는 처음 5개 샘플의 타깃값을 예측&lt;/p&gt;
&lt;pre id=&quot;code_1753014547191&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(kn.predict(test_scaled[:5]))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이킷런의 분류 모델은 &lt;b&gt;predict_proba()&lt;/b&gt; 메서드로 클래스별 확률값을 반환한다. demicals 매개변수로유지할 소수점 아래 자릿수를 정할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1753014607808&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
proba = kn.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=4))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 실행하면 열은 몇 번째 클래스에 대한 확률이고 행은 하나의 샘플이 각각의 클래스에 대한 확률이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tFSgG/btsPpvqnnfp/knMnevS5eFocFFxho49cak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tFSgG/btsPpvqnnfp/knMnevS5eFocFFxho49cak/img.png&quot; data-alt=&quot;predict_proba() 출력 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tFSgG/btsPpvqnnfp/knMnevS5eFocFFxho49cak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtFSgG%2FbtsPpvqnnfp%2FknMnevS5eFocFFxho49cak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;390&quot; height=&quot;87&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;predict_proba() 출력 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네 번째 샘플의 최근접 이웃의 클래스를 확인하면&lt;/p&gt;
&lt;pre id=&quot;code_1753014844831&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;distances, indexes = kn.kneighbors(test_scaled[3:4])
print(train_target.iloc[indexes[0]])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;76&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HC4Hk/btsPr8mq3Tg/63tT5wScgkn7O4pm9cF0iK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HC4Hk/btsPr8mq3Tg/63tT5wScgkn7O4pm9cF0iK/img.png&quot; data-alt=&quot;네 번째 샘플의 최근접 이웃 클래스 출력값&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HC4Hk/btsPr8mq3Tg/63tT5wScgkn7O4pm9cF0iK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHC4Hk%2FbtsPr8mq3Tg%2F63tT5wScgkn7O4pm9cF0iK%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;225&quot; height=&quot;76&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;76&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;네 번째 샘플의 최근접 이웃 클래스 출력값&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넘파이를 사용하여 시그모이드 그래프를 출력&lt;/p&gt;
&lt;pre id=&quot;code_1753015140487&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
import matplotlib.pyplot as plt
z = np.arange(-5, 5, 0.1)
phi = 1 / (1+np.exp(-z))
plt.plot(z,phi)
plt.xlabel('z')
plt.ylabel('phi')
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;423&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s7IwS/btsPpuSwhLz/DTcQrrzWnQUYgKMuFI325k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s7IwS/btsPpuSwhLz/DTcQrrzWnQUYgKMuFI325k/img.png&quot; data-alt=&quot;시그모이드 그래프&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s7IwS/btsPpuSwhLz/DTcQrrzWnQUYgKMuFI325k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs7IwS%2FbtsPpuSwhLz%2FDTcQrrzWnQUYgKMuFI325k%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;556&quot; height=&quot;423&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;423&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시그모이드 그래프&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넘파이 배열은 True, False 값을 전달하여 행을 선택할 수 있다. 이를 불리언 인덱싱이라고 부른다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불리언 인덱싱 예시&lt;/p&gt;
&lt;pre id=&quot;code_1753015235983&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;char_arr = np.array(['A', 'B', 'C', 'D', 'E'])
print(char_arr[[True, False, True, False, False]])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도미(Bream), 빙어(Smelt) 행만 불리언 인덱싱을 이용해서 골라내기&lt;/p&gt;
&lt;pre id=&quot;code_1753015511039&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bream_smelt_indexes = (train_target == 'Bream') | (train_target == 'Smelt')
train_bream_smelt = train_scaled[bream_smelt_indexes]
target_bream_smelt = train_target[bream_smelt_indexes]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 골라낸 데이터를 통해 로지스틱 회귀 모델을 훈련&lt;/p&gt;
&lt;pre id=&quot;code_1753015678127&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
lr = LogisticRegression()
lr.fit(train_bream_smelt, target_bream_smelt)

# 처음 5개의 샘플 예측
print(lr.predict(train_bream_smelt[:5]))

# 처음 5개 샘플의 예측 확률 출력
print(lr.predict_proba(train_bream_smelt[:5]))

# classes_ 속성에서 확인
print(lr.classes_)

# 계수확인
print(lr.coef_, lr.intercept_)

# 처음 5개 샘플의 z 값을 출력
decisions = lr.decision_function(train_bream_smelt[:5])
print(decisions)

# 사이파이 라이브러리에 있는 시그모이드 함수를 통해 decisions 배열의 값을 확률로 변환
from scipy.special import expit
print(expit(decisions))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;로지스틱 회귀로 다중 분류를 수행할 수도 있는데 릿지 회귀와 같이 계수의 제곱을 규제한다. LogisticRegression에서 규제를 제어하는 매개변수는 C이다. C는 릿지 회귀에서의 alpha 매겨변수와는 다르게 작을수록 규제가 커진다. C의 기본값은 1이지만 여기서는 규제를 조금 완화하기 위해 20을로 늘렸다.&lt;/p&gt;
&lt;pre id=&quot;code_1753016306527&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lr = LogisticRegression(C=20, max_iter=1000)
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target))
print(lr.score(test_scaled, test_target))

# 테스트 세트 처음 5개 샘플에 대한 예측
print(lr.predict(test_scaled[:5]))

# 테스트 세트의 처음 5개 샘플에 대한 예측 확률
proba = lr.predict_proba(test_scaled[:5])
print(np.round(proba, decimals=3))

# classes_ 속성에서 클래스 정보 확인
print(lr.classes_)

# 계수 출력
print(lr.coef_.shape, lr.intercept_.shape)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다중 분류는 시그모이드 함수가 아닌&lt;b&gt;&amp;nbsp;소프트맥스 함수&lt;/b&gt;를 사용하여 7개의 z값을 확률로 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시그모이드 함수는 하나의 선형 방정식의 출력값을 0~1 사이로 압축한다. 이와 달리 소프트맥스 함수는 여러 개의 선형 방정식의 출력값을 0~1 사이의 확률로 압축하고 전체 합이 1이 되도록 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;decision_function() 메서드로 z1~z7까지의 값을 구한 다음 소프트맥스 함수를 사용하여 확률로 바꾸는 과정&lt;/p&gt;
&lt;pre id=&quot;code_1753016616543&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# z1부터 z7의 값
decision = lr.decision_function(test_scaled[:5])
print(np.round(decision, decimals=2))

# 사이파이는 소프트맥스 함수도 제공
from scipy.special import softmax
proba = softmax(decision, axis=1)
print(np.round(proba, decimals=3))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;04-2 (확률적 경사 하강법)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;경사 하강법 알고리즘을 이해하는 단원&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;확률적 경사 하강법에서 훈련 세트를 한 번 모두 사용하는 과정을&amp;nbsp;&lt;b&gt;에포크&lt;/b&gt;라고 부른다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1개씩 샘플을 선택하는 확률적 경사 하강법, 여러 개씩 꺼내는 미니배치 경사 하강법, 몽땅 꺼내는 배치 경사 하강법이 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;손실함수&lt;/b&gt;는 어떤 문제에서 머신러닝 알고리즘이 얼마나 엉터리인지를 측정하는 기준이다. 그렇기에 작을수록 좋다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;로지스틱 손실 함수&lt;/b&gt;는 (예측)X(정답 혹은 타깃)인데 타깃이 1인 경우에는 곱한 후 음수로 변환해주면 되지만 0인 경우에는 예측에 1을 곱한 후 1에서 뺀 값을 음수로 바꿔주면 된다. 예측이 1에 가까울수록 예측과 타깃의 곱의 음수는 점점 작아진다. 여기에서 예측 확률에 로그 함수를 적용하면 더 좋은데 예측 확률의 범위가 0~1 사이인데 로그 함수는 이 사이에서 음수가 되므로 최종 손실 값은 양수가 된다. 손실이 양수가되면 이해하기 더 쉽고 로그 함수는 0에 가까울수록 아주 큰 음수가 되기 때문에 손실을 아주 크게 만들어 모델에 영향을 미칠 수 있다. 이 손실함수를 로지스틱 손실 함수 또는 이진 크로스엔트로피 손실 함수라고 부른다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753017706094&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')

# Species 열을 제외한 나머지 5개는 입력 데이터로 사용
fish_input = fish[['Weight','Length','Diagonal','Height','Width']]
fish_target = fish['Species']

# 훈련 세트와 테스트 세트로 나누기
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
    fish_input, fish_target, random_state=42)
    
# 전처리
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)

# 사이킷런에서 확률적 경사 하강법을 제공하는 대표적인 분류용 클래스는 SGDClassifier이다.
from sklearn.linear_model import SGDClassifier

# SGDClassifier의 객체를 만들 때 2개의 매개변수 지정
# loss는 손실함수의 종류를 지정
# max_iter는 수행할 에포크 횟수 지정
sc = SGDClassifier(loss='log_loss', max_iter=10, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))
# 출력된 훈련 세트와 테스트 세트 정확도가 낮다. 지정한 반복 횟쉬 10번이 부족한 것으로 보임

# partial_fit() 메서드는 1 에포크씩 이어서 훈련가능
sc.partial_fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))

# 에포크마다 훈련세트와 테스트 세트에 대한 점수를 기록하기 위해 2개의 리스트 준비
sc.partial_fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))

# 300번의 에포크 동안 훈련을 반복하여 진행
for _ in range(0,300):
  sc.partial_fit(train_scaled, train_target, classes=classes)
  train_score.append(sc.score(train_scaled, train_target))
  test_score.append(sc.score(test_scaled, test_target))
  
# 300번의 에포크 동안 기록한 훈련 세트와 테스트 세트의 점수를 그래프로 표현
import matplotlib.pyplot as plt
plt.plot(train_score)
plt.plot(test_score)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()
# 약 100번 정도의 에포크가 적절한 반복 횟수로 보임
# 훈련 세트와 테스트 세트의 차이가 크지 않고 과소적합도 아니기에

# 반복 횟수를 100에 맞추고 모델을 훈련 시킨 후 최종적으로 훈련 세트와 테스트 세트에서 점수 출력
sc = SGDClassifier(loss='log_loss', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zry8E/btsPrhqRuDu/2ahm9mJQPSS7qHa5wRMkCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zry8E/btsPrhqRuDu/2ahm9mJQPSS7qHa5wRMkCK/img.png&quot; data-alt=&quot;300번의 에포크 동안 기록된 점수 그래프&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zry8E/btsPrhqRuDu/2ahm9mJQPSS7qHa5wRMkCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzry8E%2FbtsPrhqRuDu%2F2ahm9mJQPSS7qHa5wRMkCK%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;566&quot; height=&quot;421&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;300번의 에포크 동안 기록된 점수 그래프&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;숙제 (확인문제 2번 풀고 설명하기)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;답은 1번이다. 로지스틱 회귀가 이진 분류에서 확률을 출력하기 위해서는 선형 방정식의 결과를 0과 1사이의 값으로 나타내기 위하여 시그모이드 함수를 사용한다.&lt;/p&gt;</description>
      <category>[혼공머신]</category>
      <author>해야지11</author>
      <guid isPermaLink="true">https://dmdkdk0129.tistory.com/3</guid>
      <comments>https://dmdkdk0129.tistory.com/3#entry3comment</comments>
      <pubDate>Sun, 20 Jul 2025 22:32:46 +0900</pubDate>
    </item>
    <item>
      <title>[혼공머신] 2주차</title>
      <link>https://dmdkdk0129.tistory.com/2</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;03-1 (k-최근접 이웃 회귀)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분류에 이어 회귀에 대해서 알려주고 있다.&lt;/li&gt;
&lt;li&gt;k-최근접 이웃 회귀란 가장 가까웃 이웃 샘플들을 찾고 그 샘플들의 평균하여 예측으로 삼는다.&lt;/li&gt;
&lt;li&gt;결정계수는 대표적인 회귀 문제의 성능 측정 도구로 1에 가까울수록 좋고 0에 가까울수록 성능이 나쁜 모델이다.&lt;/li&gt;
&lt;li&gt;과대적합은 모델의 훈련 세트 성능이 테스트 세트 성능보다 훨씬 높을 때 일어나고 과소적합은 과대적합과는 반대로 훈련 세트와 테스트 세트 성능이 모두 동일하게 낮거나 테스트 세트 성능이 오히려 더 높을 때 일어난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1752356838804&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 KNeighborsRegressor
knr = KNeighborsRegressor()
knr.fit(train_input, train_target)
print(knr.score(test_input, test_target))

from sklearn.metrics import mean_absolute_error
# 테스트 세트에 대한 예측
test_prediction = knr.predict(test_input)
# 테스트 세트에 대한 평균 절댓값 오차를 계산
mae = mean_absolute_error(test_target, test_prediction)
print(mae)

# 과대적합 vs 과소적합
print(knr.score(train_input, train_target))

# k 조정 후 조정된 값으로 학습
knr.n_neighbors = 3
knr.fit(train_input, train_target)
print(knr.score(train_input, train_target))
print(knr.score(test_input, test_target))

# 확인 문제 4
knr = KNeighborsRegressor()
x = np.arange(5, 45).reshape(-1, 1)
for n in [1, 5, 10]:
  knr.n_neighbors = n
  knr.fit(train_input, train_target)
  prediction = knr.predict(x)

  plt.scatter(train_input, train_target)
  plt.plot(x, prediction)
  plt.title('n_neighbors = {}'.format(n))
  plt.xlabel('length')
  plt.ylabel('weight')
  plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zmJUm/btsPp8amdKg/qyP26Y8rZKO7WR0CbekTjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zmJUm/btsPp8amdKg/qyP26Y8rZKO7WR0CbekTjk/img.png&quot; data-alt=&quot;확인문제 4 출력 그래프&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zmJUm/btsPp8amdKg/qyP26Y8rZKO7WR0CbekTjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzmJUm%2FbtsPp8amdKg%2FqyP26Y8rZKO7WR0CbekTjk%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;579&quot; height=&quot;455&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;확인문제 4 출력 그래프&lt;/figcaption&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;03-2 (선형 회귀)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;선형 회귀는 특성과 타깃 사이의 관계를 가장 잘 나타내는 선형 방정식을 찾는다.&lt;/li&gt;
&lt;li&gt;특성이 하나면 직선 방정식이 된다.&lt;/li&gt;
&lt;li&gt;모델 파라미터는 선형 회귀가 찾은 가중치처럼 머신러닝 모델이 특성에서 학습한 파라미터를 말한다.&lt;/li&gt;
&lt;li&gt;다항 회귀는 다항식을 사용하여 특성과 타깃 사이의 관계를 나타낸다. 이 함수는 비선형일 수 있지만 여전히 선형 회귀로 표현할 수 있다.&lt;/li&gt;
&lt;li&gt;선형 회귀의 선형은 입력과 타깃 사이의 관계가 아니라 가중치(계수)와 타깃 사이의 관계를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1752357707809&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
train_input, test_input, train_target, test_target = train_test_split(perch_length, perch_weight, random_state=42)
train_input = train_input.reshape(-1,1)
test_input = test_input.reshape(-1,1)

# k-최근접 이웃 회귀 학습
from sklearn.neighbors import KNeighborsRegressor
knr = KNeighborsRegressor(n_neighbors=3)
knr.fit(train_input, train_target)

# 예측
print(knr.predict([[50]]))

# 시각화
import matplotlib.pyplot as plt
distances, indexes = knr.kneighbors([[50]])
plt.scatter(train_input, train_target)
plt.scatter(train_input[indexes], train_target[indexes], marker='D')
plt.scatter(50,1033,marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 50이든 100이든 같은 값으로 출력됨.
# 왜냐하면 주어진 데이터에선 50이후의 샘플이 없기 때문에 50 이후는 전부 최근접 샘플이 같음

# 선형 회귀 사용
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_input, train_target)
print(lr.predict([[50]]))

# 찾은 모델 파라미터 출력
print(lr.coef_, lr.intercept_)

# 시각화
plt.scatter(train_input, train_target)
plt.plot([15,50],[15*lr.coef_+lr.intercept_, 50*lr.coef_+lr.intercept_])
plt.scatter(50, 1241.8, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 다항 회귀 데이터 준비 및 데이터셋 확인
train_poly = np.column_stack((train_input**2, train_input))
test_poly = np.column_stack((test_input**2, test_input))
print(train_poly.shape, test_poly.shape)

# 다항 회귀 사용
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.predict([[50**2,50]]))
print(lr.coef_, lr.intercept_)

# 시각화
point = np.arange(15,50)
plt.scatter(train_input, train_target)
plt.plot(point, 1.01*point**2 - 21.6*point +116.05)
plt.scatter(50, 1574, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 훈련 세트와 데이터 세트의 결정계수 평가
print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))&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;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;03-3 (특성 공학과 규제)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다중 회귀는 여러 개의 특성을 사용하는 회귀 모델, 특성이 많으면 선형 모델은 강력한 성능을 발휘&lt;/li&gt;
&lt;li&gt;특성 공학은 주어진 특성을 조합하여 새로운 특성을 만드는 일련의 작업 과정&lt;/li&gt;
&lt;li&gt;릿지는 규제가 있는 선형 회귀 모델 중 하나이며&amp;nbsp; 선형 모델의 계수를 작게 만들어 과대적합을 완화시킨다. 릿지는 비교적 효과가 좋아 널리 사용하는 규제 방법&lt;/li&gt;
&lt;li&gt;라쏘는 또 다른 규제가 있는 선형 회귀 모델이며 릿지와 달리 계수 값ㅇ르 아예 0으로 만들 수도 있다.&lt;/li&gt;
&lt;li&gt;하이퍼파라미터는 머신러닝 알고리즘이 학습하지 않는 파라미터이다. 이런 파라미터는 사람이 사전에 지정해야 한다. 대표적으로 릿지와 라쏘의 규제 강도 alpha 파라미터이다.&lt;/li&gt;
&lt;li&gt;변환기는 사이킷런에서 특성을 만들거나 전처리하기 위한 다양한 클래스를 제공&lt;/li&gt;
&lt;li&gt;규제는 머신러닝 모델이 훈련 세트를 너무 과도하게 학습하지 못하도록 훼방하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1752358061280&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

# 2개의 특성 2와 3으로 이루어진 샘플을 적용
poly = PolynomialFeatures()
poly.fit([[2,3]])
print(poly.transform([[2,3]]))

# include_bias = False로 지정하지 않아도 사이킷런 모델은 자동으로 특성에 추가된 절편 항을 무시

# 아래 코드는 명시적으로 지정
poly = PolynomialFeatures(include_bias=False)
poly.fit([[2,3]])
print(poly.transform([[2,3]]))

# 다중 회귀 모델 훈련
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))

# 5제곱까지 특성을 만들어 출력 (degree=5)
poly = PolynomialFeatures(degree=5, include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)
print(train_poly.shape)

# 출력하면 55개의 특성이 만들어졌음을 알 수 있다.
# 55개의 특성을 가지고 선형 회귀 모델 훈련
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))

# 표준점수로 바꾸는 변환기
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_poly)
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)

# 릿지 회귀
from sklearn.linear_model import Ridge
ridge = Ridge()
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))

import matplotlib.pyplot as plt
train_score = []
test_score = []

alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
for alpha in alpha_list:
  ridge = Ridge(alpha=alpha)
  ridge.fit(train_scaled, train_target)
  train_score.append(ridge.score(train_scaled, train_target))
  test_score.append(ridge.score(test_scaled, test_target))

plt.plot(alpha_list, train_score)
plt.plot(alpha_list, test_score)
plt.xscale('log')
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()

# alpha=0.1일 때 두 그래프가 가장 가깝고 테스트 세트의 점수가 가장 높기에 0.1로 최종 모델 훈련
ridge = Ridge(alpha=0.1)
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
print(ridge.score(test_scaled, test_target))

# 라쏘 회귀
from sklearn.linear_model import Lasso
lasso = Lasso()
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
print(lasso.score(test_scaled, test_target))
train_score = []
test_score = []

alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
for alpha in alpha_list:
    # 라쏘 모델을 만듭니다
    lasso = Lasso(alpha=alpha, max_iter=10000)
    # 라쏘 모델을 훈련합니다
    lasso.fit(train_scaled, train_target)
    # 훈련 점수와 테스트 점수를 저장합니다
    train_score.append(lasso.score(train_scaled, train_target))
    test_score.append(lasso.score(test_scaled, test_target))
plt.plot(alpha_list, train_score)
plt.plot(alpha_list, test_score)
plt.xscale('log')
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()

# 라쏘 모델에서 최적의 alpha 값은 10이기에 10으로 모델 훈련
lasso = Lasso(alpha=10)
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
print(lasso.score(test_scaled, test_target))

# 라쏘 모델은 계수 값을 아예 0으로 만들 수 있다.
print(np.sum(lasso.coef_ == 0))&lt;/code&gt;&lt;/pre&gt;</description>
      <category>[혼공머신]</category>
      <category>k-최근접 이웃</category>
      <category>다중 회귀</category>
      <category>선형 회귀</category>
      <category>특성 공학</category>
      <category>혼공머신</category>
      <category>혼공학습단</category>
      <author>해야지11</author>
      <guid isPermaLink="true">https://dmdkdk0129.tistory.com/2</guid>
      <comments>https://dmdkdk0129.tistory.com/2#entry2comment</comments>
      <pubDate>Sun, 13 Jul 2025 07:20:33 +0900</pubDate>
    </item>
    <item>
      <title>[혼공머신] 1주차</title>
      <link>https://dmdkdk0129.tistory.com/1</link>
      <description>&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V7L9u/btsO672YmQY/sZZu2Qxq0uXO95FOVxK3Zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V7L9u/btsO672YmQY/sZZu2Qxq0uXO95FOVxK3Zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V7L9u/btsO672YmQY/sZZu2Qxq0uXO95FOVxK3Zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV7L9u%2FbtsO672YmQY%2FsZZu2Qxq0uXO95FOVxK3Zk%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;971&quot; height=&quot;503&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;503&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;01- 3&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;k-최근접 이웃 알고리즘을 이용하여 도미와 빙어를 분류하는 머신러닝 모델 훈련&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/858kS/btsO66Qx0f6/Dp53DEdxgGkOpCwKcr8JcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/858kS/btsO66Qx0f6/Dp53DEdxgGkOpCwKcr8JcK/img.png&quot; data-alt=&quot;도미 데이터 와 도미 데이터를 산점도로 표현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/858kS/btsO66Qx0f6/Dp53DEdxgGkOpCwKcr8JcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F858kS%2FbtsO66Qx0f6%2FDp53DEdxgGkOpCwKcr8JcK%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;896&quot; height=&quot;748&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;도미 데이터 와 도미 데이터를 산점도로 표현&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQajEu/btsO5wJ7fzQ/D5glvSGdQ9ACwF6SXykixK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQajEu/btsO5wJ7fzQ/D5glvSGdQ9ACwF6SXykixK/img.png&quot; data-alt=&quot;빙어 데이터와 빙어 데이터를 산점도로 표현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQajEu/btsO5wJ7fzQ/D5glvSGdQ9ACwF6SXykixK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQajEu%2FbtsO5wJ7fzQ%2FD5glvSGdQ9ACwF6SXykixK%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;896&quot; height=&quot;574&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;빙어 데이터와 빙어 데이터를 산점도로 표현&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;834&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGGLVN/btsO5Xf2vDN/kKnmGxJB0QV45r2fHU25J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGGLVN/btsO5Xf2vDN/kKnmGxJB0QV45r2fHU25J0/img.png&quot; data-alt=&quot;도미와 빙어 데이터를 하나의 객체에 산점도로 표현, zip()함수를 이용해 2차원 리스트 만듦, 정답데이터 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGGLVN/btsO5Xf2vDN/kKnmGxJB0QV45r2fHU25J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGGLVN%2FbtsO5Xf2vDN%2FkKnmGxJB0QV45r2fHU25J0%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;902&quot; height=&quot;834&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;834&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;도미와 빙어 데이터를 하나의 객체에 산점도로 표현, zip()함수를 이용해 2차원 리스트 만듦, 정답데이터 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;745&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k1BHp/btsO6Dg10c3/JF0h8XahBm4JcCkD8JQ3Xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k1BHp/btsO6Dg10c3/JF0h8XahBm4JcCkD8JQ3Xk/img.png&quot; data-alt=&quot;k-최근접 이웃 알고리즘 구현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k1BHp/btsO6Dg10c3/JF0h8XahBm4JcCkD8JQ3Xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk1BHp%2FbtsO6Dg10c3%2FJF0h8XahBm4JcCkD8JQ3Xk%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;883&quot; height=&quot;745&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;745&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;k-최근접 이웃 알고리즘 구현&lt;/figcaption&gt;
&lt;/figure&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;zip() - 나열된 리스트 각각에서 하나씩 원소를 꺼내 반환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scikit-learn&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;fit() - 사이킷런 모델을 훈련할 때 사용하는 메서드&lt;/li&gt;
&lt;li&gt;predict() - 사이킷런 모델을 훈련하고 예측할 때 사용하는 메서드&lt;/li&gt;
&lt;li&gt;score() - 훈련된 사이킷런 모델의 성능을 측정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;02- 1&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신러닝 알고리즘의 성능을 평가하려면 훈련 데이터와 평가에 사용할 데이터가 각각 달라야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgl0Ms/btsO5XG49NJ/tchOII98kh3KtSxPXYNOp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgl0Ms/btsO5XG49NJ/tchOII98kh3KtSxPXYNOp1/img.png&quot; data-alt=&quot;zip()함수 이용, 슬라이싱&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgl0Ms/btsO5XG49NJ/tchOII98kh3KtSxPXYNOp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbgl0Ms%2FbtsO5XG49NJ%2FtchOII98kh3KtSxPXYNOp1%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;893&quot; height=&quot;639&quot; data-origin-width=&quot;893&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;zip()함수 이용, 슬라이싱&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpltYw/btsO5ok6quB/kackgqU3q1655bVdSpIRb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpltYw/btsO5ok6quB/kackgqU3q1655bVdSpIRb1/img.png&quot; data-alt=&quot;넘파이 변환, 넘파이 배열 크기 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpltYw/btsO5ok6quB/kackgqU3q1655bVdSpIRb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpltYw%2FbtsO5ok6quB%2FkackgqU3q1655bVdSpIRb1%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;874&quot; height=&quot;242&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;넘파이 변환, 넘파이 배열 크기 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;829&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F49tr/btsO5yViDtT/Of4JnhkuUo6qusqkqJjqIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F49tr/btsO5yViDtT/Of4JnhkuUo6qusqkqJjqIK/img.png&quot; data-alt=&quot;랜덤으로 추출, 배열 인덱싱 이용, 시각화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F49tr/btsO5yViDtT/Of4JnhkuUo6qusqkqJjqIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF49tr%2FbtsO5yViDtT%2FOf4JnhkuUo6qusqkqJjqIK%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;853&quot; height=&quot;829&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;829&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;랜덤으로 추출, 배열 인덱싱 이용, 시각화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckdzAE/btsO7OWa2gz/Lk7ifJj22iGk4ZaQvaRzQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckdzAE/btsO7OWa2gz/Lk7ifJj22iGk4ZaQvaRzQ1/img.png&quot; data-alt=&quot;정확도 확인, 테스트 세트의 예측결과와 실제 타깃을 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckdzAE/btsO7OWa2gz/Lk7ifJj22iGk4ZaQvaRzQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckdzAE%2FbtsO7OWa2gz%2FLk7ifJj22iGk4ZaQvaRzQ1%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;834&quot; height=&quot;148&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정확도 확인, 테스트 세트의 예측결과와 실제 타깃을 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;용어:&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;지도 학습 - 타깃(정답)이 있어 알고리즘이 정답을 맞히는 것을 학습&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비지도 학습 - 타깃 없이 입력 데이터만 사용, 데이터를 잘 파악하거나 변형하는데 도움을 줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 세트 - 평가에 사용하는 데이터, 전체 데-이터에서 에서 20~30% 정도 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;훈련 세트 - 훈련에 사용되는 데이터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플링 편향 - 훈련 세트와 테스트 세트에 샘플이 골고루 섞여 있지 않으면 샘플링이 한쪽으로 치우쳤다는 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;numpy&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;seed() - 넘파이에서 난수를 생성하기 위한 정수 초깃값을 지정, 초깃값이 같은면 동일한 난수 추출 가능&lt;/li&gt;
&lt;li&gt;arange() - 일정한 간격의 정수 또는 실수 배열을 만듦&lt;/li&gt;
&lt;li&gt;shuffle() - 주어진 배열을 랜덤하게 섞음, 다차원 배열일 경우 첫 번째 축(행)에 대해서만 섞음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;02- 2&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터의 스케일이 다르다면 전처리를 해야 함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Re8lC/btsO7ysvzzs/htZXuQiKEc87c5kr5y1Ry0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Re8lC/btsO7ysvzzs/htZXuQiKEc87c5kr5y1Ry0/img.png&quot; data-alt=&quot;훈련데이터 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Re8lC/btsO7ysvzzs/htZXuQiKEc87c5kr5y1Ry0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRe8lC%2FbtsO7ysvzzs%2FhtZXuQiKEc87c5kr5y1Ry0%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;872&quot; height=&quot;764&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;훈련데이터 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;881&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUOCkY/btsO6dwlWSc/YPxcnrW5AypYWVPqnqUHvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUOCkY/btsO6dwlWSc/YPxcnrW5AypYWVPqnqUHvk/img.png&quot; data-alt=&quot;훈련 세트, 데이터 세트 크기 확인 및 train_test_split() 함수 이용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUOCkY/btsO6dwlWSc/YPxcnrW5AypYWVPqnqUHvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUOCkY%2FbtsO6dwlWSc%2FYPxcnrW5AypYWVPqnqUHvk%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;881&quot; height=&quot;476&quot; data-origin-width=&quot;881&quot; data-origin-height=&quot;476&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;훈련 세트, 데이터 세트 크기 확인 및 train_test_split() 함수 이용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;565&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzE2Hz/btsO50RlxLj/HcoJABSoE3vJnqz6VTazgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzE2Hz/btsO50RlxLj/HcoJABSoE3vJnqz6VTazgK/img.png&quot; data-alt=&quot;새로운 샘플 구분 및 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzE2Hz/btsO50RlxLj/HcoJABSoE3vJnqz6VTazgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzE2Hz%2FbtsO50RlxLj%2FHcoJABSoE3vJnqz6VTazgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;850&quot; height=&quot;565&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;새로운 샘플 구분 및 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHLWk8/btsO7xAmCO1/L9ksIKoPkl4b8Ys0sJwbK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHLWk8/btsO7xAmCO1/L9ksIKoPkl4b8Ys0sJwbK1/img.png&quot; data-alt=&quot;kn.kneighbors()를 통해 가까운 5개의 샘플 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHLWk8/btsO7xAmCO1/L9ksIKoPkl4b8Ys0sJwbK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHLWk8%2FbtsO7xAmCO1%2FL9ksIKoPkl4b8Ys0sJwbK1%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;762&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;kn.kneighbors()를 통해 가까운 5개의 샘플 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdHos7/btsO7PnffLz/O2KGKYzi20nmCZ1pZeGMg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdHos7/btsO7PnffLz/O2KGKYzi20nmCZ1pZeGMg1/img.png&quot; data-alt=&quot;기준(범위)를 동일하게 맞춤&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdHos7/btsO7PnffLz/O2KGKYzi20nmCZ1pZeGMg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdHos7%2FbtsO7PnffLz%2FO2KGKYzi20nmCZ1pZeGMg1%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;837&quot; height=&quot;661&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기준(범위)를 동일하게 맞춤&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn3oD5/btsO6BXMDQZ/FOnD2aFvliUZzRa2JZj1n0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn3oD5/btsO6BXMDQZ/FOnD2aFvliUZzRa2JZj1n0/img.png&quot; data-alt=&quot;표준점수 방법으로 전처리 (새로운 샘플에는 적용 안함)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn3oD5/btsO6BXMDQZ/FOnD2aFvliUZzRa2JZj1n0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn3oD5%2FbtsO6BXMDQZ%2FFOnD2aFvliUZzRa2JZj1n0%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;830&quot; height=&quot;637&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표준점수 방법으로 전처리 (새로운 샘플에는 적용 안함)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg5cnN/btsO6YSIAab/cnDOJNfOO3SKYKy0K6nuK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg5cnN/btsO6YSIAab/cnDOJNfOO3SKYKy0K6nuK0/img.png&quot; data-alt=&quot;새로운 샘플에도 동일한 전처리 방법 사용하여 시각화 후 모델 평가 및 새로운 샘플에 대한 모델의 예측 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg5cnN/btsO6YSIAab/cnDOJNfOO3SKYKy0K6nuK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg5cnN%2FbtsO6YSIAab%2FcnDOJNfOO3SKYKy0K6nuK0%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;674&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;새로운 샘플에도 동일한 전처리 방법 사용하여 시각화 후 모델 평가 및 새로운 샘플에 대한 모델의 예측 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cC733H/btsO5AZT8A9/ldshX3g14aeLbyFBXaR8mK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cC733H/btsO5AZT8A9/ldshX3g14aeLbyFBXaR8mK/img.png&quot; data-alt=&quot;특성을 표준점수 방법을 전처리 후 kneighbors() 함수로 가장 가까운 샘플 5개 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cC733H/btsO5AZT8A9/ldshX3g14aeLbyFBXaR8mK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcC733H%2FbtsO5AZT8A9%2FldshX3g14aeLbyFBXaR8mK%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;829&quot; height=&quot;548&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;특성을 표준점수 방법을 전처리 후 kneighbors() 함수로 가장 가까운 샘플 5개 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;용어:&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스케일 - 두 특성의 값이 놓인 범위가 매우 다를 때 두 특성의 스케일이 다르다고 함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 전처리 - 샘플 간의 거리에 영향을 많이 받으므로 특성값을 일정한 기준으로 맞춰주는 작업(예: 표준점수)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;브로드캐스팅 - 크기가 다른 넘파이 배열에서 자동을 사칙 연산을 모든행이나 열로 확장하여 수행&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수:&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;numpy&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;column_stack() - 전달받은 리스트를 일렬로 세운 다음 차례대로 나란히 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scikit-learn&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;train_test_split() - 훈련 데이터를 훈련 세트와 테스트 세트로 나누는 함수&lt;/li&gt;
&lt;li&gt;kneighbors() - k-최근접 이웃 객체의 메서드, 입력한 데이터에 가장 가까운 이웃을 찾아 거리와 이웃 샘플의 인덱스를 반환&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>[혼공머신]</category>
      <category>k-최근접 이웃</category>
      <category>머신러닝</category>
      <category>혼공머신</category>
      <category>혼공학습단</category>
      <author>해야지11</author>
      <guid isPermaLink="true">https://dmdkdk0129.tistory.com/1</guid>
      <comments>https://dmdkdk0129.tistory.com/1#entry1comment</comments>
      <pubDate>Sun, 6 Jul 2025 16:29:43 +0900</pubDate>
    </item>
  </channel>
</rss>