<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jst-jin-hyeong.log</title>
        <link>https://velog.io/</link>
        <description>안티프래질!</description>
        <lastBuildDate>Fri, 18 Apr 2025 07:24:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jst-jin-hyeong.log</title>
            <url>https://velog.velcdn.com/images/jst-jin-hyeong/profile/31dff923-794d-4827-be37-16128c67e17f/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jst-jin-hyeong.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jst-jin-hyeong" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Need to research]]></title>
            <link>https://velog.io/@jst-jin-hyeong/Need-to-research</link>
            <guid>https://velog.io/@jst-jin-hyeong/Need-to-research</guid>
            <pubDate>Fri, 18 Apr 2025 07:24:13 GMT</pubDate>
            <description><![CDATA[<p>IO 병합
컨텍스트 스위칭
쓰레드
프로세스
WriteIOPs 와 Throuput 상관관계
wait event
<a href="https://myinfrabox.tistory.com/197">https://myinfrabox.tistory.com/197</a>
performance insights 에 찍히는 CPU</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mutex & Semaphore]]></title>
            <link>https://velog.io/@jst-jin-hyeong/Mutex-Semaphore</link>
            <guid>https://velog.io/@jst-jin-hyeong/Mutex-Semaphore</guid>
            <pubDate>Tue, 15 Apr 2025 22:28:36 GMT</pubDate>
            <description><![CDATA[<p>참고 영상1: <a href="https://www.youtube.com/watch?v=kd8b9Fr0Xbo&amp;t=3s">https://www.youtube.com/watch?v=kd8b9Fr0Xbo&amp;t=3s</a>
<img src="https://velog.velcdn.com/images/jst-jin-hyeong/post/a1887571-5387-446b-80e4-79d841cb88ec/image.png" alt="">
참고 영상2: <a href="https://www.youtube.com/watch?v=oazGbhBCOfU">https://www.youtube.com/watch?v=oazGbhBCOfU</a>
<img src="https://velog.velcdn.com/images/jst-jin-hyeong/post/a930fed8-e063-4022-8706-acc2930c1052/image.png" alt=""></p>
<h2 id="mutex">Mutex</h2>
<h3 id="semaphore-와의-차이점">Semaphore 와의 차이점</h3>
<ul>
<li>Single Thread</li>
<li>2 개의 상태<ul>
<li>Lock</li>
<li>Unlocked</li>
</ul>
</li>
<li>Locking Mechanism<ul>
<li><h2 id="example-producer-와-cunsumer-그리고-1개의-버퍼">Example: Producer 와 Cunsumer, 그리고 1개의 버퍼</h2>
</li>
</ul>
</li>
</ul>
<h2 id="semaphore">Semaphore</h2>
<h2 id="mutex-와의-차이점">Mutex 와의 차이점</h2>
<ul>
<li>Multi Thread</li>
<li>Count</li>
<li>Signaling Mechanism<ul>
<li>Example: 2개의 쓰레드, 1개의 버퍼 의 개념<ul>
<li>Producer and Consumer
  프로듀서가 버퍼에 데이터를 채워놓으면
  컨슈머가 버퍼의 데이터를 사용
  그 후 컨슈머가 프로듀서에게 나 다 사용했다고 알려준다.</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Aurora MySQL Load Data FROM S3]]></title>
            <link>https://velog.io/@jst-jin-hyeong/Aurora-MySQL-Load-Data-FROM-S3</link>
            <guid>https://velog.io/@jst-jin-hyeong/Aurora-MySQL-Load-Data-FROM-S3</guid>
            <pubDate>Tue, 15 Apr 2025 17:24:59 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>버킷 생성</p>
</li>
<li><p>폴리시 생성 - 위에 생성한 버킷을 리소스로 등록
[+] Amazon S3 리소스에 액세스할 수 있는 IAM 정책 생성 - <a href="https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.S3CreatePolicy.html">https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.S3CreatePolicy.html</a></p>
</li>
<li><p>롤 생성 - 위에 생성한 폴리시 등록
[+] Amazon Aurora에서 AWS 서비스에 액세스하도록 허용하는 IAM 역할 생성 - <a href="https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.CreateRole.html">https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.CreateRole.html</a></p>
</li>
<li><p>Aurora 클러스터에 롤 등록
=&gt; 콘솔 - Cluster - Connectivity &amp; Security - Manage IAM roles 탭 - Select IAM roles to add to this cluster - Choose an IAM role to add 드롭박스에서 위에서 생성한 role 등록
[+] 콘솔을 사용하여 IAM 역할을 Aurora DB 클러스터와 연결하려면 - <a href="https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.AddRoleToDBCluster.html">https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.AddRoleToDBCluster.html</a></p>
</li>
<li><p>aws_default_s3_role 파라미터 수정
=&gt; Cluster parameter 에서 aws_default_s3_role 파라미터를 role의 arn 으로 수정
ex: aws_default_s3_role 을
arn:aws:iam::123456789012:role/AllowS3Access
또는 
arn:aws:iam::321869854760:role/jh-role-2025-apr-c08-load-data-from-s3
등으로 수정</p>
<blockquote>
<p>select @@aws_default_s3_role;
로 확인 가능
[+] 연결된 IAM 역할에 클러스터 수준 파라미터를 설정하는 방법 - <a href="https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.AddRoleToDBCluster.html">https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Integrating.Authorizing.IAM.AddRoleToDBCluster.html</a></p>
</blockquote>
</li>
</ol>
<p>예시 데이터:
11111111111111111111111111111111111111111
1111111111111111
111111111</p>
<p>예시 테이블:
CREATE TABLE number_data (
    line_content VARCHAR(255)
);</p>
<p>예시 로드 쿼리:
LOAD DATA FROM S3 &#39;s3://버킷명/test_text1.txt&#39;
INTO TABLE number_data
LINES TERMINATED BY &#39;\n&#39;
(line_content);</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 설치 직후 root 접속 불가한 이유 - ERROR 1045 (28000)]]></title>
            <link>https://velog.io/@jst-jin-hyeong/MySQL-%EC%84%A4%EC%B9%98-%EC%A7%81%ED%9B%84-root-%EC%A0%91%EC%86%8D-%EB%B6%88%EA%B0%80%ED%95%9C-%EC%9D%B4%EC%9C%A0-ERROR-1045-28000</link>
            <guid>https://velog.io/@jst-jin-hyeong/MySQL-%EC%84%A4%EC%B9%98-%EC%A7%81%ED%9B%84-root-%EC%A0%91%EC%86%8D-%EB%B6%88%EA%B0%80%ED%95%9C-%EC%9D%B4%EC%9C%A0-ERROR-1045-28000</guid>
            <pubDate>Mon, 30 Dec 2024 22:43:42 GMT</pubDate>
            <description><![CDATA[<h2 id="요약">요약</h2>
<p>root의 임시 비밀번호가 있으며 이것은 mysqld.log 에서 확인할 수 있다.</p>
<h2 id="내용">내용</h2>
<h3 id="에러---비밀번호-실패">에러 - 비밀번호 실패</h3>
<p>요즘 버전에서는 MySQL 설치 직후 root 사용자로 접속 시 아래와 같은 에러가 발생한다.</p>
<p>ERROR 1045 (28000): Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password: NO)
<img src="https://velog.velcdn.com/images/jst-jin-hyeong/post/6ac0ab29-f6bf-4882-a774-e2132e362ae5/image.png" alt=""></p>
<h3 id="원인---임시비밀번호">원인 - 임시비밀번호</h3>
<p>이유는 패스워드가 틀렸기 때문인데, 최초 설치할 때 분명 별도의 패스워드를 입력하지 않았는데도 이런 에러가 발생한다. 어쩌란 말인가? 이유는 무엇인가?
답은 임시 비밀번호가 주어진다는 것이다.</p>
<h3 id="해결-방법---mysqldlog">해결 방법 - mysqld.log</h3>
<h4 id="mysqldlog-에서-비밀번호를-찾기">mysqld.log 에서 비밀번호를 찾기</h4>
<p>MySQL에는 mysqld.log가 있다.
최초 설치 직후 생성된 임시 비멀번호가 이곳에 기록된다.
&quot;temporary password&quot; 를 grep 으로 잡아보자.
<img src="https://velog.velcdn.com/images/jst-jin-hyeong/post/d3d8bc77-93b0-402e-a0a7-35444b770896/image.png" alt=""></p>
<p>이렇게 임시비밀번호가 생성된걸 확인할 수 있다.</p>
<h4 id="root-비밀번호-변경해주기">root 비밀번호 변경해주기</h4>
<p>저 임시번호로 접속해서 비밀번호를 변경하거나, mysql_secure_installation 를 통해서 비밀번호를 변경해준다.
mysql_secure_installation 로 비밀번호를 변경하는 방법은 아래 글에 잘 설명되어있어서 좋았다.
<a href="https://lifeinprogram.tistory.com/21">https://lifeinprogram.tistory.com/21</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[EC2(Amazon Linux 2)에 MySQL 설치하기]]></title>
            <link>https://velog.io/@jst-jin-hyeong/EC2Amazon-Linux-2%EC%97%90-MySQL-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@jst-jin-hyeong/EC2Amazon-Linux-2%EC%97%90-MySQL-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 30 Dec 2024 22:20:03 GMT</pubDate>
            <description><![CDATA[<h2 id="요약">요약</h2>
<ul>
<li>MySQL 공식 사이트에서 레포 링크 얻기<ul>
<li>wget 으로 링크를 통해 다운로드해도 되고 링크를 바로 레포로 등록해도 된다</li>
</ul>
</li>
<li>레포 등록</li>
<li>레포 확인</li>
<li>MySQL 설치</li>
<li>MySQL 실행</li>
</ul>
<pre><code>yum install -y https://dev.mysql.com/get/mysql84-community-release-el7-1.noarch.rpm
yum repolist
yum install -y mysql-community-server
systemctl start mysqld</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[# 운영 체제 : 컴퓨터 과학 특강 # 18]]></title>
            <link>https://velog.io/@jst-jin-hyeong/%EC%9A%B4%EC%98%81-%EC%B2%B4%EC%A0%9C-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B3%BC%ED%95%99-%ED%8A%B9%EA%B0%95-18</link>
            <guid>https://velog.io/@jst-jin-hyeong/%EC%9A%B4%EC%98%81-%EC%B2%B4%EC%A0%9C-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B3%BC%ED%95%99-%ED%8A%B9%EA%B0%95-18</guid>
            <pubDate>Wed, 04 Dec 2024 08:02:50 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.youtube.com/watch?v=26QPDBe-NB8&amp;list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo&amp;index=20">https://www.youtube.com/watch?v=26QPDBe-NB8&amp;list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo&amp;index=20</a></p>
<h3 id="virtual-memory">Virtual Memory</h3>
<p>Virtual Memory: 실제 사용되는 메모리는 흩어져있지만 이것을 가상화하여 추상화하고 숨긴다. 따라서프로그램은 0번부터 차근차근 사용한다고 행각한다.</p>
<p>(실제 사용되는 A 프로그램의 메모리는 0번부터 999, 1000번부터 1999이 아니라 0번부터 999, 2000부터 2999일 수 있다는 것이다. 그렇지만 이것은 메모리 관리의 혼란을 야기한다.)</p>
<p>이것은 동적 메모리 할당을 가능케한다. 프로그램 자체에 메모리를 할당하는 것이다. 또한 서로로부터 격리되게 해준다.</p>
<h3 id="memory-protection">Memory Protection</h3>
<p>Memory Protection: 버그가 있는 프로그램이 잘못되어 문제가 발생할 수 있는 표현을 write 를 하면 다른 프로그램의 메모리가 아닌 자신의 메모리를 버리는 데에서 그칩니다. 이 기능을 메모리 보호(Memory Protection)라고 합니다.</p>
<p>이것은 바이러스와 같은 악의적인 소프트웨어로부터 보호하는 데에도 유용합니다. </p>
<h3 id="time-sharing">Time Sharing</h3>
<p>운영체제는 시간 공유 기능을 제공하도록 개발되었습니다. </p>
<p>컴퓨터의 성능이 좋아지면서 컴퓨터 한 대에 터미널 PC 가 50대가 붙어 사용했었습니다. 터미널 PC는 자체적인 컴퓨팅 기능은 없으며 모니터 화면만 있을 뿐이었죠.</p>
<h3 id="unix">Unix</h3>
<p>Multics 연구원인 Ken Thomson과 Dennis는 Multics를 파업하고 Unix 구축</p>
<p>OS 를 두 부분으로 분리</p>
<ul>
<li>커널: I/O 를 다루는 기능인 메모리 관리, 멀티 태스킹과 같은 OS의 핵심 기능</li>
<li>프로그램과 라이브러리 같은 유용한 도구들</li>
</ul>
<p>커널을 만드는 것은 의도적으로 일부 기능만 남겨두어 군살없게 만들었습니다. Multic 에서는 코드의 절반이 에로 복구일 정도였는데, 이러한 것들을 들어냈습니다.</p>
<p>유닉스는 대신에 오류가 발생하면 패닉이라고 하는 루틴을 갖게 됩니다. 패닉이 발생하면 그냥 Reboot 를 해버릴 뿐이죠.</p>
<p>Microsoft의 디스크 운영체제 MS-DOS는 160 킬로바이트에 불과했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB - Metadata Lock]]></title>
            <link>https://velog.io/@jst-jin-hyeong/DB-Metadata-Lock</link>
            <guid>https://velog.io/@jst-jin-hyeong/DB-Metadata-Lock</guid>
            <pubDate>Sun, 17 Nov 2024 19:46:43 GMT</pubDate>
            <description><![CDATA[<h1 id="원뎁스-1">원뎁스-1</h1>
<h2 id="metadata-lock-이란">Metadata Lock 이란?</h2>
<p>[MySQL공식문서를 먼저 확인해보자.] (<a href="https://dev.mysql.com/doc/refman/8.4/en/metadata-locking.html">https://dev.mysql.com/doc/refman/8.4/en/metadata-locking.html</a>)</p>
<ul>
<li><a href="https://dev.mysql.com/doc/refman/8.4/en/metadata-locking.html">https://dev.mysql.com/doc/refman/8.4/en/metadata-locking.html</a></li>
</ul>
<h2 id="metadata-lock은-왜-쓸까">Metadata Lock은 왜 쓸까?</h2>
<h1 id="투뎁스-1">투뎁스-1</h1>
<h2 id="metadata-lock-발생시키기">Metadata Lock 발생시키기</h2>
<h2 id="metadata-lock-해소하기">Metadata Lock 해소하기</h2>
<hr>
<h3 id="쓰리뎁슨가">쓰리뎁슨가</h3>
<h4 id="글쎄다">글쎄다</h4>
<h5 id="뭐라">뭐라</h5>
<h6 id="뭐라고">뭐라고</h6>
  <table>
    <tr>
      <th scope="col">이름</td>
      <th scope="col">나이</td>
      <th scope="col">성별</td>
    </tr>
    <tr>
      <td>이시도로</td>
      <td>77</td>
      <td>남</td>
    </tr>
    <tr>
      <td>루카</td>
      <td>77</td>
      <td>남</td>
    </tr>
  </table>

]]></description>
        </item>
        <item>
            <title><![CDATA[md - Table]]></title>
            <link>https://velog.io/@jst-jin-hyeong/md-Table</link>
            <guid>https://velog.io/@jst-jin-hyeong/md-Table</guid>
            <pubDate>Sun, 17 Nov 2024 19:35:15 GMT</pubDate>
            <description><![CDATA[<p>구성을 외워두자</p>
<ul>
<li>테이블 &gt; 티알 &gt; 티에이치스콥은콜 또는 티디</li>
</ul>
<pre><code> &lt;table&gt;
    &lt;tr&gt;
      &lt;th scope=&quot;col&quot;&gt;이름&lt;/td&gt;
      &lt;th scope=&quot;col&quot;&gt;나이&lt;/td&gt;
      &lt;th scope=&quot;col&quot;&gt;성별&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;이시도로&lt;/td&gt;
      &lt;td&gt;77&lt;/td&gt;
      &lt;td&gt;남&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;루카&lt;/td&gt;
      &lt;td&gt;77&lt;/td&gt;
      &lt;td&gt;남&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;</code></pre> <table>
    <tr>
      <th scope="col">이름</td>
      <th scope="col">나이</td>
      <th scope="col">성별</td>
    </tr>
    <tr>
      <td>이시도로</td>
      <td>77</td>
      <td>남</td>
    </tr>
    <tr>
      <td>루카</td>
      <td>77</td>
      <td>남</td>
    </tr>
  </table>]]></description>
        </item>
        <item>
            <title><![CDATA[[DNS] host resolv.conf]]></title>
            <link>https://velog.io/@jst-jin-hyeong/DNS-host-resolv.conf</link>
            <guid>https://velog.io/@jst-jin-hyeong/DNS-host-resolv.conf</guid>
            <pubDate>Wed, 22 Mar 2023 12:23:10 GMT</pubDate>
            <description><![CDATA[<h1 id="dnsdomain-name-server">DNS(Domain Name Server)</h1>
<p><strong>DNS</strong>는 <strong>도메인 이름</strong>과 <strong>IP 주소</strong>를 서로 변환하는 역할을 한다</p>
<ul>
<li><strong>리소스 레코드</strong>(Resource record)를 가지며, 이 리소스 레코드는 <strong>A, AAAA, CNAME, NS, MX, SPF, PTR</strong> 등으로 이루어져있다.</li>
</ul>
<hr>
<h2 id="headline-keywords">Headline (Keywords)</h2>
<ul>
<li><strong>리소스 레코드</strong>
 A, AAAA, CNAME, NS, MX, SPF, PTR</li>
<li>** DNS 동작 **
  /etc/host.conf
  /etc/hosts
  /etc/resolv.conf</li>
</ul>
<hr>
<h2 id="본문-시작">본문 시작!</h2>
<h3 id="etchostsconf-파일부터-알아볼까요">/etc/hosts.conf 파일부터 알아볼까요?</h3>
<blockquote>
<p>요약: 도메인 네임 서비스를 어디서 받을 지 순위를 정해놓은 파일!</p>
</blockquote>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2314694B56BF535D29" alt="">
실제로 파일을 열어보면 위와 같이 되어있습니다.</p>
<ul>
<li>hosts: 여기서 hosts란, <strong>/etc/hosts</strong> 파일을 말합니다.</li>
<li>bind: 여기서 bind란, <strong>/etc/resolv.conf</strong>에 정의된 <strong>nameserver</strong>를 의미합니다.</li>
<li>nis: 추가로 nis도 있습니다. nis란, nis에 의한 <strong>도메인 쿼리</strong>를 말해요!</li>
</ul>
<p>그래서 위의 이미지를 해석하면, 어떤 PC로부터 자신(DNS)에게 질의요청이 오면, 맨 처음은</p>
<p>1) <strong>/etc/hosts</strong>파일에서 찾아봅니다.
2) 거기에 없으면, <strong>/etc/resolv.conf</strong>에 정의된 <strong>nameserver</strong>에게 쿼리하게 되는 것이지요!</p>
<h3 id="etcresolvconf를-이어서-알아볼까요">/etc/resolv.conf를 이어서 알아볼까요?</h3>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F21562B4756BF535618" alt="">
실제로 <strong>/etc/resolv.conf</strong> 파일을 열어보면 위와 같이 되어있어요.
이 파일이 열람되는 시점은,
/etc/host.conf에 지정된 우선순위에 따라 상위 레벨에서 찾지 못하여 bind 순서에 도달하였을 때입니다.
그 때 nameserver 항목에 지정된 ip로 갑니다.  (해당 nameserver의 도메인주소는 search에 적힌 값입니다)</p>
<p>출처: <a href="https://itdexter.tistory.com/321">https://itdexter.tistory.com/321</a></p>
<h2 id="dns-동작">DNS 동작</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[sklearn 프렙프 omniPrep]]></title>
            <link>https://velog.io/@jst-jin-hyeong/sklearn-%ED%94%84%EB%A0%99%ED%94%84-omniPrep</link>
            <guid>https://velog.io/@jst-jin-hyeong/sklearn-%ED%94%84%EB%A0%99%ED%94%84-omniPrep</guid>
            <pubDate>Tue, 21 Mar 2023 06:20:40 GMT</pubDate>
            <description><![CDATA[<p>object 타입은 범주형. 머신러닝에선 숫자형으로 바꾸어줘야 한다.</p>
<p>number 타입은 숫자형. 숫자형은 스케일링 해줘야 한다.</p>
<p>##################################전처리#################################</p>
<p>import pandas as pd</p>
<p>pd.read_csv(&#39; 파일명 &#39;)</p>
<p>df.columns                                                   기억     #컬럼명 확인, s붙는거 기억</p>
<p>df.values                                                                기억      #values 확인, s붙는거 기억</p>
<p>df.isnull().sum()                                              기억     #null 값 확인 ------------ () 괄호 위치 기억</p>
<p>df.shape                                                                 #행 수, 열 수 확인할 수 있음</p>
<p>df.info()                                                                  #df.info 말고 df.info()가 편리하다.</p>
<p>df.info                                                                   #괄호가 없으면 ------------ 숫자형 데이터 가능성 있는 것들을 용이하게 확인할 수 있다.</p>
<p>df.describe()                                                  기억     #&quot;숫자형&quot; 정보들의 통계정보를 보여준다.</p>
<p>df.boxplot()                                                  기억     #숫자형 정보들의 boxplot을 볼 수 있다</p>
<p>df[&#39; 해당컬럼 &#39;].astype(float)                                         기억      #float type으로 컬럼들을 변경하여 보여줌(값이 바뀌지는 않음)</p>
<p>df[&#39; 컬럼 &#39;].replace( [&#39; 값 &#39;], [&#39; 바꾼결과값 &#39;], inplace=True)    기억      #replace로 값 바꾸기</p>
<pre><code>                                                                       #boolean으로 공백찾기 - 예시는 밑에서 확인</code></pre><p>(df[&#39; 컬럼명&#39; ] == &gt; &lt;등 조건식)</p>
<pre><code>                                                                       #(예시) null이 아니지만 공란이거나 스페이스인 경우 확인

                                                                       #결과는=&gt;    해당컬럼인덱스  탭  False나 True</code></pre><p>cond = (df[&#39; 조사대상컬럼명 &#39;] == &#39;&#39;) | (df[&#39; 조사대상컬럼명 &#39;] == &#39; &#39;)  #cond에 필터링 해서 True, False로 집어넣기</p>
<p>df[cond]                                                                 #로 확인할 수 있음</p>
<p>df[&#39; 컬럼 &#39;].value_counts()                                 기억     #범주 별 건수 확인. 스펠, 언더바, 괄호 확인, value에 s 안 붙음</p>
<p>df[&#39; 컬럼 &#39;].replace([&#39;Yes&#39;, &#39;No&#39;], [1, 0], inplace = True)           #replace에 여러 값을 한 번에 넣을 수도 있음</p>
<p>df.drop(&#39; 컬럼명 &#39;, axis = 1, inplace = True)                      #컬럼 제거, dropna 하기 전에 한 번 무조건 확인</p>
<p>df_BacDropna=df.copy()                                              #drop하기 전에 백업해두는 것도 좋은방법일듯</p>
<p>df.dropna(inplace = True)</p>
<p>df.reset_index(drop = True)                                          기억      #인덱스 reorg</p>
<p>import matplotlib.pyplot as plt                           기억     #시각화 임포트</p>
<p>df.value_counts().plot(kind = &#39;bar&#39;)                       기억     #시각화는 value_counts와 짝꿍이다</p>
<pre><code>       #한꺼번에 Object type 시각화하기, 그리고 불균형 심한거 제거하기</code></pre><p>.select_dtypes(&#39;O&#39;)                                                     기억      #Object type만 보기. O (대문자)대신 object(소문자)라고 해도 될 거다</p>
<p>.columns.values                                             기억     3columns.values</p>
<p>df.select_dtypes(&#39;O&#39;).columns.values                      기억     #select_dtypes()와 columns.values 조합</p>
<p>변수명=df.select_dtypes(&#39;O&#39;).columns.values 로 담기 기억</p>
<p>for col in 변수명</p>
<pre><code>       df[col].value_counts().plot(kind = &#39;bar&#39;)

       plt.title(col)

       plt.show()</code></pre><p>#연속형 자료는 value_counts().plot으로 보는거 아니다</p>
<p>!pip install seaborn</p>
<p>import seaborn as sns</p>
<p>sns.histplot(data=df, x=&#39; 컬럼명 &#39;)                       기억     histogram로 보기</p>
<p>sns.histplot(data=df, x=&#39; 컬럼명 &#39;, hue(&#39; 컬럼명2 &#39;))  기억     컬럼명2로 비교</p>
<p>kdeplot            #곡선</p>
<p>countplot          #</p>
<p>df[[&#39; 컬럼1 &#39;, ... &#39; 컬럼n&#39;]].corr()                           기억     여러 컬럼들의 상관관계분석 가능</p>
<p>sns.heatmap( ~~ .corr(), annot=True)                              기억      히트맵으로 상관관계 볼 수 있음</p>
<p>sns.boxplot(data=df, x=&#39; 컬럼명 &#39;, y= &#39; 컬럼명2 &#39;)    기억     boxplot으로 이상치 등을 볼 수 있음</p>
<p>df.to_csv(&#39; 저장할파일명 &#39;, index = False)               기억     csv파일로 저장하기. index=false를 줘야 index 없이 저장할 수 있음</p>
<p>###############################머신러닝################################</p>
<p>1) get_dummies</p>
<p>2) train_test_split</p>
<p>3) MinMaxScaler</p>
<p>df = pd.read_csv(&#39; 파일 명 &#39;, sep= &quot; ~ &quot;)               기억     csv 가져올 때</p>
<p>pd.get_dummies(data=df, columns=[&#39; 컬럼명 &#39;])                 기억      인코딩! 그리고 columns=[ ] 대괄호니까 안에 값이 여러개 들어갈 수도 있겠지</p>
<p>dum_list</p>
<p>df1=pd.get_dummies(data=df, columns=dum_list)    기억     columns=변수명 으로 해버려도 됨 (Q. columns=[dum_list]로 왜 안 하지?)</p>
<p>X=df1.drop(&#39; 컬럼명 &#39;, axis = 1).values                            기억      뒤에 .values를 붙여야하는 걸 잊지마. 데이터프레임으로 저장이 아니라 값들만으로 저장해야해</p>
<p>X.shape, y.shape                                            기억     shape로 행 개수, 컬럼개수 확인 가능</p>
<p>from sklearn.model_selection import train_test_split</p>
<p>=train_test_split(X, y, test_size=0.3, stratify = y, random_state = 42)    #트레인 세트 분리</p>
<p>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify = y, random_state = 42)</p>
<p>from sklearn.preprocessing import MinMaxScaler     기억     scaler 임포트</p>
<p>scaler = MinMaxScaler()                                   기억     scaler에 MinMaxScaler() 함수를 담는다.</p>
<p>X_train = scaler.fit_transform(X_train)                              기억      X_train으로 scale을 fit함과 동시에 다시 그대로 담는다</p>
<p>X_test = scaler.transform(X_test)                         기억     X_test를 위에서 fit 된걸 기반으로 담는다.</p>
<p>X_train[:2], y_train[:2]                                       기억     담긴거 확인(2개 컬럼만 확인한다)</p>
<p>==================================================함수</p>
<h1 id="모델별로-recall-점수-저장">모델별로 Recall 점수 저장</h1>
<h1 id="모델-recall-점수-순서대로-바차트를-그려-모델별로-성능-확인-가능">모델 Recall 점수 순서대로 바차트를 그려 모델별로 성능 확인 가능</h1>
<p>from sklearn.metrics import accuracy_score</p>
<p>my_predictions = {}</p>
<p>colors = [&#39;r&#39;, &#39;c&#39;, &#39;m&#39;, &#39;y&#39;, &#39;k&#39;, &#39;khaki&#39;, &#39;teal&#39;, &#39;orchid&#39;, &#39;sandybrown&#39;,</p>
<pre><code>      &#39;greenyellow&#39;, &#39;dodgerblue&#39;, &#39;deepskyblue&#39;, &#39;rosybrown&#39;, &#39;firebrick&#39;,

      &#39;deeppink&#39;, &#39;crimson&#39;, &#39;salmon&#39;, &#39;darkred&#39;, &#39;olivedrab&#39;, &#39;olive&#39;,

      &#39;forestgreen&#39;, &#39;royalblue&#39;, &#39;indigo&#39;, &#39;navy&#39;, &#39;mediumpurple&#39;, &#39;chocolate&#39;,

      &#39;gold&#39;, &#39;darkorange&#39;, &#39;seagreen&#39;, &#39;turquoise&#39;, &#39;steelblue&#39;, &#39;slategray&#39;,

      &#39;peru&#39;, &#39;midnightblue&#39;, &#39;slateblue&#39;, &#39;dimgray&#39;, &#39;cadetblue&#39;, &#39;tomato&#39;

     ]</code></pre><h1 id="모델명-예측값-실제값을-주면-위의-plot_predictions-함수-호출하여-scatter-그래프-그리며">모델명, 예측값, 실제값을 주면 위의 plot_predictions 함수 호출하여 Scatter 그래프 그리며</h1>
<h1 id="모델별-mse값을-bar-chart로-그려줌">모델별 MSE값을 Bar chart로 그려줌</h1>
<p>def recall_eval(name_, pred, actual):</p>
<pre><code>global predictions

global colors




plt.figure(figsize=(12, 9))




#acc = accuracy_score(actual, pred)

acc = recall_score(actual, pred)

my_predictions[name_] = acc * 100




y_value = sorted(my_predictions.items(), key=lambda x: x[1], reverse=True)



df = pd.DataFrame(y_value, columns=[&#39;model&#39;, &#39;recall&#39;])

print(df)



length = len(df)



plt.figure(figsize=(10, length))

ax = plt.subplot()

ax.set_yticks(np.arange(len(df)))

ax.set_yticklabels(df[&#39;model&#39;], fontsize=15)

bars = ax.barh(np.arange(len(df)), df[&#39;recall&#39;])



for i, v in enumerate(df[&#39;recall&#39;]):

    idx = np.random.choice(len(colors))

    bars[i].set_color(colors[idx])

    ax.text(v + 2, i, str(round(v, 3)), color=&#39;k&#39;, fontsize=15, fontweight=&#39;bold&#39;)



plt.title(&#39;recall&#39;, fontsize=18)

plt.xlim(0, 100)



plt.show()</code></pre><p>===========================================함수 끝</p>
<p>X_train, X_test, y_train, y_test = train_test_split(X=X_train, stratify=y, random_state = 42)</p>
<p>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state = 42)</p>
<p>X_train = scaler.fit_transform(X_train)</p>
<p>X_test = scaler.transform(X_test)</p>
<p>#===============================로지스틱</p>
<p>from sklearn.linear_model import LogisticRegression</p>
<p>from sklearn.metrics import confusion_matrix</p>
<p>from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score</p>
<p>from sklearn.metrics import classification_report</p>
<p>lg = LogisticRegression()</p>
<p>lg.fit(X_train, y_train)</p>
<p>lg.score(X_test, y_test)</p>
<p>lg_pred = lg.predict(X_test)                                          #pred</p>
<p>confusion_matrix(y_test, lg_pred)                         #혼돈행렬</p>
<p>accuracy_score(y_test, lg_pred)                           #정확도</p>
<p>precision_score(y_test, lg_pred)                           #정밀도</p>
<p>recall_score(y_test, lg_pred)                                          #재현율</p>
<p>f1_score(y_test, lg_pred)                                   #정밀도 + 재현율</p>
<p>print(classification_report(y_test, lg_pred))              #한눈에 보기</p>
<p>recall_eval(&#39;LogisticRegression&#39;, lg_pred, y_test)                   #함수 불러와서 확인</p>
<p>#===============================KNN</p>
<p>from sklearn.neighbors import KNeighborsClassifier</p>
<p>knn = KNeighborsClassifier(n_neighbors=5)</p>
<p>knn.fit(X_train, y_train)</p>
<p>knn.score(X_test, y_test)</p>
<p>knn_pred = knn.predict(X_test)</p>
<p>recall_eval(&#39;K-Nearest Neighbor&#39;, knn_pred, y_test)</p>
<p>#===============================Decision Tree</p>
<p>from sklearn.tree import DecisionTreeClassifier</p>
<p>dt = DecisionTreeClassifier(max_depth=10, random_state=42)</p>
<p>dt.fit(X_train, y_train)</p>
<p>dt_pred = dt.predict(X_test)</p>
<p>recall_eval(&#39;DecisionTree&#39;, dt_pred, y_test)</p>
<p>#===============================Random Forest</p>
<p>from sklearn.ensemble import RandomForestClassifier</p>
<p>rfc = RandomForestClassifier(n_estimators=3, random_state=42)</p>
<p>rfc.fit(X_train, y_train)</p>
<p>rfc_pred = rfc.predict(X_test)</p>
<p>recall_eval(&#39;RandomForest Ensemble&#39;, rfc_pred, y_test)</p>
<p>#===============================XGBoost</p>
<p>!pip install xgboost</p>
<p>from xgboost import XGBClassifier</p>
<p>xgb = XGBClassifier(n_estimators=3, random_state=42)</p>
<p>xgb.fit(X_train, y_train)</p>
<p>xgb_pred=xgb.predict(X_test)</p>
<p>recall_eval(&#39;XGBoost&#39;, xgb_pred, y_test)</p>
<p>#==============================Light GBM</p>
<p>!pip install lightgbm</p>
<p>from lightgbm import LGBMClassifier</p>
<p>lgbm = LGBMClassifier(n_estimators=3, random_state=42)</p>
<p>lgbm.fit(X_train, y_train)</p>
<p>lgbm_pred = lgbm.predict(X_test)</p>
<p>recall_eval(&#39;LGBM&#39;, lgbm_pred, y_test)</p>
<p>lgbm.score(X_test, y_test)</p>
<p>recall_score(y_test, lgbm_pred)  #별도 재현율</p>
<p>#====================================================딥러닝</p>
<p>import tensorflow as tf</p>
<p>from tensorflow.keras.models import Sequential</p>
<p>from tensorflow.keras.layers import Dense, Dropout</p>
<p>tf.random.set_seed(100)</p>
<p>batch_size = 16</p>
<p>epochs = 20</p>
<p>X_train.shape</p>
<p>y_train.shape</p>
<h1 id="sequential-모델-정의-하고-model로-저장">Sequential() 모델 정의 하고 model로 저장</h1>
<h1 id="input-layer는-input_shape-옵션을-사용한다">input layer는 input_shape=() 옵션을 사용한다.</h1>
<h1 id="39개-input-layer">39개 input layer</h1>
<h1 id="unit-4개-hidden-layer">unit 4개 hidden layer</h1>
<h1 id="unit-3개-hidden-layer">unit 3개 hidden layer</h1>
<h1 id="1개-output-layser--이진분류">1개 output layser : 이진분류</h1>
<p>#Sequential 모델 만들기</p>
<p>model = Sequential()</p>
<p>model.add(Dense(4, activation=&#39;relu&#39;, input_shape=(39,)))</p>
<p>model.add(Dense(3, activation=&#39;relu&#39;))</p>
<p>model.add(Dense(1, activation=&#39;sigmoid&#39;))</p>
<p>#모델 확인</p>
<p>model.summary()</p>
<p>#모델 만들기 - 과적합방지</p>
<p>model = Sequential()</p>
<p>model.add(Dense(4, activation=&#39;relu&#39;, input_shape=(39,)))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(3, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(1, activation=&#39;sigmoid&#39;))</p>
<p>#과적합 확인</p>
<p>model.summary()</p>
<p>#모델 컴파일</p>
<p>model.compile(optimizer=&#39;adam&#39;,</p>
<pre><code>          loss=&#39;binary_crossentropy&#39;,

          metrics=[&#39;accuracy&#39;])</code></pre><p>#==================================DNN</p>
<h1 id="앞쪽에서-정의된-모델-이름--model">앞쪽에서 정의된 모델 이름 : model</h1>
<h1 id="sequential-모델의-fit-함수-사용">Sequential 모델의 fit() 함수 사용</h1>
<h1 id="인자">@인자</h1>
<h3 id="x-y--x_train-y_train">X, y : X_train, y_train</h3>
<h3 id="validation_datax_test-y_test">validation_data=(X_test, y_test)</h3>
<h3 id="epochs-10번">epochs 10번</h3>
<h3 id="batch_size-10번">batch_size 10번</h3>
<p>#모델 FIT</p>
<p>model.fit(X_train, y_train,</p>
<pre><code>      validation_data=(X_test, y_test),

      epochs=10,

      batch_size=10)</code></pre><p>#모델 만들기</p>
<h1 id="39개-input-layer-1">39개 input layer</h1>
<h1 id="unit-5개-hidden-layer">unit 5개 hidden layer</h1>
<h1 id="dropout">dropout</h1>
<h1 id="unit-4개-hidden-layer-1">unit 4개 hidden layer</h1>
<h1 id="dropout-1">dropout</h1>
<h1 id="2개-output-layser--다중분류">2개 output layser : 다중분류</h1>
<p>model = Sequential()</p>
<p>model.add(Dense(5, activation=&#39;relu&#39;, input_shape=(39,)))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(4, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(2, activation=&#39;softmax&#39;))</p>
<p>#모델 확인</p>
<p>model.summary()</p>
<p>#모델 컴파일</p>
<p>model.compile(optimizer=&#39;adam&#39;,</p>
<pre><code>          loss=&#39;sparse_categorical_crossentropy&#39;,

          metrics=[&#39;accuracy&#39;])</code></pre><p>#모델 학습</p>
<p>history = model.fit(X_train, y_train,</p>
<pre><code>      validation_data=(X_test, y_test),

      epochs=20,

      batch_size=16)</code></pre><p>#조기 종료 모델, 모델 저장</p>
<p>from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint</p>
<h1 id="val_loss-모니터링해서-성능이-5번-지나도록-좋아지지-않으면-조기-종료">val_loss 모니터링해서 성능이 5번 지나도록 좋아지지 않으면 조기 종료</h1>
<p>early_stop = EarlyStopping(monitor=&#39;val_loss&#39;, mode=&#39;min&#39;,</p>
<pre><code>                       verbose=1, patience=5)</code></pre><h1 id="val_loss-가장-낮은-값을-가질때마다-모델저장">val_loss 가장 낮은 값을 가질때마다 모델저장</h1>
<p>check_point = ModelCheckpoint(&#39;best_model.h5&#39;, verbose=1,</p>
<pre><code>                          monitor=&#39;val_loss&#39;, mode=&#39;min&#39;, save_best_only=True)</code></pre><p>#모델 학습</p>
<p>history = model.fit(x=X_train, y=y_train,</p>
<pre><code>      epochs=50 , batch_size=20,

      validation_data=(X_test, y_test), verbose=1,

      callbacks=[early_stop, check_point])</code></pre><p>#모델 성능 평가</p>
<p>losses = pd.DataFrame(model.history.history)</p>
<p>losses.head()</p>
<p>#성능 시각화</p>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;]].plot()</p>
<h1 id="여러개-시각화">여러개 시각화</h1>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;, &#39;accuracy&#39;,&#39;val_accuracy&#39;]].plot()</p>
<h1 id="그래프">그래프...?</h1>
<p>plt.plot(history.history[&#39;accuracy&#39;])</p>
<p>plt.plot(history.history[&#39;val_accuracy&#39;])</p>
<p>plt.title(&#39;Accuracy&#39;)</p>
<p>plt.xlabel(&#39;Epochs&#39;)</p>
<p>plt.ylabel(&#39;Acc&#39;)</p>
<p>plt.legend([&#39;acc&#39;, &#39;val_acc&#39;])</p>
<p>plt.show()</p>
<p>#성능 평가</p>
<p>from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score</p>
<p>from sklearn.metrics import classification_report</p>
<p>pred = model.predict(X_test)</p>
<p>pred.shape</p>
<p>y_pred = np.argmax(pred, axis=1)</p>
<h1 id="정확도-80">정확도 80%</h1>
<p>accuracy_score(y_test, y_pred)</p>
<h1 id="재현율-성능이-좋지-않다">재현율 성능이 좋지 않다</h1>
<p>recall_score(y_test, y_pred)</p>
<h1 id="accuracy-recall-precision-성능-한번에-보기">accuracy, recall, precision 성능 한번에 보기</h1>
<p>print(classification_report(y_test, y_pred))</p>
<p>#================================== 재현율 성능 높이기</p>
<p>!pip install -U imbalanced-learn</p>
<p>#SMOTE 함수 이용하여 Oversampling</p>
<p>from imblearn.over_sampling import SMOTE</p>
<h1 id="smote-함수-정의-및-oversampling-수행">SMOTE 함수 정의 및 Oversampling 수행</h1>
<p>smote = SMOTE(random_state=0)</p>
<p>X_train_over, y_train_over = smote.fit_resample(X_train, y_train)</p>
<p>print(&#39;SMOTE 적용 전 학습용 피처/레이블 데이터 세트: &#39;, X_train.shape, y_train.shape)</p>
<p>print(&#39;SMOTE 적용 후 학습용 피처/레이블 데이터 세트: &#39;, X_train_over.shape, y_train_over.shape)</p>
<h1 id="smote-적용-후-레이블-값-분포--0과-1-갯수가-동일">SMOTE 적용 후 레이블 값 분포 : 0과 1 갯수가 동일</h1>
<p>pd.Series(y_train_over).value_counts()</p>
<p>#데이터 정규화</p>
<h1 id="minmaxscaler">MinMaxScaler</h1>
<p>from sklearn.preprocessing import MinMaxScaler</p>
<p>scaler = MinMaxScaler()</p>
<p>scaler.fit(X_train)</p>
<p>X_train_over = scaler.transform(X_train_over)</p>
<p>X_test = scaler.transform(X_test)</p>
<p>X_train_over.shape, y_train_over.shape, X_test.shape, y_test.shape</p>
<p>#모델 개발</p>
<p>model = Sequential()</p>
<p>model.add(Dense(64, activation=&#39;relu&#39;, input_shape=(39,)))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(32, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(16, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(2, activation=&#39;softmax&#39;))</p>
<p>model.compile(optimizer=&#39;adam&#39;,</p>
<pre><code>          loss=&#39;sparse_categorical_crossentropy&#39;,

          metrics=[&#39;accuracy&#39;])</code></pre><h1 id="여기서는-val_accuracy-모니터링해서-성능이-좋아지지-않으면-조기-종료-하게-함">여기서는 val_accuracy 모니터링해서 성능이 좋아지지 않으면 조기 종료 하게 함.</h1>
<p>early_stop = EarlyStopping(monitor=&#39;val_accuracy&#39;, mode=&#39;max&#39;,</p>
<pre><code>                       verbose=1, patience=5)</code></pre><p>check_point = ModelCheckpoint(&#39;best_model.h5&#39;, verbose=1,</p>
<pre><code>                          monitor=&#39;val_loss&#39;, mode=&#39;min&#39;,

                          save_best_only=True)</code></pre><p>history = model.fit(x=X_train_over, y=y_train_over,</p>
<pre><code>      epochs=50 , batch_size=32,

      validation_data=(X_test, y_test), verbose=1,

      callbacks=[early_stop, check_point])</code></pre><p>#모델 성능 평가</p>
<p>losses = pd.DataFrame(model.history.history)</p>
<p>#위에 이어서</p>
<p>losses.head()</p>
<p>#성능 시각화</p>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;]].plot()</p>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;, &#39;accuracy&#39;,&#39;val_accuracy&#39;]].plot()</p>
<p>plt.plot(history.history[&#39;accuracy&#39;])</p>
<p>plt.plot(history.history[&#39;val_accuracy&#39;])</p>
<p>plt.title(&#39;Accuracy&#39;)</p>
<p>plt.xlabel(&#39;Epochs&#39;)</p>
<p>plt.ylabel(&#39;Acc&#39;)</p>
<p>plt.legend([&#39;acc&#39;, &#39;val_acc&#39;])</p>
<p>plt.show()</p>
<p>#성능 평가</p>
<p>from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score</p>
<p>from sklearn.metrics import classification_report</p>
<p>pred = model.predict(X_test)</p>
<p>pred.shape</p>
<p>y_pred = np.argmax(pred, axis=1)</p>
<h1 id="정확도-7080">정확도 70~80%</h1>
<p>accuracy_score(y_test, y_pred)</p>
<h1 id="재현율-70-정도로-이전보다-좋아졌다">재현율 70% 정도로 이전보다 좋아졌다.</h1>
<p>recall_score(y_test, y_pred)</p>
<h1 id="recall-성능을-올렸지만-반대급부로-precision-성능은-떨어진다">recall 성능을 올렸지만, 반대급부로 precision 성능은 떨어진다.</h1>
<h1 id="accuracy-recall-precision-어떤것에-집중할지-선택하는것도-필요하다">accuracy, recall, precision 어떤것에 집중할지 선택하는것도 필요하다.</h1>
<p>print(classification_report(y_test, y_pred))</p>
<p>딥러닝 심층신경망(DNN) 모델 프로세스</p>
<p>데이터 가져오기</p>
<p>데이터 전처리</p>
<p>Train, Test 데이터셋 분할</p>
<p>데이터 정규화</p>
<p>DNN 딥러닝 모델</p>
<p>재현율 성능이 좋지 않다. 어떻게 성능향상 방법은?</p>
<p>Feature Engineering : 성능 잘 나올수 있도록 데이터 가공</p>
<p>불균현 데이터 문제 해소 : under-sampling, over-sampling</p>
<p>Over-Sampling 기법 : SMOTE</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[sklearn 프렙프 scentomni]]></title>
            <link>https://velog.io/@jst-jin-hyeong/sklearn-%ED%94%84%EB%A0%99%ED%94%84-scentomni</link>
            <guid>https://velog.io/@jst-jin-hyeong/sklearn-%ED%94%84%EB%A0%99%ED%94%84-scentomni</guid>
            <pubDate>Tue, 21 Mar 2023 06:06:15 GMT</pubDate>
            <description><![CDATA[<p>.      ㄴ[실습-퀴즈] Python 활용한 AI 모델링 - 전처리 파트</p>
<pre><code>       • 이번시간에는 Python을 활용한 AI 모델링에서 전처리에 대해 실습해 보겠습니다.

       • 머신러닝과 AI 모델링 전체에서 60~70% 차지하는 부분이 바로 전처리 파트입니다.

       • 굉장히 시간과 노력이 많이 투입되며, 어려운 부분일수 있습니다.

       • 데이터가 깨끗이 정리되지 않는다면 머신러닝/AI 성능을 장담할수 없으므로 데이터 전처리에 심혈을 기울려 주시기 바랍니다.

       • 한가지 당부 드리고 싶은 말은 &quot;백문이불여일타&quot; 입니다.

       • 이론보다 실습이 더 많은 시간과 노력이 투자 되어야 합니다.</code></pre><p>학습목차</p>
<pre><code>       1. 실습 내용 확인

       2. 필요 라이브러리 임포트 및 파일 읽어오기

       3. EDA (Exploratory Data Analysis) 탐색적 데이터 분석

       4. 데이터 전처리 수행

       • 불필요 컬럼 삭제

       • 컬럼 내용 변경하기

       • Null 처리

       • 컬럼 type 변경하기

       4. 시각화

       5. 결과 저장하기</code></pre><ol start="0">
<li>실습 내용 확인</li>
</ol>
<p>머신러닝, 딥러닝을 사용한 통신 서비스 이탈 예측 </p>
<p>모든 관련 고객 데이터를 분석하고 강력하고 정확한 이탈 예측 모델을 개발하여 고객을 유지하고 고객 이탈률을 줄이기 위한 전략을 수립합니다.</p>
<p>Churn은 서비스를 중단하거나 업계의 경쟁업체로 이전한 고객 또는 사용자를 의미합니다. 모든 조직이 기존 고객을 유지하고 새로운 고객을 유치하는 것이 매우 중요합니다. 그 중 하나가 실패하면 비즈니스에 좋지 않습니다. 목표는 업계에서 경쟁 우위를 유지하기 위해 이탈 예측을 위한 머신러닝, 딥러닝의 가능성을 탐색하는 것입니다.</p>
<ol>
<li>필요 라이브러리 임포트 및 파일 읽어오기</li>
</ol>
<p>Numpy</p>
<p>[문제] numpy 라이브러리를 np alias로 임포트하세요. </p>
<p>[1]:</p>
<p>import numpy as np</p>
<p>​</p>
<p>​</p>
<p>Pandas</p>
<p>[문제] pandas 라이브러리를 pd alias로 임포트하세요. </p>
<p>[2]:</p>
<p>import pandas as pd</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>읽어올 데이터 파일 : data_v1.csv</p>
<p>Telco Customer Churn Dataset 컬럼</p>
<pre><code>       1. CustomerID: Customer ID unique for each customer

       2. gender: Whether the customer is a male or a female

       3. SeniorCitizen: Whether the customer is a senior citizen or not (1, 0) : 고령자 여부

       4. Partner: Whether the customer has a partner or not (Yes, No)

       5. Dependents: Whether the customer has dependents or not (Yes, No) : 부양가족 여부

       6. Tenure: Number of months the customer has stayed with the company : 서비스 사용 개월수

       7. PhoneService: Whether the customer has a phone service or not (Yes, No)

       8. MultipleLines: Whether the customer has multiple lines or not (Yes, No, No phone service)

       9. InternetService: Customer’s internet service provider (DSL, Fiber optic, No)

       10. OnlineSecurity: Whether the customer has online security or not (Yes, No, No internet service)

       11. OnlineBackup: Whether the customer has an online backup or not (Yes, No, No internet service)

       12. DeviceProtection: Whether the customer has device protection or not (Yes, No, No internet service)

       13. TechSupport: Whether the customer has tech support or not (Yes, No, No internet service)

       14. StreamingTV: Whether the customer has streaming TV or not (Yes, No, No internet service)

       15. StreamingMovies: Whether the customer has streaming movies or not (Yes, No, No internet service)

       16. Contract: The contract term of the customer (Month-to-month, One year, Two years)

       17. PaperlessBilling: Whether the customer has paperless billing or not (Yes, No)

       18. PaymentMethod: The customer’s payment method (Electronic check, Mailed check, Bank transfer (automatic), Credit card (automatic))

       19. MonthlyCharges: The amount charged to the customer monthly

       20. TotalCharges: The total amount charged to the customer

       21. Churn: Whether the customer churned or not (Yes or No) : 이탈 여부</code></pre><p>CSV 파일 데이터 읽어오기</p>
<p>[문제] data.csv 파일을 Pandas read_csv 함수를 이용하여 읽어 df 변수에 저장하세요. </p>
<p>[3]:</p>
<h1 id="읽어-들일-파일명--datacsv">읽어 들일 파일명 : data,csv</h1>
<h1 id="pandas-read_csv-함수-활용">Pandas read_csv 함수 활용</h1>
<h1 id="결과--df-저장">결과 : df 저장</h1>
<p>df = pd.read_csv(&#39;(라이브교육)data_v1.csv&#39;)</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>[4]:</p>
<h1 id="읽어온-데이터프레임-확인하기">읽어온 데이터프레임 확인하기</h1>
<p>df</p>
<p>[4]:</p>
<pre><code>       customerID        gender  SeniorCitizen      Partner  Dependents       tenure   PhoneService           MultipleLines      InternetService   OnlineSecurity    ...         DeviceProtection TechSupport           StreamingTV      StreamingMovies Contract PaperlessBilling   PaymentMethod MonthlyCharges           TotalCharges      Churn</code></pre><p>0         7590-VHVEG       NaN     0.0       Yes       No       1         No       No phone service           DSL           No       ...         No       No       No       No       NaN     Yes       Electronic check  29.85    29.85           No</p>
<p>1         5575-GNVDE      Male     0.0       No       No       34        Yes       No       DSL      Yes       ...           Yes       No       No       No       One year          No       Mailed check     56.95     1889.5   No</p>
<p>2         3668-QPYBK       Male     0.0       No       No       2         Yes       No       DSL      Yes       ...           NaN     No       No       No       Month-to-month Yes       Mailed check     53.85     108.15   Yes</p>
<p>3         7795-CFOCW      Male     0.0       No       No       45        No       No phone service           DSL           Yes       ...         NaN     Yes       No       No       One year          No       Bank transfer (automatic)           42.30     1840.75  No</p>
<p>4         9237-HQITU       Female  0.0       No       No       2         Yes       No       Fiber optic         No       ...           NaN     No       No       No       Month-to-month Yes       Electronic check  70.70     151.65   Yes</p>
<p>...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...           ...         ...         ...         ...         ...         ...         ...         ...</p>
<p>7038     6840-RESVB       Male     0.0       Yes       Yes       24        Yes       Yes       DSL      Yes       ...           Yes       Yes       Yes       Yes       One year          Yes       Mailed check     84.80     1990.5   No</p>
<p>7039     2234-XADUH      Female  0.0       Yes       Yes       72        Yes       Yes       Fiber optic         No       ...           Yes       No       Yes       Yes       One year          Yes       Credit card (automatic)    103.20   7362.9           No</p>
<p>7040     4801-JZAZL        Female  0.0       Yes       Yes       11        No       No phone service           DSL           Yes       ...         No       No       No       No       Month-to-month Yes       Electronic check  29.60           346.45   No</p>
<p>7041     8361-LTMKD       Male     1.0       Yes       No       4         Yes       Yes       Fiber optic         No       ...           No       No       No       No       Month-to-month Yes       Mailed check     74.40     306.6    Yes</p>
<p>7042     3186-AJIEK        NaN     0.0       No       No       66        Yes       No       Fiber optic         Yes       ...           Yes       Yes       Yes       Yes       Two year          Yes       Bank transfer (automatic)  105.65   6844.5           No</p>
<p>7043 rows × 21 columns</p>
<ol start="2">
<li>EDA (Exploratory Data Analysis) 탐색적 데이터 분석</li>
</ol>
<p>데이터 탐색하기</p>
<p>[5]:</p>
<p>df.head()</p>
<p>[5]:</p>
<pre><code>       customerID        gender  SeniorCitizen      Partner  Dependents       tenure   PhoneService           MultipleLines      InternetService   OnlineSecurity    ...         DeviceProtection TechSupport           StreamingTV      StreamingMovies Contract PaperlessBilling   PaymentMethod MonthlyCharges           TotalCharges      Churn</code></pre><p>0         7590-VHVEG       NaN     0.0       Yes       No       1         No       No phone service           DSL           No       ...         No       No       No       No       NaN     Yes       Electronic check  29.85    29.85           No</p>
<p>1         5575-GNVDE      Male     0.0       No       No       34        Yes       No       DSL      Yes       ...           Yes       No       No       No       One year          No       Mailed check     56.95     1889.5   No</p>
<p>2         3668-QPYBK       Male     0.0       No       No       2         Yes       No       DSL      Yes       ...           NaN     No       No       No       Month-to-month Yes       Mailed check     53.85     108.15   Yes</p>
<p>3         7795-CFOCW      Male     0.0       No       No       45        No       No phone service           DSL           Yes       ...         NaN     Yes       No       No       One year          No       Bank transfer (automatic)           42.30     1840.75  No</p>
<p>4         9237-HQITU       Female  0.0       No       No       2         Yes       No       Fiber optic         No       ...           NaN     No       No       No       Month-to-month Yes       Electronic check  70.70     151.65   Yes</p>
<p>5 rows × 21 columns</p>
<p>[6]:</p>
<p>df.tail()</p>
<p>[6]:</p>
<pre><code>       customerID        gender  SeniorCitizen      Partner  Dependents       tenure   PhoneService           MultipleLines      InternetService   OnlineSecurity    ...         DeviceProtection TechSupport           StreamingTV      StreamingMovies Contract PaperlessBilling   PaymentMethod MonthlyCharges           TotalCharges      Churn</code></pre><p>7038     6840-RESVB       Male     0.0       Yes       Yes       24        Yes       Yes       DSL      Yes       ...           Yes       Yes       Yes       Yes       One year          Yes       Mailed check     84.80     1990.5   No</p>
<p>7039     2234-XADUH      Female  0.0       Yes       Yes       72        Yes       Yes       Fiber optic         No       ...           Yes       No       Yes       Yes       One year          Yes       Credit card (automatic)    103.20   7362.9           No</p>
<p>7040     4801-JZAZL        Female  0.0       Yes       Yes       11        No       No phone service           DSL           Yes       ...         No       No       No       No       Month-to-month Yes       Electronic check  29.60           346.45   No</p>
<p>7041     8361-LTMKD       Male     1.0       Yes       No       4         Yes       Yes       Fiber optic         No       ...           No       No       No       No       Month-to-month Yes       Mailed check     74.40     306.6    Yes</p>
<p>7042     3186-AJIEK        NaN     0.0       No       No       66        Yes       No       Fiber optic         Yes       ...           Yes       Yes       Yes       Yes       Two year          Yes       Bank transfer (automatic)  105.65   6844.5           No</p>
<p>5 rows × 21 columns</p>
<p>자료구조 파악</p>
<p>[7]:</p>
<p>df.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;</p>
<p>RangeIndex: 7043 entries, 0 to 7042</p>
<p>Data columns (total 21 columns):</p>
<h1 id="column------------non-null-count--dtype">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   customerID        7043 non-null   object</p>
<p> 1   gender            7034 non-null   object</p>
<p> 2   SeniorCitizen     7042 non-null   float64</p>
<p>3   Partner           7043 non-null   object</p>
<p> 4   Dependents        7041 non-null   object</p>
<p> 5   tenure            7043 non-null   int64 </p>
<p> 6   PhoneService      7040 non-null   object</p>
<p> 7   MultipleLines     7043 non-null   object</p>
<p> 8   InternetService   7043 non-null   object</p>
<p> 9   OnlineSecurity    7043 non-null   object</p>
<p> 10  OnlineBackup      7043 non-null   object</p>
<p> 11  DeviceProtection  3580 non-null   object</p>
<p> 12  TechSupport       7043 non-null   object</p>
<p> 13  StreamingTV       7043 non-null   object</p>
<p> 14  StreamingMovies   7043 non-null   object</p>
<p> 15  Contract          7042 non-null   object</p>
<p> 16  PaperlessBilling  7043 non-null   object</p>
<p> 17  PaymentMethod     7042 non-null   object</p>
<p> 18  MonthlyCharges    7042 non-null   float64</p>
<p>19  TotalCharges      7043 non-null   object</p>
<p> 20  Churn             7043 non-null   object</p>
<p>dtypes: float64(2), int64(1), object(18)</p>
<p>memory usage: 1.1+ MB</p>
<p>데이터 타입, 인덱스, 컬럼명, Values 확인</p>
<p>[8]:</p>
<h1 id="인덱스">인덱스</h1>
<p>df.index</p>
<p>[8]:</p>
<p>RangeIndex(start=0, stop=7043, step=1)</p>
<p>[9]:</p>
<h1 id="컬럼명">컬럼명</h1>
<p>df.columns</p>
<p>[9]:</p>
<p>Index([&#39;customerID&#39;, &#39;gender&#39;, &#39;SeniorCitizen&#39;, &#39;Partner&#39;, &#39;Dependents&#39;,</p>
<pre><code>   &#39;tenure&#39;, &#39;PhoneService&#39;, &#39;MultipleLines&#39;, &#39;InternetService&#39;,

   &#39;OnlineSecurity&#39;, &#39;OnlineBackup&#39;, &#39;DeviceProtection&#39;, &#39;TechSupport&#39;,

   &#39;StreamingTV&#39;, &#39;StreamingMovies&#39;, &#39;Contract&#39;, &#39;PaperlessBilling&#39;,

   &#39;PaymentMethod&#39;, &#39;MonthlyCharges&#39;, &#39;TotalCharges&#39;, &#39;Churn&#39;],

  dtype=&#39;object&#39;)</code></pre><p>[11]:</p>
<h1 id="values">Values</h1>
<p>df.values</p>
<p>[11]:</p>
<p>array([[&#39;7590-VHVEG&#39;, nan, 0.0, ..., 29.85, &#39;29.85&#39;, &#39;No&#39;],</p>
<pre><code>   [&#39;5575-GNVDE&#39;, &#39;Male&#39;, 0.0, ..., 56.95, &#39;1889.5&#39;, &#39;No&#39;],

   [&#39;3668-QPYBK&#39;, &#39;Male&#39;, 0.0, ..., 53.85, &#39;108.15&#39;, &#39;Yes&#39;],

   ...,

   [&#39;4801-JZAZL&#39;, &#39;Female&#39;, 0.0, ..., 29.6, &#39;346.45&#39;, &#39;No&#39;],

   [&#39;8361-LTMKD&#39;, &#39;Male&#39;, 1.0, ..., 74.4, &#39;306.6&#39;, &#39;Yes&#39;],

   [&#39;3186-AJIEK&#39;, nan, 0.0, ..., 105.65, &#39;6844.5&#39;, &#39;No&#39;]],

  dtype=object)</code></pre><p>Null 데이터 확인</p>
<p>[10]:</p>
<p>df.isnull().sum()</p>
<p>[10]:</p>
<p>customerID             0</p>
<p>gender                 9</p>
<p>SeniorCitizen          1</p>
<p>Partner                0</p>
<p>Dependents             2</p>
<p>tenure                 0</p>
<p>PhoneService           3</p>
<p>MultipleLines          0</p>
<p>InternetService        0</p>
<p>OnlineSecurity         0</p>
<p>OnlineBackup           0</p>
<p>DeviceProtection    3463</p>
<p>TechSupport            0</p>
<p>StreamingTV            0</p>
<p>StreamingMovies        0</p>
<p>Contract               1</p>
<p>PaperlessBilling       0</p>
<p>PaymentMethod          1</p>
<p>MonthlyCharges         1</p>
<p>TotalCharges           0</p>
<p>Churn                  0</p>
<p>dtype: int64</p>
<p>통계 정보</p>
<p>[12]:</p>
<h1 id="seniorcitizen-컬럼--고령자-여부-범주형-01">SeniorCitizen 컬럼 : 고령자 여부, 범주형 0,1</h1>
<h1 id="tenure--서비스-사용한-월수로-평균-32개월-사용-최대-72개월-충성고객-있음-확인">tenure : 서비스 사용한 월수로 평균 32개월 사용, 최대 72개월 충성고객 있음 확인</h1>
<h1 id="25-50-75-비율과-max를-보니-아무래도-outliner-있는것으로-사료됨">25%, 50%, 75% 비율과 Max를 보니, 아무래도 Outliner 있는것으로 사료됨.</h1>
<h1 id="monthlycharges--월사용요금-평균-64--최소-18-최대-118">MonthlyCharges : 월사용요금, 평균 64$ , 최소 18$, 최대 118$</h1>
<p>​</p>
<p>df.describe()</p>
<p>[12]:</p>
<pre><code>       SeniorCitizen      tenure   MonthlyCharges</code></pre><p>count    7042.000000       7043.000000       7042.000000</p>
<p>mean    0.162170           32.371149          64.763256</p>
<p>std       0.368633           24.559481          30.091898</p>
<p>min      0.000000           0.000000           18.250000</p>
<p>25%      0.000000           9.000000           35.500000</p>
<p>50%      0.000000           29.000000          70.350000</p>
<p>75%      0.000000           55.000000          89.850000</p>
<p>max      1.000000           72.000000          118.750000</p>
<p>[13]:</p>
<p>df.boxplot()</p>
<p>Duplicate key in file PosixPath(&#39;/usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/matplotlibrc&#39;), line 758 (&#39;font.family\t: NanumGothicCoding&#39;)</p>
<p>[13]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<ol start="3">
<li>데이터 전처리 수행</li>
</ol>
<p>자료구조 파악</p>
<p>[문제] df1 DataFrame의 함수를 활용해서 자료구조(Row, columnm , Not-null, type)을 파악 하세요. </p>
<p>[14]:</p>
<h1 id="dataframe-info-함수">DataFrame info 함수</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>df.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;</p>
<p>RangeIndex: 7043 entries, 0 to 7042</p>
<p>Data columns (total 21 columns):</p>
<h1 id="column------------non-null-count--dtype-1">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   customerID        7043 non-null   object</p>
<p> 1   gender            7034 non-null   object</p>
<p> 2   SeniorCitizen     7042 non-null   float64</p>
<p>3   Partner           7043 non-null   object</p>
<p> 4   Dependents        7041 non-null   object</p>
<p> 5   tenure            7043 non-null   int64 </p>
<p> 6   PhoneService      7040 non-null   object</p>
<p> 7   MultipleLines     7043 non-null   object</p>
<p> 8   InternetService   7043 non-null   object</p>
<p> 9   OnlineSecurity    7043 non-null   object</p>
<p> 10  OnlineBackup      7043 non-null   object</p>
<p> 11  DeviceProtection  3580 non-null   object</p>
<p> 12  TechSupport       7043 non-null   object</p>
<p> 13  StreamingTV       7043 non-null   object</p>
<p> 14  StreamingMovies   7043 non-null   object</p>
<p> 15  Contract          7042 non-null   object</p>
<p> 16  PaperlessBilling  7043 non-null   object</p>
<p> 17  PaymentMethod     7042 non-null   object</p>
<p> 18  MonthlyCharges    7042 non-null   float64</p>
<p>19  TotalCharges      7043 non-null   object</p>
<p> 20  Churn             7043 non-null   object</p>
<p>dtypes: float64(2), int64(1), object(18)</p>
<p>memory usage: 1.1+ MB</p>
<p>컬럼 삭제</p>
<p>[문제] df 데이터프레임에서 &#39;customerID&#39; 컬럼 삭제 하세요. </p>
<p>[15]:</p>
<h1 id="dataframe-drop-함수">DataFrame drop 함수</h1>
<h1 id="customerid-컬럼-삭제">&#39;customerID&#39; 컬럼 삭제</h1>
<h1 id="axis1-옵션-사용해서-컬럼단위-삭제-수행">axis=1 옵션 사용해서 컬럼단위 삭제 수행</h1>
<h1 id="inplacetrue-옵션-사용하여-df-dataframe에-저장">inplace=True 옵션 사용하여 df DataFrame에 저장</h1>
<p>​</p>
<p>​</p>
<p>df.drop(&#39;customerID&#39;, axis=1, inplace=True)</p>
<p>[16]:</p>
<h1 id="21컬럼에서-20개-컬럼으로-1개-줄어듬-확인">21컬럼에서 20개 컬럼으로 1개 줄어듬 확인</h1>
<h1 id="totalcharges-컬럼은-사용요금으로-숫자형이어야-하는데-ojbect로-나옴-확인-필요">TotalCharges 컬럼은 사용요금으로 숫자형이어야 하는데 Ojbect로 나옴. 확인 필요</h1>
<p>​</p>
<p>df.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;</p>
<p>RangeIndex: 7043 entries, 0 to 7042</p>
<p>Data columns (total 20 columns):</p>
<h1 id="column------------non-null-count--dtype-2">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   gender            7034 non-null   object</p>
<p> 1   SeniorCitizen     7042 non-null   float64</p>
<p>2   Partner           7043 non-null   object</p>
<p> 3   Dependents        7041 non-null   object</p>
<p> 4   tenure            7043 non-null   int64 </p>
<p> 5   PhoneService      7040 non-null   object</p>
<p> 6   MultipleLines     7043 non-null   object</p>
<p> 7   InternetService   7043 non-null   object</p>
<p> 8   OnlineSecurity    7043 non-null   object</p>
<p> 9   OnlineBackup      7043 non-null   object</p>
<p> 10  DeviceProtection  3580 non-null   object</p>
<p> 11  TechSupport       7043 non-null   object</p>
<p> 12  StreamingTV       7043 non-null   object</p>
<p> 13  StreamingMovies   7043 non-null   object</p>
<p> 14  Contract          7042 non-null   object</p>
<p> 15  PaperlessBilling  7043 non-null   object</p>
<p> 16  PaymentMethod     7042 non-null   object</p>
<p> 17  MonthlyCharges    7042 non-null   float64</p>
<p>18  TotalCharges      7043 non-null   object</p>
<p> 19  Churn             7043 non-null   object</p>
<p>dtypes: float64(2), int64(1), object(17)</p>
<p>memory usage: 1.1+ MB</p>
<p>컬럼 내용 변경하기</p>
<p>범주형 문자 데이터를 숫자 변환하는것은 성능에 많은 영향을 미치므로 꼭 변환하로록 하자.</p>
<p>null, _ 문제있는 문자 데이터를 모델링하기 전에 미리 다른 데이터로 변경하거나 필요없을 경우 삭제하도록 하자.</p>
<p>TotalCharges 컬럼 타입 변경하기</p>
<p>[18]:</p>
<h1 id="totalcharges--월사용요금-실수형으로-보인다">TotalCharges : 월사용요금, 실수형으로 보인다.</h1>
<p>df[&#39;TotalCharges&#39;]</p>
<p>[18]:</p>
<p>0         29.85</p>
<p>1        1889.5</p>
<p>2        108.15</p>
<p>3       1840.75</p>
<p>4        151.65</p>
<pre><code>     ...  </code></pre><p>7038     1990.5</p>
<p>7039     7362.9</p>
<p>7040     346.45</p>
<p>7041      306.6</p>
<p>7042     6844.5</p>
<p>Name: TotalCharges, Length: 7043, dtype: object</p>
<p>[19]:</p>
<h1 id="totalcharges-컬럼-타입을-float로-변경해-보자">TotalCharges 컬럼 타입을 float로 변경해 보자.</h1>
<h1 id="문자열을-숫자형으로-변경할수-없으므로-에러-발생">문자열을 숫자형으로 변경할수 없으므로 에러 발생</h1>
<p>​</p>
<p>df[&#39;TotalCharges&#39;].astype(float)</p>
<hr>
<p>ValueError                                Traceback (most recent call last)</p>
<p><ipython-input-19-1e59e59e1978> in <module></p>
<pre><code>  2 # 문자열을 숫자형으로 변경할수 없으므로 에러 발생

  3</code></pre><p>----&gt; 4 df[&#39;TotalCharges&#39;].astype(float)</p>
<p>/usr/local/lib/python3.6/dist-packages/pandas/core/generic.py in astype(self, dtype, copy, errors)</p>
<p>   5546         else:</p>
<p>   5547             # else, only a single dtype is given</p>
<p>-&gt; 5548             new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors,)</p>
<p>   5549             return self.<em>constructor(new_data).<em>_finalize</em></em>(self, method=&quot;astype&quot;)</p>
<p>   5550</p>
<p>/usr/local/lib/python3.6/dist-packages/pandas/core/internals/managers.py in astype(self, dtype, copy, errors)</p>
<pre><code>602         self, dtype, copy: bool = False, errors: str = &quot;raise&quot;

603     ) -&gt; &quot;BlockManager&quot;:</code></pre><p>--&gt; 604         return self.apply(&quot;astype&quot;, dtype=dtype, copy=copy, errors=errors)</p>
<pre><code>605

606     def convert(</code></pre><p>/usr/local/lib/python3.6/dist-packages/pandas/core/internals/managers.py in apply(self, f, align_keys, **kwargs)</p>
<pre><code>407                 applied = b.apply(f, **kwargs)

408             else:</code></pre><p>--&gt; 409                 applied = getattr(b, f)(**kwargs)</p>
<pre><code>410             result_blocks = _extend_blocks(applied, result_blocks)

411</code></pre><p>/usr/local/lib/python3.6/dist-packages/pandas/core/internals/blocks.py in astype(self, dtype, copy, errors)</p>
<pre><code>593             vals1d = values.ravel()

594             try:</code></pre><p>--&gt; 595                 values = astype_nansafe(vals1d, dtype, copy=True)</p>
<pre><code>596             except (ValueError, TypeError):

597                 # e.g. astype_nansafe can fail on object-dtype of strings</code></pre><p>/usr/local/lib/python3.6/dist-packages/pandas/core/dtypes/cast.py in astype_nansafe(arr, dtype, copy, skipna)</p>
<pre><code>995     if copy or is_object_dtype(arr) or is_object_dtype(dtype):

996         # Explicit copy, or required since NumPy can&#39;t view from / to object.</code></pre><p>--&gt; 997         return arr.astype(dtype, copy=True)</p>
<pre><code>998

999     return arr.view(dtype)</code></pre><p>ValueError: could not convert string to float:</p>
<p>[20]:</p>
<h1 id="boolean-indexing으로-검색">Boolean indexing으로 검색</h1>
<p>(df[&#39;TotalCharges&#39;] == &#39;&#39;) | (df[&#39;TotalCharges&#39;] == &#39; &#39;)</p>
<p>[20]:</p>
<p>0       False</p>
<p>1       False</p>
<p>2       False</p>
<p>3       False</p>
<p>4       False</p>
<pre><code>    ... </code></pre><p>7038    False</p>
<p>7039    False</p>
<p>7040    False</p>
<p>7041    False</p>
<p>7042    False</p>
<p>Name: TotalCharges, Length: 7043, dtype: bool</p>
<p>[23]:</p>
<h1 id="boolean-indexing으로-검색-1">Boolean indexing으로 검색</h1>
<p>​</p>
<p>cond = (df[&#39;TotalCharges&#39;] == &#39;&#39;) | (df[&#39;TotalCharges&#39;] == &#39; &#39;)</p>
<p>df[cond]</p>
<p>[23]:</p>
<p>gender  SeniorCitizen      Partner  Dependents       tenure   PhoneService     MultipleLines      InternetService           OnlineSecurity    OnlineBackup     DeviceProtection TechSupport      StreamingTV      StreamingMovies           Contract PaperlessBilling   PaymentMethod  MonthlyCharges  TotalCharges      Churn</p>
<p>[문제] df 데이터프레임의 &#39;TotalCharges&#39; 컬럼의 값 &#39; &#39; --&gt; &#39;0&#39; 변경하세요. </p>
<p>[21]:</p>
<h1 id="dataframe-replace-함수">DataFrame replace 함수</h1>
<h1 id="대상-컬럼--totalcharges">대상 컬럼 : &#39;TotalCharges&#39;</h1>
<p>​</p>
<p>​</p>
<p>df[&#39;TotalCharges&#39;].replace([&#39; &#39;], [&#39;0&#39;], inplace = True )</p>
<p>[문제] df 데이터프레임의 &#39;TotalCharges&#39; 컬럼 타입을 object에서 float 변경하세요. </p>
<p>[29]:</p>
<h1 id="totalcharges-컬럼-type을-float로-변경">&#39;TotalCharges&#39; 컬럼 type을 float로 변경</h1>
<h1 id="결과를-totalcharges-컬럼에-다시-넣어야-합니다">결과를 TotalCharges 컬럼에 다시 넣어야 합니다.</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>df[&#39;TotalCharges&#39;]=df[&#39;TotalCharges&#39;].astype(float)</p>
<p>[25]:</p>
<h1 id="다시-boolean-indexing으로-검색---값을-가진-row-없음">다시 Boolean indexing으로 검색 : &#39;&#39; 값을 가진 Row 없음</h1>
<p>​</p>
<p>cond = (df[&#39;TotalCharges&#39;] == &#39;&#39;) | (df[&#39;TotalCharges&#39;] == &#39; &#39;)</p>
<p>df[cond]</p>
<p>[25]:</p>
<p>gender  SeniorCitizen      Partner  Dependents       tenure   PhoneService     MultipleLines      InternetService           OnlineSecurity    OnlineBackup     DeviceProtection TechSupport      StreamingTV      StreamingMovies           Contract PaperlessBilling   PaymentMethod  MonthlyCharges  TotalCharges      Churn</p>
<p>[ ]:</p>
<p>​</p>
<p>[30]:</p>
<h1 id="totalcharges-컬럼-float-변경-확인">TotalCharges 컬럼 float 변경 확인</h1>
<p>df.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;</p>
<p>RangeIndex: 7043 entries, 0 to 7042</p>
<p>Data columns (total 20 columns):</p>
<h1 id="column------------non-null-count--dtype-3">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   gender            7034 non-null   object</p>
<p> 1   SeniorCitizen     7042 non-null   float64</p>
<p>2   Partner           7043 non-null   object</p>
<p> 3   Dependents        7041 non-null   object</p>
<p> 4   tenure            7043 non-null   int64 </p>
<p> 5   PhoneService      7040 non-null   object</p>
<p> 6   MultipleLines     7043 non-null   object</p>
<p> 7   InternetService   7043 non-null   object</p>
<p> 8   OnlineSecurity    7043 non-null   object</p>
<p> 9   OnlineBackup      7043 non-null   object</p>
<p> 10  DeviceProtection  3580 non-null   object</p>
<p> 11  TechSupport       7043 non-null   object</p>
<p> 12  StreamingTV       7043 non-null   object</p>
<p> 13  StreamingMovies   7043 non-null   object</p>
<p> 14  Contract          7042 non-null   object</p>
<p> 15  PaperlessBilling  7043 non-null   object</p>
<p> 16  PaymentMethod     7042 non-null   object</p>
<p> 17  MonthlyCharges    7042 non-null   float64</p>
<p>18  TotalCharges      7043 non-null   float64</p>
<p>19  Churn             7043 non-null   object</p>
<p>dtypes: float64(3), int64(1), object(16)</p>
<p>memory usage: 1.1+ MB</p>
<p>Churn 컬럼의 문자열값을 숫자로 변경</p>
<p>[31]:</p>
<h1 id="churn-컬럼의-분포-확인">Churn 컬럼의 분포 확인</h1>
<h1 id="churn-yes--이탈--no--이탈안함-언밸런스하게-no쪽이-많은-차지하고-있음">Churn Yes : 이탈 , No : 이탈안함. 언밸런스하게 No쪽이 많은 차지하고 있음</h1>
<p>​</p>
<p>df[&#39;Churn&#39;].value_counts()</p>
<p>[31]:</p>
<p>No     5174</p>
<p>Yes    1869</p>
<p>Name: Churn, dtype: int64</p>
<p>[32]:</p>
<h1 id="churn-컬럼의-yes-no----1-0-변경하기">&#39;Churn&#39; 컬럼의 [&#39;Yes&#39;, &#39;No&#39;] --&gt; [1, 0] 변경하기</h1>
<h1 id="컴퓨터는-문자열-이해-잘-하지-못해-숫자로-변경해야-함">컴퓨터는 문자열 이해 잘 하지 못해 숫자로 변경해야 함.</h1>
<p>​</p>
<p>df[&#39;Churn&#39;].replace([&#39;Yes&#39;, &#39;No&#39;], [1, 0], inplace=True)</p>
<p>[33]:</p>
<h1 id="churn-컬럼의-분포-확인-1">Churn 컬럼의 분포 확인</h1>
<p>df[&#39;Churn&#39;].value_counts()</p>
<p>[33]:</p>
<p>0    5174</p>
<p>1    1869</p>
<p>Name: Churn, dtype: int64</p>
<p>Null 데이터 확인</p>
<p>[문제] df 데이터프레임에 대해 컬럼별로 null 얼마나 있는지 null 갯수를 나열 하세요. </p>
<p>[34]:</p>
<h1 id="dataframe-isnull-sum-함수-활용">DataFrame isnull(), sum() 함수 활용</h1>
<p>​</p>
<p>df.isnull().sum()</p>
<p>​</p>
<p>[34]:</p>
<p>gender                 9</p>
<p>SeniorCitizen          1</p>
<p>Partner                0</p>
<p>Dependents             2</p>
<p>tenure                 0</p>
<p>PhoneService           3</p>
<p>MultipleLines          0</p>
<p>InternetService        0</p>
<p>OnlineSecurity         0</p>
<p>OnlineBackup           0</p>
<p>DeviceProtection    3463</p>
<p>TechSupport            0</p>
<p>StreamingTV            0</p>
<p>StreamingMovies        0</p>
<p>Contract               1</p>
<p>PaperlessBilling       0</p>
<p>PaymentMethod          1</p>
<p>MonthlyCharges         1</p>
<p>TotalCharges           0</p>
<p>Churn                  0</p>
<p>dtype: int64</p>
<p>결측치 처리</p>
<p>데이터에 결측치 있으면 모델링시 알지 못하는 에러 발생할수 있으므로 반드시 결측치를 제거나 변경해야 한다.</p>
<p>결측치 제거시 dropna() 함수 활용하면 된다.</p>
<p>결측치를 변경시 변경하는 방법이 꼭 정답이 아니며, 여러가지 판단하고 고민이 필요하다.</p>
<p>주로, 문자형 컬럼에 대해 최빈값으로 , 숫자형 컬럼에 대해 중간값으로 결측치 대신해서 채울수 있다.</p>
<p>[문제] df 데이터프레임의 결측치 많은 컬럼은 컬럼 제거하고 나머지 결측치는 Row 제거 하세요. </p>
<p>[35]:</p>
<h1 id="1-결측치-많은-컬럼---deviceprotection------drop-함수-이용하여-해당-컬럼-제거">1. 결측치 많은 컬럼 :  DeviceProtection   --&gt; drop 함수 이용하여 해당 컬럼 제거</h1>
<h1 id="2-결측치-작은-row에-대해서-dropna로-제거">2. 결측치 작은 Row에 대해서 dropna로 제거</h1>
<h1 id="inplacetrue-옵션으로-자체-저장">inplace=True 옵션으로 자체 저장</h1>
<p>​</p>
<p>df.drop(&#39;DeviceProtection&#39;, axis=1, inplace = True)</p>
<p>df.dropna(inplace=True)</p>
<p>#여러개도 가능</p>
<p>#df.drop([&#39;DeviceProtection&#39;, &#39;<del>&#39;, &#39;</del>&#39;], axis=1, inplace = True)</p>
<p>​</p>
<p>​</p>
<p>[36]:</p>
<h1 id="null-여부-다시-확인">Null 여부 다시 확인</h1>
<p>df.isnull().sum()</p>
<p>[36]:</p>
<p>gender              0</p>
<p>SeniorCitizen       0</p>
<p>Partner             0</p>
<p>Dependents          0</p>
<p>tenure              0</p>
<p>PhoneService        0</p>
<p>MultipleLines       0</p>
<p>InternetService     0</p>
<p>OnlineSecurity      0</p>
<p>OnlineBackup        0</p>
<p>TechSupport         0</p>
<p>StreamingTV         0</p>
<p>StreamingMovies     0</p>
<p>Contract            0</p>
<p>PaperlessBilling    0</p>
<p>PaymentMethod       0</p>
<p>MonthlyCharges      0</p>
<p>TotalCharges        0</p>
<p>Churn               0</p>
<p>dtype: int64</p>
<p>[39]:</p>
<p>df2 = df.copy()</p>
<p>[41]:</p>
<h1 id="deviceprotection-컬럼-삭제-확인">DeviceProtection 컬럼 삭제 확인</h1>
<p>df.info()</p>
<p>​</p>
<p>df2.reset_index(drop = True)</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;</p>
<p>Int64Index: 7027 entries, 1 to 7041</p>
<p>Data columns (total 19 columns):</p>
<h1 id="column------------non-null-count--dtype-4">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   gender            7027 non-null   object</p>
<p> 1   SeniorCitizen     7027 non-null   float64</p>
<p>2   Partner           7027 non-null   object</p>
<p> 3   Dependents        7027 non-null   object</p>
<p> 4   tenure            7027 non-null   int64 </p>
<p> 5   PhoneService      7027 non-null   object</p>
<p> 6   MultipleLines     7027 non-null   object</p>
<p> 7   InternetService   7027 non-null   object</p>
<p> 8   OnlineSecurity    7027 non-null   object</p>
<p> 9   OnlineBackup      7027 non-null   object</p>
<p> 10  TechSupport       7027 non-null   object</p>
<p> 11  StreamingTV       7027 non-null   object</p>
<p> 12  StreamingMovies   7027 non-null   object</p>
<p> 13  Contract          7027 non-null   object</p>
<p> 14  PaperlessBilling  7027 non-null   object</p>
<p> 15  PaymentMethod     7027 non-null   object</p>
<p> 16  MonthlyCharges    7027 non-null   float64</p>
<p>17  TotalCharges      7027 non-null   float64</p>
<p>18  Churn             7027 non-null   int64 </p>
<p>dtypes: float64(3), int64(2), object(14)</p>
<p>memory usage: 1.1+ MB</p>
<p>[41]:</p>
<pre><code>       gender  SeniorCitizen      Partner  Dependents       tenure   PhoneService     MultipleLines           InternetService   OnlineSecurity    OnlineBackup     TechSupport      StreamingTV      StreamingMovies           Contract PaperlessBilling   PaymentMethod  MonthlyCharges  TotalCharges      Churn</code></pre><p>0         Male     0.0       No       No       34        Yes       No       DSL      Yes       No       No       No           No       One year          No       Mailed check     56.95     1889.50  0</p>
<p>1         Male     0.0       No       No       2         Yes       No       DSL      Yes       Yes       No       No           No       Month-to-month Yes       Mailed check     53.85     108.15   1</p>
<p>2         Male     0.0       No       No       45        No       No phone service           DSL      Yes       No           Yes       No       No       One year          No       Bank transfer (automatic)  42.30     1840.75  0</p>
<p>3         Female  0.0       No       No       2         Yes       No       Fiber optic        No       No       No           No       No       Month-to-month Yes       Electronic check  70.70    151.65   1</p>
<p>4         Female  0.0       No       No       8         Yes       Yes       Fiber optic        No       No       No           Yes       Yes       Month-to-month Yes       Electronic check  99.65    820.50   1</p>
<p>...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...         ...           ...         ...         ...         ...         ...         ...</p>
<p>7022     Female  0.0       No       No       72        Yes       No       No       No internet service         No internet service   No internet service         No internet service         No internet service         Two year           Yes       Bank transfer (automatic)  21.15    1419.40  0</p>
<p>7023     Male     0.0       Yes       Yes       24        Yes       Yes       DSL      Yes       No       Yes       Yes           Yes       One year          Yes       Mailed check     84.80     1990.50  0</p>
<p>7024     Female  0.0       Yes       Yes       72        Yes       Yes       Fiber optic        No       Yes       No           Yes       Yes       One year          Yes       Credit card (automatic)    103.20   7362.90  0</p>
<p>7025     Female  0.0       Yes       Yes       11        No       No phone service           DSL      Yes       No           No       No       No       Month-to-month Yes       Electronic check  29.60    346.45   0</p>
<p>7026     Male     1.0       Yes       No       4         Yes       Yes       Fiber optic        No       No       No           No       No       Month-to-month Yes       Mailed check      74.40    306.60   1</p>
<p>7027 rows × 19 columns</p>
<ol start="4">
<li>시각화</li>
</ol>
<p>라이브러리 임포트</p>
<p>[42]:</p>
<p>import matplotlib.pyplot as plt</p>
<p>%matplotlib inline</p>
<p>Bar 차트</p>
<p>[43]:</p>
<p>df[&#39;gender&#39;].value_counts()</p>
<p>[43]:</p>
<p>Male      3550</p>
<p>Female    3477</p>
<p>Name: gender, dtype: int64</p>
<p>[44]:</p>
<p>df[&#39;gender&#39;].value_counts().plot(kind=&#39;bar&#39;)</p>
<p>[44]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>[문제] df 데이터프레임의 &#39;Partner&#39; 컬럼의 값 분포를 구하고 Bar 차트를 그리세요. </p>
<p>[45]:</p>
<h1 id="dataframe-value_counts와-plot-함수-활용">DataFrame value_counts()와 plot() 함수 활용</h1>
<h1 id="대상-컬럼--partner">대상 컬럼 : &#39;Partner&#39;</h1>
<h1 id="plot-함수의-인자--kindbar">plot 함수의 인자 : kind=&#39;bar&#39;</h1>
<p>​</p>
<p>df[&#39;Partner&#39;].value_counts().plot(kind = &#39;bar&#39;)</p>
<p>​</p>
<p>​</p>
<p>[45]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>한꺼번에 Object 컬럼에 대해서 분포 Bar 차트 확인해 봅시다.</p>
<p>[47]:</p>
<h1 id="object-컬럼만-뽑으려면">Object 컬럼만 뽑으려면</h1>
<h1 id="1-일일히-눈으로-보고-object-컬럼-고른다">1. 일일히 눈으로 보고 Object 컬럼 고른다</h1>
<h1 id="2-select_dtype-함수-활용한다">2. select_dtype() 함수 활용한다.</h1>
<p>​</p>
<p>df.select_dtypes(&#39;O&#39;).head(3)</p>
<p>[47]:</p>
<pre><code>       gender  Partner  Dependents       PhoneService     MultipleLines      InternetService   OnlineSecurity           OnlineBackup     TechSupport      StreamingTV      StreamingMovies Contract PaperlessBilling           PaymentMethod</code></pre><p>1         Male     No       No       Yes       No       DSL      Yes       No       No       No       No       One year           No       Mailed check</p>
<p>2         Male     No       No       Yes       No       DSL      Yes       Yes       No       No       No       Month-to-month   Yes       Mailed check</p>
<p>3         Male     No       No       No       No phone service           DSL      Yes       No       Yes       No           No       One year          No       Bank transfer (automatic)</p>
<p>[48]:</p>
<h1 id="object-컬럼명만-뽑아보자">Object 컬럼명만 뽑아보자</h1>
<p>df.select_dtypes(&#39;O&#39;).columns.values</p>
<p>[48]:</p>
<p>array([&#39;gender&#39;, &#39;Partner&#39;, &#39;Dependents&#39;, &#39;PhoneService&#39;, &#39;MultipleLines&#39;,</p>
<pre><code>   &#39;InternetService&#39;, &#39;OnlineSecurity&#39;, &#39;OnlineBackup&#39;, &#39;TechSupport&#39;,

   &#39;StreamingTV&#39;, &#39;StreamingMovies&#39;, &#39;Contract&#39;, &#39;PaperlessBilling&#39;,

   &#39;PaymentMethod&#39;], dtype=object)</code></pre><p>[49]:</p>
<h1 id="object-컬럼-하나씩-가져와서-bar-차트-그려보기">Object 컬럼 하나씩 가져와서 Bar 차트 그려보기</h1>
<h1 id="불균형-컬럼--dependents-phoneservice-심한-불균형-가진-phoneservice-컬럼-삭제-필요">불균형 컬럼 : Dependents, PhoneService. 심한 불균형 가진 PhoneService 컬럼 삭제 필요</h1>
<p>​</p>
<p>object_list = df.select_dtypes(&#39;object&#39;).columns.values</p>
<p>​</p>
<p>for col in object_list:</p>
<pre><code>df[col].value_counts().plot(kind=&#39;bar&#39;)

plt.title(col)

plt.show()</code></pre><p>불균형 심한 PhoneService 컬럼 삭제</p>
<p>[55]:</p>
<p>df.drop(&#39;PhoneService&#39;, axis=1, inplace=True)</p>
<p>숫자형 컬럼에 대한 시각화</p>
<p>[50]:</p>
<h1 id="numberint-float-컬럼에-대해-검색">number(int, float) 컬럼에 대해 검색</h1>
<p>df.select_dtypes( &#39;number&#39;).head(3)</p>
<p>[50]:</p>
<pre><code>       SeniorCitizen      tenure   MonthlyCharges  TotalCharges      Churn</code></pre><p>1         0.0       34        56.95    1889.50  0</p>
<p>2         0.0       2         53.85    108.15   1</p>
<p>3         0.0       45        42.30    1840.75  0</p>
<p>Churn 컬럼</p>
<p>[51]:</p>
<h1 id="churn-컬럼은-0-1-되어-있으므로-분포-확인">Churn 컬럼은 0, 1 되어 있으므로 분포 확인</h1>
<p>df[&#39;Churn&#39;].value_counts()</p>
<p>[51]:</p>
<p>0    5161</p>
<p>1    1866</p>
<p>Name: Churn, dtype: int64</p>
<p>[52]:</p>
<h1 id="churn-컬럼에-대한-bar-차트-확인">Churn 컬럼에 대한 Bar 차트 확인</h1>
<h1 id="이탈1가-이탈않음0에-비해-13-수준임--불균형">이탈(1)가 이탈않음(0)에 비해 1/3 수준임 : 불균형</h1>
<p>​</p>
<p>df[&#39;Churn&#39;].value_counts().plot(kind=&#39;bar&#39;)</p>
<p>[52]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>SeniorCitizen 컬럼</p>
<p>[53]:</p>
<h1 id="seniorcitizen-컬럼은-0-1-되어-있으므로-분포-확인">SeniorCitizen 컬럼은 0, 1 되어 있으므로 분포 확인</h1>
<p>df[&#39;SeniorCitizen&#39;].value_counts()</p>
<p>[53]:</p>
<p>0.0    5885</p>
<p>1.0    1142</p>
<p>Name: SeniorCitizen, dtype: int64</p>
<p>[54]:</p>
<h1 id="seniorcitizen-컬럼에-대한-bar-차트-확인">SeniorCitizen 컬럼에 대한 Bar 차트 확인</h1>
<h1 id="이탈1가-이탈않음0에-비해-15-수준임--불균형">이탈(1)가 이탈않음(0)에 비해 1/5 수준임 : 불균형</h1>
<p>​</p>
<p>df[&#39;SeniorCitizen&#39;].value_counts().plot(kind=&#39;bar&#39;)</p>
<p>[54]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>[문제] 불균형 심한 &#39;SeniorCitizen&#39; 컬럼을 삭제하세요. </p>
<p>[56]:</p>
<h1 id="dataframe-drop-함수-활용">DataFrame drop() 함수 활용</h1>
<h1 id="대상-컬럼--seniorcitizen">대상 컬럼 : &#39;SeniorCitizen&#39;</h1>
<h1 id="axis-와-inplace-옵션-사용">axis 와 inplace 옵션 사용</h1>
<p>​</p>
<p>​</p>
<p>df.drop(&#39;SeniorCitizen&#39;, axis=1, inplace=True)</p>
<p>[57]:</p>
<h1 id="seniorcitizen-삭제-확인">SeniorCitizen 삭제 확인</h1>
<p>df.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;</p>
<p>Int64Index: 7027 entries, 1 to 7041</p>
<p>Data columns (total 17 columns):</p>
<h1 id="column------------non-null-count--dtype-5">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   gender            7027 non-null   object</p>
<p> 1   Partner           7027 non-null   object</p>
<p> 2   Dependents        7027 non-null   object</p>
<p> 3   tenure            7027 non-null   int64 </p>
<p> 4   MultipleLines     7027 non-null   object</p>
<p> 5   InternetService   7027 non-null   object</p>
<p> 6   OnlineSecurity    7027 non-null   object</p>
<p> 7   OnlineBackup      7027 non-null   object</p>
<p> 8   TechSupport       7027 non-null   object</p>
<p> 9   StreamingTV       7027 non-null   object</p>
<p> 10  StreamingMovies   7027 non-null   object</p>
<p> 11  Contract          7027 non-null   object</p>
<p> 12  PaperlessBilling  7027 non-null   object</p>
<p> 13  PaymentMethod     7027 non-null   object</p>
<p> 14  MonthlyCharges    7027 non-null   float64</p>
<p>15  TotalCharges      7027 non-null   float64</p>
<p>16  Churn             7027 non-null   int64 </p>
<p>dtypes: float64(2), int64(2), object(13)</p>
<p>memory usage: 988.2+ KB</p>
<p>Histgram</p>
<p>[60]:</p>
<h1 id="seaborn-라이브러리-임포트">seaborn 라이브러리 임포트</h1>
<p>#!pip install seaborn</p>
<p>#!pip install seaborn</p>
<p>​</p>
<p>import seaborn as sns</p>
<p>tenure 컬럼</p>
<p>[61]:</p>
<h1 id="tenure-서비스-사용기간에-대한-히스토그램">tenure (서비스 사용기간)에 대한 히스토그램</h1>
<h1 id="처음에-많이-사용하고--70개월-사용하는-충성고객도-있다">처음에 많이 사용하고 , 70개월 사용하는 충성고객도 있다.</h1>
<p>​</p>
<p>sns.histplot(data=df, x=&#39;tenure&#39;)</p>
<p>[61]:</p>
<p>&lt;AxesSubplot:xlabel=&#39;tenure&#39;, ylabel=&#39;Count&#39;&gt;</p>
<p>[63]:</p>
<h1 id="tenure-서비스-사용기간-대한-히스토그램을-churn-으로-구분">tenure (서비스 사용기간) 대한 히스토그램을 Churn 으로 구분</h1>
<h1 id="히스토그램으로-churn-구분하니-겹쳐서-보기-어렵다">히스토그램으로 Churn 구분하니 겹쳐서 보기 어렵다.</h1>
<p>​</p>
<p>sns.histplot(data=df, x=&#39;tenure&#39;, hue=&#39;Churn&#39;)</p>
<p>[63]:</p>
<p>&lt;AxesSubplot:xlabel=&#39;tenure&#39;, ylabel=&#39;Count&#39;&gt;</p>
<p>[64]:</p>
<h1 id="kdeplot--히스토그램을-곡선으로-그려보자">kdeplot : 히스토그램을 곡선으로 그려보자</h1>
<h1 id="처음엔-서비스-가입도-많이-하고-이탈도-많이-하는것으로-보이고">처음엔 서비스 가입도 많이 하고 이탈도 많이 하는것으로 보이고</h1>
<h1 id="70개월-이상-충성고객수는-점점-줄어-들고-특히-60개월이상-넘어가면-이탈이-많이-늘어난다">70개월 이상 충성고객수는 점점 줄어 들고, 특히 60개월이상 넘어가면 이탈이 많이 늘어난다.</h1>
<p>​</p>
<p>sns.kdeplot(data=df, x=&#39;tenure&#39;, hue=&#39;Churn&#39;)</p>
<p>[64]:</p>
<p>&lt;AxesSubplot:xlabel=&#39;tenure&#39;, ylabel=&#39;Density&#39;&gt;</p>
<p>TotalCharges 컬럼</p>
<p>[65]:</p>
<h1 id="totalcharges-서비스-총요금에-대한-히스토그램">TotalCharges (서비스 총요금)에 대한 히스토그램</h1>
<h1 id="처음에-많이-사용하고-금액이-커질수록-사용자수가-줄어든다">처음에 많이 사용하고 금액이 커질수록 사용자수가 줄어든다</h1>
<p>​</p>
<p>sns.histplot(data=df, x=&#39;TotalCharges&#39;)</p>
<p>[65]:</p>
<p>&lt;AxesSubplot:xlabel=&#39;TotalCharges&#39;, ylabel=&#39;Count&#39;&gt;</p>
<p>[66]:</p>
<h1 id="kdeplot--히스토그램을-곡선으로-그려보자-1">kdeplot : 히스토그램을 곡선으로 그려보자</h1>
<h1 id="최근-가입자가-이탈하기-쉽다">최근 가입자가 이탈하기 쉽다.</h1>
<h1 id="monthlycharges서비스-총요금이-클수록-이탈하기-쉽다">MonthlyCharges(서비스 총요금)이 클수록 이탈하기 쉽다.</h1>
<p>​</p>
<p>sns.kdeplot(data=df, x=&#39;TotalCharges&#39;, hue=&#39;Churn&#39;)</p>
<p>[66]:</p>
<p>&lt;AxesSubplot:xlabel=&#39;TotalCharges&#39;, ylabel=&#39;Density&#39;&gt;</p>
<p>Countplot</p>
<p>[67]:</p>
<h1 id="multiplelines-서비스를-사용하는-고객이-약간-더-높은-이탈율을-보인다">MultipleLines 서비스를 사용하는 고객이 약간 더 높은 이탈율을 보인다.</h1>
<p>sns.countplot(data=df, x=&#39;MultipleLines&#39;,  hue=&#39;Churn&#39;)</p>
<p>[67]:</p>
<p>&lt;AxesSubplot:xlabel=&#39;MultipleLines&#39;, ylabel=&#39;count&#39;&gt;</p>
<p>heatmap</p>
<p>[68]:</p>
<h1 id="tenuremonthlychargestotalcharges-컬럼간의-상관관계를-확인해-보자">&#39;tenure&#39;,&#39;MonthlyCharges&#39;,&#39;TotalCharges&#39; 컬럼간의 상관관계를 확인해 보자</h1>
<p>df[[&#39;tenure&#39;,&#39;MonthlyCharges&#39;,&#39;TotalCharges&#39;]].corr()</p>
<p>[68]:</p>
<pre><code>       tenure   MonthlyCharges TotalCharges</code></pre><p>tenure   1.000000           0.247630           0.826172</p>
<p>MonthlyCharges  0.247630           1.000000           0.651049</p>
<p>TotalCharges      0.826172           0.651049           1.000000</p>
<p>[69]:</p>
<h1 id="tenuremonthlychargestotalcharges-컬럼간의-상관관계를-heatmap으로-그려보자">tenure&#39;,&#39;MonthlyCharges&#39;,&#39;TotalCharges&#39; 컬럼간의 상관관계를 heatmap으로 그려보자</h1>
<h1 id="tenure서비스-사용기간과-totalcharges서비스-총요금간의-깊은-상관관계가-있어-보인다">tenure(서비스 사용기간)과 TotalCharges(서비스 총요금)간의 깊은 상관관계가 있어 보인다.</h1>
<p>​</p>
<p>sns.heatmap(df[[&#39;tenure&#39;,&#39;MonthlyCharges&#39;,&#39;TotalCharges&#39;]].corr(), annot=True)</p>
<p>[69]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>boxplot</p>
<p>[70]:</p>
<h1 id="이탈하는-고객이-이탈하지-않는-고객에-비해-총사용금액이-낮으며-outlier-보인다">이탈하는 고객이 이탈하지 않는 고객에 비해 총사용금액이 낮으며, Outlier 보인다.</h1>
<p>sns.boxplot(data=df, x=&#39;Churn&#39;, y=&#39;TotalCharges&#39;)</p>
<p>[70]:</p>
<p>&lt;AxesSubplot:xlabel=&#39;Churn&#39;, ylabel=&#39;TotalCharges&#39;&gt;</p>
<ol start="5">
<li>결과 저장하기</li>
</ol>
<p>결과를 csv 파일로 저장하기</p>
<p>[71]:</p>
<h1 id="indexfalse-주어야-기존-인덱스-값이-저장되지-않음">index=False 주어야 기존 인덱스 값이 저장되지 않음</h1>
<p>df.to_csv(&#39;data_v1_save.csv&#39;, index=False)</p>
<p>[72]:</p>
<p>pd.read_csv(&#39;data_v1_save.csv&#39;).head()</p>
<p>[72]:</p>
<pre><code>       gender  Partner  Dependents       tenure   MultipleLines      InternetService   OnlineSecurity           OnlineBackup     TechSupport      StreamingTV      StreamingMovies Contract PaperlessBilling           PaymentMethod  MonthlyCharges  TotalCharges      Churn</code></pre><p>0         Male     No       No       34        No       DSL      Yes       No       No       No       No       One year           No       Mailed check     56.95     1889.50  0</p>
<p>1         Male     No       No       2         No       DSL      Yes       Yes       No       No       No       Month-to-month   Yes       Mailed check     53.85     108.15   1</p>
<p>2         Male     No       No       45        No phone service           DSL      Yes       No       Yes       No           No       One year          No       Bank transfer (automatic)  42.30    1840.75  0</p>
<p>3         Female  No       No       2         No       Fiber optic         No       No       No       No       No           Month-to-month Yes       Electronic check  70.70    151.65   1</p>
<p>4         Female  No       No       8         Yes       Fiber optic         No       No       No       Yes       Yes           Month-to-month Yes       Electronic check  99.65    820.50   1</p>
<p>[ ]:</p>
<p>​</p>
<p>배운 내용 정리</p>
<pre><code>       1. 필요 라이브러리 임포트 및 파일 읽어오기 : pd.read_csv()

       2. EDA (Exploratory Data Analysis) 탐색적 데이터 분석 : df.info(), df.head(), df.tail()

       3. 데이터 전처리 수행

       • 불필요 컬럼 삭제 : df.drop()

       • 컬럼 내용 변경하기 : df.replace()

       • Null 처리 : df.replace(), df.fillna()

       • 컬럼 type 변경하기 : df[&#39;col&#39;].astype(int)

       4. 시각화

       • matplotlib, seaborn

       • bar, scatter, countplot, boxplot

       5. 결과 저장하기

       • to_csv()</code></pre><p>[ ]:</p>
<p>​</p>
<p>D:\바탕화면_2021\ETC A2Z\2022 코딩챌린지<em>및</em>계발\10. 2023 AICE Associate 교육</p>
<p>[실습-퀴즈] Python을 활용한 AI 모델링 - 머신러닝 파트</p>
<p>·         이번시간에는 Python을 활용한 AI 모델링에서 머신러닝에 대해 실습해 보겠습니다.</p>
<p>·         머신러닝 모델에는 아래와 같이 모델들이 있습니다.</p>
<p>·         단일 분류예측 모델 : LogisticRegression, KNN, DecisionTree</p>
<p>·         앙상블(Ensemble) 모델 : RandomForest, XGBoost, LGBM, Stacking, Weighted Blending</p>
<p>·         솔직히, 머신러닝이 딥러닝보다 코딩하기 쉽습니다. 4줄 템플릿에 맞쳐 코딩하면 되기 때문입니다.</p>
<p>·         한가지 당부 드리고 싶은 말은 &quot;백문이불여일타&quot; 입니다.</p>
<p>·         이론보다 실습이 더 많은 시간과 노력이 투자 되어야 합니다.</p>
<p>학습목차</p>
<ol>
<li>머신러닝 모델 프로세스</li>
</ol>
<p>·         데이터 가져오기</p>
<p>·         데이터 전처리</p>
<p>·         Train, Test 데이터셋 분할</p>
<p>·         데이터 정규화</p>
<p>·         단일 분류예측 모델 : LogisticRegression, KNN, DecisionTree</p>
<p>·         앙상블(Ensemble) 모델 : RandomForest, XGBoost, LGBM</p>
<ol start="2">
<li><p>재현율 성능이 너무 안나온다. 어떻게 해결할수 있을까?</p>
</li>
<li><p>머신러닝 모델 프로세스</p>
</li>
</ol>
<p>① 라이브러리 임포트(import)</p>
<p>② 데이터 가져오기(Loading the data)</p>
<p>③ 탐색적 데이터 분석(Exploratory Data Analysis)</p>
<p>④ 데이터 전처리(Data PreProcessing) : 데이터타입 변환, Null 데이터 처리, 누락데이터 처리, 더미특성 생성, 특성 추출 (feature engineering) 등</p>
<p>⑤ Train, Test 데이터셋 분할</p>
<p>⑥ 데이터 정규화(Normalizing the Data)</p>
<p>⑦ 모델 개발(Creating the Model)</p>
<p>⑧ 모델 성능 평가</p>
<p>① 라이브러리 임포트</p>
<p>필요 라이브러리 임포트</p>
<p>[1]:</p>
<p>import numpy as np</p>
<p>import pandas as pd</p>
<p>import matplotlib.pyplot as plt</p>
<p>Duplicate key in file PosixPath(&#39;/usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/matplotlibrc&#39;), line 758 (&#39;font.family\t: NanumGothicCoding&#39;)</p>
<p>② 데이터 로드</p>
<p>data_v1_save.csv 파일 읽어오기</p>
<p>[2]:</p>
<h1 id="앞쪽-전처리에서-저장한-cust_datacsv-파일-읽기">앞쪽 전처리에서 저장한 cust_data.csv 파일 읽기</h1>
<h1 id="df--pdread_csvdata_v1_savetxt-">df = pd.read_csv(&#39;data_v1_save.txt&#39;, )</h1>
<p>​</p>
<p>df = pd.read_csv(&#39;(라이브교육)data_v1_save.csv&#39;,sep = &quot;,&quot;)</p>
<p>③ 데이터 분석</p>
<p>[3]:</p>
<h1 id="17컬럼-7027-라인">17컬럼, 7,027 라인</h1>
<p>df.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;
RangeIndex: 7027 entries, 0 to 7026
Data columns (total 17 columns):</p>
<h1 id="column------------non-null-count--dtype-6">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   gender            7027 non-null   object
 1   Partner           7027 non-null   object
 2   Dependents        7027 non-null   object
 3   tenure            7027 non-null   int64 
 4   MultipleLines     7027 non-null   object
 5   InternetService   7027 non-null   object
 6   OnlineSecurity    7027 non-null   object
 7   OnlineBackup      7027 non-null   object
 8   TechSupport       7027 non-null   object
 9   StreamingTV       7027 non-null   object
 10  StreamingMovies   7027 non-null   object
 11  Contract          7027 non-null   object
 12  PaperlessBilling  7027 non-null   object
 13  PaymentMethod     7027 non-null   object
 14  MonthlyCharges    7027 non-null   float64
15  TotalCharges      7027 non-null   float64
16  Churn             7027 non-null   int64 
dtypes: float64(2), int64(2), object(13)
memory usage: 933.4+ KB</p>
<p>[4]:</p>
<p>df.tail()</p>
<p>[4]:</p>
<p>gender</p>
<p>Partner</p>
<p>Dependents</p>
<p>tenure</p>
<p>MultipleLines</p>
<p>InternetService</p>
<p>OnlineSecurity</p>
<p>OnlineBackup</p>
<p>TechSupport</p>
<p>StreamingTV</p>
<p>StreamingMovies</p>
<p>Contract</p>
<p>PaperlessBilling</p>
<p>PaymentMethod</p>
<p>MonthlyCharges</p>
<p>TotalCharges</p>
<p>Churn</p>
<p>7022</p>
<p>Female</p>
<p>No</p>
<p>No</p>
<p>72</p>
<p>No</p>
<p>No</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>Two year</p>
<p>Yes</p>
<p>Bank transfer (automatic)</p>
<p>21.15</p>
<p>1419.40</p>
<p>0</p>
<p>7023</p>
<p>Male</p>
<p>Yes</p>
<p>Yes</p>
<p>24</p>
<p>Yes</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>Yes</p>
<p>Yes</p>
<p>One year</p>
<p>Yes</p>
<p>Mailed check</p>
<p>84.80</p>
<p>1990.50</p>
<p>0</p>
<p>7024</p>
<p>Female</p>
<p>Yes</p>
<p>Yes</p>
<p>72</p>
<p>Yes</p>
<p>Fiber optic</p>
<p>No</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>Yes</p>
<p>One year</p>
<p>Yes</p>
<p>Credit card (automatic)</p>
<p>103.20</p>
<p>7362.90</p>
<p>0</p>
<p>7025</p>
<p>Female</p>
<p>Yes</p>
<p>Yes</p>
<p>11</p>
<p>No phone service</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Electronic check</p>
<p>29.60</p>
<p>346.45</p>
<p>0</p>
<p>7026</p>
<p>Male</p>
<p>Yes</p>
<p>No</p>
<p>4</p>
<p>Yes</p>
<p>Fiber optic</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Mailed check</p>
<p>74.40</p>
<p>306.60</p>
<p>1</p>
<p>[5]:</p>
<p>df[&#39;Churn&#39;].value_counts()</p>
<p>[5]:</p>
<p>0    5161
1    1866
Name: Churn, dtype: int64</p>
<p>[7]:</p>
<h1 id="churn-레이블-불균형">Churn 레이블 불균형</h1>
<p>df[&#39;Churn&#39;].value_counts()[:].plot(kind=&#39;bar&#39;)</p>
<p>[7]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>④ 데이터 전처리</p>
<ul>
<li><p>모든 데이터값들은 숫자형으로 되어야 한다. 즉, Ojbect 타입을 모든 숫자형 변경 필요</p>
</li>
<li><p>전처리 시간에 했던 replace 대신 Label ending 과 OneHot 함수를 활용 하여 인코딩</p>
</li>
<li><p>Object 컬럼에 대해 Pandas get_dummies 함수 활용하여 One-Hot-Encoding</p>
</li>
</ul>
<p>​</p>
<p>[8]:</p>
<h1 id="multiplelines-컬럼-내용-보기">MultipleLines 컬럼 내용 보기</h1>
<p>df[[&#39;MultipleLines&#39;]].head()</p>
<p>[8]:</p>
<p>MultipleLines</p>
<p>0</p>
<p>No</p>
<p>1</p>
<p>No</p>
<p>2</p>
<p>No phone service</p>
<p>3</p>
<p>No</p>
<p>4</p>
<p>Yes</p>
<p>[9]:</p>
<h1 id="multiplelines-컬럼에-대한-분포-확인--3가지-되어-있음-확인">MultipleLines 컬럼에 대한 분포 확인 : 3가지 되어 있음 확인</h1>
<p>df[&#39;MultipleLines&#39;].value_counts()</p>
<p>[9]:</p>
<p>No                  3380
Yes                 2966
No phone service     681
Name: MultipleLines, dtype: int64</p>
<p>[10]:</p>
<h1 id="multiplelines-컬럼의-값들이-문자열로-되어-있어-숫자로-변환해야-함-컴퓨터가-이해할수-있도록">MultipleLines 컬럼의 값들이 문자열로 되어 있어 숫자로 변환해야 함. 컴퓨터가 이해할수 있도록</h1>
<h1 id="object-컬럼의-데이터를-원-핫-인코딩해서-숫자로-변경해-주는-함수--pandas-get_dummies">Object 컬럼의 데이터를 원-핫-인코딩해서 숫자로 변경해 주는 함수 : Pandas get_dummies()</h1>
<p>​</p>
<p>pd.get_dummies(data=df, columns=[&#39;MultipleLines&#39;])</p>
<p>[10]:</p>
<p>gender</p>
<p>Partner</p>
<p>Dependents</p>
<p>tenure</p>
<p>InternetService</p>
<p>OnlineSecurity</p>
<p>OnlineBackup</p>
<p>TechSupport</p>
<p>StreamingTV</p>
<p>StreamingMovies</p>
<p>Contract</p>
<p>PaperlessBilling</p>
<p>PaymentMethod</p>
<p>MonthlyCharges</p>
<p>TotalCharges</p>
<p>Churn</p>
<p>MultipleLines_No</p>
<p>MultipleLines_No phone service</p>
<p>MultipleLines_Yes</p>
<p>0</p>
<p>Male</p>
<p>No</p>
<p>No</p>
<p>34</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>One year</p>
<p>No</p>
<p>Mailed check</p>
<p>56.95</p>
<p>1889.50</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>Male</p>
<p>No</p>
<p>No</p>
<p>2</p>
<p>DSL</p>
<p>Yes</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Mailed check</p>
<p>53.85</p>
<p>108.15</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>2</p>
<p>Male</p>
<p>No</p>
<p>No</p>
<p>45</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>One year</p>
<p>No</p>
<p>Bank transfer (automatic)</p>
<p>42.30</p>
<p>1840.75</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>3</p>
<p>Female</p>
<p>No</p>
<p>No</p>
<p>2</p>
<p>Fiber optic</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Electronic check</p>
<p>70.70</p>
<p>151.65</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>4</p>
<p>Female</p>
<p>No</p>
<p>No</p>
<p>8</p>
<p>Fiber optic</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Yes</p>
<p>Yes</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Electronic check</p>
<p>99.65</p>
<p>820.50</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>7022</p>
<p>Female</p>
<p>No</p>
<p>No</p>
<p>72</p>
<p>No</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>Two year</p>
<p>Yes</p>
<p>Bank transfer (automatic)</p>
<p>21.15</p>
<p>1419.40</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>7023</p>
<p>Male</p>
<p>Yes</p>
<p>Yes</p>
<p>24</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>Yes</p>
<p>Yes</p>
<p>One year</p>
<p>Yes</p>
<p>Mailed check</p>
<p>84.80</p>
<p>1990.50</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>7024</p>
<p>Female</p>
<p>Yes</p>
<p>Yes</p>
<p>72</p>
<p>Fiber optic</p>
<p>No</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>Yes</p>
<p>One year</p>
<p>Yes</p>
<p>Credit card (automatic)</p>
<p>103.20</p>
<p>7362.90</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>7025</p>
<p>Female</p>
<p>Yes</p>
<p>Yes</p>
<p>11</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Electronic check</p>
<p>29.60</p>
<p>346.45</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>7026</p>
<p>Male</p>
<p>Yes</p>
<p>No</p>
<p>4</p>
<p>Fiber optic</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Mailed check</p>
<p>74.40</p>
<p>306.60</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>7027 rows × 19 columns</p>
<p>[11]:</p>
<h1 id="object-컬럼-확인">Object 컬럼 확인</h1>
<p>df.select_dtypes(&#39;object&#39;).head(3)</p>
<p>[11]:</p>
<p>gender</p>
<p>Partner</p>
<p>Dependents</p>
<p>MultipleLines</p>
<p>InternetService</p>
<p>OnlineSecurity</p>
<p>OnlineBackup</p>
<p>TechSupport</p>
<p>StreamingTV</p>
<p>StreamingMovies</p>
<p>Contract</p>
<p>PaperlessBilling</p>
<p>PaymentMethod</p>
<p>0</p>
<p>Male</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>One year</p>
<p>No</p>
<p>Mailed check</p>
<p>1</p>
<p>Male</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>DSL</p>
<p>Yes</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Mailed check</p>
<p>2</p>
<p>Male</p>
<p>No</p>
<p>No</p>
<p>No phone service</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>One year</p>
<p>No</p>
<p>Bank transfer (automatic)</p>
<p>[14]:</p>
<h1 id="object-컬럼명-수집">Object 컬럼명 수집</h1>
<p>​</p>
<p>cal_cols = df.select_dtypes(&#39;object&#39;).columns.values</p>
<p>cal_cols</p>
<p>[14]:</p>
<p>array([&#39;gender&#39;, &#39;Partner&#39;, &#39;Dependents&#39;, &#39;MultipleLines&#39;,
       &#39;InternetService&#39;, &#39;OnlineSecurity&#39;, &#39;OnlineBackup&#39;, &#39;TechSupport&#39;,
       &#39;StreamingTV&#39;, &#39;StreamingMovies&#39;, &#39;Contract&#39;, &#39;PaperlessBilling&#39;,
       &#39;PaymentMethod&#39;], dtype=object)</p>
<p>[문제] Object 컬럼에 대해 One-Hot-Encoding 수행하고 그 결과를 df1 변수에 저장하세요. </p>
<p>[15]:</p>
<h1 id="pandas-get_dummies-함수-이용">Pandas get_dummies() 함수 이용</h1>
<h1 id="원-핫-인코딩-결과를-df1-저장">원-핫-인코딩 결과를 df1 저장</h1>
<p>​</p>
<p>​</p>
<p>df1 = pd.get_dummies(data = df, columns=cal_cols)</p>
<p>[16]:</p>
<h1 id="모든-컬럼-데이터가-숫자되어-있음을-확인">모든 컬럼 데이터가 숫자되어 있음을 확인</h1>
<h1 id="40컬럼-7027-라인">40컬럼, 7,027 라인</h1>
<p>​</p>
<p>df1.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;
RangeIndex: 7027 entries, 0 to 7026
Data columns (total 40 columns):</p>
<h1 id="column-----------------------------------non-null-count--dtype">Column                                   Non-Null Count  Dtype</h1>
<hr>
<p> 0   tenure                                   7027 non-null   int64 
 1   MonthlyCharges                           7027 non-null   float64
2   TotalCharges                             7027 non-null   float64
3   Churn                                    7027 non-null   int64 
 4   gender_Female                            7027 non-null   uint8 
 5   gender_Male                              7027 non-null   uint8 
 6   Partner_No                               7027 non-null   uint8 
 7   Partner_Yes                              7027 non-null   uint8 
 8   Dependents_No                            7027 non-null   uint8 
 9   Dependents_Yes                           7027 non-null   uint8 
 10  MultipleLines_No                         7027 non-null   uint8 
 11  MultipleLines_No phone service           7027 non-null   uint8 
 12  MultipleLines_Yes                        7027 non-null   uint8 
 13  InternetService_DSL                      7027 non-null   uint8 
 14  InternetService_Fiber optic              7027 non-null   uint8 
 15  InternetService_No                       7027 non-null   uint8 
 16  OnlineSecurity_No                        7027 non-null   uint8 
 17  OnlineSecurity_No internet service       7027 non-null   uint8 
 18  OnlineSecurity_Yes                       7027 non-null   uint8 
 19  OnlineBackup_No                          7027 non-null   uint8 
 20  OnlineBackup_No internet service         7027 non-null   uint8 
 21  OnlineBackup_Yes                         7027 non-null   uint8 
 22  TechSupport_No                           7027 non-null   uint8 
 23  TechSupport_No internet service          7027 non-null   uint8 
 24  TechSupport_Yes                          7027 non-null   uint8 
 25  StreamingTV_No                           7027 non-null   uint8 
 26  StreamingTV_No internet service          7027 non-null   uint8 
 27  StreamingTV_Yes                          7027 non-null   uint8 
 28  StreamingMovies_No                       7027 non-null   uint8 
 29  StreamingMovies_No internet service      7027 non-null   uint8 
 30  StreamingMovies_Yes                      7027 non-null   uint8 
 31  Contract_Month-to-month                  7027 non-null   uint8 
 32  Contract_One year                        7027 non-null   uint8 
 33  Contract_Two year                        7027 non-null   uint8 
 34  PaperlessBilling_No                      7027 non-null   uint8 
 35  PaperlessBilling_Yes                     7027 non-null   uint8 
 36  PaymentMethod_Bank transfer (automatic)  7027 non-null   uint8 
 37  PaymentMethod_Credit card (automatic)    7027 non-null   uint8 
 38  PaymentMethod_Electronic check           7027 non-null   uint8 
 39  PaymentMethod_Mailed check               7027 non-null   uint8 
dtypes: float64(2), int64(2), uint8(36)
memory usage: 466.8 KB</p>
<p>[17]:</p>
<p>df1.head(3)</p>
<p>[17]:</p>
<p>tenure</p>
<p>MonthlyCharges</p>
<p>TotalCharges</p>
<p>Churn</p>
<p>gender_Female</p>
<p>gender_Male</p>
<p>Partner_No</p>
<p>Partner_Yes</p>
<p>Dependents_No</p>
<p>Dependents_Yes</p>
<p>...</p>
<p>StreamingMovies_Yes</p>
<p>Contract_Month-to-month</p>
<p>Contract_One year</p>
<p>Contract_Two year</p>
<p>PaperlessBilling_No</p>
<p>PaperlessBilling_Yes</p>
<p>PaymentMethod_Bank transfer (automatic)</p>
<p>PaymentMethod_Credit card (automatic)</p>
<p>PaymentMethod_Electronic check</p>
<p>PaymentMethod_Mailed check</p>
<p>0</p>
<p>34</p>
<p>56.95</p>
<p>1889.50</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>...</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>2</p>
<p>53.85</p>
<p>108.15</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>...</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>2</p>
<p>45</p>
<p>42.30</p>
<p>1840.75</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>...</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>3 rows × 40 columns</p>
<p>⑤ Train, Test 데이터셋 분할</p>
<p>입력(X)과 레이블(y) 나누기</p>
<p>[문제] df1 DataFrame에서 &#39;Churn&#39; 컬럼을 제외한 나머지 정보를 X에 저장하세요. </p>
<p>[18]:</p>
<h1 id="dataframe-drop-함수-활용-1">DataFrame drop 함수 활용</h1>
<h1 id="churn-컬럼-삭제">&#39;Churn&#39; 컬럼 삭제</h1>
<h1 id="dataframe에서-values만-x에-저장">DataFrame에서 values만 X에 저장</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>X = df1.drop(&#39;Churn&#39;, axis=1).values</p>
<p>[문제] df DataFrame에서 &#39;Churn&#39; 컬럼을 y로 저장하세요. </p>
<p>[20]:</p>
<h1 id="dataframe-churn-컬럼-사용">DataFrame &#39;Churn&#39; 컬럼 사용</h1>
<h1 id="dataframe에서-values만-y에-저장">DataFrame에서 values만 y에 저장</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>y = df1[&#39;Churn&#39;].values</p>
<p>[21]:</p>
<p>X.shape, y.shape</p>
<p>[21]:</p>
<p>((7027, 39), (7027,))</p>
<p>Train , Test dataset 나누기</p>
<p>[22]:</p>
<p>from sklearn.model_selection import train_test_split</p>
<p>[문제] Train dataset, Test dataset 나누세요. </p>
<p>[23]:</p>
<h1 id="train-dataset-test-dataset-나누기--train_test_split-함수-사용">Train dataset, Test dataset 나누기 : train_test_split 함수 사용</h1>
<h1 id="입력--x-y">입력 : X, y</h1>
<h1 id="train--test-비율--7-3-----test_size03">Train : Test 비율 = 7: 3  --&gt; test_size=0.3</h1>
<h1 id="y-class-비율에-맞게-나누기--stratifyy">y Class 비율에 맞게 나누기 : stratify=y</h1>
<h1 id="여러번-수행해도-같은-결과-나오게-고정하기--random_state42">여러번 수행해도 같은 결과 나오게 고정하기 : random_state=42</h1>
<h1 id="결과--x_train-x_test-y_train-y_test">결과 : X_train, X_test, y_train, y_test</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, stratify = y, random_state = 42)</p>
<p>​</p>
<p>[24]:</p>
<p>X_train.shape</p>
<p>[24]:</p>
<p>(4918, 39)</p>
<p>[25]:</p>
<p>y_train.shape</p>
<p>[25]:</p>
<p>(4918,)</p>
<p>⑥ 데이터 정규화/스케일링(Normalizing/Scaling)</p>
<p>[26]:</p>
<h1 id="숫자-분포-이루어진-컬럼-확인">숫자 분포 이루어진 컬럼 확인</h1>
<p>df1.tail()</p>
<p>[26]:</p>
<p>tenure</p>
<p>MonthlyCharges</p>
<p>TotalCharges</p>
<p>Churn</p>
<p>gender_Female</p>
<p>gender_Male</p>
<p>Partner_No</p>
<p>Partner_Yes</p>
<p>Dependents_No</p>
<p>Dependents_Yes</p>
<p>...</p>
<p>StreamingMovies_Yes</p>
<p>Contract_Month-to-month</p>
<p>Contract_One year</p>
<p>Contract_Two year</p>
<p>PaperlessBilling_No</p>
<p>PaperlessBilling_Yes</p>
<p>PaymentMethod_Bank transfer (automatic)</p>
<p>PaymentMethod_Credit card (automatic)</p>
<p>PaymentMethod_Electronic check</p>
<p>PaymentMethod_Mailed check</p>
<p>7022</p>
<p>72</p>
<p>21.15</p>
<p>1419.40</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>...</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>7023</p>
<p>24</p>
<p>84.80</p>
<p>1990.50</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>...</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>7024</p>
<p>72</p>
<p>103.20</p>
<p>7362.90</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>...</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>7025</p>
<p>11</p>
<p>29.60</p>
<p>346.45</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>...</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>7026</p>
<p>4</p>
<p>74.40</p>
<p>306.60</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>...</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>5 rows × 40 columns</p>
<p>[27]:</p>
<p>from sklearn.preprocessing import MinMaxScaler</p>
<p>[문제] MinMaxScaler 함수를 &#39;scaler&#39;로 정의 하세요. </p>
<p>[28]:</p>
<h1 id="사이키런의-minmaxscaler-함수-활용">사이키런의 MinMaxScaler() 함수 활용</h1>
<h1 id="정의할-결과를-scaler로-매핑">정의할 결과를 &#39;scaler&#39;로 매핑</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>scaler = MinMaxScaler()</p>
<p>[29]:</p>
<p>X_train = scaler.fit_transform(X_train)</p>
<p>X_test = scaler.transform(X_test)</p>
<p>[30]:</p>
<p>X_train[:2], y_train[:2]</p>
<p>[30]:</p>
<p>(array([[0.65277778, 0.56851021, 0.40877722, 1.        , 0.        ,
         1.        , 0.        , 1.        , 0.        , 1.        ,
         0.        , 0.        , 0.        , 1.        , 0.        ,
         0.        , 0.        , 1.        , 1.        , 0.        ,
         0.        , 1.        , 0.        , 0.        , 1.        ,
         0.        , 0.        , 1.        , 0.        , 0.        ,
         1.        , 0.        , 0.        , 1.        , 0.        ,
         0.        , 1.        , 0.        , 0.        ],
        [0.27777778, 0.00498256, 0.04008671, 1.        , 0.        ,
         1.        , 0.        , 1.        , 0.        , 1.        ,
         0.        , 0.        , 0.        , 0.        , 1.        ,
         0.        , 1.        , 0.        , 0.        , 1.        ,
         0.        , 0.        , 1.        , 0.        , 0.        ,
         1.        , 0.        , 0.        , 1.        , 0.        ,
         1.        , 0.        , 0.        , 0.        , 1.        ,
         0.        , 1.        , 0.        , 0.        ]]),
array([0, 0]))</p>
<p>[31]:</p>
<p>​</p>
<hr>
<p>AttributeError                            Traceback (most recent call last)
<ipython-input-31-bb36220e8bab> in <module>
----&gt; 1 X_train.tail()</p>
<p>AttributeError: &#39;numpy.ndarray&#39; object has no attribute &#39;tail&#39;</p>
<p>⑦ 모델 개발</p>
<p>(참고) 모델별 바차트 그려주고 성능 확인을 위한 함수</p>
<p>[44]:</p>
<h1 id="모델별로-recall-점수-저장">모델별로 Recall 점수 저장</h1>
<h1 id="모델-recall-점수-순서대로-바차트를-그려-모델별로-성능-확인-가능">모델 Recall 점수 순서대로 바차트를 그려 모델별로 성능 확인 가능</h1>
<p>​</p>
<p>from sklearn.metrics import accuracy_score</p>
<p>​</p>
<p>my_predictions = {}</p>
<p>​</p>
<p>colors = [&#39;r&#39;, &#39;c&#39;, &#39;m&#39;, &#39;y&#39;, &#39;k&#39;, &#39;khaki&#39;, &#39;teal&#39;, &#39;orchid&#39;, &#39;sandybrown&#39;,</p>
<pre><code>      &#39;greenyellow&#39;, &#39;dodgerblue&#39;, &#39;deepskyblue&#39;, &#39;rosybrown&#39;, &#39;firebrick&#39;,

      &#39;deeppink&#39;, &#39;crimson&#39;, &#39;salmon&#39;, &#39;darkred&#39;, &#39;olivedrab&#39;, &#39;olive&#39;,

      &#39;forestgreen&#39;, &#39;royalblue&#39;, &#39;indigo&#39;, &#39;navy&#39;, &#39;mediumpurple&#39;, &#39;chocolate&#39;,

      &#39;gold&#39;, &#39;darkorange&#39;, &#39;seagreen&#39;, &#39;turquoise&#39;, &#39;steelblue&#39;, &#39;slategray&#39;,

      &#39;peru&#39;, &#39;midnightblue&#39;, &#39;slateblue&#39;, &#39;dimgray&#39;, &#39;cadetblue&#39;, &#39;tomato&#39;

     ]</code></pre><p>​</p>
<h1 id="모델명-예측값-실제값을-주면-위의-plot_predictions-함수-호출하여-scatter-그래프-그리며">모델명, 예측값, 실제값을 주면 위의 plot_predictions 함수 호출하여 Scatter 그래프 그리며</h1>
<h1 id="모델별-mse값을-bar-chart로-그려줌">모델별 MSE값을 Bar chart로 그려줌</h1>
<p>def recall_eval(name_, pred, actual):</p>
<pre><code>global predictions

global colors</code></pre><p>​</p>
<pre><code>plt.figure(figsize=(12, 9))</code></pre><p>​</p>
<pre><code>#acc = accuracy_score(actual, pred)

acc = recall_score(actual, pred)

my_predictions[name_] = acc * 100</code></pre><p>​</p>
<pre><code>y_value = sorted(my_predictions.items(), key=lambda x: x[1], reverse=True)



df = pd.DataFrame(y_value, columns=[&#39;model&#39;, &#39;recall&#39;])

print(df)



length = len(df)



plt.figure(figsize=(10, length))

ax = plt.subplot()

ax.set_yticks(np.arange(len(df)))

ax.set_yticklabels(df[&#39;model&#39;], fontsize=15)

bars = ax.barh(np.arange(len(df)), df[&#39;recall&#39;])



for i, v in enumerate(df[&#39;recall&#39;]):

    idx = np.random.choice(len(colors))

    bars[i].set_color(colors[idx])

    ax.text(v + 2, i, str(round(v, 3)), color=&#39;k&#39;, fontsize=15, fontweight=&#39;bold&#39;)



plt.title(&#39;recall&#39;, fontsize=18)

plt.xlim(0, 100)



plt.show()</code></pre><p>1) 로지스틱 회귀 (LogisticRegression, 분류)</p>
<p>[32]:</p>
<p>from sklearn.linear_model import LogisticRegression</p>
<p>from sklearn.metrics import confusion_matrix</p>
<p>from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score</p>
<p>from sklearn.metrics import classification_report</p>
<p>[문제] LogisticRegression 모델 정의하고 학습시키세요. </p>
<p>[33]:</p>
<h1 id="logisticregression-함수-사용-및-정의--lg-저장">LogisticRegression 함수 사용 및 정의 : lg 저장</h1>
<h1 id="정의된-logisticregression-학습-fit--입력값으로-x_train-y_train-준다">정의된 LogisticRegression 학습 fit() : 입력값으로 X_train, y_train 준다.</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>lg = LogisticRegression()</p>
<p>lg.fit(X_train, y_train)</p>
<p>[33]:</p>
<p>LogisticRegression()</p>
<p>[34]:</p>
<h1 id="분류기-성능-평가score">분류기 성능 평가(score)</h1>
<p>lg.score(X_test, y_test)</p>
<p>[34]:</p>
<p>0.8060692271218587</p>
<p>·         분류기 성능 평가 지표</p>
<p>[35]:</p>
<p>lg_pred = lg.predict(X_test)</p>
<p>[36]:</p>
<p>lg_pred</p>
<p>[36]:</p>
<p>array([0, 0, 0, ..., 1, 1, 0])</p>
<p>[37]:</p>
<h1 id="오차행렬">오차행렬</h1>
<h1 id="tn--fp">TN  FP</h1>
<h1 id="fn--tp">FN  TP</h1>
<p>​</p>
<p>confusion_matrix(y_test, lg_pred)</p>
<p>[37]:</p>
<p>array([[1386,  163],
       [ 246,  314]])</p>
<p>[38]:</p>
<h1 id="정확도">정확도</h1>
<p>accuracy_score(y_test, lg_pred) </p>
<p>[38]:</p>
<p>0.8060692271218587</p>
<p>[39]:</p>
<h1 id="정밀도">정밀도</h1>
<p>precision_score(y_test, lg_pred)</p>
<p>[39]:</p>
<p>0.6582809224318659</p>
<p>[40]:</p>
<h1 id="재현율--낮다">재현율 : 낮다.</h1>
<p>recall_score(y_test, lg_pred) </p>
<p>[40]:</p>
<p>0.5607142857142857</p>
<p>[41]:</p>
<h1 id="정밀도--재현율">정밀도 + 재현율</h1>
<p>f1_score(y_test, lg_pred)</p>
<p>[41]:</p>
<p>0.6055930568948892</p>
<p>[42]:</p>
<p>print(classification_report(y_test, lg_pred))</p>
<pre><code>          precision    recall  f1-score   support</code></pre><p>0       0.85      0.89      0.87      1549
           1       0.66      0.56      0.61       560</p>
<p>accuracy                           0.81      2109
   macro avg       0.75      0.73      0.74      2109
weighted avg       0.80      0.81      0.80      2109</p>
<p>[45]:</p>
<p>recall_eval(&#39;LogisticRegression&#39;, lg_pred, y_test)</p>
<pre><code>            model     recall</code></pre><p>0  LogisticRegression  56.071429</p>
<Figure size 864x648 with 0 Axes>

<p>2) KNN (K-Nearest Neighbor)</p>
<p>[46]:</p>
<p>from sklearn.neighbors import KNeighborsClassifier</p>
<p>[47]:</p>
<p>knn = KNeighborsClassifier(n_neighbors=5)</p>
<p>knn.fit(X_train, y_train)</p>
<p>[47]:</p>
<p>KNeighborsClassifier()</p>
<p>[48]:</p>
<p>knn_pred = knn.predict(X_test)</p>
<p>[49]:</p>
<p>recall_eval(&#39;K-Nearest Neighbor&#39;, knn_pred, y_test)</p>
<pre><code>            model     recall</code></pre><p>0  LogisticRegression  56.071429
1  K-Nearest Neighbor  52.142857</p>
<Figure size 864x648 with 0 Axes>

<p>3) 결정트리(DecisionTree)</p>
<p>[50]:</p>
<p>from sklearn.tree import DecisionTreeClassifier</p>
<p>[51]:</p>
<p>dt = DecisionTreeClassifier(max_depth=10, random_state=42)</p>
<p>dt.fit(X_train, y_train)</p>
<p>[51]:</p>
<p>DecisionTreeClassifier(max_depth=10, random_state=42)</p>
<p>[문제] 학습된 DecisionTreeClassifier 모델로 예측해 보기 </p>
<p>[52]:</p>
<h1 id="decisiontreeclassifier-학습-모델--dt">DecisionTreeClassifier 학습 모델 : dt</h1>
<h1 id="decisiontreeclassifier-모델의-predict-활용--입력값으로-x_test">DecisionTreeClassifier 모델의 predict() 활용 : 입력값으로 X_test</h1>
<h1 id="결과--dt_pred-저장">결과 : dt_pred 저장</h1>
<p>​</p>
<p>​</p>
<p>​</p>
<p>dt_pred = dt.predict(X_test)</p>
<p>[53]:</p>
<p>recall_eval(&#39;DecisionTree&#39;, dt_pred, y_test)</p>
<pre><code>            model     recall</code></pre><p>0  LogisticRegression  56.071429
1        DecisionTree  55.714286
2  K-Nearest Neighbor  52.142857</p>
<Figure size 864x648 with 0 Axes>

<p>앙상블 기법의 종류</p>
<p>·         배깅 (Bagging): 여러개의 DecisionTree 활용하고 샘플 중복 생성을 통해 결과 도출. RandomForest</p>
<p>·         부스팅 (Boosting): 약한 학습기를 순차적으로 학습을 하되, 이전 학습에 대하여 잘못 예측된 데이터에 가중치를 부여해 오차를 보완해 나가는 방식. XGBoost, LGBM</p>
<p>앙상블</p>
<p>4) 랜덤포레스트(RandomForest)</p>
<p>·         Bagging 대표적인 모델로써, 훈련셋트를 무작위로 각기 다른 서브셋으로 데이터셋을 만들고</p>
<p>·         여러개의 DecisonTree로 학습하고 다수결로 결정하는 모델</p>
<p>주요 Hyperparameter</p>
<p>·         random_state: 랜덤 시드 고정 값. 고정해두고 튜닝할 것!</p>
<p>·         n_jobs: CPU 사용 갯수</p>
<p>·         max_depth: 깊어질 수 있는 최대 깊이. 과대적합 방지용</p>
<p>·         n_estimators: 앙상블하는 트리의 갯수</p>
<p>·         max_features: 최대로 사용할 feature의 갯수. 과대적합 방지용</p>
<p>·         min_samples_split: 트리가 분할할 때 최소 샘플의 갯수. default=2. 과대적합 방지용</p>
<p>[54]:</p>
<p>from sklearn.ensemble import RandomForestClassifier</p>
<p>[55]:</p>
<p>rfc = RandomForestClassifier(n_estimators=3, random_state=42)</p>
<p>rfc.fit(X_train, y_train)</p>
<p>[55]:</p>
<p>RandomForestClassifier(n_estimators=3, random_state=42)</p>
<p>[56]:</p>
<p>rfc_pred = rfc.predict(X_test)</p>
<p>[57]:</p>
<p>recall_eval(&#39;RandomForest Ensemble&#39;, rfc_pred, y_test)</p>
<pre><code>               model     recall</code></pre><p>0     LogisticRegression  56.071429
1           DecisionTree  55.714286
2     K-Nearest Neighbor  52.142857
3  RandomForest Ensemble  52.142857</p>
<Figure size 864x648 with 0 Axes>

<p>5) XGBoost</p>
<p>·         여러개의 DecisionTree를 결합하여 Strong Learner 만드는 Boosting 앙상블 기법</p>
<p>·         Kaggle 대회에서 자주 사용하는 모델이다.</p>
<p>5-1) Boosting 기본 개념</p>
<p>5-2) Boosting 상세</p>
<p>주요 특징</p>
<p>·         scikit-learn 패키지가 아닙니다.</p>
<p>·         성능이 우수함</p>
<p>·         GBM보다는 빠르고 성능도 향상되었습니다.</p>
<p>·         여전히 학습시간이 매우 느리다</p>
<p>주요 Hyperparameter</p>
<p>·         random_state: 랜덤 시드 고정 값. 고정해두고 튜닝할 것!</p>
<p>·         n_jobs: CPU 사용 갯수</p>
<p>·         learning_rate: 학습율. 너무 큰 학습율은 성능을 떨어뜨리고, 너무 작은 학습율은 학습이 느리다. 적절한 값을 찾아야함. n_estimators와 같이 튜닝. default=0.1</p>
<p>·         n_estimators: 부스팅 스테이지 수. (랜덤포레스트 트리의 갯수 설정과 비슷한 개념). default=100</p>
<p>·         max_depth: 트리의 깊이. 과대적합 방지용. default=3.</p>
<p>·         subsample: 샘플 사용 비율. 과대적합 방지용. default=1.0</p>
<p>·         max_features: 최대로 사용할 feature의 비율. 과대적합 방지용. default=1.0</p>
<p>[58]:</p>
<p>!pip install xgboost</p>
<p>Looking in indexes: <a href="http://10.220.235.19/pypi/simple">http://10.220.235.19/pypi/simple</a>
Requirement already satisfied: xgboost in /usr/local/lib/python3.6/dist-packages (0.90)
Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from xgboost) (1.19.5)
Requirement already satisfied: scipy in /usr/local/lib/python3.6/dist-packages (from xgboost) (1.5.4)
WARNING: Running pip as the &#39;root&#39; user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: <a href="https://pip.pypa.io/warnings/venv">https://pip.pypa.io/warnings/venv</a></p>
<p>[59]:</p>
<p>from xgboost import XGBClassifier</p>
<p>[60]:</p>
<p>xgb = XGBClassifier(n_estimators=3, random_state=42) </p>
<p>xgb.fit(X_train, y_train)</p>
<p>[60]:</p>
<p>XGBClassifier(n_estimators=3, random_state=42)</p>
<p>[61]:</p>
<p>xgb_pred = xgb.predict(X_test)</p>
<p>[62]:</p>
<p>recall_eval(&#39;XGBoost&#39;, xgb_pred, y_test)</p>
<pre><code>               model     recall</code></pre><p>0     LogisticRegression  56.071429
1           DecisionTree  55.714286
2     K-Nearest Neighbor  52.142857
3  RandomForest Ensemble  52.142857
4                XGBoost  48.214286</p>
<Figure size 864x648 with 0 Axes>

<p>6) Light GBM</p>
<p>·         XGBoost와 함께 주목받는 DecisionTree 알고리즘 기반의 Boosting 앙상블 기법</p>
<p>·         XGBoost에 비해 학습시간이 짧은 편이다.</p>
<p>주요 특징</p>
<p>·         scikit-learn 패키지가 아닙니다.</p>
<p>·         성능이 우수함</p>
<p>·         속도도 매우 빠릅니다.</p>
<p>주요 Hyperparameter</p>
<p>·         random_state: 랜덤 시드 고정 값. 고정해두고 튜닝할 것!</p>
<p>·         n_jobs: CPU 사용 갯수</p>
<p>·         learning_rate: 학습율. 너무 큰 학습율은 성능을 떨어뜨리고, 너무 작은 학습율은 학습이 느리다. 적절한 값을 찾아야함. n_estimators와 같이 튜닝. default=0.1</p>
<p>·         n_estimators: 부스팅 스테이지 수. (랜덤포레스트 트리의 갯수 설정과 비슷한 개념). default=100</p>
<p>·         max_depth: 트리의 깊이. 과대적합 방지용. default=3.</p>
<p>·         colsample_bytree: 샘플 사용 비율 (max_features와 비슷한 개념). 과대적합 방지용. default=1.0</p>
<p>[63]:</p>
<p>!pip install lightgbm</p>
<p>Looking in indexes: <a href="http://10.220.235.19/pypi/simple">http://10.220.235.19/pypi/simple</a>
Requirement already satisfied: lightgbm in /usr/local/lib/python3.6/dist-packages (2.3.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from lightgbm) (1.19.5)
Requirement already satisfied: scipy in /usr/local/lib/python3.6/dist-packages (from lightgbm) (1.5.4)
Requirement already satisfied: scikit-learn in /usr/local/lib/python3.6/dist-packages (from lightgbm) (0.24.2)
Requirement already satisfied: joblib&gt;=0.11 in /usr/local/lib/python3.6/dist-packages (from scikit-learn-&gt;lightgbm) (1.1.0)
Requirement already satisfied: threadpoolctl&gt;=2.0.0 in /usr/local/lib/python3.6/dist-packages (from scikit-learn-&gt;lightgbm) (3.1.0)
WARNING: Running pip as the &#39;root&#39; user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: <a href="https://pip.pypa.io/warnings/venv">https://pip.pypa.io/warnings/venv</a></p>
<p>[64]:</p>
<p>from lightgbm import LGBMClassifier</p>
<p>[65]:</p>
<p>lgbm = LGBMClassifier(n_estimators=3, random_state=42) </p>
<p>lgbm.fit(X_train, y_train)</p>
<p>[65]:</p>
<p>LGBMClassifier(n_estimators=3, random_state=42)</p>
<p>[66]:</p>
<p>lgbm_pred = lgbm.predict(X_test)</p>
<p>[67]:</p>
<p>recall_eval(&#39;LGBM&#39;, lgbm_pred, y_test)</p>
<pre><code>               model     recall</code></pre><p>0     LogisticRegression  56.071429
1           DecisionTree  55.714286
2     K-Nearest Neighbor  52.142857
3  RandomForest Ensemble  52.142857
4                XGBoost  48.214286
5                   LGBM   0.000000</p>
<Figure size 864x648 with 0 Axes>

<p>[68]:</p>
<h1 id="정확도는-73-정도-나온다">정확도는 73% 정도 나온다.</h1>
<p>lgbm.score(X_test, y_test)</p>
<p>[68]:</p>
<p>0.7344713134186819</p>
<p>[69]:</p>
<h1 id="재현율-0으로-나온다">재현율 0으로 나온다.</h1>
<p>recall_score(y_test, lgbm_pred) </p>
<p>[69]:</p>
<p>0.0</p>
<ol start="2">
<li>재현율 성능이 너무 안나온다. 어떻게 해결할수 있을까?</li>
</ol>
<p>[ ]:</p>
<p>​</p>
<p>배운 내용 정리</p>
<ol>
<li><p>머신러닝 모델 프로세스
① 라이브러리 임포트(import)
② 데이터 가져오기(Loading the data)
③ 탐색적 데이터 분석(Exploratory Data Analysis)
④ 데이터 전처리(Data PreProcessing) : 데이터타입 변환, Null 데이터 처리, 누락데이터 처리, 더미특성 생성, 특성 추출 (feature engineering) 등
⑤ Train, Test 데이터셋 분할
⑥ 데이터 정규화(Normalizing the Data)
⑦ 모델 개발(Creating the Model)
⑧ 모델 성능 평가</p>
</li>
<li><p>평가 지표 활용 : 모델별 성능 확인을 위한 함수 (가져다 쓰면 된다)</p>
</li>
<li><p>단일 회귀예측 모델 : LogisticRegression, KNN, DecisionTree</p>
</li>
<li><p>앙상블 (Ensemble) : RandomForest, XGBoost, LGBM</p>
</li>
<li><p>재현율 성능이 너무 안나온다. 어떻게 해결할수 있을까?</p>
</li>
</ol>
<p>[ ]:</p>
<p>​</p>
<p>D:\바탕화면_2021\ETC A2Z\2022 코딩챌린지<em>및</em>계발\10. 2023 AICE Associate 교육</p>
<p>[실습-퀴즈] Python을 활용한 AI 모델링 - 딥러닝 파트</p>
<p>·         이번시간에는 Python을 활용한 AI 모델링에서 딥러닝에 대해 실습해 보겠습니다.</p>
<p>·         여기서는 딥러닝 모델 DNN에 대해 코딩하여 모델 구축해 보겠습니다.</p>
<p>·         한가지 당부 드리고 싶은 말은 &quot;백문이불여일타&quot; 입니다.</p>
<p>·         이론보다 실습이 더 많은 시간과 노력이 투자 되어야 합니다.</p>
<p>학습목차</p>
<ol>
<li>딥러닝 심층신경망(DNN) 모델 프로세스</li>
</ol>
<p>·         데이터 가져오기</p>
<p>·         데이터 전처리</p>
<p>·         Train, Test 데이터셋 분할</p>
<p>·         데이터 정규화</p>
<p>·         DNN 딥러닝 모델</p>
<ol start="2">
<li><p>재현율 성능이 좋지 않다. 어떻게 성능향상 할수 있나?</p>
</li>
<li><p>딥러닝 심층신경망(DNN) 모델 프로세스</p>
</li>
</ol>
<p>① 라이브러리 임포트(import)</p>
<p>② 데이터 가져오기(Loading the data)</p>
<p>③ 탐색적 데이터 분석(Exploratory Data Analysis)</p>
<p>④ 데이터 전처리(Data PreProcessing) : 데이터타입 변환, Null 데이터 처리, 누락데이터 처리, 더미특성 생성, 특성 추출 (feature engineering) 등</p>
<p>⑤ Train, Test 데이터셋 분할</p>
<p>⑥ 데이터 정규화(Normalizing the Data)</p>
<p>⑦ 모델 개발(Creating the Model)</p>
<p>⑧ 모델 성능 평가</p>
<p>① 라이브러리 임포트</p>
<p>필요 라이브러리 임포트</p>
<p>[1]:</p>
<p>import numpy as np</p>
<p>import pandas as pd</p>
<p>import matplotlib.pyplot as plt</p>
<p>Duplicate key in file PosixPath(&#39;/usr/local/lib/python3.6/dist-packages/matplotlib/mpl-data/matplotlibrc&#39;), line 758 (&#39;font.family\t: NanumGothicCoding&#39;)</p>
<p>② 데이터 로드</p>
<p>[문제] 같은 폴더내에 있는 data_v1_save.csv 파일을 Pandas read_csv 함수를 이용하여 읽어 df 변수에 저장하세요. </p>
<p>[2]:</p>
<h1 id="읽어-들일-파일명--data_v1_savecsv">읽어 들일 파일명 : data_v1_save.csv</h1>
<h1 id="pandas-read_csv-함수-활용-1">Pandas read_csv 함수 활용</h1>
<h1 id="결과--df-저장-1">결과 : df 저장</h1>
<p>​</p>
<p>​</p>
<p>df = pd.read_csv(&#39;(라이브교육)data_v1_save.csv&#39;)</p>
<p>③ 데이터 분석</p>
<p>[3]:</p>
<h1 id="17컬럼-7027-라인-1">17컬럼, 7027 라인</h1>
<p>df.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;
RangeIndex: 7027 entries, 0 to 7026
Data columns (total 17 columns):</p>
<h1 id="column------------non-null-count--dtype-7">Column            Non-Null Count  Dtype</h1>
<hr>
<p> 0   gender            7027 non-null   object
 1   Partner           7027 non-null   object
 2   Dependents        7027 non-null   object
 3   tenure            7027 non-null   int64 
 4   MultipleLines     7027 non-null   object
 5   InternetService   7027 non-null   object
 6   OnlineSecurity    7027 non-null   object
 7   OnlineBackup      7027 non-null   object
 8   TechSupport       7027 non-null   object
 9   StreamingTV       7027 non-null   object
 10  StreamingMovies   7027 non-null   object
 11  Contract          7027 non-null   object
 12  PaperlessBilling  7027 non-null   object
 13  PaymentMethod     7027 non-null   object
 14  MonthlyCharges    7027 non-null   float64
15  TotalCharges      7027 non-null   float64
16  Churn             7027 non-null   int64 
dtypes: float64(2), int64(2), object(13)
memory usage: 933.4+ KB</p>
<p>[4]:</p>
<p>df.tail()</p>
<p>[4]:</p>
<p>gender</p>
<p>Partner</p>
<p>Dependents</p>
<p>tenure</p>
<p>MultipleLines</p>
<p>InternetService</p>
<p>OnlineSecurity</p>
<p>OnlineBackup</p>
<p>TechSupport</p>
<p>StreamingTV</p>
<p>StreamingMovies</p>
<p>Contract</p>
<p>PaperlessBilling</p>
<p>PaymentMethod</p>
<p>MonthlyCharges</p>
<p>TotalCharges</p>
<p>Churn</p>
<p>7022</p>
<p>Female</p>
<p>No</p>
<p>No</p>
<p>72</p>
<p>No</p>
<p>No</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>No internet service</p>
<p>Two year</p>
<p>Yes</p>
<p>Bank transfer (automatic)</p>
<p>21.15</p>
<p>1419.40</p>
<p>0</p>
<p>7023</p>
<p>Male</p>
<p>Yes</p>
<p>Yes</p>
<p>24</p>
<p>Yes</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>Yes</p>
<p>Yes</p>
<p>One year</p>
<p>Yes</p>
<p>Mailed check</p>
<p>84.80</p>
<p>1990.50</p>
<p>0</p>
<p>7024</p>
<p>Female</p>
<p>Yes</p>
<p>Yes</p>
<p>72</p>
<p>Yes</p>
<p>Fiber optic</p>
<p>No</p>
<p>Yes</p>
<p>No</p>
<p>Yes</p>
<p>Yes</p>
<p>One year</p>
<p>Yes</p>
<p>Credit card (automatic)</p>
<p>103.20</p>
<p>7362.90</p>
<p>0</p>
<p>7025</p>
<p>Female</p>
<p>Yes</p>
<p>Yes</p>
<p>11</p>
<p>No phone service</p>
<p>DSL</p>
<p>Yes</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Electronic check</p>
<p>29.60</p>
<p>346.45</p>
<p>0</p>
<p>7026</p>
<p>Male</p>
<p>Yes</p>
<p>No</p>
<p>4</p>
<p>Yes</p>
<p>Fiber optic</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>No</p>
<p>Month-to-month</p>
<p>Yes</p>
<p>Mailed check</p>
<p>74.40</p>
<p>306.60</p>
<p>1</p>
<p>[5]:</p>
<h1 id="churn-레이블-불균형-1">Churn 레이블 불균형</h1>
<p>df[&#39;Churn&#39;].value_counts().plot(kind=&#39;bar&#39;)</p>
<p>[5]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>④ 데이터 전처리</p>
<p>·         모든 데이터값들은 숫자형으로 되어야 한다. 즉, Ojbect 타입을 모든 숫자형 변경 필요</p>
<p>·         Object 컬럼에 대해 Pandas get_dummies 함수 활용하여 One-Hot-Encoding</p>
<p>[6]:</p>
<h1 id="object-컬럼명-수집-1">Object 컬럼명 수집</h1>
<p>​</p>
<p>cal_cols = df.select_dtypes(&#39;object&#39;).columns.values</p>
<p>cal_cols</p>
<p>[6]:</p>
<p>array([&#39;gender&#39;, &#39;Partner&#39;, &#39;Dependents&#39;, &#39;MultipleLines&#39;,
       &#39;InternetService&#39;, &#39;OnlineSecurity&#39;, &#39;OnlineBackup&#39;, &#39;TechSupport&#39;,
       &#39;StreamingTV&#39;, &#39;StreamingMovies&#39;, &#39;Contract&#39;, &#39;PaperlessBilling&#39;,
       &#39;PaymentMethod&#39;], dtype=object)</p>
<p>[문제] Object 컬럼에 대해 One-Hot-Encoding 수행하고 그 결과를 df1 변수에 저장하세요. </p>
<p>[7]:</p>
<h1 id="pandas-get_dummies-함수-이용-1">Pandas get_dummies() 함수 이용</h1>
<h1 id="원-핫-인코딩-결과를-df1-저장-1">원-핫-인코딩 결과를 df1 저장</h1>
<p>​</p>
<p>​</p>
<p>df1 = pd.get_dummies(data = df, columns = cal_cols)</p>
<p>[8]:</p>
<h1 id="40컬럼-7026-라인">40컬럼, 7026 라인</h1>
<p>df1.info()</p>
<p>&lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;
RangeIndex: 7027 entries, 0 to 7026
Data columns (total 40 columns):</p>
<h1 id="column-----------------------------------non-null-count--dtype-1">Column                                   Non-Null Count  Dtype</h1>
<hr>
<p> 0   tenure                                   7027 non-null   int64 
 1   MonthlyCharges                           7027 non-null   float64
2   TotalCharges                             7027 non-null   float64
3   Churn                                    7027 non-null   int64 
 4   gender_Female                            7027 non-null   uint8 
 5   gender_Male                              7027 non-null   uint8 
 6   Partner_No                               7027 non-null   uint8 
 7   Partner_Yes                              7027 non-null   uint8 
 8   Dependents_No                            7027 non-null   uint8 
 9   Dependents_Yes                           7027 non-null   uint8 
 10  MultipleLines_No                         7027 non-null   uint8 
 11  MultipleLines_No phone service           7027 non-null   uint8 
 12  MultipleLines_Yes                        7027 non-null   uint8 
 13  InternetService_DSL                      7027 non-null   uint8 
 14  InternetService_Fiber optic              7027 non-null   uint8 
 15  InternetService_No                       7027 non-null   uint8 
 16  OnlineSecurity_No                        7027 non-null   uint8 
 17  OnlineSecurity_No internet service       7027 non-null   uint8 
 18  OnlineSecurity_Yes                       7027 non-null   uint8 
 19  OnlineBackup_No                          7027 non-null   uint8 
 20  OnlineBackup_No internet service         7027 non-null   uint8 
 21  OnlineBackup_Yes                         7027 non-null   uint8 
 22  TechSupport_No                           7027 non-null   uint8 
 23  TechSupport_No internet service          7027 non-null   uint8 
 24  TechSupport_Yes                          7027 non-null   uint8 
 25  StreamingTV_No                           7027 non-null   uint8 
 26  StreamingTV_No internet service          7027 non-null   uint8 
 27  StreamingTV_Yes                          7027 non-null   uint8 
 28  StreamingMovies_No                       7027 non-null   uint8 
 29  StreamingMovies_No internet service      7027 non-null   uint8 
 30  StreamingMovies_Yes                      7027 non-null   uint8 
 31  Contract_Month-to-month                  7027 non-null   uint8 
 32  Contract_One year                        7027 non-null   uint8 
 33  Contract_Two year                        7027 non-null   uint8 
 34  PaperlessBilling_No                      7027 non-null   uint8 
 35  PaperlessBilling_Yes                     7027 non-null   uint8 
 36  PaymentMethod_Bank transfer (automatic)  7027 non-null   uint8 
 37  PaymentMethod_Credit card (automatic)    7027 non-null   uint8 
 38  PaymentMethod_Electronic check           7027 non-null   uint8 
 39  PaymentMethod_Mailed check               7027 non-null   uint8 
dtypes: float64(2), int64(2), uint8(36)
memory usage: 466.8 KB</p>
<p>⑤ Train, Test 데이터셋 분할</p>
<p>[10]:</p>
<p>from sklearn.model_selection import train_test_split</p>
<p>[11]:</p>
<p>X = df1.drop(&#39;Churn&#39;, axis=1).values</p>
<p>y = df1[&#39;Churn&#39;].values</p>
<p>[12]:</p>
<p>X_train, X_test, y_train, y_test = train_test_split(X, y,</p>
<pre><code>                                                test_size=0.3,

                                                stratify=y,

                                                random_state=42)</code></pre><p>[13]:</p>
<p>X_train.shape</p>
<p>[13]:</p>
<p>(4918, 39)</p>
<p>[14]:</p>
<p>y_train.shape</p>
<p>[14]:</p>
<p>(4918,)</p>
<p>⑥ 데이터 정규화/스케일링(Normalizing/Scaling)</p>
<p>[15]:</p>
<h1 id="숫자-분포-이루어진-컬럼-확인-1">숫자 분포 이루어진 컬럼 확인</h1>
<p>df1.tail()</p>
<p>[15]:</p>
<p>tenure</p>
<p>MonthlyCharges</p>
<p>TotalCharges</p>
<p>Churn</p>
<p>gender_Female</p>
<p>gender_Male</p>
<p>Partner_No</p>
<p>Partner_Yes</p>
<p>Dependents_No</p>
<p>Dependents_Yes</p>
<p>...</p>
<p>StreamingMovies_Yes</p>
<p>Contract_Month-to-month</p>
<p>Contract_One year</p>
<p>Contract_Two year</p>
<p>PaperlessBilling_No</p>
<p>PaperlessBilling_Yes</p>
<p>PaymentMethod_Bank transfer (automatic)</p>
<p>PaymentMethod_Credit card (automatic)</p>
<p>PaymentMethod_Electronic check</p>
<p>PaymentMethod_Mailed check</p>
<p>7022</p>
<p>72</p>
<p>21.15</p>
<p>1419.40</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>...</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>7023</p>
<p>24</p>
<p>84.80</p>
<p>1990.50</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>...</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>7024</p>
<p>72</p>
<p>103.20</p>
<p>7362.90</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>...</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>7025</p>
<p>11</p>
<p>29.60</p>
<p>346.45</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>...</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>7026</p>
<p>4</p>
<p>74.40</p>
<p>306.60</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>1</p>
<p>1</p>
<p>0</p>
<p>...</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>0</p>
<p>0</p>
<p>0</p>
<p>1</p>
<p>5 rows × 40 columns</p>
<p>[16]:</p>
<p>from sklearn.preprocessing import MinMaxScaler</p>
<p>[17]:</p>
<p>scaler = MinMaxScaler()</p>
<p>X_train = scaler.fit_transform(X_train)</p>
<p>X_test = scaler.transform(X_test)</p>
<p>[18]:</p>
<p>X_train[:2]</p>
<p>[18]:</p>
<p>array([[0.65277778, 0.56851021, 0.40877722, 1.        , 0.        ,
        1.        , 0.        , 1.        , 0.        , 1.        ,
        0.        , 0.        , 0.        , 1.        , 0.        ,
        0.        , 0.        , 1.        , 1.        , 0.        ,
        0.        , 1.        , 0.        , 0.        , 1.        ,
        0.        , 0.        , 1.        , 0.        , 0.        ,
        1.        , 0.        , 0.        , 1.        , 0.        ,
        0.        , 1.        , 0.        , 0.        ],
       [0.27777778, 0.00498256, 0.04008671, 1.        , 0.        ,
        1.        , 0.        , 1.        , 0.        , 1.        ,
        0.        , 0.        , 0.        , 0.        , 1.        ,
        0.        , 1.        , 0.        , 0.        , 1.        ,
        0.        , 0.        , 1.        , 0.        , 0.        ,
        1.        , 0.        , 0.        , 1.        , 0.        ,
        1.        , 0.        , 0.        , 0.        , 1.        ,
        0.        , 1.        , 0.        , 0.        ]])</p>
<p>⑦ 딥러닝 심층신경망(DNN) 모델 구현</p>
<p>라이브러리 임포트</p>
<p>[19]:</p>
<p>import tensorflow as tf</p>
<p>from tensorflow.keras.models import Sequential</p>
<p>from tensorflow.keras.layers import Dense, Dropout</p>
<p>​</p>
<p>tf.random.set_seed(100)</p>
<p>하이퍼파라미터 설정 : batch_size, epochs</p>
<p>[20]:</p>
<p>batch_size = 16</p>
<p>epochs = 20</p>
<p>모델 입력(features) 갯수 확인</p>
<p>[21]:</p>
<p>X_train.shape</p>
<p>[21]:</p>
<p>(4918, 39)</p>
<p>모델 출력(label) 갯수 확인</p>
<p>[22]:</p>
<p>y_train.shape</p>
<p>[22]:</p>
<p>(4918,)</p>
<p>A. 이진분류 DNN모델 구성</p>
<p>hidden Layer</p>
<p>·         [출처] <a href="https://subscription.packtpub.com/book/data/9781788995207/1/ch01lvl1sec03/deep-learning-intuition">https://subscription.packtpub.com/book/data/9781788995207/1/ch01lvl1sec03/deep-learning-intuition</a></p>
<p>[문제] 요구사항대로 Sequential 모델을 만들어 보세요. </p>
<p>[23]:</p>
<h1 id="sequential-모델-정의-하고-model로-저장">Sequential() 모델 정의 하고 model로 저장</h1>
<h1 id="input-layer는-input_shape-옵션을-사용한다">input layer는 input_shape=() 옵션을 사용한다.</h1>
<h1 id="39개-input-layer">39개 input layer</h1>
<h1 id="unit-4개-hidden-layer">unit 4개 hidden layer</h1>
<h1 id="unit-3개-hidden-layer">unit 3개 hidden layer</h1>
<h1 id="1개-output-layser--이진분류">1개 output layser : 이진분류</h1>
<p>​</p>
<p>model = Sequential()</p>
<p>model.add(Dense(4, activation = &#39;relu&#39;, input_shape = (39,)))</p>
<p>model.add(Dense(3, activation = &#39;relu&#39;))</p>
<p>model.add(Dense(1, activation = &#39;sigmoid&#39;))</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>모델 확인</p>
<p>[24]:</p>
<p>model.summary()</p>
<p>Model: &quot;sequential&quot;</p>
<hr>
<h1 id="layer-type-----------------output-shape--------------param-">Layer (type)                 Output Shape              Param #  </h1>
<p>dense (Dense)                (None, 4)                 160      </p>
<hr>
<p>dense_1 (Dense)              (None, 3)                 15       </p>
<hr>
<h1 id="dense_2-dense--------------none-1-----------------4">dense_2 (Dense)              (None, 1)                 4        </h1>
<p>Total params: 179
Trainable params: 179
Non-trainable params: 0</p>
<hr>
<p>모델 구성 - 과적합 방지</p>
<p>dropout</p>
<p>·         [출처] <a href="https://medium.com/@amarbudhiraja/https-medium-com-amarbudhiraja-learning-less-to-learn-better-dropout-in-deep-machine-learning-74334da4bfc5">https://medium.com/@amarbudhiraja/https-medium-com-amarbudhiraja-learning-less-to-learn-better-dropout-in-deep-machine-learning-74334da4bfc5</a></p>
<p>[25]:</p>
<p>model = Sequential()</p>
<p>​</p>
<p>model.add(Dense(4, activation=&#39;relu&#39;, input_shape=(39,)))</p>
<p>model.add(Dropout(0.3))</p>
<p>​</p>
<p>model.add(Dense(3, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>​</p>
<p>model.add(Dense(1, activation=&#39;sigmoid&#39;))</p>
<p>과적합 방지 모델 확인</p>
<p>[26]:</p>
<p>model.summary()</p>
<p>Model: &quot;sequential_1&quot;</p>
<hr>
<h1 id="layer-type-----------------output-shape--------------param--1">Layer (type)                 Output Shape              Param #  </h1>
<p>dense_3 (Dense)              (None, 4)                 160      </p>
<hr>
<p>dropout (Dropout)            (None, 4)                 0        </p>
<hr>
<p>dense_4 (Dense)              (None, 3)                 15       </p>
<hr>
<p>dropout_1 (Dropout)          (None, 3)                 0        </p>
<hr>
<h1 id="dense_5-dense--------------none-1-----------------4">dense_5 (Dense)              (None, 1)                 4        </h1>
<p>Total params: 179
Trainable params: 179
Non-trainable params: 0</p>
<hr>
<p>모델 컴파일 – 이진 분류 모델</p>
<p>[27]:</p>
<p>model.compile(optimizer=&#39;adam&#39;,</p>
<pre><code>          loss=&#39;binary_crossentropy&#39;,

          metrics=[&#39;accuracy&#39;])</code></pre><p>·         모델 컴파일 – 다중 분류 모델 (Y값을 One-Hot-Encoding 한경우)
model.compile(optimizer=&#39;adam&#39;, loss=&#39;categorical_crossentropy&#39;, metrics=[&#39;accuracy&#39;])</p>
<p>·         모델 컴파일 – 다중 분류 모델 (Y값을 One-Hot-Encoding 하지 않은 경우)
model.compile(optimizer=&#39;adam&#39;, loss=&#39;sparse_categorical_crossentropy&#39;, metrics=[&#39;accuracy&#39;])</p>
<p>·         모델 컴파일 – 예측 모델 model.compile(optimizer=&#39;adam&#39;, loss=&#39;mse&#39;)</p>
<p>모델 학습</p>
<p>[문제] 요구사항대로 DNN 모델을 학습시키세요. </p>
<p>·         모델 이름 : model</p>
<p>·         epoch : 10번</p>
<p>·         batch_size : 10번</p>
<p>[28]:</p>
<h1 id="앞쪽에서-정의된-모델-이름--model">앞쪽에서 정의된 모델 이름 : model</h1>
<h1 id="sequential-모델의-fit-함수-사용">Sequential 모델의 fit() 함수 사용</h1>
<h1 id="인자">@인자</h1>
<h3 id="x-y--x_train-y_train">X, y : X_train, y_train</h3>
<h3 id="validation_datax_test-y_test">validation_data=(X_test, y_test)</h3>
<h3 id="epochs-10번">epochs 10번</h3>
<h3 id="batch_size-10번">batch_size 10번</h3>
<p>​</p>
<p>​</p>
<p>​</p>
<p>​</p>
<p>model.fit(X_train, y_train, validation_data = (X_test, y_test), epochs = 10, batch_size = 10)</p>
<p>​</p>
<p>Epoch 1/10
492/492 [==============================] - 2s 3ms/step - loss: 0.6015 - accuracy: 0.7318 - val_loss: 0.5247 - val_accuracy: 0.7345
Epoch 2/10
492/492 [==============================] - 2s 3ms/step - loss: 0.5439 - accuracy: 0.7416 - val_loss: 0.4802 - val_accuracy: 0.7345
Epoch 3/10
492/492 [==============================] - 1s 3ms/step - loss: 0.5225 - accuracy: 0.7548 - val_loss: 0.4734 - val_accuracy: 0.7345
Epoch 4/10
492/492 [==============================] - 2s 4ms/step - loss: 0.5139 - accuracy: 0.7623 - val_loss: 0.4646 - val_accuracy: 0.7364
Epoch 5/10
492/492 [==============================] - 2s 3ms/step - loss: 0.5153 - accuracy: 0.7554 - val_loss: 0.4651 - val_accuracy: 0.7368
Epoch 6/10
492/492 [==============================] - 1s 3ms/step - loss: 0.5016 - accuracy: 0.7674 - val_loss: 0.4550 - val_accuracy: 0.7653
Epoch 7/10
492/492 [==============================] - 1s 3ms/step - loss: 0.5042 - accuracy: 0.7593 - val_loss: 0.4532 - val_accuracy: 0.7496
Epoch 8/10
492/492 [==============================] - 1s 3ms/step - loss: 0.4989 - accuracy: 0.7633 - val_loss: 0.4536 - val_accuracy: 0.7620
Epoch 9/10
492/492 [==============================] - 1s 3ms/step - loss: 0.5035 - accuracy: 0.7609 - val_loss: 0.4553 - val_accuracy: 0.7539
Epoch 10/10
492/492 [==============================] - 1s 3ms/step - loss: 0.5023 - accuracy: 0.7588 - val_loss: 0.4567 - val_accuracy: 0.7544</p>
<p>[28]:</p>
<p>&lt;keras.callbacks.History at 0x7fe61404f908&gt;</p>
<p>B. 다중 분류 DNN 구성</p>
<p>·         13개 input layer</p>
<p>·         unit 5개 hidden layer</p>
<p>·         dropout</p>
<p>·         unit 4개 hidden layer</p>
<p>·         dropout</p>
<p>·         2개 output layser : 이진분류</p>
<p>다중분류</p>
<p>·         [출처] <a href="https://www.educba.com/dnn-neural-network/">https://www.educba.com/dnn-neural-network/</a></p>
<p>[29]:</p>
<h1 id="39개-input-layer-1">39개 input layer</h1>
<h1 id="unit-5개-hidden-layer">unit 5개 hidden layer</h1>
<h1 id="dropout">dropout</h1>
<h1 id="unit-4개-hidden-layer-1">unit 4개 hidden layer</h1>
<h1 id="dropout-1">dropout</h1>
<h1 id="2개-output-layser--다중분류">2개 output layser : 다중분류</h1>
<p>​</p>
<p>model = Sequential()</p>
<p>model.add(Dense(5, activation=&#39;relu&#39;, input_shape=(39,)))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(4, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(2, activation=&#39;softmax&#39;))</p>
<p>모델 확인</p>
<p>[30]:</p>
<p>model.summary()</p>
<p>Model: &quot;sequential_2&quot;</p>
<hr>
<h1 id="layer-type-----------------output-shape--------------param--2">Layer (type)                 Output Shape              Param #   </h1>
<p>dense_6 (Dense)              (None, 5)                 200      </p>
<hr>
<p>dropout_2 (Dropout)          (None, 5)                 0        </p>
<hr>
<p>dense_7 (Dense)              (None, 4)                 24       </p>
<hr>
<p>dropout_3 (Dropout)          (None, 4)                 0        </p>
<hr>
<h1 id="dense_8-dense--------------none-2-----------------10">dense_8 (Dense)              (None, 2)                 10       </h1>
<p>Total params: 234
Trainable params: 234
Non-trainable params: 0</p>
<hr>
<p>모델 컴파일 – 다중 분류 모델</p>
<p>[31]:</p>
<p>model.compile(optimizer=&#39;adam&#39;,</p>
<pre><code>          loss=&#39;sparse_categorical_crossentropy&#39;,

          metrics=[&#39;accuracy&#39;])</code></pre><p>모델 학습</p>
<p>[32]:</p>
<p>history = model.fit(X_train, y_train,</p>
<pre><code>      validation_data=(X_test, y_test),

      epochs=20,

      batch_size=16)</code></pre><p>Epoch 1/20
308/308 [==============================] - 2s 4ms/step - loss: 0.5507 - accuracy: 0.7322 - val_loss: 0.4708 - val_accuracy: 0.7345
Epoch 2/20
308/308 [==============================] - 1s 4ms/step - loss: 0.5011 - accuracy: 0.7351 - val_loss: 0.4540 - val_accuracy: 0.7345
Epoch 3/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4894 - accuracy: 0.7338 - val_loss: 0.4482 - val_accuracy: 0.7345
Epoch 4/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4916 - accuracy: 0.7344 - val_loss: 0.4455 - val_accuracy: 0.7345
Epoch 5/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4850 - accuracy: 0.7340 - val_loss: 0.4420 - val_accuracy: 0.7345
Epoch 6/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4899 - accuracy: 0.7342 - val_loss: 0.4447 - val_accuracy: 0.7345
Epoch 7/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4749 - accuracy: 0.7344 - val_loss: 0.4360 - val_accuracy: 0.7345
Epoch 8/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4779 - accuracy: 0.7342 - val_loss: 0.4374 - val_accuracy: 0.7345
Epoch 9/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4744 - accuracy: 0.7340 - val_loss: 0.4358 - val_accuracy: 0.7345
Epoch 10/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4808 - accuracy: 0.7344 - val_loss: 0.4379 - val_accuracy: 0.7345
Epoch 11/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4761 - accuracy: 0.7344 - val_loss: 0.4379 - val_accuracy: 0.7345
Epoch 12/20
308/308 [==============================] - 1s 4ms/step - loss: 0.4679 - accuracy: 0.7344 - val_loss: 0.4340 - val_accuracy: 0.7345
Epoch 13/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4712 - accuracy: 0.7617 - val_loss: 0.4358 - val_accuracy: 0.7824
Epoch 14/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4790 - accuracy: 0.7489 - val_loss: 0.4388 - val_accuracy: 0.7691
Epoch 15/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4760 - accuracy: 0.7637 - val_loss: 0.4360 - val_accuracy: 0.7345
Epoch 16/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4759 - accuracy: 0.7527 - val_loss: 0.4391 - val_accuracy: 0.7710
Epoch 17/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4739 - accuracy: 0.7562 - val_loss: 0.4375 - val_accuracy: 0.7904
Epoch 18/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4668 - accuracy: 0.7605 - val_loss: 0.4348 - val_accuracy: 0.7985
Epoch 19/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4695 - accuracy: 0.7674 - val_loss: 0.4330 - val_accuracy: 0.7899
Epoch 20/20
308/308 [==============================] - 1s 3ms/step - loss: 0.4758 - accuracy: 0.7684 - val_loss: 0.4345 - val_accuracy: 0.7876</p>
<p>Callback : 조기종료, 모델 저장</p>
<p>[ ]:</p>
<p>from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint</p>
<p>[ ]:</p>
<h1 id="val_loss-모니터링해서-성능이-5번-지나도록-좋아지지-않으면-조기-종료">val_loss 모니터링해서 성능이 5번 지나도록 좋아지지 않으면 조기 종료</h1>
<p>early_stop = EarlyStopping(monitor=&#39;val_loss&#39;, mode=&#39;min&#39;,</p>
<pre><code>                       verbose=1, patience=5)</code></pre><p>[ ]:</p>
<h1 id="val_loss-가장-낮은-값을-가질때마다-모델저장">val_loss 가장 낮은 값을 가질때마다 모델저장</h1>
<p>check_point = ModelCheckpoint(&#39;best_model.h5&#39;, verbose=1,</p>
<pre><code>                          monitor=&#39;val_loss&#39;, mode=&#39;min&#39;, save_best_only=True)</code></pre><p>모델 학습</p>
<p>[ ]:</p>
<p>history = model.fit(x=X_train, y=y_train,</p>
<pre><code>      epochs=50 , batch_size=20,

      validation_data=(X_test, y_test), verbose=1,

      callbacks=[early_stop, check_point])</code></pre><p>Epoch 1/50
231/246 [===========================&gt;..] - ETA: 0s - loss: 0.4702 - accuracy: 0.7712
Epoch 1: val_loss improved from inf to 0.43752, saving model to best_model.h5
246/246 [==============================] - 1s 2ms/step - loss: 0.4726 - accuracy: 0.7686 - val_loss: 0.4375 - val_accuracy: 0.7956
Epoch 2/50
241/246 [============================&gt;.] - ETA: 0s - loss: 0.4734 - accuracy: 0.7587
Epoch 2: val_loss improved from 0.43752 to 0.43419, saving model to best_model.h5
246/246 [==============================] - 1s 2ms/step - loss: 0.4727 - accuracy: 0.7603 - val_loss: 0.4342 - val_accuracy: 0.7966
Epoch 3/50
239/246 [============================&gt;.] - ETA: 0s - loss: 0.4754 - accuracy: 0.7692
Epoch 3: val_loss did not improve from 0.43419
246/246 [==============================] - 1s 2ms/step - loss: 0.4733 - accuracy: 0.7698 - val_loss: 0.4343 - val_accuracy: 0.7923
Epoch 4/50
241/246 [============================&gt;.] - ETA: 0s - loss: 0.4699 - accuracy: 0.7645
Epoch 4: val_loss improved from 0.43419 to 0.43329, saving model to best_model.h5
246/246 [==============================] - 1s 2ms/step - loss: 0.4688 - accuracy: 0.7647 - val_loss: 0.4333 - val_accuracy: 0.7975
Epoch 5/50
218/246 [=========================&gt;....] - ETA: 0s - loss: 0.4628 - accuracy: 0.7743
Epoch 5: val_loss improved from 0.43329 to 0.43201, saving model to best_model.h5
246/246 [==============================] - 1s 2ms/step - loss: 0.4633 - accuracy: 0.7694 - val_loss: 0.4320 - val_accuracy: 0.7980
Epoch 6/50
234/246 [===========================&gt;..] - ETA: 0s - loss: 0.4799 - accuracy: 0.7650
Epoch 6: val_loss did not improve from 0.43201
246/246 [==============================] - 1s 2ms/step - loss: 0.4783 - accuracy: 0.7629 - val_loss: 0.4376 - val_accuracy: 0.7980
Epoch 7/50
240/246 [============================&gt;.] - ETA: 0s - loss: 0.4704 - accuracy: 0.7675
Epoch 7: val_loss did not improve from 0.43201
246/246 [==============================] - 1s 2ms/step - loss: 0.4691 - accuracy: 0.7676 - val_loss: 0.4331 - val_accuracy: 0.7961
Epoch 8/50
226/246 [==========================&gt;...] - ETA: 0s - loss: 0.4679 - accuracy: 0.7710
Epoch 8: val_loss did not improve from 0.43201
246/246 [==============================] - 1s 3ms/step - loss: 0.4706 - accuracy: 0.7700 - val_loss: 0.4369 - val_accuracy: 0.7985
Epoch 9/50
222/246 [==========================&gt;...] - ETA: 0s - loss: 0.4734 - accuracy: 0.7716
Epoch 9: val_loss did not improve from 0.43201
246/246 [==============================] - 1s 2ms/step - loss: 0.4734 - accuracy: 0.7674 - val_loss: 0.4357 - val_accuracy: 0.7980
Epoch 10/50
221/246 [=========================&gt;....] - ETA: 0s - loss: 0.4707 - accuracy: 0.7667
Epoch 10: val_loss did not improve from 0.43201
246/246 [==============================] - 1s 2ms/step - loss: 0.4718 - accuracy: 0.7670 - val_loss: 0.4337 - val_accuracy: 0.7999
Epoch 10: early stopping</p>
<p>⑧ 모델 성능 평가</p>
<p>[33]:</p>
<p>losses = pd.DataFrame(model.history.history)</p>
<p>[34]:</p>
<p>losses.head()</p>
<p>[34]:</p>
<p>loss</p>
<p>accuracy</p>
<p>val_loss</p>
<p>val_accuracy</p>
<p>0</p>
<p>0.550660</p>
<p>0.732208</p>
<p>0.470834</p>
<p>0.734471</p>
<p>1</p>
<p>0.501130</p>
<p>0.735055</p>
<p>0.453986</p>
<p>0.734471</p>
<p>2</p>
<p>0.489383</p>
<p>0.733835</p>
<p>0.448154</p>
<p>0.734471</p>
<p>3</p>
<p>0.491561</p>
<p>0.734445</p>
<p>0.445530</p>
<p>0.734471</p>
<p>4</p>
<p>0.484967</p>
<p>0.734038</p>
<p>0.441958</p>
<p>0.734471</p>
<p>성능 시각화</p>
<p>[35]:</p>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;]].plot()</p>
<p>[35]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>[36]:</p>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;, &#39;accuracy&#39;,&#39;val_accuracy&#39;]].plot()</p>
<p>[36]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>[37]:</p>
<p>plt.plot(history.history[&#39;accuracy&#39;])</p>
<p>plt.plot(history.history[&#39;val_accuracy&#39;])</p>
<p>plt.title(&#39;Accuracy&#39;)</p>
<p>plt.xlabel(&#39;Epochs&#39;)</p>
<p>plt.ylabel(&#39;Acc&#39;)</p>
<p>plt.legend([&#39;acc&#39;, &#39;val_acc&#39;])</p>
<p>plt.show()</p>
<p>성능 평가</p>
<p>[38]:</p>
<p>from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score</p>
<p>from sklearn.metrics import classification_report</p>
<p>[39]:</p>
<p>pred = model.predict(X_test)</p>
<p>[40]:</p>
<p>pred.shape</p>
<p>[40]:</p>
<p>(2109, 2)</p>
<p>[41]:</p>
<p>y_pred = np.argmax(pred, axis=1)</p>
<p>[42]:</p>
<h1 id="정확도-80">정확도 80%</h1>
<p>accuracy_score(y_test, y_pred)</p>
<p>[42]:</p>
<p>0.7875770507349454</p>
<p>[43]:</p>
<h1 id="재현율-성능이-좋지-않다">재현율 성능이 좋지 않다</h1>
<p>recall_score(y_test, y_pred)</p>
<p>[43]:</p>
<p>0.3464285714285714</p>
<p>[44]:</p>
<h1 id="accuracy-recall-precision-성능-한번에-보기">accuracy, recall, precision 성능 한번에 보기</h1>
<p>​</p>
<p>print(classification_report(y_test, y_pred))</p>
<pre><code>          precision    recall  f1-score   support</code></pre><p>0       0.80      0.95      0.87      1549
           1       0.70      0.35      0.46       560</p>
<p>accuracy                           0.79      2109
   macro avg       0.75      0.65      0.67      2109
weighted avg       0.77      0.79      0.76      2109</p>
<h2 id="-2-재현율-성능이-좋지-않다-어떻게-성능향상-할수-있나"># 2. 재현율 성능이 좋지 않다. 어떻게 성능향상 할수 있나?</h2>
<ul>
<li><p>성능향상 할수 있는 방법은 여러가지 있습니다.</p>
</li>
<li><p>DNN 하이퍼 파라미터 수정하면서 성능향상이 되는지 확인</p>
</li>
<li><p>데이터 줄이거나 늘리거나, Feature(컬럼)을 늘리거나 줄이거나 하는 식의 Feature Engineering 방법</p>
</li>
</ul>
<p>Feature Engineering 통한 성능향상</p>
<p>·         불균현 Churn 데이터 균형 맞추기 : OverSampling, UnderSampling</p>
<p>·         OverSampling 기법 : SMOTE(Synthetic Minority Over-sampling Technique)</p>
<p>·         참조사이트 : <a href="https://datascienceschool.net/03%20machine%20learning/14.02%20%EB%B9%84%EB%8C%80%EC%B9%AD%20%EB%8D%B0%EC%9D%B4%ED%84%B0%20%EB%AC%B8%EC%A0%9C.html">https://datascienceschool.net/03%20machine%20learning/14.02%20%EB%B9%84%EB%8C%80%EC%B9%AD%20%EB%8D%B0%EC%9D%B4%ED%84%B0%20%EB%AC%B8%EC%A0%9C.html</a></p>
<p>SMOTE</p>
<p>imbalanced-learn 패키지 설치</p>
<p>·         imbalanced data 문제를 해결하기 위한 다양한 샘플링 방법을 구현한 파이썬 패키지</p>
<p>[45]:</p>
<p>!pip install -U imbalanced-learn</p>
<p>Looking in indexes: <a href="http://10.220.235.19/pypi/simple">http://10.220.235.19/pypi/simple</a>
Collecting imbalanced-learn
  Downloading <a href="http://10.220.235.19/pypi/packages/19/79/e86c8fd859dca4fb1fbfc61376afc63210177a235a7bfbe7219b02edf8f3/imbalanced_learn-0.9.1-py3-none-any.whl">http://10.220.235.19/pypi/packages/19/79/e86c8fd859dca4fb1fbfc61376afc63210177a235a7bfbe7219b02edf8f3/imbalanced_learn-0.9.1-py3-none-any.whl</a> (199 kB)
     |████████████████████████████████| 199 kB 47.8 MB/s<br>  Downloading <a href="http://10.220.235.19/pypi/packages/83/92/a4d1f42b29e9f62f9c3fad68d28282a9610a02801e1d89945702f981dd8e/imbalanced_learn-0.9.0-py3-none-any.whl">http://10.220.235.19/pypi/packages/83/92/a4d1f42b29e9f62f9c3fad68d28282a9610a02801e1d89945702f981dd8e/imbalanced_learn-0.9.0-py3-none-any.whl</a> (199 kB)
     |████████████████████████████████| 199 kB 105.7 MB/s<br>Requirement already satisfied: scipy&gt;=1.1.0 in /usr/local/lib/python3.6/dist-packages (from imbalanced-learn) (1.5.4)
  Downloading <a href="http://10.220.235.19/pypi/packages/b1/bd/4bb46fb4d317fd0f19aa7463d8906598e5fee073c0842b57cb112f023a45/imbalanced_learn-0.8.1-py3-none-any.whl">http://10.220.235.19/pypi/packages/b1/bd/4bb46fb4d317fd0f19aa7463d8906598e5fee073c0842b57cb112f023a45/imbalanced_learn-0.8.1-py3-none-any.whl</a> (189 kB)
     |████████████████████████████████| 189 kB 90.7 MB/s<br>Requirement already satisfied: scikit-learn&gt;=0.24 in /usr/local/lib/python3.6/dist-packages (from imbalanced-learn) (0.24.2)
Requirement already satisfied: joblib&gt;=0.11 in /usr/local/lib/python3.6/dist-packages (from imbalanced-learn) (1.1.0)
Requirement already satisfied: numpy&gt;=1.13.3 in /usr/local/lib/python3.6/dist-packages (from imbalanced-learn) (1.19.5)
Requirement already satisfied: threadpoolctl&gt;=2.0.0 in /usr/local/lib/python3.6/dist-packages (from scikit-learn&gt;=0.24-&gt;imbalanced-learn) (3.1.0)
Installing collected packages: imbalanced-learn
Successfully installed imbalanced-learn-0.8.1
WARNING: Running pip as the &#39;root&#39; user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: <a href="https://pip.pypa.io/warnings/venv">https://pip.pypa.io/warnings/venv</a></p>
<p>SMOTE 함수 이용하여 Oversampling</p>
<p>[46]:</p>
<p>from imblearn.over_sampling import SMOTE</p>
<p>[47]:</p>
<h1 id="smote-함수-정의-및-oversampling-수행">SMOTE 함수 정의 및 Oversampling 수행</h1>
<p>​</p>
<p>smote = SMOTE(random_state=0)</p>
<p>X_train_over, y_train_over = smote.fit_resample(X_train, y_train)</p>
<p>[48]:</p>
<p>print(&#39;SMOTE 적용 전 학습용 피처/레이블 데이터 세트: &#39;, X_train.shape, y_train.shape)</p>
<p>print(&#39;SMOTE 적용 후 학습용 피처/레이블 데이터 세트: &#39;, X_train_over.shape, y_train_over.shape)</p>
<p>SMOTE 적용 전 학습용 피처/레이블 데이터 세트:  (4918, 39) (4918,)
SMOTE 적용 후 학습용 피처/레이블 데이터 세트:  (7224, 39) (7224,)</p>
<p>[49]:</p>
<h1 id="smote-적용-후-레이블-값-분포--0과-1-갯수가-동일">SMOTE 적용 후 레이블 값 분포 : 0과 1 갯수가 동일</h1>
<p>pd.Series(y_train_over).value_counts()</p>
<p>[49]:</p>
<p>1    3612
0    3612
dtype: int64</p>
<p>데이터 정규화</p>
<p>[50]:</p>
<h1 id="minmaxscaler">MinMaxScaler</h1>
<p>from sklearn.preprocessing import MinMaxScaler</p>
<p>​</p>
<p>scaler = MinMaxScaler()</p>
<p>scaler.fit(X_train)</p>
<p>X_train_over = scaler.transform(X_train_over)</p>
<p>X_test = scaler.transform(X_test)</p>
<p>[51]:</p>
<p>X_train_over.shape, y_train_over.shape, X_test.shape, y_test.shape</p>
<p>[51]:</p>
<p>((7224, 39), (7224,), (2109, 39), (2109,))</p>
<p>모델 개발(Creating the Model)</p>
<p>[52]:</p>
<p>model = Sequential()</p>
<p>model.add(Dense(64, activation=&#39;relu&#39;, input_shape=(39,)))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(32, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(16, activation=&#39;relu&#39;))</p>
<p>model.add(Dropout(0.3))</p>
<p>model.add(Dense(2, activation=&#39;softmax&#39;))</p>
<p>[53]:</p>
<p>model.compile(optimizer=&#39;adam&#39;,</p>
<pre><code>          loss=&#39;sparse_categorical_crossentropy&#39;,

          metrics=[&#39;accuracy&#39;])</code></pre><p>[55]:</p>
<h1 id="여기서는-val_accuracy-모니터링해서-성능이-좋아지지-않으면-조기-종료-하게-함">여기서는 val_accuracy 모니터링해서 성능이 좋아지지 않으면 조기 종료 하게 함.</h1>
<p>from tensorflow.python.keras.callbacks import EarlyStopping</p>
<p>early_stop = EarlyStopping(monitor=&#39;val_accuracy&#39;, mode=&#39;max&#39;,</p>
<pre><code>                       verbose=1, patience=5)</code></pre><p>[56]:</p>
<p>from tensorflow.python.keras.callbacks import ModelCheckpoint</p>
<p>check_point = ModelCheckpoint(&#39;best_model.h5&#39;, verbose=1,</p>
<pre><code>                          monitor=&#39;val_loss&#39;, mode=&#39;min&#39;,

                          save_best_only=True)</code></pre><p>[57]:</p>
<p>history = model.fit(x=X_train_over, y=y_train_over,</p>
<pre><code>      epochs=50 , batch_size=32,

      validation_data=(X_test, y_test), verbose=1,

      callbacks=[early_stop, check_point])</code></pre><p>Epoch 1/50
226/226 [==============================] - 2s 6ms/step - loss: 0.5762 - accuracy: 0.7006 - val_loss: 0.4876 - val_accuracy: 0.7307</p>
<p>Epoch 00001: val_loss improved from inf to 0.48763, saving model to best_model.h5
Epoch 2/50
226/226 [==============================] - 1s 5ms/step - loss: 0.5148 - accuracy: 0.7546 - val_loss: 0.4987 - val_accuracy: 0.7250</p>
<p>Epoch 00002: val_loss did not improve from 0.48763
Epoch 3/50
226/226 [==============================] - 1s 5ms/step - loss: 0.5035 - accuracy: 0.7625 - val_loss: 0.4921 - val_accuracy: 0.7297</p>
<p>Epoch 00003: val_loss did not improve from 0.48763
Epoch 4/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4912 - accuracy: 0.7667 - val_loss: 0.4960 - val_accuracy: 0.7283</p>
<p>Epoch 00004: val_loss did not improve from 0.48763
Epoch 5/50
226/226 [==============================] - 1s 6ms/step - loss: 0.4875 - accuracy: 0.7655 - val_loss: 0.4844 - val_accuracy: 0.7468</p>
<p>Epoch 00005: val_loss improved from 0.48763 to 0.48436, saving model to best_model.h5
Epoch 6/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4808 - accuracy: 0.7744 - val_loss: 0.4664 - val_accuracy: 0.7525</p>
<p>Epoch 00006: val_loss improved from 0.48436 to 0.46640, saving model to best_model.h5
Epoch 7/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4730 - accuracy: 0.7825 - val_loss: 0.5007 - val_accuracy: 0.7255</p>
<p>Epoch 00007: val_loss did not improve from 0.46640
Epoch 8/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4731 - accuracy: 0.7777 - val_loss: 0.4724 - val_accuracy: 0.7530</p>
<p>Epoch 00008: val_loss did not improve from 0.46640
Epoch 9/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4676 - accuracy: 0.7781 - val_loss: 0.4657 - val_accuracy: 0.7639</p>
<p>Epoch 00009: val_loss improved from 0.46640 to 0.46568, saving model to best_model.h5
Epoch 10/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4566 - accuracy: 0.7879 - val_loss: 0.5155 - val_accuracy: 0.7141</p>
<p>Epoch 00010: val_loss did not improve from 0.46568
Epoch 11/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4582 - accuracy: 0.7883 - val_loss: 0.5009 - val_accuracy: 0.7283</p>
<p>Epoch 00011: val_loss did not improve from 0.46568
Epoch 12/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4528 - accuracy: 0.7926 - val_loss: 0.4852 - val_accuracy: 0.7425</p>
<p>Epoch 00012: val_loss did not improve from 0.46568
Epoch 13/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4476 - accuracy: 0.7928 - val_loss: 0.4655 - val_accuracy: 0.7520</p>
<p>Epoch 00013: val_loss improved from 0.46568 to 0.46549, saving model to best_model.h5
Epoch 14/50
226/226 [==============================] - 1s 5ms/step - loss: 0.4446 - accuracy: 0.7935 - val_loss: 0.4678 - val_accuracy: 0.7492</p>
<p>Epoch 00014: val_loss did not improve from 0.46549
Epoch 00014: early stopping</p>
<p>모델 성능 평가</p>
<p>[58]:</p>
<p>losses = pd.DataFrame(model.history.history)</p>
<p>[59]:</p>
<p>losses.head()</p>
<p>[59]:</p>
<p>loss</p>
<p>accuracy</p>
<p>val_loss</p>
<p>val_accuracy</p>
<p>0</p>
<p>0.576232</p>
<p>0.700581</p>
<p>0.487635</p>
<p>0.730678</p>
<p>1</p>
<p>0.514756</p>
<p>0.754568</p>
<p>0.498698</p>
<p>0.724988</p>
<p>2</p>
<p>0.503462</p>
<p>0.762458</p>
<p>0.492146</p>
<p>0.729730</p>
<p>3</p>
<p>0.491154</p>
<p>0.766750</p>
<p>0.496050</p>
<p>0.728307</p>
<p>4</p>
<p>0.487461</p>
<p>0.765504</p>
<p>0.484363</p>
<p>0.746799</p>
<p>성능 시각화</p>
<p>[60]:</p>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;]].plot()</p>
<p>[60]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>[61]:</p>
<p>losses[[&#39;loss&#39;,&#39;val_loss&#39;, &#39;accuracy&#39;,&#39;val_accuracy&#39;]].plot()</p>
<p>[61]:</p>
<p><a href="AxesSubplot:">AxesSubplot:</a></p>
<p>[62]:</p>
<p>plt.plot(history.history[&#39;accuracy&#39;])</p>
<p>plt.plot(history.history[&#39;val_accuracy&#39;])</p>
<p>plt.title(&#39;Accuracy&#39;)</p>
<p>plt.xlabel(&#39;Epochs&#39;)</p>
<p>plt.ylabel(&#39;Acc&#39;)</p>
<p>plt.legend([&#39;acc&#39;, &#39;val_acc&#39;])</p>
<p>plt.show()</p>
<p>성능 평가</p>
<p>[63]:</p>
<p>from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score</p>
<p>from sklearn.metrics import classification_report</p>
<p>[64]:</p>
<p>pred = model.predict(X_test)</p>
<p>[65]:</p>
<p>pred.shape</p>
<p>[65]:</p>
<p>(2109, 2)</p>
<p>[66]:</p>
<p>y_pred = np.argmax(pred, axis=1)</p>
<p>[67]:</p>
<h1 id="정확도-7080">정확도 70~80%</h1>
<p>accuracy_score(y_test, y_pred)</p>
<p>[67]:</p>
<p>0.7491702228544334</p>
<p>[68]:</p>
<h1 id="재현율-70-정도로-이전보다-좋아졌다">재현율 70% 정도로 이전보다 좋아졌다.</h1>
<p>recall_score(y_test, y_pred)</p>
<p>[68]:</p>
<p>0.7625</p>
<p>[69]:</p>
<h1 id="recall-성능을-올렸지만-반대급부로-precision-성능은-떨어진다">recall 성능을 올렸지만, 반대급부로 precision 성능은 떨어진다.</h1>
<h1 id="accuracy-recall-precision-어떤것에-집중할지-선택하는것도-필요하다">accuracy, recall, precision 어떤것에 집중할지 선택하는것도 필요하다.</h1>
<p>​</p>
<p>print(classification_report(y_test, y_pred))</p>
<pre><code>          precision    recall  f1-score   support</code></pre><p>0       0.90      0.74      0.81      1549
           1       0.52      0.76      0.62       560</p>
<p>accuracy                           0.75      2109
   macro avg       0.71      0.75      0.72      2109
weighted avg       0.80      0.75      0.76      2109</p>
<p>배운 내용 정리</p>
<ol>
<li>딥러닝 심층신경망(DNN) 모델 프로세스</li>
</ol>
<p>·         데이터 가져오기</p>
<p>·         데이터 전처리</p>
<p>·         Train, Test 데이터셋 분할</p>
<p>·         데이터 정규화</p>
<p>·         DNN 딥러닝 모델</p>
<ol start="2">
<li>재현율 성능이 좋지 않다. 어떻게 성능향상 방법은?</li>
</ol>
<p>·         Feature Engineering : 성능 잘 나올수 있도록 데이터 가공</p>
<p>·         불균현 데이터 문제 해소 : under-sampling, over-sampling</p>
<p>·         Over-Sampling 기법 : SMOTE</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이태원 할로윈 사망자는 20대가 많다. 이 일은 20대의 책임일까.]]></title>
            <link>https://velog.io/@jst-jin-hyeong/%EC%9D%B4%ED%83%9C%EC%9B%90-%ED%95%A0%EB%A1%9C%EC%9C%88-%EC%82%AC%EB%A7%9D%EC%9E%90%EB%8A%94-20%EB%8C%80%EA%B0%80-%EB%A7%8E%EB%8B%A4.-%EC%9D%B4-%EC%9D%BC%EC%9D%80-20%EB%8C%80%EC%9D%98-%EC%B1%85%EC%9E%84%EC%9D%BC%EA%B9%8C</link>
            <guid>https://velog.io/@jst-jin-hyeong/%EC%9D%B4%ED%83%9C%EC%9B%90-%ED%95%A0%EB%A1%9C%EC%9C%88-%EC%82%AC%EB%A7%9D%EC%9E%90%EB%8A%94-20%EB%8C%80%EA%B0%80-%EB%A7%8E%EB%8B%A4.-%EC%9D%B4-%EC%9D%BC%EC%9D%80-20%EB%8C%80%EC%9D%98-%EC%B1%85%EC%9E%84%EC%9D%BC%EA%B9%8C</guid>
            <pubDate>Sun, 30 Oct 2022 14:21:10 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/jst-jin-hyeong/post/d98ea112-66ac-407e-8381-0aca8dffc5bd/image.jpg" alt=""></p>
<p>..저녁에 출근을 했다. 멍하니 출근을 했다. 저녁 출근길에 마음이 이리도 비통하고 머릿속이 복잡한 적은 없었다. 이태원 핼러윈은 왜 그렇게...
..다른 세대와 마찬가지로, 20대 또한 너무도 다양한 가능성이 많은 시기인데…</p>
<p>..많은 사람이 죽었고 이를 목격한 <strong>사람들의 안타까운 감정의 흐름은 갈 길을 잃었다</strong>. 살인자 없는 죽음이기 때문이다. 여론의 감정은 어디로 흘러갔을까…
사망자는 20대가 많다. 이 일은 20대의 책임일까.</p>
<p>..<strong>구조적으로 문제를 살펴보면</strong> 이 참사는 좁은 공간에 많은 사람이 모였고, 나오는 사람과 들어가는 사람의 동선이 분리되지 않아서 생긴 일이다.
..그렇다는 것은 오히려 늦은 밤이 되기 전 <strong>내일을 생각하며 귀가하려는 사람</strong>들도 포함되었다고 예상해본다. (<strong>’왜 무리까지 하며 그렇게 놀러갔을까’로 생각이 이어져서는 안 된다고 생각이 들었다.</strong>)</p>
<p>..불꽃축제였다면 해당 역은 무정차 통과를 시키고 역 출입이 제한되었을 것이다. 하지만 이 주체 없는 행사는, 표기법 조차 다양한 이 할로윈은 그러하지를 못하였다.
그 날에 발생하는 추가 이익이나 세금으로는, 질서 통제를 할 수 있는 여력을 만들 수 없었을까.</p>
<p>..상황은 이러한데 코로나에 휩쓸린 이태원의 이미지와 MZ 세대의 이미지가 더해진 것인가. 불필요한 이야기 또한 더해지고, 가슴 깊은 애도가 흐려지는 듯하여 더더욱 마음이 아프다.
..특정 면적에 수만 명 이상이 모이는 이벤트가 예상되면 진행되어야 하는 지자체의 프로세스가 분명 있을 텐데 이 경우에는 왜 이루어지지 않은 것일까.
..<strong>분명 20대 안에서도 방법을 찾고 있을 것이다.</strong> 이태원 상인회나 지자체뿐 아니라 각각의 사회 구성원이 문제의식을 나누어 가졌으면 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[velog 시작!]]></title>
            <link>https://velog.io/@jst-jin-hyeong/velog-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@jst-jin-hyeong/velog-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Wed, 19 Oct 2022 12:39:07 GMT</pubDate>
            <description><![CDATA[<p>공유함으로써 성장하는 velog Life! 컨셉의 시작!</p>
]]></description>
        </item>
    </channel>
</rss>