<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hate_all.log</title>
        <link>https://velog.io/</link>
        <description>과제-공부용</description>
        <lastBuildDate>Sun, 17 Dec 2023 20:45:02 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hate_all.log</title>
            <url>https://velog.velcdn.com/images/hate_all/profile/4d62f794-d0ed-444a-b326-0ddcff2c5cc1/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hate_all.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hate_all" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[데이터 전처리 프로젝트]]></title>
            <link>https://velog.io/@hate_all/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@hate_all/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Sun, 17 Dec 2023 20:45:02 GMT</pubDate>
            <description><![CDATA[<h1 id="1-서론">1. 서론</h1>
<p>데이터 전처리는 데이터를 분석하기 전에 적합한 형태로 가공하는 과정이다. 데이터 전처리는 매우 중요한 과정으로 전체 프로세스의 80% 정도를 차지한다. 특히, 머신러닝의 학습을 위해서 학습이 용이한 형태로 가공이 필요하다. 데이터 전처리는 보통 데이터 수집 -&gt; 데이터 프로파일링 -&gt; 데이터 정제 -&gt; 데이터 축소 -&gt; 데이터 변환 -&gt; 데이터 준비의 과정을 거친다. 
<img src="https://velog.velcdn.com/images/hate_all/post/ed3c2157-5fb6-4962-90e0-902f5ca9f86e/image.png" alt=""></p>
<p>최초에 수집된 데이터는 다양한 요인에 의해 분석을 방해하는 요소가 존재하기 마련이다. 그렇기 때문에 데이터의 잘못된 분석 결과를 막기 위해서 데이터 전처리는 필수적이다. 하지만 데이터 전처리 과정을 이해하는 것은 아직 나에게는 매우 어려운 일이다. 통계적인 지식은 물론이고, 파이썬을 비롯한 다양한 프로그래밍 언어 또한 숙련되어야 한다. 거기다 많이 수행해봐야 한다는 점에서 포털에 존재하는 다양한 데이터들로 연습을 해봐야 한다. 따라서, 아직 나의 상태로는 데이터 전처리를 아무 도움 없이 하기에 매우 서툴고 어렵기 때문에 데이터 전처리 강의를 통해 배운 내용과 타인이 수행한 데이터 전처리 코드와 내용을 참고하여 해당 내용을 직접 연습해보고 진행 과정을 스스로 분석해봄으로써 데이터 전처리 과정과 목적을 다시 한번 깨닫고 부족한 코딩 실력에도 도움이 될 수 있게 연습하는 게 이번 프로젝트의 목적이다. </p>
<p><img src="https://velog.velcdn.com/images/hate_all/post/281f93f9-d6d3-4637-9d20-d8c714557889/image.png" alt=""></p>
<p>이번 데이터 전처리의 내용은 질병관리청의 지역사회 건강조사 사이트에서 진행된 설문조사 자료를 통해 진행된다. 공원과 건강 간의 상관관계를 분석해보고자 해당 데이터를 수집하여 데이터 전처리를 해보는 것이다. 해당 자료를 수집한 후 데이터 전처리 과정을 통해 정제 및 변환을 수행하고, 데이터를 시각화 해보는 순서로 프로젝트가 진행된다.</p>
<h1 id="2-본론">2. 본론</h1>
<h2 id="데이터-수집">데이터 수집</h2>
<ol>
<li>2019년에 각 설문조사가 진행된 보건소정보와 세대유형</li>
<li>2019년에 진행된 설문조사에서 서울특별시에 해당하는 설문조사 (지역 사회 건강 조사 원시 자료)</li>
<li>2019년 서울시 주민등록인구(연령별구별) 통계 (이미 정제된 데이터)</li>
<li>2019년 서울시 자치구 재정자립도 (이미 정제된 데이터)</li>
<li>2019년 서울시 신고 등록 체육시설 통계 (이미 정제된 데이터)</li>
<li>2019년 서울시 공원 데이터 (이미 정제된 데이터)</li>
</ol>
<h2 id="데이터-정리">데이터 정리</h2>
<ol>
<li>서울시의 각 자치구별 구분을 하기 위해서 1번 자료에서 보건소 정보를 추출하였다.<pre><code class="language-python">import pandas as pd
</code></pre>
</li>
</ol>
<p>df = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등&#39;+<br>                   &#39;/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,
                   header=3) # # 엑셀 파일이기 때문에 시작위치가 고정되지 않음. header를 사용하여 불러올 시작 위치 지정
df</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/368b9abf-9c0a-4e96-b200-253850575e6a/image.png)

시도명이 서울특별시인 보건소코드와 보건소명을 데이터프레임으로 뽑는다. 다음에 다른 데이터프레임에 사용할 것이다.

```python
data_pbhlth_code = df[df[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
# 시도코드 11 (서울특별시)인 보건소코드와 보건소명만 데이터프레임으로 입력

data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
# 보건소명을 제외하고 자치구만 남기기 위해서 replace로 공백 대체

data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;] # 보건소코드와 자치구를 column으로 지정

data_pbhlth_code.set_index(&#39;보건소코드&#39;,inplace=True)
# inplace = True는 원본 데이터프레임을 변경하는 것이다. (기본값은 False여서 해당 데이터프레임을 copy한 결과를 보여준다)
# 보건소코드를 인덱스로 지정하여 추후에 데이터프레임에서 인덱스로 연산
data_pbhlth_code.head(6)</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/8e5f3537-0c66-4831-8cdd-5bc0fd49359e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hate_all/post/04d991e6-450d-4364-ba9e-d31739752cfa/image.png" alt="">
2. 위는 2번 자료에 대한 사진이다. 해당 자료에는 다양한 항목들이 존재한다. 서론에서의 목적에 맞게 공원이나 신체활동, 건강상태와 관련된 항목들을 추출한다. 추가로 소득도 관련이 있나 뽑아보았다. 그리하여 가져오기로 한 자료의 변수 명에 대하여 알아보자면 age는 만 나이, sex는 성별, pbhlth_code는 보건소번호, qoa_01z1는 주관적 건강수준, pha_04z1는 격렬한 신체활동 일수, pha_05z1는 격렬한 신체활동 시간(시), pha_06z1는 격렬한 신체활동 시간(분), pha_07z1는 중등도 신체활동 일수, pha_08z1는 중등도 신체활동 시간(시), pha_09z1는 중등도 신체활동 시간(분), phb_01z1는 걷기 실천 일수, phb_02z1는 걷기 실천 시간(시), phb_03z1는 걷기 실천 시간(분), obb_01z1는 체중조절 경험 여부, mta_01z1는 주관적 스트레스 수준, mtb_01z1는 우울감 경험 여부, qoc_07z1는 행복감 지수, ena_01d1는 사회환경_동네 자연환경, ena_01e1는 사회환경_동네 생활환경, fma_01z1는 가구원수, fma_12z1는 가구소득_년월, fma_13z1는 가구소득_년금액, fma_14z1는 가구소득_월금액, fma_24z2는 조건부가구소득이다.</p>
<pre><code class="language-python">data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 원시자료/chs19_a.txt&#39;,sep =&#39;\t&#39;, encoding = &#39;cp949&#39;)
data_raw.head()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/b4923c10-2d79-4004-a9cc-7032b47255ec/image.png" alt=""></p>
<pre><code class="language-python">df_raw1 = data_raw[[&#39;age&#39;,&#39;sex&#39;,&#39;pbhlth_code&#39;,&#39;qoa_01z1&#39;,
                    &#39;pha_04z1&#39;,&#39;pha_05z1&#39;,&#39;pha_06z1&#39;,&#39;pha_07z1&#39;,&#39;pha_08z1&#39;,&#39;pha_09z1&#39;,
                    &#39;phb_01z1&#39;,&#39;phb_02z1&#39;,&#39;phb_03z1&#39;,&#39;obb_01z1&#39;,&#39;mta_01z1&#39;,&#39;mtb_01z1&#39;,
                    &#39;qoc_07z1&#39;,&#39;ena_01d1&#39;,&#39;ena_01e1&#39;,
                    &#39;fma_01z1&#39;,&#39;fma_12z1&#39;,&#39;fma_13z1&#39;,&#39;fma_14z1&#39;,&#39;fma_24z2&#39;]]

index = [&#39;만나이&#39;,&#39;성별&#39;,&#39;보건소번호&#39;,&#39;주관적 건강수준&#39;,
         &#39;격렬한 신체활동 일수&#39;,&#39;격렬한 신체활동 시간(시)&#39;,&#39;격렬한 신체활동 시간(분)&#39;,
         &#39;중등도 신체활동 일수&#39;,&#39;중등도 신체활동 시간(시)&#39;,&#39;중등도 신체활동 시간(분)&#39;,
         &#39;걷기 실천 일수&#39;,&#39;걷기 실천 시간(시)&#39;,&#39;걷기 실천 시간(분)&#39;,
         &#39;체중조절 경험 여부&#39;,&#39;주관적 스트레스 수준&#39;,&#39;우울감 경험 여부&#39;,&#39;행복감 지수&#39;,
         &#39;사회환경_동네 자연환경&#39;,&#39;사회환경_동네 생활환경&#39;,
         &#39;가구원수&#39;,&#39;가구소득_년월&#39;,&#39;가구소득_년금액&#39;,&#39;가구소득_월금액&#39;,&#39;조건부가구소득&#39;]

df_raw1.columns = index # 각 항목에 들어있는 코드들을 이해할 수 있는 변수 라벨로 변경하여 column으로 설정
df_raw2 = df_raw1.copy() # SettingWithCopyWarning 방지

df_raw2[&#39;자치구&#39;] = df_raw2[&#39;보건소번호&#39;].map(data_pbhlth_code.to_dict()[&#39;자치구&#39;])
# map을 이용하여 위에서 구한 보건소번호에 해당하는 자치구를 df_raq2에 추가
df_raw3 = df_raw2.drop([&#39;보건소번호&#39;],axis=1) # 더 이상 필요없는 보건소번호를 drop을 시킴
df_raw3.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 1차 전처리_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)
df_raw3</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/ce53c4d9-2fcf-4322-8450-f5928670b26e/image.png" alt=""></p>
<p>이 다음부터 사용할 데이터는 지역사회건강조사 1차 전처리_2019.csv 파일이다.</p>
<h2 id="범주형-데이터-전처리">범주형 데이터 전처리</h2>
<ul>
<li><p>주관적 건강수준이나 행복감지수 같은 범주형 데이터는 결측치를 제거하고, 전체와 각 자치구 별로 나누었다. 그리고 그 안에서도 나이대별과 성별로 나눠서 인덱스를 지정하였다. (코드 진행이 비슷)</p>
</li>
<li><p>결측치에 해당하는 모름이나 응답거부에 해당하는 데이터들을 삭제하였다.(예-행복감지수에서 77은 응답거부, 99는 모름이다.)</p>
</li>
</ul>
<ol>
<li>행복감지수 전처리 수행<pre><code class="language-python">data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)
</code></pre>
</li>
</ol>
<p>df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;행복감 지수&#39;,&#39;자치구&#39;]]</p>
<p>df_hi1=df[df[&#39;행복감 지수&#39;] != 99] # 99는 모름
df_hi2=df_hi1[df_hi1[&#39;행복감 지수&#39;] != 77] # 77은 응답거부</p>
<p>data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]</p>
<p>list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;] # 전체 합에 해당하는 서울시 추가
list_region.reverse() # 서울시가 맨 위에 올라오도록 reverse 사용</p>
<pre><code>list_region에는 서울시를 비롯한 각 자치구가 들어오게 된다. 그 다음 데이터들을 자치구끼리 묶고, 전체 데이터를 서울시로 묶는다.

```python
list_df = []
for value in list_region:
    temp = df_hi2[&#39;자치구&#39;] == value
    # list_region에 들어있는 자치구와 df_hi2에 있는 자치구와 동일하면 temp에는 True과 들어가고, 같지 않으면 False

    list_df.append(df_hi2[temp]) # 그래서 temp가 true이면 value와 동일한 자치구를 가진 데이터프레임을 리스트에 넣는다

list_df[0] = df_hi2
# df_hi2에서 자치구 column에는 서울시가 없기 때문에 list_df[0]은 빈 데이터프레임이 들어있는데 여기에 전체 데이터를 넣어준다.</code></pre><p>각 자치구별 데이터들을 연령별, 성별로 나눠서 하나의 데이터프레임으로 만든다.</p>
<pre><code class="language-python">list_age = [&#39;19~200&#39;,&#39;19~44&#39;,&#39;45~64&#39;,&#39;65~74&#39;,&#39;75~200&#39;] # 전체 / 19~44  45~64 / 65~74 / 75이상 으로 나누기 위해서 범위 설정
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_hi = []
# 크게 자치구 -&gt; 연령대 -&gt; 성별로 하위 인덱스를 만드식으로 작업하면서 계(전체)에 해당하는 값을 살리려고 함
for i, value1 in enumerate(list_region): # enumerate를 이용해 list_df의 인덱스와 자치구로 이용
    for j in list_age:
        for k in list_sex:            
            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;~&#39;)[0])] 
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])] # 연령대를 ~를 기준으로 이상, 이하로 데이터 처리

            # 이 부분은 위에 list_age에서 넘어오는 계 / 남 / 여를 구분해서 만들기 위해 아래와 같이 조건문 사용
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1

            # 행복감 지수는 범주형 데이터여서 value_counts()롤 각각의 값에 해당하는 데이터들의 갯수를 세어서 딕셔너리로 만듬
            temp3 = temp2[&#39;행복감 지수&#39;].value_counts().to_dict()
            # 행복감 지수는 1부터 10까지 이루어져있지만, 설문조사상 해당하는 값이 없는 경우는 딕셔너리가 만들어지지 않음
            # 그래서 없는 값도 생성 후 0으로 넣어서 추후 전처리 작업 진행간에 오류 발생 방지
            for m in range(1,11): 
                if m not in temp3: 
                    temp3[m] = 0

            temp_sum = 0
            # 이 구간에서 없는 값은 오류가 발생할 수도 있어서 위에서 방지
            # 그리고 각 구간별 수와 값을 곱해서 계속해서 더한 후 나눠서, 전체 평균을 구함
            for n in range(1,11):
                temp_sum += temp3[n]*n  
            value_hi.append(round(temp_sum / len(temp2[&#39;행복감 지수&#39;]),2))

            # 아래 작업은 멀티 인덱스를 생성하기 위해서 순서대로 idx 리스트에 해당하는 값을 삽입
            if j == &#39;19~200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)

df_final = pd.DataFrame({&#39;행복감 지수&#39;:value_hi, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})

df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])

df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 (전처리된 데이터)_2019/지역사회건강조사 (행복감 지수)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)

df_final</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/4dfd76dd-23ef-44fc-af81-83803771ac9a/image.png" alt=""></p>
<ol start="2">
<li>체중조절 경험 여부 전처리 수행
(9 -&gt; 모름, 7 -&gt; 응답거부)</li>
</ol>
<pre><code class="language-python">import pandas as pd
import numpy as np

data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)

df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;체중조절 경험 여부&#39;,&#39;자치구&#39;]]

df_cw1=df[df[&#39;체중조절 경험 여부&#39;] != 9]
df_cw2=df_cw1[df_cw1[&#39;체중조절 경험 여부&#39;] != 7]
df_cw2[&#39;체중조절 경험 여부&#39;].value_counts(normalize = True)
# 고유 값별 데이터 수를 나타낸다.
# normalize 옵션도 가능.

data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/5efd515e-e231-4b08-8eb8-4584971738c3/image.png" alt=""></p>
<pre><code class="language-python">list_df = []
for value in list_region:
    temp = df_cw2[&#39;자치구&#39;] == value
    list_df.append(df_cw2[temp])
list_df[0] = df_cw2

list_age = [&#39;19~200&#39;,&#39;19~44&#39;,&#39;45~64&#39;,&#39;65~74&#39;,&#39;75~200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_cw = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:            
            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;~&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            temp3 = temp2[&#39;체중조절 경험 여부&#39;].value_counts(normalize = True).to_dict()
            if 4 not in temp3:
                temp3[4] = 0
            if 3 not in temp3:
                temp3[3] = 0
            value_cw.append(round(100 - (temp3[3]+temp3[4])*100,1)) # 위 조건으로 경험 여부(1,2,3,4)가 최종 형태처럼(한지 안 한지에 대한 비율 형태) 변함.

            if j == &#39;19~200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)

df_final = pd.DataFrame({&#39;체중조절 경험 여부&#39;:value_cw, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})

df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])

df_final

df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (체중조절)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/19646035-64cf-49f8-9f60-df2a73753502/image.png" alt=""></p>
<ol start="3">
<li>우울감 전처리 수행
(9 -&gt; 모름, 7 -&gt; 응답거부, 응답 -&gt; 1 or 2)</li>
</ol>
<pre><code class="language-python">import pandas as pd
import numpy as np

data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)

df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;우울감 경험 여부&#39;,&#39;자치구&#39;]]

df_dep1=df[df[&#39;우울감 경험 여부&#39;] != 9]
df_dep2=df_dep1[df_dep1[&#39;우울감 경험 여부&#39;] != 7]

data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()

list_df = []
for value in list_region:
    temp = df_dep2[&#39;자치구&#39;] == value
    list_df.append(df_dep2[temp])
list_df[0] = df_dep2

list_age = [&#39;19~200&#39;,&#39;19~44&#39;,&#39;45~64&#39;,&#39;65~74&#39;,&#39;75~200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_dep = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:            
            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;~&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            value_dep.append(round(100 - temp2[&#39;우울감 경험 여부&#39;].value_counts(normalize = True)[2]*100,1))
            if j == &#39;19~200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)

df_final = pd.DataFrame({&#39;우울감 경험률&#39;:value_dep, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})

df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])

df_final

df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (우울감)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/be8a33a5-c648-46b0-8d76-1d97c9476ad4/image.png" alt=""></p>
<ol start="4">
<li>스트레스 전처리 수행 (9 -&gt; 모름, 7 -&gt; 응답거부)<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ol>
<p>data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)</p>
<p>df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;주관적 스트레스 수준&#39;,&#39;자치구&#39;]]</p>
<p>df_sl1=df[df[&#39;주관적 스트레스 수준&#39;] != 9]
df_sl2=df_sl1[df_sl1[&#39;주관적 스트레스 수준&#39;] != 7]
df_sl2[&#39;주관적 스트레스 수준&#39;].value_counts(normalize = True)</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/e300ab1d-3520-4e3b-adf5-d877f7f18387/image.png)

```python
data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()

list_df = []
for value in list_region:
    temp = df_sl2[&#39;자치구&#39;] == value
    list_df.append(df_sl2[temp])
list_df[0] = df_sl2

list_age = [&#39;19~200&#39;,&#39;19~44&#39;,&#39;45~64&#39;,&#39;65~74&#39;,&#39;75~200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_hl = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:            
            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;~&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            temp3 = temp2[&#39;주관적 스트레스 수준&#39;].value_counts(normalize = True).to_dict()
            if 4 not in temp3:
                temp3[4] = 0
            if 1 not in temp3:
                temp3[1] = 0
            value_hl.append(round((temp3[1]+temp3[2])*100,1))

            if j == &#39;19~200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)

df_final = pd.DataFrame({&#39;주관적 스트레스 수준&#39;:value_hl, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})

df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])

df_final

df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (스트레스)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/ec6b836e-f37e-4c48-be92-ad5bf97712ec/image.png" alt=""></p>
<ol start="5">
<li>자연환경 전처리 수행 (9 -&gt; 모름, 7 -&gt; 응답거부)<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ol>
<p>data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)</p>
<p>df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;사회환경_동네 자연환경&#39;,&#39;자치구&#39;]]</p>
<p>df_ne1=df[df[&#39;사회환경_동네 자연환경&#39;] != 9]
df_ne2=df_ne1[df_ne1[&#39;사회환경_동네 자연환경&#39;] != 7]</p>
<p>data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()</p>
<p>list_df = []
for value in list_region:
    temp = df_ne2[&#39;자치구&#39;] == value
    list_df.append(df_ne2[temp])
list_df[0] = df_ne2</p>
<p>list_age = [&#39;19<del>200&#39;,&#39;19</del>44&#39;,&#39;45<del>64&#39;,&#39;65</del>74&#39;,&#39;75<del>200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_ne = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:<br>            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;</del>&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;<del>&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            value_ne.append(round(temp2[&#39;사회환경_동네 자연환경&#39;].value_counts(normalize = True)[1]*100,1))
            if j == &#39;19</del>200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)</p>
<p>df_final = pd.DataFrame({&#39;긍정적 태도율(자연환경)&#39;:value_ne, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})</p>
<p>df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])</p>
<p>df_final</p>
<p>df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (긍정적 태도율(자연환경))_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/2ca57813-2283-41ed-839f-6062d4ca7e49/image.png)

6. 건강수준 전처리 수행 (9 -&gt; 모름, 7 -&gt; 응답거부)
```python
import pandas as pd
import numpy as np

data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)

df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;주관적 건강수준&#39;,&#39;자치구&#39;]]

df_hl1=df[df[&#39;주관적 건강수준&#39;] != 9]
df_hl2=df_hl1[df_hl1[&#39;주관적 건강수준&#39;] != 7]
df_hl2[&#39;주관적 건강수준&#39;].value_counts(normalize = True)</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/ce6469fb-7074-4cb8-8f6b-5f3a18bf4b0b/image.png" alt=""></p>
<pre><code class="language-python">data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()

list_df = []
for value in list_region:
    temp = df_hl2[&#39;자치구&#39;] == value
    list_df.append(df_hl2[temp])
list_df[0] = df_hl2

list_age = [&#39;19~200&#39;,&#39;19~44&#39;,&#39;45~64&#39;,&#39;65~74&#39;,&#39;75~200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_hl = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:            
            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;~&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            temp3 = temp2[&#39;주관적 건강수준&#39;].value_counts(normalize = True).to_dict()
            if 5 not in temp3:
                temp3[5] = 0
            if 1 not in temp3:
                temp3[1] = 0
            value_hl.append(round(100 - (temp3[3]+temp3[4]+temp3[5])*100,1))
            if j == &#39;19~200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)

df_final = pd.DataFrame({&#39;주관적 건강수준&#39;:value_hl, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})

df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])

df_final

df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (건강수준)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/0e015100-06a4-475d-a92c-d7afd859b69e/image.png" alt=""></p>
<h2 id="연속형-데이터-전처리">연속형 데이터 전처리</h2>
<ul>
<li>해당 자료에서 남은 데이터들은 시간이나 날짜로 나누어져 있기 때문에 이를 합치는 전처리를 진행할 것이다.</li>
<li>함수를 만들어 합치고 apply를 적용한 후, 멀티 인덱스를 적용하여 전처리한다.</li>
</ul>
<ol>
<li>중등도 신체활동 전처리 (99 -&gt; 모름, 77 -&gt; 응답거부)<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ol>
<p>data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)</p>
<p>df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;자치구&#39;, &#39;중등도 신체활동 일수&#39;, &#39;중등도 신체활동 시간(시)&#39;,&#39;중등도 신체활동 시간(분)&#39;]]</p>
<p>df1=df[df[&#39;중등도 신체활동 일수&#39;] != 99]
df2=df1[df1[&#39;중등도 신체활동 일수&#39;] != 77]</p>
<p>data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]</p>
<p>list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;] # 전체 합에 해당하는 서울시 추가
list_region.reverse() # 서울시가 맨 위에 올라오도록 reverse 사용</p>
<pre><code>```python
def transtime(df_activity) : # 시와 분을 합쳐서 총 분으로 환산하는 과정
    if 0 &lt;= df_activity[&#39;중등도 신체활동 시간(시)&#39;] &lt;= 24 and df_activity[&#39;중등도 신체활동 시간(분)&#39;] &lt;= 59 :
        return df_activity[&#39;중등도 신체활동 시간(시)&#39;]*60 + df_activity[&#39;중등도 신체활동 시간(분)&#39;]
    else :
        return 0

def health_index(df_activity) :
    if df_activity[&#39;중등도 신체활동 일수&#39;] &lt; 5 :
        return 0
    # 중등도 신체활동 실천율은 다음과 같다
    # 최근 1주일 동안 평소보다 몸이 조금 힘들거나 숨이 약간 가쁜 중등도 신체활동을 1일 30분 이상, 주 5일 이상 실천한 사람의 분율
    # 따라서 아래 조건으로 해당하는 사람들은 1을 리턴하고 아니면 0을 리턴하도록 한다.
    elif 5 &lt;= df_activity[&#39;중등도 신체활동 일수&#39;] and df_activity[&#39;중등도 시분 환산&#39;] &gt;= 30 :
        return 1
    else :
        return 0

df_activity = df2.copy()

# 먼저 시분 환산이라는 새로운 column을 만들고 우리가 사용할 데이터프레임에 함수를 적용하자
df_activity[&quot;중등도 시분 환산&quot;] = df_activity.apply(transtime, axis =1)

# 그리고 추가로 만들어진 시분 환산 column과 신체활동 일수를 이용하여
# 이 사람이 중등도 신체활동을 실천했으면 1, 그렇지 않으면 0을 주도록 하자.
df_activity[&#39;중등도 신체활동 실천&#39;] = df_activity.apply(health_index, axis =1)

# 그리고 필요없는 column은 drop 함수를 이용하여 제거하자
df_activity = df_activity.drop([&#39;중등도 신체활동 시간(시)&#39;,&#39;중등도 신체활동 시간(분)&#39;,&#39;중등도 신체활동 일수&#39;,&#39;중등도 시분 환산&#39;],axis=1)        </code></pre><pre><code class="language-python">list_df = []
for value in list_region:
    temp = df_activity[&#39;자치구&#39;] == value
    list_df.append(df_activity[temp])
list_df[0] = df_activity

list_age = [&#39;19~200&#39;,&#39;19~44&#39;,&#39;45~64&#39;,&#39;65~74&#39;,&#39;75~200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_act = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:            
            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;~&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            temp3 = temp2[&#39;중등도 신체활동 실천&#39;].value_counts(normalize = True).to_dict()
            if 1 not in temp3:
                temp3[1] = 0
            if 0 not in temp3:
                temp3[0] = 0
            value_act.append(round(temp3[1]*100,1))

            if j == &#39;19~200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)

df_final = pd.DataFrame({&#39;중등도 신체활동 실천&#39;:value_act, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})

df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])

df_final

df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (중등도 신체활동)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/35ab4a5c-5f96-4b6d-bd82-d83af7acd548/image.png" alt=""></p>
<ol start="2">
<li>격렬한 신체활동 전처리 (99 -&gt; 모름, 77 -&gt; 응답거부)<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ol>
<p>data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)</p>
<p>df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;자치구&#39;, &#39;격렬한 신체활동 일수&#39;, &#39;격렬한 신체활동 시간(시)&#39;,&#39;격렬한 신체활동 시간(분)&#39;]]</p>
<p>df1=df[df[&#39;격렬한 신체활동 일수&#39;] != 99]
df2=df1[df1[&#39;격렬한 신체활동 일수&#39;] != 77]
df3=df2[df2[&#39;격렬한 신체활동 시간(시)&#39;] != 99]
df4=df3[df3[&#39;격렬한 신체활동 시간(시)&#39;] != 77]</p>
<p>data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()</p>
<p>def transtime(df_activity) :
    if 0 &lt;= df_activity[&#39;격렬한 신체활동 시간(시)&#39;] &lt;= 24 and df_activity[&#39;격렬한 신체활동 시간(분)&#39;] &lt;= 59 :
        return df_activity[&#39;격렬한 신체활동 시간(시)&#39;]*60 + df_activity[&#39;격렬한 신체활동 시간(분)&#39;]
    else :
        return 0</p>
<p>def health_index(df_activity) :
    if df_activity[&#39;격렬한 신체활동 일수&#39;] &lt; 3 :
        return 0
    elif 3 &lt;= df_activity[&#39;격렬한 신체활동 일수&#39;] and df_activity[&#39;격렬 시분 환산&#39;] &gt;= 20 :
        return 1
    else :
        return 0</p>
<p>df_activity = df4.copy() # 오류제거
df_activity[&quot;격렬 시분 환산&quot;] = df_activity.apply(transtime, axis =1)
df_activity[&#39;격렬한 신체활동 실천&#39;] = df_activity.apply(health_index, axis =1)
df_activity = df_activity.drop([&#39;격렬한 신체활동 시간(시)&#39;,&#39;격렬한 신체활동 시간(분)&#39;,&#39;격렬한 신체활동 일수&#39;,&#39;격렬 시분 환산&#39;],axis=1)</p>
<p>list_df = []
for value in list_region:
    temp = df_activity[&#39;자치구&#39;] == value
    list_df.append(df_activity[temp])
list_df[0] = df_activity</p>
<p>list_age = [&#39;19<del>200&#39;,&#39;19</del>44&#39;,&#39;45<del>64&#39;,&#39;65</del>74&#39;,&#39;75<del>200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_act = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:<br>            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;</del>&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            temp3 = temp2[&#39;격렬한 신체활동 실천&#39;].value_counts(normalize = True).to_dict()
            if 1 not in temp3:
                temp3[1] = 0
            if 0 not in temp3:
                temp3[0] = 0
            value_act.append(round(temp3[1]*100,1))</p>
<pre><code>        if j == &#39;19~200&#39;:
            idx_age.append(&#39;계&#39;)
        elif j == &#39;75~200&#39;:
            idx_age.append(&#39;75 이상&#39;)
        else:
            idx_age.append(j)
        idx_sex.append(k)
        idx_region.append(value1)</code></pre><p>df_final = pd.DataFrame({&#39;격렬한 신체활동 실천&#39;:value_act, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})</p>
<p>df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])</p>
<p>df_final</p>
<p>df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (격렬한 신체활동)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/9b54a7c0-1db8-47eb-9485-4d5f27a8860a/image.png)

3. 걷기 전처리 (99 -&gt; 모름, 77 -&gt; 응답거부)
```python
import pandas as pd
import numpy as np

data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)

df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;자치구&#39;, &#39;걷기 실천 일수&#39;, &#39;걷기 실천 시간(시)&#39;,&#39;걷기 실천 시간(분)&#39;]]

df1=df[df[&#39;걷기 실천 일수&#39;] != 99]
df2=df1[df1[&#39;걷기 실천 일수&#39;] != 77]

data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()

def transtime(df_walk) :
    if 0 &lt;= df_walk[&#39;걷기 실천 시간(시)&#39;] &lt;= 24 and df_walk[&#39;걷기 실천 시간(분)&#39;] &lt;= 59 :
        return df_walk[&#39;걷기 실천 시간(시)&#39;]*60 + df_walk[&#39;걷기 실천 시간(분)&#39;]
    else :
        return 0

def health_index(df_walk) :
    if df_walk[&#39;걷기 실천 일수&#39;] &lt; 5 :
        return 0
    elif 5 &lt;= df_walk[&#39;걷기 실천 일수&#39;] and df_walk[&#39;걷기 시분 환산&#39;] &gt;= 30 :
        return 1
    else :
        return 0

df_walk = df2.copy() # 오류제거
df_walk[&quot;걷기 시분 환산&quot;] = df_walk.apply(transtime, axis =1)
df_walk[&#39;걷기 실천&#39;] = df_walk.apply(health_index, axis =1)
df_walk = df_walk.drop([&#39;걷기 실천 시간(시)&#39;,&#39;걷기 실천 시간(분)&#39;,&#39;걷기 실천 일수&#39;,&#39;걷기 시분 환산&#39;],axis=1)

list_df = []
for value in list_region:
    temp = df_walk[&#39;자치구&#39;] == value
    list_df.append(df_walk[temp])
list_df[0] = df_walk

list_age = [&#39;19~200&#39;,&#39;19~44&#39;,&#39;45~64&#39;,&#39;65~74&#39;,&#39;75~200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_walk = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:            
            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;~&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;~&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            temp3 = temp2[&#39;걷기 실천&#39;].value_counts(normalize = True).to_dict()
            if 1 not in temp3:
                temp3[1] = 0
            if 0 not in temp3:
                temp3[0] = 0
            value_walk.append(round(temp3[1]*100,1))

            if j == &#39;19~200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)

df_final = pd.DataFrame({&#39;걷기 실천&#39;:value_walk, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})

df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])

df_final

df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (걷기)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/61017011-4aae-4c19-b2ea-3114f4b7a607/image.png" alt=""></p>
<ol start="4">
<li>소득 전처리 (9, 99999 -&gt; 모름, 7, 77777 -&gt; 응답거부)<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ol>
<p>data_raw = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 1차 전처리_2019.csv&#39;)</p>
<p>df = data_raw[[&#39;만나이&#39;,&#39;성별&#39;,&#39;가구원수&#39;,&#39;가구소득_년월&#39;,&#39;가구소득_년금액&#39;,&#39;가구소득_월금액&#39;,&#39;자치구&#39;]]</p>
<p>df_hi1=df[df[&#39;가구소득_년금액&#39;] != 99999]
df_hi2=df_hi1[df_hi1[&#39;가구소득_년금액&#39;] != 77777]
df_hi3=df_hi2[df_hi2[&#39;가구소득_월금액&#39;] != 99999]
df_hi4=df_hi3[df_hi3[&#39;가구소득_월금액&#39;] != 77777]
df_hi5=df_hi4[df_hi4[&#39;가구소득_년월&#39;] != 9]
df_hi6=df_hi5[df_hi5[&#39;가구소득_년월&#39;] != 7]</p>
<p>data_pbhlth_code = pd.read_excel(&#39;C:/Users/Public/zrzr/walk_with_me-main/raw/지역사회건강조사 2019년 원시자료 이용지침서 등/지역사회건강조사 2019 원시자료 참고사항_보건소정보, 세대유형.xlsx&#39;,header=3)
data_pbhlth_code = data_pbhlth_code[data_pbhlth_code[&#39;시도코드&#39;] == 11][[&#39;보건소코드&#39;,&#39;보건소명&#39;]]
data_pbhlth_code[&quot;보건소명&quot;] = data_pbhlth_code[&quot;보건소명&quot;].str.replace(&#39;보건소&#39;, &#39;&#39;, regex=True)
data_pbhlth_code.columns=[&#39;보건소코드&#39;,&#39;자치구&#39;]
list_region = list(data_pbhlth_code.to_dict()[&#39;자치구&#39;].values()) + [&#39;서울시&#39;]
list_region.reverse()</p>
<p>def transincome(df_income) :
    if df_income[&#39;가구소득_년월&#39;] == 1: # 1은 년 
        return df_income[&#39;가구소득_년금액&#39;] / df_income[&#39;가구원수&#39;]
    elif df_income[&#39;가구소득_년월&#39;] == 2: # 2는 월
        return df_income[&#39;가구소득_월금액&#39;]*12  / df_income[&#39;가구원수&#39;]
    else :
        return 0</p>
<p>df_income = df_hi6.copy() # 오류제거
df_income[&quot;소득 연봉 환산&quot;] = df_income.apply(transincome, axis =1)
df_income = df_income.drop([&#39;가구소득_년월&#39;,&#39;가구소득_년금액&#39;,&#39;가구소득_월금액&#39;,&#39;가구원수&#39;],axis=1)</p>
<p>list_df = []
for value in list_region:
    temp = df_income[&#39;자치구&#39;] == value
    list_df.append(df_income[temp])
list_df[0] = df_income</p>
<p>list_age = [&#39;19<del>200&#39;,&#39;19</del>44&#39;,&#39;45<del>64&#39;,&#39;65</del>74&#39;,&#39;75<del>200&#39;]
list_sex = [&#39;계&#39;,&#39;남&#39;,&#39;여&#39;]
idx_sex = []
idx_age = []
idx_region = []
value_hi = []
for i, value1 in enumerate(list_region):
    for j in list_age:
        for k in list_sex:<br>            temp = list_df[i][list_df[i][&#39;만나이&#39;]&gt;=int(j.split(&#39;</del>&#39;)[0])]
            temp1 = temp[temp[&#39;만나이&#39;] &lt;= int(j.split(&#39;<del>&#39;)[1])]
            if k == &#39;남&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 1]
            elif k == &#39;여&#39;:
                temp2 = temp1[temp1[&#39;성별&#39;] == 2]
            else:
                temp2 = temp1
            temp3 = temp2[&quot;소득 연봉 환산&quot;].value_counts().to_dict()
            total_sum = 0
            for m,n in temp3.items():
                total_sum += m*n
            value_hi.append(round(total_sum/len(temp2[&#39;소득 연봉 환산&#39;]),1))
            if j == &#39;19</del>200&#39;:
                idx_age.append(&#39;계&#39;)
            elif j == &#39;75~200&#39;:
                idx_age.append(&#39;75 이상&#39;)
            else:
                idx_age.append(j)
            idx_sex.append(k)
            idx_region.append(value1)</p>
<p>df_final = pd.DataFrame({&#39;1인당 연소득&#39;:value_hi, &#39;지역&#39;:idx_region,&#39;연령별&#39;:idx_age,&#39;성별&#39;:idx_sex})</p>
<p>df_final = df_final.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;])</p>
<p>df_final</p>
<p>df_final.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/지역사회건강조사 (1인당 연소득)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/4e780c20-3929-4972-9aba-e2c26fde1381/image.png)

## 전처리된 데이터 통합
- OS 모듈 사용
- 편한 시각화를 위해 통합된 테이블이 필요함.

1. 건강 관련 데이터 통합
```python
import pandas as pd
import os

path_dir = &#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/&#39;

file_list = os.listdir(path_dir)
data_list = []
for i in file_list:
    if i ==&#39;지역사회건강조사 1차 전처리_2019.csv&#39;:
        continue
    if i.split(&#39; &#39;)[0] == &#39;지역사회건강조사&#39;:
        data_list.append(pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/%s&#39; % i))

for i in data_list:
    i.set_index([&#39;지역&#39;,&#39;연령별&#39;,&#39;성별&#39;],inplace=True)

df_health = pd.concat(data_list, axis=1, join=&#39;inner&#39;)

df_health

df_health.to_csv(&quot;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/통합 테이블(건강)_2019.csv&quot;, mode=&#39;w&#39;,encoding = &#39;utf-8-sig&#39;)</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/44a72eca-f132-49e6-9272-53c4fbfa2e51/image.png" alt=""></p>
<ol start="2">
<li>전처리된 데이터 모두 통합<pre><code class="language-python">import pandas as pd
</code></pre>
</li>
</ol>
<p>data_park = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/통합 테이블(공원)_2019.csv&#39;)
data_health = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/통합 테이블(건강)_2019.csv&#39;)
data_finance = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/서울시 자치구 재정자립도_2019.csv&#39;)
data_athletic = pd.read_csv(&#39;C:/Users/Public/zrzr/walk_with_me-main/전처리된 데이터/서울시 신고_등록 체육시설 통계_2019.csv&#39;)
data_health.rename(columns={&#39;지역&#39;:&#39;자치구&#39;},inplace = True) # 지역을 자치구로 변경하여 하나로 통일
data_health1 = data_health[(data_health[&#39;연령별&#39;] == &#39;계&#39;) &amp; (data_health[&#39;성별&#39;] == &#39;계&#39;)]
data_health1.set_index(&#39;자치구&#39;,inplace = True)
data_park.set_index(&#39;자치구&#39;,inplace = True)
data_finance.set_index(&#39;자치구&#39;,inplace = True)
data_athletic.set_index(&#39;자치구&#39;,inplace = True)
df = pd.concat([data_health1, data_finance, data_athletic,data_park],axis=1)
df = df.drop(df.index[0]) # 서울시를 일단 없앤다
df = df.drop([&#39;연령별&#39;,&#39;성별&#39;],axis=1) # 멀티인덱스때 사용했던 column들 삭제</p>
<p>df.reset_index(inplace = True)
df</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/9363b042-b329-4516-bd35-cd331972ebb0/image.png)

## 시각화
- 다양한 변수들의 상관관계에 대하여 알아보기 위해 seaborn의 heatmap을 사용하였음
- 통합된 데이터에 공원과 관련된 변수가 너무 많아서 각 자치구별 인구 비율을 반영할 수 있는 1인당 생활권 도시림 면적을 사용하였음

```python
import numpy as np
import seaborn as sns
import matplotlib as mp
import matplotlib.pyplot as plt

df1 = df.drop([&#39;공원율&#39;,&#39;1인당 공원 면적&#39;,&#39;총 도시림 면적&#39;,&#39;생활권 도시림 면적&#39;,&#39;1인당 총 도시림 면적&#39;,
               &#39;1인당 생활권 도시림 면적(산림수목)&#39;,&#39;1인당 생활권 도시림 면적(공원녹지)&#39;],axis=1)

corr=df1.corr()

# 그림 사이즈 지정
fig, ax = plt.subplots( figsize=(15,15) )


# 삼각형 마스크를 만든다(위 쪽 삼각형에 True, 아래 삼각형에 False)
mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True

# 히트맵 생성
sns.heatmap(corr, 
            cmap = &#39;RdYlBu_r&#39;, 
            annot = True,   # 실제 값을 표시
            mask=mask,      # 표시하지 않을 마스크 부분을 지정
            linewidths=1,  # 실선 조절
            cbar_kws={&quot;shrink&quot;: 1},# 컬러바 크기 조절
            vmin = -1,vmax = 1   # 컬러바 범위 조절
           )  
plt.show()               </code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/abcb8479-a853-4e60-a64a-f6bedb0cf170/image.png" alt=""></p>
<p>-&gt; 1인당 생활권 도시림 면적과 다른 변수들과의 상관관계를 비교하면 신체활동과 관련된 지표에서는 큰 상관관계를 발견하기 어려웠지만 주관적 건강수준이나 행복감 지수 등에서 유의미한 양의 상관관계를 발견할 수 있음
-&gt; 1인당 생활권 도시림 면적과 가장 큰 상관관계를 갖는 변수는 재정자립도와 1인당 연소득임</p>
<ul>
<li>행복감 지수와 1인당 생활권 도시림 면적 간의 관계를 막대그래프와 선 그래프로 나타냄<pre><code class="language-python">import scipy.stats as stats
import seaborn as sns
</code></pre>
</li>
</ul>
<p>df2= df1[[&#39;행복감 지수&#39;,&#39;주관적 건강수준&#39;,&#39;우울감 경험률&#39;]]</p>
<p>plt.rcParams[&#39;figure.figsize&#39;] = (20, 10) # 크기 지정
plt.rcParams[&#39;font.size&#39;] = 10 # 폰트 크기 지정</p>
<h1 id="subplots를-이용하여-figure-객체전체-영역와-axex-객체들어갈-그래프들을-가져온다">subplots를 이용하여 figure 객체(전체 영역)와 axex 객체(들어갈 그래프들)을 가져온다</h1>
<p>fig, ax = plt.subplots() </p>
<h1 id="ax에-그리고-싶은-막대그래프에-대한-정보를-넣는다">ax에 그리고 싶은 막대그래프에 대한 정보를 넣는다</h1>
<p>ax.bar(df[&quot;자치구&quot;], df[&quot;1인당 생활권 도시림 면적&quot;], color=&#39;deeppink&#39;, label=&#39;1인당 생활권 도시림 면적&#39;, alpha=0.3, width=0.7)</p>
<h1 id="y축에-대해서-라벨과-스케일을-조절">y축에 대해서 라벨과 스케일을 조절</h1>
<p>ax.set_ylabel(&#39;1인당 생활권 도시림 면적&#39;)
ax.set_yscale(&#39;log&#39;) # 자치구별 차이가 커서 로그 스케일로 보여주는 차이를 줄여주었다</p>
<p>plt.legend(loc=2, fontsize=13) # loc=2 는 upper left다</p>
<h1 id="twinx를-이용하여-y축을-하나-더-추가하자">twinx()를 이용하여 y축을 하나 더 추가하자</h1>
<p>ax1 = ax.twinx()</p>
<h1 id="plot을-이용하여-선-그래프를-그려주자">plot을 이용하여 선 그래프를 그려주자</h1>
<p>ax1.plot(df[&quot;자치구&quot;], df[&quot;행복감 지수&quot;], &#39;-s&#39;, color=&#39;purple&#39;, linewidth=2, alpha=0.5, label=&#39;행복감 지수&#39;)
ax1.set_xlabel(&#39;자치구&#39;)</p>
<p>ax1.set_ylabel(&#39;행복감 지수&#39;)
ax1.tick_params(axis=&#39;both&#39;, direction=&#39;in&#39;)
plt.legend(loc=1, fontsize=13) # loc=1 는 upper right
plt.ylim([6,8]) # 행복감 지수의 값이 6에서 8사이에 형성되어서 6과 8사이 오도록 설정</p>
<p>plt.show()</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/c636783f-a85a-4bf2-9896-7d135f2e92df/image.png)

-&gt; 행복감 지수와 주관적 건강수준이 1인당 생활권 도시림 면적과 유의미한 양의 상관관계가 있어 보이지만, 위에서도 확인했듯이 그 자치구의 재정자립도나 1인당 연소득이 더 높은 상관관계를 가지고 있음

- 위의 결과에 대한 내용인 (행복감 지수, 주관적 건강수준)과 (1인당 생활권 도시림 면적, 재정자립도, 1인당 연소득) 간의 관계를 막대그래프로 나타냄
```python
A =corr[[&#39;1인당 생활권 도시림 면적&#39;,&#39;1인당 연소득&#39;,&#39;재정자립도&#39;]]
B= A.T.reset_index()


plt.rcParams[&#39;figure.figsize&#39;] = (10, 8)
plt.rcParams[&#39;font.size&#39;] = 10


index = np.arange(3)/2
label=[&#39;1인당 생활권 도시림 면적&#39;,&#39;1인당 연소득&#39;,&#39;재정자립도&#39;]

ax = plt.subplot()
p1 =ax.barh(index-0.1,B[&quot;행복감 지수&quot;],height=0.2,color=&#39;deeppink&#39;, label=&#39;행복감 지수&#39;, alpha=0.3)
p2 =ax.barh(index+0.1,B[&quot;주관적 건강수준&quot;], height=0.2,  color=&#39;pink&#39;, label=&#39;주관적 건강수준&#39;, alpha=0.3)

plt.xlabel(&#39;상관 계수&#39;, fontsize=18)


plt.legend((p1[0], p2[0]), (&#39;행복감 지수&#39;, &#39;주관적 건강수준&#39;),loc=&#39;upper center&#39;, ncol=1, bbox_to_anchor=(0.83, 0.8), fontsize=15)


plt.yticks(index, label,fontsize=12)

plt.show()</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/7ae7394e-9bc9-4e8d-9626-1a5383313f64/image.png" alt=""></p>
<h1 id="3-결론">3. 결론</h1>
<p>데이터 전처리 과정 중 데이터 수집, 데이터 정제, 가공의 과정을 직접 수행하였다. 특히, 결측치를 제거와 단순 대체법을 수행하였다. 수집한 모든 데이터들을 전처리한 후, 통합하여 분석 목적인 공원과 건강, 소득 간의 상관관계를 알아보고자 시각화를 수행하였다. 시각화 결과 신체적 건강(걷기, 중등도, 격렬)과 공원(도시림 면적) 간에는 큰 상관관계가 나타나지 않았고, 신체적 건강과 소득(재정자립도, 연소득) 역시 큰 상관관계가 나타나지 않았다. 반면에 심리적 건강(행복감지수, 주관적 건강수준 등)은 공원과 유의미한 상관관계가 나타났고, 소득과도 유의미한 상관관계가 나타났다.</p>
<p>이번 프로젝트를 진행하면서 데이터 전처리는 아직도 매우 어렵고, 복잡한 과정이지만 이 과정이 데이터 분석에 있어서 얼마나 중요한지 다시금 깨닫게 되었다. 그리고 스스로한테도 앞으로의 전공과 진로에 대하여 많은 도움을 받게 되었다. 데이터 전처리 과정이 단순하게 값과 데이터를 조작하는 것이 아닌 논리적이고 통계적인 지식을 갖고 수행해야 함을 또 느꼈다. 더 많은 데이터를 접해보고 기초적인 지식을 쌓아야 할 필요성을 느끼게 되었다. 아직 데이터를 변환하는 것이 약한 것 같아서 그 부분에 있어서 이번 프로젝트와 같은 추가적인 예제 학습과 분석을 방학동안 수행해야 겠다고 생각했다. </p>
<h1 id="4-참고-문헌">4. 참고 문헌</h1>
<p>인용, 출처, 참고 모두 포함</p>
<p>1) <a href="https://chs.kdca.go.kr/chs/index.do">https://chs.kdca.go.kr/chs/index.do</a>
2) <a href="https://blog.naver.com/udo_peanut/222527849666">https://blog.naver.com/udo_peanut/222527849666</a>
3) <a href="https://github.com/jj150618/walk_with_me/tree/main">https://github.com/jj150618/walk_with_me/tree/main</a>
4) <a href="https://data.seoul.go.kr/">https://data.seoul.go.kr/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[PP-인코딩과 범주화, 피쳐 엔지니어링, 파이프라인]]></title>
            <link>https://velog.io/@hate_all/PP-%EC%9D%B8%EC%BD%94%EB%94%A9%EA%B3%BC-%EB%B2%94%EC%A3%BC%ED%99%94-%ED%94%BC%EC%B3%90-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8</link>
            <guid>https://velog.io/@hate_all/PP-%EC%9D%B8%EC%BD%94%EB%94%A9%EA%B3%BC-%EB%B2%94%EC%A3%BC%ED%99%94-%ED%94%BC%EC%B3%90-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8</guid>
            <pubDate>Sun, 03 Dec 2023 20:54:17 GMT</pubDate>
            <description><![CDATA[<h1 id="1-인코딩">1. 인코딩</h1>
<h2 id="11-인코딩이란">1.1 인코딩이란</h2>
<ul>
<li><p>인코딩은 컴퓨터가 처리하기 용이하도록 기존의 데이터를 변경하거나 데이터양을 줄이기 위하여 코드화하고 압축하는 것을 의미한다.</p>
</li>
<li><p>실제 데이터셋에는 수치형 변수와 범주형 변수가 많이 혼재하고 있기 때문에 인코딩을 하게 된다.</p>
</li>
<li><p>인코딩된 코드를 원래의 데이터로 변환하는 것은 디코딩이라고 한다.</p>
</li>
</ul>
<h2 id="12-인코딩의-장단점">1.2 인코딩의 장단점</h2>
<ul>
<li>장점<ul>
<li>적은 정보 기록 -&gt; 적은 메모리 사용 </li>
<li>코드화로 원데이터의 의미 알 수 없음 -&gt; 보안에 유리</li>
<li>빠른 시간에 데이터 입력이 가능</li>
<li>코드의 규격화 -&gt; 데이터 검증 유리</li>
<li>데이터의 규격화 -&gt; 비교 용이</li>
</ul>
</li>
<li>단점<ul>
<li>데이터의 정확도 손실 발생 가능</li>
<li>가치 판단에 대한 코드화 시 의미와 정확도 감소</li>
<li>사용자가 변환된 코드를 알고 있어야 사용 가능</li>
<li>코드의 수가 제한될 수 있음</li>
<li>코드가 정확히 기록된 것인지 오류의 검증이 어려움</li>
</ul>
</li>
</ul>
<h2 id="13-대표적인-인코딩">1.3 대표적인 인코딩</h2>
<ul>
<li><p>레이블 인코딩 : 범주형 데이터는 일반적으로 텍스트로 되어 있으므로 이를 숫자(일반적으로 양의 정수)로 변환</p>
</li>
<li><p>이진화, 이산화 : 분류 문제에서는 종속변수가 범주형이어야 하므로 수치형 데이터는 범주형으로 변환</p>
</li>
<li><p>원핫인코딩, 더미변수화 : 회귀 모형이나 신경망에서는 독립변수는 수치형 변수이어야 하므로 범주형 변수를 수치형으로 변환</p>
</li>
<li><p>정수인코딩 : 텍스트 데이터는 자연어 처리를 위해 토큰화 과정을 거쳐야 함</p>
</li>
</ul>
<h1 id="2-인코딩-방법">2. 인코딩 방법</h1>
<h2 id="21-데이터-생성">2.1 데이터 생성</h2>
<pre><code class="language-python">import pandas as pd
df = pd.DataFrame({&#39;weight&#39;:[40, 80, 60, 50, 90], &#39;height&#39;:[162, 155, 182, 173, 177], &#39;sex&#39;:[&#39;f&#39;, &#39;m&#39;, &#39;m&#39;, &#39;f&#39;, &#39;m&#39;], 
                   &#39;blood_type&#39;:[&#39;O&#39;, &#39;A&#39;, &#39;B&#39;, &#39;O&#39;, &#39;A&#39;], &#39;health&#39;:[&#39;good&#39;, &#39;excellent&#39;, &#39;bad&#39;, &#39;bad&#39;, &#39;good&#39;]})
df</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/6a776576-fcd0-445a-a275-6088f673f086/image.png" alt="">
weight, height -&gt; 연속 수치형
sex, blood_type, health -&gt; 범주형</p>
<h2 id="22-범주형-데이터-→-이산-수치형-데이터">2.2 범주형 데이터 → 이산 수치형 데이터</h2>
<h3 id="221-ordinalencoder">2.2.1 OrdinalEncoder</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import OrdinalEncoder

df_oe = df.copy()
oe = OrdinalEncoder()
oe.fit(df)

print(f&#39;{oe.categories_=}&#39;)

df_oe = pd.DataFrame(oe.transform(df), columns=df.columns)
df_oe</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/6e0fb79f-2d4f-4b65-a366-8f3a0d308dde/image.png" alt=""></p>
<pre><code class="language-python">df_oe = df.copy()
oe = OrdinalEncoder()
oe.fit(df[[&#39;sex&#39;, &#39;blood_type&#39;]])

print(f&#39;{oe.categories_=}&#39;)

df_oe.iloc[:,2:4] = oe.transform(df[[&#39;sex&#39;, &#39;blood_type&#39;]])
df_oe</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/90a3c4fe-f4b7-4d68-abb9-2603d8b93ee7/image.png" alt=""></p>
<pre><code class="language-python">oe.inverse_transform(df_oe.iloc[:,2:4]) </code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/bf4d840b-84cf-46cd-ba3c-3b7f6fb28017/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>Ordinal Encoder(1:1 변환)</p>
<ul>
<li>범주형 데이터를 정수로 인코딩하는 방법</li>
<li>여러 독립 변수(열)에 사용 가능</li>
<li>상태공간의 값을 컬럼으로 늘어놓는 것이 아니라 그 자체 변수에서 unique한 값을 숫자로 구분</li>
<li>2차원 데이터에 적합</li>
<li>순서를 유지할 필요가 있는 서열이 존재하는 데이터 처리에 적합</li>
</ul>
</li>
<li><p>첫번째 코드 실행</p>
<ul>
<li>데이터를 복사(df_oe) 후, oe에 Ordinal Encoder 객체 생성</li>
<li>fit 함수로 oe를 학습</li>
<li>수치형 데이터인 weight와 height도 범주형으로 인식되어 변경됨</li>
</ul>
</li>
<li><p>두번째 코드 실행</p>
<ul>
<li>데이터 복사(df_oe) 후, oe에 Ordinal Encoder 객체 생성</li>
<li>fit 함수로 oe를 학습(&#39;sex&#39;와 &#39;blood_type&#39; 특정)</li>
<li>&#39;sex&#39;와 &#39;blood_type&#39;만 인코딩된 결과 도출</li>
</ul>
</li>
<li><p>세번째 코드 실행</p>
<ul>
<li>인코딩된 &#39;sex&#39;와 &#39;blood_type&#39;을 디코딩</li>
</ul>
</li>
</ul>
<h3 id="222-labelencoder">2.2.2 LabelEncoder</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import LabelEncoder

df_le = df.copy()
health_le = LabelEncoder().fit(df.health)
df_le[&#39;health&#39;] = health_le.transform(df.health)
df_le</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/ab3482c0-5c6b-4512-a726-1c449a828d48/image.png" alt=""></p>
<pre><code class="language-python">df_le = df.copy()
df_le[&#39;health&#39;] = LabelEncoder().fit_transform(df.health)
df_le</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/fc766be7-de01-4f0b-a763-a970c2ba4b0e/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>Label Encoder(1:1 변환)</p>
<ul>
<li>범주형 데이터를 정수로 인코딩</li>
<li>하나의 종속변수(열)에만 사용 가능</li>
<li>ordinal encoder와 유사하게 label을 붙임</li>
<li>label은 array형태</li>
<li>단순 매칭이라 볼 수 있음</li>
</ul>
</li>
<li><p>첫번째 코드 실행</p>
<ul>
<li>데이터 복사(df_le) 후, Label Encoder 객체 생성 및 fit 함수 적용</li>
<li>하나의 변수(health)에 대해서 변환(알파벳 순서)</li>
</ul>
</li>
<li><p>두번째 코드 실행</p>
</li>
</ul>
<pre><code>- 데이터 복사(df_le) 후, Label Encoder 객체 생성 및 fit 함수 적용
- fit_transform을 통해 한번에 인코딩 수행(health 변수)</code></pre><h3 id="223-targetencoder">2.2.3 TargetEncoder</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import TargetEncoder

df_te = df.copy()

te = TargetEncoder(smooth=0, target_type=&#39;continuous&#39;)

te.fit(df[&#39;blood_type&#39;].values.reshape(-1, 1), df.weight)

print(f&#39;{te.categories_=}&#39;)

df_te[&#39;blood_type_target&#39;] = te.transform(df[&#39;blood_type&#39;].values.reshape(-1, 1))
df_te</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/58745254-18ca-4203-9963-64262f94b53e/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>TargetEncoder(1:1 변환)</p>
<ul>
<li>범주형 데이터를 특정한 컬럼(타겟)의 값의 크기와 비례한 숫자로 인코딩, 주로 평균값</li>
<li>인코딩 값이 ordinal처럼 숫자이지만 타겟값과 관련된 순서</li>
<li>low cardinality</li>
<li>target값을 사용하기 때문에 가능성 유 =&gt; CV를 통해 조절 가능</li>
<li>train set의 target 평균과 test set의 target 평균이 매우 다를 경우의 과적합 =&gt; smoothing 파라미터로 조절</li>
</ul>
</li>
<li><p>코드 실행</p>
<ul>
<li>데이터 복사 후, TargetEncoder 객체 생성</li>
<li>smooth로 정밀도를 조정, target_type으로 인코딩 타입 지정</li>
<li>fit -&gt; 데이터 학습</li>
<li>타겟(weight) &amp; blood_type 인코딩 -&gt; blood_type_target 생성</li>
<li>reshape -&gt; 인코딩 되는 값 2차원 변환 필요</li>
</ul>
</li>
</ul>
<h2 id="23-범주형-데이터-→-이진-데이터">2.3 범주형 데이터 → 이진 데이터</h2>
<h3 id="231-one-hot-encoding">2.3.1 One-Hot-Encoding</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import OneHotEncoder

df_ohe = df.copy()

ohe = OneHotEncoder().fit(df_ohe[[&#39;blood_type&#39;]])

print(f&#39;{ohe.categories_=}&#39;)

df_ohe[ohe.categories_[0]] = ohe.transform(df_ohe[[&#39;blood_type&#39;]]).toarray()
df_ohe</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/192eb358-06be-4462-a0a2-98688b3ada01/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>One-Hot-Encoding(1:M 변환)</p>
<ul>
<li>하나의 컬럼에 있는 범주형 데이터를 여러개의 이진수 컬럼(수치형 데이터)로 인코딩</li>
<li>one-of-K 인코딩이라고도 함</li>
<li>matrix형태나 array형태로도 반환 가능</li>
<li>특정 카테고리에 해당(1), 나머지(0)으로 매핑, 카테고리 종류의 개수만큼 추가적인 column들을 만들어 냄 -&gt; 범주형 변수 값들의 종류가 많아진다면, 모델링의 학습속도가 매우 느려짐.</li>
<li>분류 -&gt; n개 카테고리, 회귀 -&gt; n-1개 카테고리(자유도 반영)</li>
</ul>
</li>
<li><p>코드 실행</p>
<ul>
<li>데이터 복사 후, OneHotEncoder 객체 생성 및 fit 적용</li>
<li>sparse matrix(희소 행렬; 0 원소 많음)로 결과 반환 -&gt; toarray를 사용(조밀 행렬 변환) -&gt; ndarray로 변환</li>
<li>새로운 컬럼 삽입</li>
</ul>
</li>
</ul>
<h3 id="232-dummy-encoding">2.3.2 Dummy encoding</h3>
<p>기본</p>
<pre><code class="language-python">pd.get_dummies(df, columns=[&#39;sex&#39;, &#39;blood_type&#39;], drop_first=False)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/362d6853-6cbf-4a9f-aff3-c8670b7cc26f/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>Dummy encoding(1:M 변환)</p>
<ul>
<li>One-hot encoding과 동일한 기능</li>
<li>회귀분석에서 범주형 변수를 고려할 때 사용</li>
<li>Pandas에서 제공</li>
<li>여러 컬럼을 한 번에 변환 가능</li>
<li>컬럼의 수가 상태공간 크기만큼 많아질 수 있음</li>
<li>train 데이터의 상태공간 크기와 test 데이터의 상태공간 크기가 다르면 predict할때 오류 발생</li>
</ul>
</li>
<li><p>코드 실행</p>
<ul>
<li>pd.get_dummies() 사용</li>
<li>컬럼 지정(sex, blood_type)</li>
</ul>
</li>
</ul>
<h2 id="24-연속-수치형-데이터-→-이진-데이터">2.4 연속 수치형 데이터 → 이진 데이터</h2>
<h3 id="241-binarizer">2.4.1 Binarizer</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import Binarizer

df_bin = df.copy()

df_bin[&#39;weight_bin&#39;] = Binarizer(threshold=50).fit_transform(df.weight.values.reshape(-1,1))
df_bin[&#39;height_bin&#39;] = Binarizer(threshold=170).fit_transform(df.height.values.reshape(-1,1))
df_bin</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/d6e6366d-03df-4014-a600-36cabf2a2d73/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>Binarizer(1:1 변환)</p>
<ul>
<li>연속 수치형 데이터를 기준값을 기준으로 이진수로 인코딩</li>
<li>수치형 변수에 대해서만 변환 가능</li>
<li>threshold 파라미터 -&gt; 기준값을 나타냄</li>
</ul>
</li>
<li><p>코드 실행</p>
<ul>
<li>데이터 복사 후, Binarizer 객체 생성 및 fit_transform 적용</li>
<li>weight_bin 생성, 기준값 50 -&gt; 크면 1 작거나 같으면 0</li>
<li>height_bin 생성, 기준값 170 -&gt; 크면 1 작거나 같으면 0</li>
</ul>
</li>
</ul>
<h3 id="242-labelbinarizer">2.4.2 LabelBinarizer</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import LabelBinarizer

df_lb = df.copy()

lb = LabelBinarizer().fit(df.health)

print(f&#39;{lb.classes_ = }&#39;)

health_lb = lb.transform(df.health)
print(&#39;health_lb = \n&#39;, health_lb)

df_lb[lb.classes_] = health_lb
df_lb</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/dbfa0d39-474c-43e3-8168-0ef7d8d89a45/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>LabelBinarizer(1:M 변환)</p>
<ul>
<li>연속형 데이터를 이진수 컬럼으로 인코딩</li>
<li>하나의 컬럼(종속변수, 타겟)에만 사용 가능</li>
<li>One-Hot-Encoding 형식의 target 얻을 수 있음</li>
</ul>
</li>
<li><p>코드 실행</p>
<ul>
<li>데이터 복사 후, LabelBinarizer 객체 생성 및 fit 적용</li>
<li>lb.classes_ -&gt; 인코딩한 클래스 확인</li>
<li>lb.transform() -&gt; 인코딩 변환</li>
</ul>
</li>
</ul>
<h3 id="243-multilabelbinarizer">2.4.3 MultiLabelBinarizer</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import MultiLabelBinarizer

df_mlb = df.copy()

df_mlb[&#39;test&#39;] = [[&#39;math&#39;, &#39;english&#39;], [&#39;math&#39;, &#39;science&#39;], [&#39;science&#39;], [&#39;math&#39;, &#39;english&#39;], [&#39;science&#39;]]
df_mlb</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/e5a51dbe-ddd1-44b1-90bf-f80c0980f799/image.png" alt=""></p>
<pre><code class="language-python">mlb = MultiLabelBinarizer().fit(df_mlb.test)

print(f&#39;{mlb.classes_ = }&#39;)

df_mlb[mlb.classes_] = mlb.transform(df_mlb.test)
df_mlb</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/a510626c-4773-4580-91e2-4a2081042d9d/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>MultiLabelBinarizer(1:M 변환)</p>
<ul>
<li>multi-class(여러 개의 범주가 있는) 데이터를 이진수 컬럼으로 인코딩</li>
<li>하나의 컬럼(종속변수, 타겟)에만 사용 가능</li>
<li>한 데이터 셋에 대해 여러 레이블을 할당할 수 있음</li>
</ul>
</li>
<li><p>첫번째 코드 실행</p>
<ul>
<li>데이터 복사 후, test 컬럼 추가</li>
<li>해당 컬럼에는 여러 개의 범주를 적용</li>
</ul>
</li>
<li><p>두번째 코드 실행</p>
<ul>
<li>MultiLabelBinarizer 객체 생성 및 fit 적용</li>
<li>classes_로 인코딩된 클래스 확인</li>
</ul>
</li>
</ul>
<h1 id="3-범주화">3. 범주화</h1>
<ul>
<li>연속형 변수를 구간별로 나누어 범주형 변수로 변환하는 것</li>
<li>quantization 또는 binning이라고도 함</li>
</ul>
<h2 id="31-k-bins-discretization">3.1 K-bins discretization</h2>
<p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import KBinsDiscretizer

df_kbd = df.copy()

kbd = KBinsDiscretizer(n_bins=3, encode=&#39;ordinal&#39;).fit(df[[&#39;weight&#39;, &#39;height&#39;]])

df_kbd[[&#39;weight_bin&#39;, &#39;height_bin&#39;]] = kbd.transform(df[[&#39;weight&#39;, &#39;height&#39;]])
df_kbd</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/f2360787-1ca2-4b37-b9ec-cf73ab43cf35/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>코드 실행</p>
<ul>
<li>데이터 복사 후 , KBinsDiscretizer 객체 생성 및 fit 적용</li>
<li>bin(3), 동일 빈도, kbd.transform() : 인코딩 변환</li>
</ul>
</li>
</ul>
<h1 id="4-피쳐-엔지니어링">4. 피쳐 엔지니어링</h1>
<h2 id="41-피쳐">4.1 피쳐</h2>
<ul>
<li>데이터 모델(특히, 인공지능)에서 예측을 수행하는 데 사용되는 입력변수를 의미</li>
<li>통계학에서는 독립 변수라고 함</li>
</ul>
<h2 id="42-피쳐의-유형">4.2 피쳐의 유형</h2>
<ul>
<li><p>속성에 따라</p>
<ul>
<li>범주형(categorical): 범주나 순위가 있는 변수</li>
<li>수치형(numerical): 수치로 표현되는 변수</li>
</ul>
</li>
<li><p>인과관계에 따라</p>
<ul>
<li>독립변수(independent variable): 다른 변수에 영향을 받지 않고 종속변수에 영향을 주는 변수</li>
<li>종속변수(dependent variable): 독립 변수로부터 영향을 받는 변수</li>
</ul>
</li>
</ul>
<ul>
<li><p>머신 러닝에서</p>
<ul>
<li>입력(input): 변수(Feature), 속성(Attribute), 예측변수(Predictor), 차원(Dimension), 관측치(Observation), 독립변수(Independent Variable)</li>
<li>출력(output): 라벨(Label), 클래스(Class), 목푯값(Target), 반응(Response), 종속변수(Dependent Variable)</li>
</ul>
</li>
</ul>
<h2 id="43-피쳐-엔지니어링">4.3 피쳐 엔지니어링</h2>
<ul>
<li>머신러닝 알고리즘의 성능을 향상시키기 위하여 데이터에 대한 도메인 지식을 활용하여 변수를 조합하거나 새로운 변수를 만드는 과정</li>
<li>머신러닝 성능 향상 -&gt; 피쳐 엔지니어링 + 하이퍼 파라미터 최적화
<img src="https://velog.velcdn.com/images/hate_all/post/9637f911-909a-49ee-9b21-8436fd49525f/image.png" alt="">
<img src="https://velog.velcdn.com/images/hate_all/post/39410abd-4bb6-4f70-ba90-919f1d8fa09e/image.png" alt=""></li>
</ul>
<h2 id="44-피쳐-추출">4.4 피쳐 추출</h2>
<ul>
<li>변수들 사이에 내재한 특성이나 관계를 분석하여 이들을 잘 표현할 수 있는 새로운 선형 혹은 비선형 결합 변수를 만들어 데이터를 줄이는 방법</li>
<li>고차원의 원본 피쳐 공간을 저차원의 새로운 피쳐 공간으로 투영</li>
</ul>
<h3 id="441-주성분-분석">4.4.1 주성분 분석</h3>
<ul>
<li>가장 널리 사용되는 차원(변수) 축소 기법 중 하나</li>
<li>원 데이터의 분산(variance)을 최대한 보존하면서 서로 직교하는 새 기저(축)를 찾아, 고차원 공간의 표본들을 선형 연관성이 없는 저차원 공간으로 변환하는 기법</li>
<li>PCA는 기존의 변수를 조합하여 서로 연관성이 없는 새로운 변수, 즉 주성분(principal component, PC)들을 만들어 냄</li>
<li>주성분의 개수를 증가시킴에 따라 원 데이터의 분산의 보존수준이 높아짐</li>
<li>변수들의 공분산 행렬이나 상관행렬을 이용</li>
<li>행의 수와 열의 수가 같은 정방행렬에서만 사용</li>
<li>PCA는 Target값을 사용하지 않으므로 비지도 학습
<img src="https://velog.velcdn.com/images/hate_all/post/d6ac6935-2038-4315-a623-5984da1996af/image.png" alt=""></li>
</ul>
<h4 id="4411-주성분-분석-절차">4.4.1.1 주성분 분석 절차</h4>
<ol>
<li>학습 데이터셋에서 분산이 최대인 축(axis)을 찾음</li>
<li>첫번째 축과 직교(orthogonal)하면서 분산이 최대인 두 번째 축을 찾음</li>
<li>첫 번째 축과 두 번째 축에 직교하고 분산을 최대한 보존하는 세 번째 축을 찾음</li>
<li>1~3과 같은 방법으로 데이터셋의 차원(특성 수)만큼의 축을 찾음</li>
</ol>
<h3 id="442-선형판별분석">4.4.2 선형판별분석</h3>
<ul>
<li>입력 데이터 세트를 저차원 공간으로 투영(projection)해 차원을 축소하는 기법</li>
<li>데이터의 Target값 클래스끼리 최대한 분리할 수 있는 축을 찾음 → 지도 학습</li>
<li>특정 공간상에서 클래스 분리를 최대화하는 축을 찾기 위해 클래스 간 분산(between-class scatter)과 클래스 내부 분산(within-class scatter)의 비율을 최대화하는 방식으로 차원을 축소</li>
<li>SVM 같은 다른 분류 알고리즘을 적용하기 전에 차원을 축소시키는 데 사용
<img src="https://velog.velcdn.com/images/hate_all/post/4b0b3bd1-e605-4173-b33f-058ae6b4654c/image.png" alt=""></li>
</ul>
<h3 id="443-pca와-lda-수행하기">4.4.3 PCA와 LDA 수행하기</h3>
<h4 id="4431-데이터셋-로드">4.4.3.1 데이터셋 로드</h4>
<pre><code class="language-python">from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

iris = datasets.load_iris()

X = iris.data
y = iris.target
target_names = list(iris.target_names)

print(f&#39;{X.shape = }, {y.shape = }&#39;)
print(f&#39;{target_names = }&#39;)</code></pre>
<p>x -&gt; 피쳐
y -&gt; 타겟
target_names -&gt; 타겟 이름 [&#39;setosa&#39;, &#39;versicolor&#39;, &#39;virginica&#39;]
<img src="https://velog.velcdn.com/images/hate_all/post/635e96ea-b876-4b64-9275-03a37b0de3e3/image.png" alt=""></p>
<h4 id="4432-pca">4.4.3.2 PCA</h4>
<p>기본</p>
<pre><code class="language-python">pca = PCA(n_components=2)

pca_fitted = pca.fit(X)

print(f&#39;{pca_fitted.components_ = }&#39;)
print(f&#39;{pca_fitted.explained_variance_ratio_ = }&#39;)

X_pca = pca_fitted.transform(X)
print(f&#39;{X_pca.shape = }&#39;) </code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/7a480e0e-485a-4053-ad49-5e742ae22a0f/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>PCA</p>
<ul>
<li>차원을 줄이기 위해 축을 최전 -&gt; 새로운 축 찾아내는 방법</li>
<li>몇 개의 점은 서로 겹치게 되는 문제점 발생 -&gt; 정보 유실 발생 -&gt; 분산이 가장 넓은 지역 찾기</li>
<li>비지도 학습 -&gt; 정답 없음, 분석가가 주성분 개수 지정</li>
<li>주성분 개수 적음 -&gt; 차원축소 많이 됨, 정보손실 발생</li>
<li>주성분 개수 많음 -&gt; 정보손실 적음, 차원축소 의미 퇴색</li>
<li>적절한 주성분 개수 선택 중요</li>
<li>고유값-주성분 분산 변화 확인 -&gt; 분산 비율이 완만하게 감소되는 차원 버림</li>
<li>데이터의 클래스 차이가 평균보다 분산의 차이에 있을 때 뛰어난 성능</li>
</ul>
</li>
<li><p>코드 실행(코드 학습)</p>
<ul>
<li>PCA 객체 생성 및 차원 설정</li>
<li>현재 피쳐(x) 4개 -&gt; n_components=2 2차원 설정</li>
<li>PCA는 비지도 학습이므로 y값을 넣지 않음</li>
<li>주성분 벡터(pca_fitted.components_)와 분산 비율(pca_fitted.explained_variance_ratio_)</li>
</ul>
</li>
</ul>
<h4 id="4433-lda">4.4.3.3 LDA</h4>
<p>기본</p>
<pre><code class="language-python">lda = LinearDiscriminantAnalysis(n_components=2)

lda_fitted = lda.fit(X, y)

print(f&#39;{lda_fitted.coef_=}&#39;)
print(f&#39;{lda_fitted.explained_variance_ratio_=}&#39;)

X_lda = lda_fitted.transform(X)
print(f&#39;{X_lda.shape = }&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/85afb08a-cb30-45aa-a8f9-d6e8b76438e8/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>LDA</p>
<ul>
<li>두 범주를 잘 구분하는 직선 -&gt; 사영 후 두 범주 중심(평균)이 서로 멀고 그 분산이 작아야 함</li>
<li>범주 간 분산이 최대 -&gt; 각 범주간 중심(평균)이 서로 멀어지게 분류</li>
<li>범주 내부 분산이 작아짐 -&gt; 하나의 범주끼리는 조밀하게 뭉쳐있음</li>
<li>데이터의 클래스 차이가 분산보다 평균의 차이가 있을 때 성능이 뛰어남</li>
<li>3D plot으로 표현할 때 뛰어난 성능</li>
</ul>
</li>
<li><p>코드 실행</p>
<ul>
<li>LDA 객체 생성 및 차원 설정</li>
<li>현재 피쳐(x) 4개 -&gt; n_components=2 2차원 설정</li>
<li>LDA는 지도학습이므로 타겟값(y)이 필요</li>
<li>LDA의 계수(lda_fitted.coef_)와 LDA의 분산에 대한 설명력(lda_fitted.explained_variance_ratio_)</li>
</ul>
</li>
</ul>
<h4 id="4434-시각화">4.4.3.4 시각화</h4>
<p>기본</p>
<pre><code class="language-python">import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

df_pca = pd.DataFrame(X_pca, columns=[&#39;PC1&#39;, &#39;PC2&#39;])
df_lda = pd.DataFrame(X_lda, columns=[&#39;LD1&#39;, &#39;LD2&#39;])
y = pd.Series(y).replace({0:&#39;setosa&#39;, 1:&#39;versicolor&#39;, 2:&#39;virginica&#39;})

fig, ax = plt.subplots(1, 2, figsize=(10, 4))

sns.scatterplot(df_pca, x=&#39;PC1&#39;, y=&#39;PC2&#39;, hue=y, style=y, ax=ax[0], palette=&#39;Set1&#39;)
ax[0].set_title(&#39;PCA of IRIS dataset&#39;)

sns.scatterplot(df_lda, x=&#39;LD1&#39;, y=&#39;LD2&#39;, hue=y, style=y, ax=ax[1], palette=&#39;Set1&#39;)
ax[1].set_title(&#39;LDA of IRIS dataset&#39;)

plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/95d41e04-ebef-4110-9e60-1f1daf6206f0/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>코드 실행</p>
<ul>
<li>Seaborn을 이용하기 위해 데이터프레임으로 변환</li>
<li>subplot으로 시각화</li>
</ul>
</li>
</ul>
<h3 id="444-특이값-분해">4.4.4 특이값 분해</h3>
<ul>
<li>M X N 차원의 행렬데이터에서 특이값을 추출하고 이를 통해 주어진 데이터 세트를 효과적으로 축약할 수 있는 기법</li>
</ul>
<h3 id="445-요인분석">4.4.5 요인분석</h3>
<ul>
<li>데이터 안에 관찰할 수 있는 잠재적인 변수(Latent Variable)가 존재한다고 가정</li>
<li>모형을 세운 뒤 관찰 가능한 데이터를 이용하여 해당 잠재 요인을 도출하고 데이터 안의 구조를 해석하는 기법</li>
<li>주로 사회과학이나 설문 조사 등에서 많이 활용</li>
</ul>
<h3 id="446-독립성분분석">4.4.6 독립성분분석</h3>
<ul>
<li>주성분 분석과는 달리 다변량의 신호를 통계적으로 독립적인 하부성분으로 분리하여 차원을 축소하는 기법</li>
<li>독립 성분의 분포는 비정규 분포를 따르게 되는 차원축소 기법</li>
</ul>
<h3 id="447-다차원-척도법">4.4.7 다차원 척도법</h3>
<ul>
<li>개체들 사이의 유사성, 비유사성을 측정하여 2차원 또는 3차원 공간상에 점으로 표현하여 개체들 사이의 집단화를 시각적으로 표현하는 분석 방법</li>
</ul>
<h2 id="45-피쳐-선택">4.5 피쳐 선택</h2>
<ul>
<li>피쳐 중 타겟에 가장 관련성이 높은 피쳐만을 선정하여 피쳐의 수를 줄이는 방법</li>
<li>관련없거나 중복되는 피쳐들을 필터링하고 간결한 subset을 생성</li>
<li>모델 단순화, 훈련 시간 축소, 차원의 저주 방지, 과적합(Over-fitting)을 줄여 일반화해주는 장점이 있음</li>
</ul>
<h2 id="46-피쳐-선택-기법">4.6 피쳐 선택 기법</h2>
<ul>
<li>종속변수 활용여부에 따라 : Supervised(종속변수를 활용하여 선택), Unsupervised(독립변수들 만으로 선택)</li>
<li>선택 메커니즘에 따라 : Filter, Wrapper, Embedded, Hybrid(Filter + Wrapper)
<img src="https://velog.velcdn.com/images/hate_all/post/b2f4bf73-0bac-4f81-9372-7d970bdd1fe2/image.png" alt=""></li>
</ul>
<h3 id="461-필터-기법">4.6.1 필터 기법</h3>
<ul>
<li>데이터의 통계적 측정 방법을 사용하여 변수들의 상관관계를 알아냄</li>
<li>계산속도가 빠르고 변수 간 상관관계를 알아내는 데 적합하여 래퍼 기법(Wrapper Method)을 사용하기 전에 전처리하는 데 사용</li>
<li>특정 모델링 기법에 의존하지 않고 데이터의 통계적 특성부터 변수를 택하는 기법</li>
<li>모든 피쳐 배정 -&gt; 최적의 subset 선택 -&gt; 학습 알고리즘 -&gt; 성능 평가</li>
</ul>
<h4 id="4611-분산-기반-선택">4.6.1.1 분산 기반 선택</h4>
<p>기본</p>
<pre><code class="language-python">from sklearn import datasets
from sklearn.feature_selection import VarianceThreshold

iris = datasets.load_iris()

X = iris.data 
y = iris.target 
X_names = iris.feature_names 
y_names = iris.target_names 

sel = VarianceThreshold(threshold=0.2).fit(X)
print(f&#39;{sel.variances_ = }&#39;)

X_selected = sel.transform(X)
X_selected_names = [X_names[i] for i in sel.get_support(indices=True)]

print(f&#39;{X_selected_names = }&#39;)
print(f&#39;{X_selected[:5] = }&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/86c930c7-65b6-452a-b314-de2d49d82cf3/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>분산 기반 선택 : 분산이 낮은 변수를 제거하는 방법</p>
</li>
<li><p>코드 실행</p>
<ul>
<li>iris 데이터셋 로드, iris 데이터셋의 피쳐들(x), iris 데이터셋의 타겟(y)</li>
<li>분산이 0.2 이상인 피쳐들만 선택하도록 학습(기준값=0.2)</li>
<li>각 피쳐의 분산 확인(sel.variances_)</li>
<li>분산이 0.2 이상인 피쳐들만 선택 적용</li>
<li>선택된 피쳐들의 이름(X_selected_names)</li>
</ul>
</li>
</ul>
<h4 id="4612-정보-소득">4.6.1.2 정보 소득</h4>
<ul>
<li>가장 정보 소득이 높은 속성을 선택하여 데이터를 더 잘 구분하게 되는 것</li>
</ul>
<h4 id="4613-카이제곱-검정">4.6.1.3 카이제곱 검정</h4>
<ul>
<li>카이제곱  분포에 기초한 통계적 방법으로 관찰된 빈도가 기대되는 빈도와 의미있게 다른지 여부를 검증하기 위해 사용되는 검증 방법</li>
<li>범주형 데이터에서 두 요인간 독립성 검정에서 사용</li>
<li>χ2-value가 크면 두 요인간 독립이 아니라는 의미(즉, 상관관계가 있음)</li>
</ul>
<h4 id="4614-피셔-스코어">4.6.1.4 피셔 스코어</h4>
<ul>
<li>최대 가능성 방정식을 풀기 위해 통계에 사용되는 뉴턴(Newton)의 방법</li>
</ul>
<h4 id="4615-상관계수">4.6.1.5 상관계수</h4>
<ul>
<li>두 변수 사이의 통계적 관계를 표현하기 위해 특정한 상관관계의 정도를 수치적으로 나타낸 계수</li>
</ul>
<h4 id="4616-scikit-learn-제공-피쳐-선택-메서드">4.6.1.6 Scikit-Learn 제공 피쳐 선택 메서드</h4>
<ul>
<li>SelectKBest(): 고정된 k개의 피쳐 선택기</li>
<li>SelectPercentile(): 분위수 기반 선택기</li>
<li>SelectFpr(): False positive rate 기반 선택기</li>
<li>SelectFdr(): 추정된 False discovery rate 기반 선택기</li>
<li>SelectFwe(): familiy-wise error rate 기반 선택기</li>
<li>GenericUnivariateSelect(): 단변량 피쳐 선택기</li>
</ul>
<h4 id="4617-scikit-learn-제공-피쳐-선택-기준">4.6.1.7 Scikit-Learn 제공 피쳐 선택 기준</h4>
<ul>
<li>f_classif: ANOVA F-value 분류</li>
<li>mutual_info_classif: 상호정보량(mutual information) 분류</li>
<li>chi2: 카이제곱 분류</li>
<li>f_regression: F-value 회귀</li>
<li>mutual_info_regression: 상호정보량(mutual information) 회귀</li>
</ul>
<h4 id="4618-f-value">4.6.1.8 F-value</h4>
<ul>
<li>두 모집단(확률변수)의 분산의 비율을 나타내는 값</li>
<li>ANOVA, Regression에서는 모형이 설명하는 분산/잔자의 분산</li>
<li>F-value가 크면 모형이 잘 설명하고 있다는 의미</li>
</ul>
<h4 id="4619-상호정보량">4.6.1.9 상호정보량</h4>
<ul>
<li>하나의 확률변수가 다른 하나의 확률변수에 대해 제공하는 정보의 양</li>
<li>두 확률변수가 공유하는 엔트로피</li>
<li>두 확률변수가 독립이라면, 상호정보량은 0</li>
<li>두 확률변수의 상관관계가 강할수록 상호정보량이 커짐</li>
</ul>
<h4 id="46110-기타-코드">4.6.1.10 기타 코드</h4>
<p>기본</p>
<pre><code class="language-python">from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif, f_regression, chi2

sel_fc = SelectKBest(f_classif, k=2).fit(X, y)
print(&#39;f_classif: &#39;)
print(f&#39;{sel_fc.scores_ = }&#39;)
print(f&#39;{sel_fc.pvalues_ = }&#39;)
print(f&#39;{sel_fc.get_support() = }&#39;)
print(&#39;Selected features: &#39;, [X_names[i] for i in sel_fc.get_support(indices=True)])

sel_fr = SelectKBest(f_regression, k=2).fit(X, y)
print(&#39;\nf_regression: &#39;)
print(f&#39;{sel_fr.scores_ = }&#39;)
print(f&#39;{sel_fr.pvalues_ = }&#39;)
print(f&#39;{sel_fr.get_support() = }&#39;)
print(&#39;Selected features: &#39;, [X_names[i] for i in sel_fr.get_support(indices=True)])

sel_chi2 = SelectKBest(chi2, k=2).fit(X, y)
print(&#39;\nchi2: &#39;)
print(f&#39;{sel_chi2.scores_ = }&#39;)
print(f&#39;{sel_chi2.pvalues_ = }&#39;)
print(f&#39;{sel_chi2.get_support() = }&#39;)
print(&#39;Selected features: &#39;, [X_names[i] for i in sel_chi2.get_support(indices=True)])</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/c36c2335-d187-4bd8-aa5c-62f56a510f08/image.png" alt=""></p>
<p>학습</p>
<ul>
<li>SelectKBest : k개의 베스트 피쳐를 선택</li>
<li>f분류/f회귀/카이제곱분류</li>
</ul>
<h3 id="462-래퍼-기법">4.6.2 래퍼 기법</h3>
<ul>
<li>예측 정확도 측면에서 가장 좋은 성능을 보이는 하위 집합을 선택하는 기법</li>
<li>검색 가능한 방법으로 하위 집합을 반복해서 선택하여 테스트하는 것이므로 탐욕 알고리즘(Greedy Algorithm)에 속함</li>
<li>반복하여 선택하는 방법으로 시간이 오래 걸리고 부분집합의 수가 기하급수적으로 늘어 과적합의 위험이 발생할 수 있음</li>
<li>일반적으로 래퍼 방법은 필터 방법보다 예측 정확도가 높음
<img src="https://velog.velcdn.com/images/hate_all/post/86dd92ee-26b9-4f32-809f-77d606d7c77c/image.png" alt=""></li>
</ul>
<h4 id="4621-변수-선택을-위한-알고리즘">4.6.2.1 변수 선택을 위한 알고리즘</h4>
<ul>
<li>전진 선택법(Forward Selection) : 모형을 가장 많이 향상시키는 변수를 하나씩 점진적으로 추가하는 방법</li>
<li>후진 제거법(Backward Elimination) : 모두 포함된 상태에서 시작하여 가장 적은 영향을 주는 변수부터 하나씩 제거</li>
<li>단계적 방법(Stepwise Method) : 전진선택과 후향제거의 결합, 각 단계에서 최상의 속성을 선택하고 나머지 속성 중 최악의 속성을 제거하는 과정을 실행</li>
<li>의사결정트리</li>
</ul>
<h4 id="4622-래퍼기법의-종류">4.6.2.2 래퍼기법의 종류</h4>
<ul>
<li>RFE(Recursive Feature Elimination) : SVM(Support Vector Machine)을 사용하여 재귀적으로 제거하는 방법. 전진 선택, 후진 제거, 단계적 방법 사용</li>
<li>SFS(Sequential Feature Selection) : 그리디 알고리즘(Greedy Algorithm)으로 빈 부분 집합에서 특성 변수를 하나씩 추가하는 방법. 전진 선택, 후진 제거 사용</li>
</ul>
<h4 id="4623-코드-실행">4.6.2.3 코드 실행</h4>
<p>기본</p>
<pre><code class="language-python">from sklearn.datasets import load_iris
from sklearn.feature_selection import RFE, RFECV, SelectFromModel, SequentialFeatureSelector
from sklearn.svm import SVC, SVR

X, y = load_iris(return_X_y=True)

svc = SVR(kernel=&quot;linear&quot;, C=3)

rfe = RFE(estimator=svc, n_features_to_select=2, step=1)
rfe_cv = RFECV(estimator=svc, step=1, cv=5) 

rfe.fit(X, y)
print(&#39;RFE Rank: &#39;, rfe.ranking_)

X_selected = rfe.transform(X) 
X_selected_names = [X_names[i] for i in rfe.get_support(indices=True)]

print(f&#39;{X_selected_names = }&#39;)
print(f&#39;{X_selected[:5] = }&#39;)

rfe_cv.fit(X, y)
print(&#39;RFECV Rank: &#39;, rfe_cv.ranking_)

X_selected = rfe_cv.transform(X) 
X_selected_names = [X_names[i] for i in rfe_cv.get_support(indices=True)]

print(f&#39;{X_selected_names = }&#39;)
print(f&#39;{X_selected[:5] = }&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/c781f061-8223-404f-8f59-e2788eb68f38/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>코드 학습</p>
<ul>
<li>분류기 SVC 객체 생성, 선형분류, 3개의 클래스</li>
<li>RFE 객체 생성, 2개의 피쳐 선택, 1개씩 제거</li>
<li>RFE+CV(Cross Validation), 5개의 폴드, 1개씩 제거</li>
<li>rank가 1인 피쳐들만 선택</li>
<li>데이터셋에 RFECV 적용</li>
</ul>
</li>
</ul>
<pre><code class="language-python">from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
knn = KNeighborsClassifier(n_neighbors=3)
sfs = SequentialFeatureSelector(knn, n_features_to_select=2, direction=&#39;backward&#39;)

sfs.fit(X, y)
print(&#39;SFS selected: &#39;, sfs.get_support())

X_selected = sfs.transform(X) 
X_selected_names = [X_names[i] for i in sfs.get_support(indices=True)]

print(f&#39;{X_selected_names = }&#39;)
print(f&#39;{X_selected[:5] = }&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/ae6a9631-0444-4c0d-a5d6-d867a1489a28/image.png" alt=""></p>
<p>학습</p>
<ul>
<li>SFS(Sequential Feature Selector) : 순차적으로 특성을 선택하는 방법</li>
<li>데이터를 로드하고, 분류기를 초기화한 후 SFS를 적용</li>
<li>SFS를 학습하고, 선택된 특성을 출력</li>
</ul>
<h3 id="463-임베디드-기법">4.6.3 임베디드 기법</h3>
<ul>
<li>임베디드 기법은 모델의 정확도에 기여하는 변수를 학습함
<img src="https://velog.velcdn.com/images/hate_all/post/f2801320-157e-49b8-9551-541b16121ad7/image.png" alt=""></li>
</ul>
<h4 id="4631-selectfrommodel">4.6.3.1 SelectFromModel</h4>
<p>기본</p>
<pre><code class="language-python">from sklearn.feature_selection import SelectFromModel
from sklearn import tree
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
clf = tree.DecisionTreeClassifier()
sfm = SelectFromModel(estimator=clf)

sfm.set_output(transform=&#39;pandas&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/ca32db35-c126-47aa-9631-b219bf3a91fe/image.png" alt=""></p>
<pre><code class="language-python">sfm.fit(X, y)
print(&#39;SFM threshold: &#39;, sfm.threshold_)

X_selected = sfm.transform(X) 
X_selected.columns = [X_names[i] for i in sfm.get_support(indices=True)]

X_selected.head()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/94ae0154-e94e-4221-beab-fc4a10abdcda/image.png" alt=""></p>
<p>학습</p>
<ul>
<li><p>SelectFromModel : 의사결정나무 기반 알고리즘에서 변수를 선택하는 기법</p>
</li>
<li><p>코드 학습</p>
<ul>
<li>데이터를 로드하고, 분류기를 초기화한 후 SFS를 적용</li>
<li>모형 구조 확인 및 출력을 pandas로 설정</li>
<li>모형 학습 및 선택된 피쳐들만 선택</li>
</ul>
</li>
</ul>
<h1 id="5-파이프라인">5. 파이프라인</h1>
<ul>
<li>여러 개의 데이터의 처리(preprocessor, classifier, regressor, estimator 등)를 하나의 처리과정(pipeline, sequence)으로 만들어 데이터를 일괄처리해 주는 기능</li>
<li>파이프라인을 사용하면 데이터 전처리나 모델 구축 과정 등을 더 짧은 코드로, 더 가시성 있게, 더 효율적으로 처리할 수 있음</li>
<li>다양한 패키지에서 파이프라인을 지원하고 있음</li>
</ul>
<h2 id="51-scikit-learn의-파이프라인">5.1 SciKit-Learn의 파이프라인</h2>
<ul>
<li>SciKit-Learn에서는 Pipeline 클래스를 통해 파이프라인을 구현할 수 있음</li>
<li>Pipeline 클래스는 여러 개의 추정기(estimator)를 하나의 추정기처럼 사용할 수 있도록 해 줌</li>
<li>파이프라인 사용 목적</li>
<li>편의성과 캡슐화 : 전체 데이터 처리 시퀀스에서 fit과 predict를 한 번만 적용하면 됨</li>
<li>통합된 하이퍼 파라미터 최적화 : grid search를 이용하여 한 번에 하이퍼 파라미터 최적화 가능</li>
<li>안전성 강화 : 교차검증(cross-validation)시 랜덤성에 의한 데이터의 통계적 특성이 변경되는 것을 방지하여 일관성을 유지할 수 있음</li>
</ul>
<h2 id="52-파이프라인을-이용하여-연결형-추정기-만들기">5.2 파이프라인을 이용하여 연결형 추정기 만들기</h2>
<h3 id="521-파이프라인을-사용하지-않은-경우">5.2.1 파이프라인을 사용하지 않은 경우</h3>
<pre><code class="language-python">from sklearn.feature_selection import SelectKBest, f_classif # 피처선택 메서드
from sklearn.preprocessing import StandardScaler # 데이터 표준화
from sklearn.tree import DecisionTreeClassifier # 의사결정나무 분류기
from sklearn.datasets import load_iris # iris 데이터세트

# iris 데이터세트 로드
X, y = load_iris(return_X_y=True)

## 피쳐 선택
feat_sel = SelectKBest(f_classif, k=2)
X_selected = feat_sel.fit_transform(X, y)
print(&#39;Selected features:&#39;, feat_sel.get_feature_names_out())

## 표준화
scaler = StandardScaler()
scaler.fit(X_selected)
X_transformed = scaler.transform(X_selected)
print(&#39;Standard Scaled: \n&#39;, X_transformed[:5, :])

## 모델 학습
clf = DecisionTreeClassifier(max_depth=3)
clf.fit(X_transformed, y)
print(&#39;Estimate : &#39;, clf.predict(X_transformed)[:3])
print(&#39;Accuracy : &#39;, clf.score(X_transformed, y))</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/75a477e1-0ad2-44a7-99c9-da068030d7f5/image.png" alt=""></p>
<h3 id="522-파이프라인을-사용한-경우">5.2.2 파이프라인을 사용한 경우</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.pipeline import Pipeline # 파이프라인 구성을 위한 함수
from sklearn.feature_selection import SelectKBest, f_classif # 피처선택 메서드
from sklearn.preprocessing import StandardScaler # 데이터 표준화
from sklearn.tree import DecisionTreeClassifier # 의사결정나무 분류기
from sklearn.datasets import load_iris # iris 데이터세트

# iris 데이터세트 로드
X, y = load_iris(return_X_y=True)

## pipeline 구축
pipeline = Pipeline([
    (&#39;Feature_Selection&#39;, SelectKBest(f_classif, k=2)), ## 피쳐 선택
    (&#39;Standardization&#39;, StandardScaler()),  ## 표준화
    (&#39;Decision_Tree&#39;, DecisionTreeClassifier(max_depth=3)) ## 학습 모델
])
display(pipeline) # 파이프라인 그래프로 구성 확인

pipeline.fit(X, y) ## 모형 학습
print(&#39;Estimate : &#39;, pipeline.predict(X)[:3]) ## 예측
print(&#39;Accuracy : &#39;, pipeline.score(X, y)) ## 성능 평가</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/8e1f9eb2-824d-4c94-a21d-d444b6fb5709/image.png" alt=""></p>
<pre><code class="language-python">from sklearn.pipeline import make_pipeline # 파이프라인 구성을 위한 함수

pipeline_auto = make_pipeline(SelectKBest(f_classif, k=2), 
              StandardScaler(), 
              DecisionTreeClassifier(max_depth=3))
display(pipeline_auto) # 파이프라인 그래프로 구성 확인</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/36830271-7be6-4854-8c19-2cdc913b88b0/image.png" alt=""></p>
<pre><code class="language-python"># pipiline의 Feature_Selection step의 결과 확인
# pipeline.named_steps[&#39;Feature_Selection&#39;] == pipeline[0]
# pipeline.named_steps[&#39;Standardization&#39;] == pipeline[1]
# pipeline.named_steps[&#39;Decision_Tree&#39;] == pipeline[2]
print(&#39;Selected features:&#39;, pipeline.named_steps[&#39;Feature_Selection&#39;].get_feature_names_out())
X_transformed = pipeline[1].transform(X_selected)
print(&#39;Standard Scaled: \n&#39;, X_transformed[:5, :])</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/2989dda9-3ecb-4575-adaf-1d636b66d6f4/image.png" alt=""></p>
<p>학습</p>
<ul>
<li>파이프라인은 (key, value)의 리스트를 구성하여 만듦</li>
<li>파이프라인을 사용하면, 변환된 데이터를 별도로 저장하지 않고 연속적으로 사용하므로 속도가 개선되고 메모리가 절약됨</li>
<li>make_pipeline() 함수를 사용하여 파이프라인을 만들 수 있음</li>
<li>make_pipeline() 함수는 파이프라인의 이름을 자동으로 만들어 줌</li>
<li>파이프라인의 이름은 각 추정기의 클래스 이름을 소문자로 바꾼 것과 같음</li>
<li>파이프라인의 이름을 지정하려면 Pipeline() 클래스를 사용해야 함</li>
<li>파이프라인 내부의 중간결과 확인하기 -&gt; pipeline의 인덱스나 named_steps로 확인이 가능</li>
</ul>
<h2 id="53-파이프라인의-결합">5.3 파이프라인의 결합</h2>
<h3 id="531-수치형-데이터-파이프라인-처리">5.3.1 수치형 데이터 파이프라인 처리</h3>
<p>기본</p>
<pre><code class="language-python">import seaborn as sns
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer

# 데이터 로드
df = sns.load_dataset(&#39;diamonds&#39;)
print(df.info())
X = df.drop(&#39;price&#39;, axis=1)
y = df[&#39;price&#39;]

numeric_col = list(X.select_dtypes(exclude=&#39;category&#39;).columns)
category_col = list(X.select_dtypes(include=&#39;category&#39;).columns)
print(f&#39;numeric_col: {numeric_col}&#39;)
print(f&#39;category_col: {category_col}&#39;)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/b2f5d6a0-cd76-44eb-9fd2-14dd3a9d58d8/image.png" alt=""></p>
<pre><code class="language-python">numeric_pipeline = Pipeline(
    steps=[
        (&#39;imputer&#39;, SimpleImputer(strategy=&#39;mean&#39;)),
        (&#39;scaler&#39;, StandardScaler())
    ])

display(numeric_pipeline)

numerical_data_piped = numeric_pipeline.fit_transform(X[numeric_col])
pd.DataFrame(numerical_data_piped, columns=numeric_col).head()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/714c2dcb-c7cd-406f-8545-a239cbada89b/image.png" alt=""></p>
<p>학습</p>
<ul>
<li>데이터를 유형에 따라 분리하고, 파이프라인을 구축</li>
<li>Nan 값은 평균값으로 채우고, 표준화한다.</li>
</ul>
<h3 id="532-범주형-데이터-파이프라인-처리">5.3.2 범주형 데이터 파이프라인 처리</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder

category_pipeline = Pipeline(
    steps=[
        (&#39;imputer&#39;, SimpleImputer(strategy=&#39;constant&#39;, fill_value=&#39;missing&#39;)),
        (&#39;onehot&#39;, OneHotEncoder(sparse_output=False))
    ])

display(category_pipeline)

category_data_piped = category_pipeline.fit_transform(X[category_col])

category_colnames = category_pipeline[1].get_feature_names_out(category_col)

pd.DataFrame(category_data_piped, columns=category_colnames).head()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/190cda3a-29e0-499d-90d2-4d1d54a90541/image.png" alt=""></p>
<p>학습</p>
<ul>
<li>파이프라인 구축</li>
<li>비어있는 값 -&gt; missing 채우기</li>
<li>one-hot encoding 적용</li>
<li>파이프라인 이후 데이터는 array에서 데이터프레임이 됨</li>
</ul>
<h3 id="533-수치형--범주형-파이프라인-결합한-파이프라인">5.3.3 수치형 + 범주형 파이프라인 결합한 파이프라인</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.compose import ColumnTransformer
from sklearn.linear_model import LinearRegression

preprocessor = ColumnTransformer(
    transformers=[
        (&#39;numeric&#39;, numeric_pipeline, numeric_col),
        (&#39;category&#39;, category_pipeline, category_col)
    ])

pipe = make_pipeline(preprocessor, LinearRegression())
display(pipe) 
pipe.fit(X,y)

print(&#39;Estimate : &#39;, pipe.predict(X))
print(&#39;Accuracy : &#39;, pipe.score(X, y))</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/bc90b68a-d70e-468d-a0f6-02890b5e4f99/image.png" alt=""></p>
<p>학습</p>
<ul>
<li>ColumnTransformer 클래스를 사용하여 수치형 데이터와 범주형 데이터의 파이프라인을 결합할 수 있음</li>
</ul>
<h3 id="534-columntransformer">5.3.4 ColumnTransformer</h3>
<p>기본</p>
<pre><code class="language-python">from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
import pandas as pd
import numpy as np

data_df = pd.DataFrame({
    &quot;height&quot;:[165,  np.nan, 182],
    &quot;weight&quot;:[70,   62,     np.nan],
    &quot;age&quot;   :[np.nan,18,    15]
})

col_transformer = ColumnTransformer([
    (&quot;Impute_mean&quot;, SimpleImputer(strategy=&quot;mean&quot;), [&quot;height&quot;])
    ], 
    remainder=&quot;passthrough&quot;
)

display(col_transformer)
print(data_df)
print(col_transformer.fit_transform(data_df))</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/2c65da87-453a-4dbc-bb9e-bcb9729305a5/image.png" alt=""></p>
<pre><code class="language-python">col_transformer2 = ColumnTransformer([
    (&quot;Impute_mean&quot;  , SimpleImputer(strategy=&quot;mean&quot;)  , [&quot;height&quot;]),
    (&quot;Impute_median&quot;, SimpleImputer(strategy=&quot;median&quot;), [&quot;weight&quot;])
    ],
    remainder=SimpleImputer(strategy=&quot;constant&quot;, fill_value=-1)
)

display(col_transformer2)
print(data_df)
print(col_transformer2.fit_transform(data_df))</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/3345170d-8c9e-4f9f-bb3f-f62534a3b942/image.png" alt=""></p>
<p>학습</p>
<ul>
<li>ColumnTransformer -&gt; 컬럼 기준으로 데이터를 복합하여 처리해주는 함수</li>
<li>SimpleImputer를 사용해서 height의 null 값들은 평균으로 출력하고 나머지 column은 통과 (1)</li>
<li>SimpleImputer를 사용해서 mean과 median 값을 null에 넣고 나머지 열(column)에 대한 값은 상수로 -1 값을 넣어 줌 (2)</li>
</ul>
<h1 id="응용">응용</h1>
<pre><code class="language-python">test_df = pd.DataFrame({&#39;city&#39;:[&#39;서울&#39;,&#39;부산&#39;,&#39;대구&#39;,&#39;수원&#39;,&#39;광주&#39;,&#39;울산&#39;,&#39;강릉&#39;,&#39;제주&#39;]})</code></pre>
<pre><code class="language-python">pd.get_dummies(test_df[&#39;city&#39;])</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/78fee28f-2e72-4936-a272-5824c2ca1881/image.png" alt=""></p>
<pre><code class="language-python">from sklearn.preprocessing import OneHotEncoder

encoder = OneHotEncoder()
values = encoder.fit_transform(test_df[[&#39;city&#39;]]).toarray()

pd.DataFrame(values, columns = test_df[&#39;city&#39;])</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/c922e4a1-e761-45ff-b2e1-c700607cf2fa/image.png" alt=""></p>
<pre><code class="language-python">from sklearn.preprocessing import OrdinalEncoder

encoder = OrdinalEncoder()
encoder.fit(test_df)
df_tt = pd.DataFrame(encoder.transform(test_df), columns=test_df.columns)
df_tt</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/1ea57df9-25b0-4541-b01b-aaac1d345456/image.png" alt=""></p>
<pre><code class="language-python">from sklearn.preprocessing import LabelEncoder

encoder = LabelEncoder()

test_df[&#39;label&#39;] = encoder.fit_transform(test_df[[&#39;city&#39;]])
test_df</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/b8b27b2d-727a-4769-a1ea-b8fb59030028/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[PP-노이즈처리, 스케일링]]></title>
            <link>https://velog.io/@hate_all/PP-%EB%85%B8%EC%9D%B4%EC%A6%88%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@hate_all/PP-%EB%85%B8%EC%9D%B4%EC%A6%88%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Sun, 19 Nov 2023 19:24:28 GMT</pubDate>
            <description><![CDATA[<h1 id="1-노이즈">1. 노이즈</h1>
<h2 id="11-노이즈">1.1 노이즈</h2>
<p>노이즈라는 말은 원래 소음·잡음을 의미하는데, 이 말이 각 분야에서 여러 가지 의미로 쓰이고 있다. 데이터 분야에서는 측정된 변수에 무작위의 오류 또는 분산이 존재하는 것, 데이터를 사용할 때 제거되거나 무시되어야 하는 의미 없이 첨가된 비트나 단어들을 의미한다.</p>
<h2 id="12-정형-데이터의-노이즈">1.2 정형 데이터의 노이즈</h2>
<ul>
<li><p>정형 데이터에서 노이즈는 분산으로 나타난다.</p>
<ul>
<li>분산 : 데이터의 무작위 변동</li>
<li>이상치 -&gt; 데이터의 무작위 변동을 초과하는 특정한 값으로 별도 처리</li>
</ul>
</li>
<li><p>통계 모형에서 노이즈는 오차항으로 나타난다.
  -오차항 : 모형에서 설명하지 못하는 무작위 변동
  -예) 단순선형회귀모형에서는 오차항 ϵi가 노이즈</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hate_all/post/b16b55bb-b43e-4d6e-bd86-0eec7727b950/image.png" alt=""></p>
<h2 id="13-이미지영상-데이터의-노이즈">1.3 이미지/영상 데이터의 노이즈</h2>
<ul>
<li><p>이미지/영상 데이터에서 노이즈는 다양한 형태로 나타난다.
  -blur : 이미지가 흐릿하게 보이는 현상
  -white noise(백색 잡음) : 모든 주파수 영역에서 동일한 에너지를 가지는 잡음
  -pink noise : 특정 주파수 대역에서 강하게 나타나는 노이즈, 일반적으로 낮은 주파수 대역에서 강하게 나타남
  -Gaussian noise : 평균이 0이고, 분산이 1인 정규분포(가우시안 분포)를 따르는 잡음
<img src="https://velog.velcdn.com/images/hate_all/post/c2cbe8a6-5c84-4698-b1b9-4610d6a71ff9/image.png" alt=""></p>
</li>
<li><p>이미지/영상 데이터의 노이즈 주요 원인</p>
</li>
<li><p>이미지를 얻는 과정에서 수집된 광자의 양 너무 적음</p>
</li>
<li><p>이미지를 얻는 과정에서 센서나 렌즈의 열화가 발생</p>
</li>
<li><p>이미지를 전송 중에 무선 통신의 에코 및 대기 왜곡 발생 등</p>
</li>
</ul>
<h2 id="14-시계열음성신호-데이터의-노이즈">1.4 시계열/음성/신호 데이터의 노이즈</h2>
<p>시계열/음성/신호에서 노이즈는 일반적으로 white noise나 Gaussian noise로 나타난다. (이미지 -&gt; 가우시안 잡음에 관한 것.)
<img src="https://velog.velcdn.com/images/hate_all/post/0b88ecd7-9dc5-4d52-bda2-baa333d58450/image.png" alt=""></p>
<h2 id="15-텍스트-데이터의-노이즈">1.5 텍스트 데이터의 노이즈</h2>
<ul>
<li>텍스트 데이터의 노이즈 발생 원인은 일반적으로 철자 오류, 약어나 비표준 단어 사용, 반복되는 말, 구두점이나 대소 문자 정보 누락, “음” 및 “어”와 같은 의성어 사용 등이 있다.</li>
<li>텍스트 데이터의 노이즈는 자연어 처리의 성능을 저하시키므로 처리 대상이다.</li>
<li>자동 음성 인식, 광학 문자 인식, 기계 번역, Web Scraping 등으로 수집한 데이터에 노이즈가 많다.</li>
</ul>
<h2 id="16-비슷한-다른-용어들">1.6 비슷한 다른 용어들</h2>
<ul>
<li>Defact(결함) : 전체 데이터에 존재하는 일부 오류 데이터
  -범위에서 벗어난 이상치(outlier)가 아니라 잘못된(error) 데이터
  -주로 생산이나 제조 분야에서 사용한다. (이미지 -&gt; 반도체 결함)
<img src="https://velog.velcdn.com/images/hate_all/post/e6961f7f-71af-4d27-a282-dc858c24aed8/image.png" alt=""></li>
</ul>
<ul>
<li>Fault(불량/기능이상) : Defact에 의해 제품/설비의 기능에 손상을 입으면 발생한다.
  -모든 defect가 fault를 야기하지는 않음</li>
</ul>
<ul>
<li>Artifact : 주로 과학기술 분야에서 사용하는 용어로 특히, 이미지의 결함을 지칭한다.
<img src="https://velog.velcdn.com/images/hate_all/post/d684b0ef-e9e8-461c-a1dc-c039b33525ec/image.png" alt=""></li>
</ul>
<ul>
<li>Noise : 일반적으로 그 원인을 알 수 없는 무작위 변동을 의미한다. 데이터 과학에서는 데이터의 무작위 변동을 의미한다.
  -무작위(ramdom)가 발생하는 메커니즘을 알 수 없다는 의미로 발생 메커니즘을 알게 되면 무작위 중 수학적 모형을 통하여 반영된 것을 제외한 것이 random이 된다.
  -주로 신호처리(signal processing) 분야에서 사용하는 용어임
  -동작 메커니즘을 모르므로 제거는 불가하기 때문에 이를 저감(Denoising)하여야 한다.</li>
</ul>
<h1 id="2-디노이징">2. 디노이징</h1>
<h2 id="21-디노이징">2.1 디노이징</h2>
<p>디노이징은 데이터에서 노이즈를 저감하여 모형이 더 좋은 성능을 할 수 있도록 하는 전처리 과정이다. 앞에서 언급했듯이 노이즈는 제거가 불가능하기 때문에 디노이징이 필요하다. 기본적인 기법으로는 평활화(smoothing, 구간평균), 구간화(binning, 구간집계), 필터링(filtering, 주파성분 저감)기법이 있다.</p>
<h2 id="22-정형-데이터의-디노이징">2.2 정형 데이터의 디노이징</h2>
<ul>
<li>정형 데이터의 디노이징 방법으로는 구간화와 군집화가 있다.
  -구간화 : 정렬된 데이터 값들을 몇 개의 bin(혹은 bucket)으로 분할하여 대표값으로 대체하는 방법
  -군집화 : 유사한 값들을 하나의 군집으로 처리하여 중심점(centroid)을 대표값으로 대체하는 방법</li>
</ul>
<h2 id="23-구간화">2.3 구간화</h2>
<ul>
<li><p>구간 설정 방법</p>
<ol>
<li>동일 간격(equal-distance) 구간화 → pandas의 cut() 사용
 -정상 데이터가 한쪽으로 편중(biased)되고 이상치의 영향을 많이 받는다.
 -한쪽으로 몰려있는 데이터들은 다 동일한 bin으로 들어오기 때문에 skewed data를 다룰 수 없다.</li>
<li>동일 빈도(eual-frequency) 구간화 → pandas의 qcut() 사용
 -동일한 개수의 데이터를 가지는 구간으로 설정한다.</li>
</ol>
</li>
<li><p>구간별 대표값 설정 방법
  -평균값 평활화 : bin에 있는 값들을 평균값으로 대체
  -중앙값 평활화 : 중앙값으로 대체
  -경계값 평활화 : 경계값 중 가까운 값으로 대체</p>
</li>
<li><p>기본</p>
<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ul>
<p>df = pd.DataFrame({&#39;uniform&#39;: np.sort(np.random.uniform(0,10,10)),
                     &#39;normal&#39;: np.sort(np.random.normal(5,1,10)),
                     &#39;gamma&#39;: np.sort(np.random.gamma(2, size=10))})
df.plot(kind=&#39;hist&#39;, bins=15, alpha=0.5)
df.describe()</p>
<p>col = &#39;uniform&#39;
num_bins = 5
df_binned = pd.DataFrame()
df_binned[col] = df[col].sort_values()
df_binned[&#39;eq_dist_auto&#39;] = pd.cut(df_binned[col], num_bins)
df_binned[&#39;eq_dist_fixed&#39;] = pd.cut(df_binned[col], bins=[0,2,4,6,8,10])
df_binned[&#39;eq_freq_auto&#39;] = pd.qcut(df_binned[col], num_bins)
df_binned</p>
<p>cols = [&#39;uniform&#39;, &#39;normal&#39;, &#39;gamma&#39;]
df_ew = df.copy()
for col in cols:
    df_ew[col+&#39;_eq_dist&#39;] = pd.cut(df_ew[col], 3)
    means = df_ew.groupby(col+&#39;_eq_dist&#39;)[col].mean()
    df_ew.replace({col+&#39;_eq_dist&#39;: means}, inplace=True)
display(df_ew)
df_ef = df.copy()
for col in cols:
    df_ef[col+&#39;_eq_freq&#39;] = pd.qcut(df_ef[col], 3)
    means = df_ef.groupby(col+&#39;_eq_freq&#39;)[col].mean()
    df_ef.replace({col+&#39;_eq_freq&#39;: means}, inplace=True)
display(df_ef)</p>
<p>import matplotlib.pyplot as plt</p>
<p>fig, axes = plt.subplots(1, 2, figsize=(10,5))
df_ew.astype(float).plot(ax=axes[0])
df_ef.astype(float).plot(ax=axes[1])
plt.show()</p>
<pre><code>

* 학습 (학습한 내용 #으로 표시)
```python
import pandas as pd
import numpy as np

# 데이터를 랜덤으로 생성한다. 또한 데이터 결과를 보기 용이하도록 sort한다. 10개씩 (균일분포, 정규분포, 감마분포 추출)
aa = pd.DataFrame({&#39;uniform&#39;: np.sort(np.random.uniform(0,10,10)),
                     &#39;normal&#39;: np.sort(np.random.normal(5,1,10)),
                     &#39;gamma&#39;: np.sort(np.random.gamma(2, size=10))})

# 생성한 데이터를 확인한다. 히스토그램으로 나타낸다.(15)
aa.plot(kind=&#39;hist&#39;, bins=15, alpha=0.5)
aa.describe()</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/512abb2b-78a5-4606-b3fe-5fecfcea772e/image.png" alt="">
<img src="https://velog.velcdn.com/images/hate_all/post/aeee6eef-7f84-4b3a-a339-a9bdc164a55e/image.png" alt=""></p>
<ul>
<li>Pandas로 구간화<pre><code class="language-python"># cut(), qcut() 기본 동작 확인, cut()는 동일한 길이로 나누는 함수이고, qcut()는 동일한 개수로 나누는 함수이다.
col = &#39;uniform&#39;
num_bins = 5
aa_binned = pd.DataFrame()
aa_binned[col] = aa[col].sort_values()  # 원 데이터(해당 열)를 오름차순 정렬
aa_binned[&#39;eq_dist_auto&#39;] = pd.cut(aa_binned[col], num_bins)  # 동일한 간격(5)으로 나누기
aa_binned[&#39;eq_dist_fixed&#39;] = pd.cut(aa_binned[col], bins=[0,2,4,6,8,10]) # 지정된 구간으로 나누기, 예) 0~2 사이, 2~4 사이...
aa_binned[&#39;eq_freq_auto&#39;] = pd.qcut(aa_binned[col], num_bins) # 동일 빈도(5개 묶음)로 나누기
aa_binned</code></pre>
<img src="https://velog.velcdn.com/images/hate_all/post/fe45230c-6022-40f3-9673-93870380d9ce/image.png" alt=""></li>
</ul>
<pre><code class="language-python"># 구간화하여 평균값 대체하기
cols = [&#39;uniform&#39;, &#39;normal&#39;, &#39;gamma&#39;]

# 동일 간격 구간화 -&gt; cut
aa_ew = aa.copy()
for col in cols:
    aa_ew[col+&#39;_eq_dist&#39;] = pd.cut(aa_ew[col], 3)   # 열 별로 구간(3) 나누기
    means = aa_ew.groupby(col+&#39;_eq_dist&#39;)[col].mean() # 구간(3)별 평균값 계산
    aa_ew.replace({col+&#39;_eq_dist&#39;: means}, inplace=True) # 각 구간별 평균값으로 대체

display(aa_ew)

# 동일 빈도 구간화 -&gt; 묶이는 개수가 같게(qcut)
aa_ef = aa.copy()
for col in cols:
    aa_ef[col+&#39;_eq_freq&#39;] = pd.qcut(aa_ef[col], 3)   # 구간 개수(3)으로 나누기
    means = aa_ef.groupby(col+&#39;_eq_freq&#39;)[col].mean() # 구간별 평균값 계산
    aa_ef.replace({col+&#39;_eq_freq&#39;: means}, inplace=True) # 평균값으로 대체

display(aa_ef)

# 시각화
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(10,5))
aa_ew.astype(float).plot(ax=axes[0])
aa_ef.astype(float).plot(ax=axes[1])
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/aa196ad3-dc40-4c1b-bf43-c1f67aaac9c7/image.png" alt="">
<img src="https://velog.velcdn.com/images/hate_all/post/453b2896-728a-455e-a5ed-928e7dad3104/image.png" alt="">
<img src="https://velog.velcdn.com/images/hate_all/post/23e5a4dc-79d2-4a74-ba06-264c5a28bc48/image.png" alt=""></p>
<p>실행 결과 정리 -&gt; cut을 이용해 동일 간격, qcut을 이용해 동일 빈도로 구간화하여 평균에 대한 새로운 열을 생성한 후 그래프로 시각화 하였음.</p>
<ul>
<li>응용<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ul>
<p>ee = pd.DataFrame({&quot;gender&quot;: np.random.randint(0, 2, size=11),
                   &quot;age&quot;: np.random.randint(20, 70, size=11),
                   &#39;happiness&#39;: np.random.randint(1, 6, size=11)})
gender_lv = [&#39;male&#39;, &#39;female&#39;]
ee[&quot;gender&quot;] = pd.Categorical.from_codes(ee[&quot;gender&quot;], gender_lv)</p>
<p>ee[&#39;age_cut&#39;] = pd.cut(ee[&#39;age&#39;], 3)
ee[&#39;age_qcut&#39;] = pd.qcut(ee[&#39;age&#39;], 4)
ee</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/7e0bdb81-a10b-41eb-b591-2613253f2cc6/image.png)
실행 결과 정리 -&gt; 임의의 데이터 ee를 생성한 후 cut과 qcut을 사용하여 구간화 하였다.

## 2.4 군집화
* Scikit-Learn으로 구간화
* 기본
```python
import warnings
warnings.filterwarnings(&quot;ignore&quot;)
from sklearn.preprocessing import KBinsDiscretizer

ed_binner = KBinsDiscretizer(n_bins=3, encode=&#39;ordinal&#39;, strategy=&#39;uniform&#39;, subsample=None)
df_ed = ed_binner.fit_transform(df)
ef_binner = KBinsDiscretizer(n_bins=3, encode=&#39;ordinal&#39;, strategy=&#39;quantile&#39;, subsample=None)
df_ef = ef_binner.fit_transform(df)
km_binner = KBinsDiscretizer(n_bins=3, encode=&#39;ordinal&#39;, strategy=&#39;kmeans&#39;, subsample=None)
df_km = km_binner.fit_transform(df)
df_ed = pd.DataFrame(df_ed, columns=df.columns+&#39;_eq_dist&#39;)
df_ef = pd.DataFrame(df_ef, columns=df.columns+&#39;_eq_freq&#39;)
df_km = pd.DataFrame(df_km, columns=df.columns+&#39;_km&#39;)
df_bin = pd.concat([df, df_ed, df_ef, df_km], axis=1)
df_bin

for bin_col in df_bin.columns:
    col = bin_col.split(&#39;_&#39;)[0]
    means = df_bin.groupby(by=bin_col)[col].mean()
    df_bin.replace({bin_col: means}, inplace=True)
df_bin

import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(15,5))
pd.concat([df_bin.iloc[:,:3], df_bin.iloc[:,3:6]], axis=1).astype(float).plot(ax=axes[0])
pd.concat([df_bin.iloc[:,:3], df_bin.iloc[:,6:9]], axis=1).astype(float).plot(ax=axes[1])
pd.concat([df_bin.iloc[:,:3], df_bin.iloc[:,9:]], axis=1).astype(float).plot(ax=axes[2])
plt.show()</code></pre><ul>
<li>학습<pre><code class="language-python">from sklearn.preprocessing import KBinsDiscretizer
#KBinsDiscretizer() -&gt; 파라미터 n_bins(간격/구간 수), encode, strategy, subsample=none -&gt; training 데이터 모두 사용
# encode -&gt; onehot(수많은 0과 하나의 1로 구분)/onehot-dense(onehot 인코딩&amp;조밀한 배열)/ordinal(정수 값으로 인코딩)
#strategy -&gt; uniform(동일간격)/quantile(동일빈도)/kmeans(K-Means 군집화)
#fit_transform -&gt; train data로 학습된 Scaler()의 parameter를 통해 test data의 feature 값들이 스케일 되는 것
</code></pre>
</li>
</ul>
<h1 id="동일-간격-구간화---uniform-사용">동일 간격 구간화 -&gt; uniform 사용</h1>
<p>ed_binner = KBinsDiscretizer(n_bins=3, encode=&#39;ordinal&#39;, strategy=&#39;uniform&#39;, subsample=None)
aa_ed = ed_binner.fit_transform(aa)</p>
<h1 id="동일-빈도-구간화---quantile-사용">동일 빈도 구간화 -&gt; quantile 사용</h1>
<p>ef_binner = KBinsDiscretizer(n_bins=3, encode=&#39;ordinal&#39;, strategy=&#39;quantile&#39;, subsample=None)
aa_ef = ef_binner.fit_transform(aa)</p>
<h1 id="k-means-구간화---kmeans-사용">K-means 구간화 -&gt; kmeans 사용</h1>
<p>km_binner = KBinsDiscretizer(n_bins=3, encode=&#39;ordinal&#39;, strategy=&#39;kmeans&#39;, subsample=None)
aa_km = km_binner.fit_transform(aa)</p>
<h1 id="결과-확인">결과 확인</h1>
<p>aa_ed = pd.DataFrame(aa_ed, columns=aa.columns+&#39;_eq_dist&#39;)
aa_ef = pd.DataFrame(aa_ef, columns=aa.columns+&#39;_eq_freq&#39;)
aa_km = pd.DataFrame(aa_km, columns=aa.columns+&#39;_km&#39;)
aa_bin = pd.concat([aa, aa_ed, aa_ef, aa_km], axis=1)
aa_bin</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/71da2c7f-23f8-4c67-afb1-0b1e6b915513/image.png)

```python
# 구간화하여 평균값 대체하기 (n_bins=3)
for bin_col in aa_bin.columns:
    col = bin_col.split(&#39;_&#39;)[0] #uniform/normal/gamma
    means = aa_bin.groupby(by=bin_col)[col].mean() # 구간별 평균값 계산
    aa_bin.replace({bin_col: means}, inplace=True) # 평균값으로 대체

aa_bin</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/b6056219-a31b-4d76-b326-34cfdcb16b49/image.png" alt=""></p>
<pre><code class="language-python"># 시각화
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(15,5))
pd.concat([aa_bin.iloc[:,:3], aa_bin.iloc[:,3:6]], axis=1).astype(float).plot(ax=axes[0])
pd.concat([aa_bin.iloc[:,:3], aa_bin.iloc[:,6:9]], axis=1).astype(float).plot(ax=axes[1])
pd.concat([aa_bin.iloc[:,:3], aa_bin.iloc[:,9:]], axis=1).astype(float).plot(ax=axes[2])
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/f99857b2-5e88-41b0-9927-10ce3858f296/image.png" alt="">
실행 결과 정리 -&gt; strategy 파라미터로 각 방법별로 구간화를 한 후(구간 별 0/1/2로 표현) 구간별 평균값을 행별로 구하여 대체한 후 시각화를 하였다.</p>
<ul>
<li>응용<pre><code class="language-python"># strategy = uniform, mean 기준
from sklearn.preprocessing import KBinsDiscretizer
import matplotlib.pyplot as plt
train_pt = pd.DataFrame(ii[&#39;sepal_length&#39;])
</code></pre>
</li>
</ul>
<p>est_uni = KBinsDiscretizer(n_bins=2, encode=&#39;ordinal&#39;, strategy=&#39;uniform&#39;)
est_uni.fit(train_pt)</p>
<p>Xt_uni=est_uni.transform(train_pt)
print(&quot;edges : &quot;, est_uni.bin_edges_[0])</p>
<p>unique, counts = np.unique(Xt_uni, return_counts=True)
print(dict(zip(unique, counts)))</p>
<p>plt.hist(Xt_uni, bins=&#39;auto&#39;)
plt.xticks([0,0.5,1])
plt.rcParams[&#39;figure.figsize&#39;]=(5.5,6)
plt.show</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/bf5f6293-4232-432d-b0e9-58ca9fd203a0/image.png)

```python
# strategy = quantile, median 기준

est_quan = KBinsDiscretizer(n_bins=2, encode=&#39;ordinal&#39;, strategy=&#39;quantile&#39;)
est_quan.fit(train_pt)

Xt_quan=est_quan.transform(train_pt)
print(&quot;edges : &quot;, est_quan.bin_edges_[0])

unique_q, counts_q = np.unique(Xt_quan, return_counts=True)
print(dict(zip(unique_q, counts_q)))

plt.hist(Xt_quan, bins=&#39;auto&#39;)
plt.xticks([0,0.5,1])
plt.rcParams[&#39;figure.figsize&#39;]=(5.5,6)
plt.show</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/54b259a9-0599-42bf-8b7b-dbffd337aebb/image.png" alt=""></p>
<pre><code class="language-python"># strategy = kmeans, normal distribution 2개 생성

est_km = KBinsDiscretizer(n_bins=2, encode=&#39;ordinal&#39;, strategy=&#39;kmeans&#39;)
est_km.fit(train_pt)

Xt_km=est_km.transform(train_pt)
print(&quot;edges : &quot;, est_km.bin_edges_[0])

unique_k, counts_k = np.unique(Xt_km, return_counts=True)
print(dict(zip(unique_k, counts_k)))

plt.hist(Xt_km, bins=&#39;auto&#39;)
plt.xticks([0,0.5,1])
plt.rcParams[&#39;figure.figsize&#39;]=(5.5,6)
plt.show()</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/52d665a5-2923-49c0-b781-f34947424364/image.png" alt="">
실행 결과 정리 -&gt; iris의 sepa_length 열을 그룹핑하여 세 방법으로 범주화하였다.</p>
<h1 id="3-scikit-learn">3. Scikit-Learn</h1>
<h2 id="31-scikit-learn">3.1 Scikit-Learn</h2>
<p>python을 대표하는 머신러닝 라이브러이다. Scikit-Learn이 시행할 수 있는 여러 가지 데이터 전처리 도구 및 알고리즘은 지도 학습, 비지도 학습, 데이터 평가 등 기계 학습의 다양한 분야를 망라하고 있다.</p>
<h2 id="32-주요-기능">3.2 주요 기능</h2>
<p>분류: 로지스틱 회귀, 결정 트리, 서포트 벡터 머신(SVM)
회귀: 선형 회귀, 릿지 회귀 등
군집화: k-평균 군집화, 계층적 군집화 등
차원 축소: 주성분 분석(PCA), t-분산 확률적 이웃 내재화(t-SNE) 등
전처리: 데이터 정규화, 스케일링, 인코딩 등
<img src="https://velog.velcdn.com/images/hate_all/post/74dbfbb8-4819-4c72-a6a8-bee90ecee41e/image.png" alt="">
<img src="https://velog.velcdn.com/images/hate_all/post/82280b9a-3024-4369-a536-d7aa89524fb0/image.png" alt=""></p>
<h2 id="33-장점">3.3 장점</h2>
<ul>
<li><p>매우 다양한 전처리 도구와 알고리즘을 제공하고 있어 머신러닝 기법을 배우는 데 적합하다.
  -예제와 사용 설명서가 잘 되어있어 참고하여 코드를 작성하기 용이하다.</p>
</li>
<li><p>데이터 분석을 위한 간단하고 효율적인 도구를 제공한다.
  -간단하고 직관적인 API를 제공하므로 다양한 수준의 전문 지식을 가진 사용자가 접근 가능하다.
  -fit(), transform(), predict() 등 체계적이고 일관된 분석 및 학습모형 운용 체계를 갖추고 있다.
  -다른 많은 패키지도 scikit-learn과 동일한 체계를 제공하여 유사한 프레임에서 사용이 가능하다.</p>
</li>
<li><p>NumPy, Pandas, SciPy 및 matplotlib를 기반으로 구축되어 있어 다른 파이썬 패키지와 함께 사용하기 용이하다.
  -NumPy: 다차원 배열을 위한 기본 패키지
  -Pandas: 데이터프레임을 위한 기본 패키지
  -SciPy: 과학 계산용 함수를 모아놓은 패키지
  -matplotlib: 데이터 시각화를 위한 패키지</p>
</li>
</ul>
<h2 id="34-단점">3.4 단점</h2>
<p>하지만 딥러닝, 강화학습, 시계열 모형에는 매우 약하고 최근 개발된 대용량을 위한 데이터프레임인 Polars와 같은 라이브러리와는 연동이 잘 안 된다는 단점이 있다.</p>
<h1 id="4-스케일링">4. 스케일링</h1>
<h2 id="41-scikit-learn-preprocessing">4.1 Scikit-Learn Preprocessing</h2>
<ul>
<li>Scikit-learn의 전처리 기능은 크게 4가지로 나눌 수 있다.
  -스케일링(scaling): 서로 다른 변수의 값 범위를 선형변환을 통하여 일정한 수준으로 맞추는 것으로 표준화, 정규화, 변환이 있음
  -이진화(binarization): 연속적인 값을 0 또는 1로 나누는 것, 연속형 변수 → 이진형 변수
  -인코딩(encodig): 범주형 값을 적절한 숫자형으로 변환하는 작업, 범주형 변수 → 수치형 변수
  -변환(transformation): 데이터의 분포를 변환하여 정규성을 확보하는 것</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hate_all/post/dd764ebd-c99d-4164-bd44-9c142e4f9977/image.png" alt=""></p>
<h2 id="42-스케일링의-필요성">4.2 스케일링의 필요성</h2>
<ul>
<li>독립변수(feature)별로 값의 변위가 다르면 종속변수(target)에 대한 영향이 독립변수의 변위에 따라 크게 달라지기 때문에 머신러닝 시 학습효과가 떨어지므로 스케일링이 필요하다.</li>
<li>다차원의 값들을 동일한 수준에서 비교 분석하기 용이하게 만들어 준다.</li>
<li>컴퓨터의 비트수로 인하여 다른 값으로 인식되는 오버플로우(overflow)나 언더플로우(underflow)를 방지한다.</li>
<li>최적화 과정에서의 안정성 및 수렴 속도를 향상한다.</li>
<li>특히 k-means 등 거리 기반의 모델에서는 스케일링이 매우 중요하다.
<img src="https://velog.velcdn.com/images/hate_all/post/ea0f2aad-5204-43ab-84e5-371e06d6ded3/image.png" alt=""></li>
</ul>
<h2 id="43-스케일링-절차">4.3 스케일링 절차</h2>
<ul>
<li><p>Scaler 객체를 이용한다.
  -fit(): 주어진 데이터에 맞추어 학습한다. 데이터 변환을 위한 기준 정보 설정을 적용한다. (ex.최소값,최대값 등)
  -transform(): Scaler 적용, fit()된 정보를 이용해 데이터를 변환한다.
  -fit_transform() : fit()과 transform()을 한 번에 실행한다.</p>
</li>
<li><p>훈련(training) 데이터와 평가(test) 데이터의 스케일링 변환 시 유의점
  -훈련 데이터는 fit()과 transform() 모두 적용 가능하다.
  -평가 데이터는 fit()은 필요없으므로 transform()만 적용해야 한다. 훈련 데이터로 fit()된 스케일링 기준 정보를 그대로 테스트에 적용해야하기 때문이다.</p>
</li>
</ul>
<h2 id="44-표준화">4.4 표준화</h2>
<ul>
<li><p>표준화를 하면 평균은 0, 분산과 표준편차는 1이 되므로 데이터의 분포가 단순화되어 독립변수간 데이터 수준의 비교가 용이하다.</p>
</li>
<li><p>RBF 커널(가우시안 방사 기저함수)을 이용하는 서포트 벡터 머신, 선형회귀, 로지스틱 회귀는 데이터가 정규분포를 가지고 있다고 가정하고 구현되므로 표준화를 하면 좋다.</p>
</li>
<li><p>표준화는 이상치에 민감하며, 분류보다는 회귀에 유용하다.
<img src="https://velog.velcdn.com/images/hate_all/post/1906260c-3858-4448-bc12-2f3b285651f2/image.png" alt="">
<img src="https://velog.velcdn.com/images/hate_all/post/e7009517-4827-458d-aece-1950ffdf4250/image.png" alt=""></p>
</li>
<li><p>기본</p>
<pre><code class="language-python">import pandas as pd
import seaborn as sns
</code></pre>
</li>
</ul>
<p>pd.set_option(&#39;display.float_format&#39;, lambda x: f&#39;{x:.4f}&#39;)
iris = sns.load_dataset(&#39;iris&#39;)
iris = iris.select_dtypes(exclude=&#39;object&#39;)
iris.describe()
sns.jointplot(data=iris, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)</p>
<p>from sklearn.preprocessing import StandardScaler, RobustScaler</p>
<p>standard_scaler = StandardScaler()
robust_scaler = RobustScaler()
iris_standard = pd.DataFrame(standard_scaler.fit_transform(iris), columns=iris.columns)
iris_robust = pd.DataFrame(robust_scaler.fit_transform(iris), columns=iris.columns)
print(&#39;Standard Scaled: \n&#39;, iris_standard.describe())
print()
print(&#39;Robust Scaled: \n&#39;, iris_robust.describe())</p>
<p>import seaborn as sns
import patchworklib as pw
pw.overwrite_axisgrid()</p>
<p>g1 = sns.jointplot(data=iris_standard, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g1 = pw.load_seaborngrid(g1)
g1.set_suptitle(&quot;Standard Scaled&quot;)
g2 = sns.jointplot(data=iris_robust, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g2 = pw.load_seaborngrid(g2)
g2.set_suptitle(&quot;Robust Scaled&quot;)
g12 = (g1|g2)
g12</p>
<pre><code>
* 학습
```python
#데이터 로드
import pandas as pd
import seaborn as sns

# 소수점 4째자리 이하에서 반올림 설정
pd.set_option(&#39;display.float_format&#39;, lambda x: f&#39;{x:.4f}&#39;)

# iris 데이터 로드
ii = sns.load_dataset(&#39;iris&#39;)

# iris의 수치형 변수만 선택(문자형 제외)
ii = ii.select_dtypes(exclude=&#39;object&#39;)

# iris의 기술통계량을 확인
ii.describe()

# sepal_lengh와 petal_length의 jointplot을 그림
# 조인트 플롯 -&gt; 두 수치형 변수 간의 관계 연구 가능
sns.jointplot(data=ii, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/d8e8dd7c-b4d1-49d4-b47b-f3b2a24a1091/image.png" alt=""></p>
<pre><code class="language-python">#표준화
from sklearn.preprocessing import StandardScaler, RobustScaler

# Scaler 객체 생성
#StandardScaler(): 기본 스케일러, 평균과 표준편차 사용
#RobustScaler(): 중앙값과 IQR(Q3-Q1)을 사용. 이상치의 영향을 최소화
standard_scaler = StandardScaler()
robust_scaler = RobustScaler()

# 데이터 변환, 각각 (평균=0, 표준편차=1) (중앙값=0, IQR=1)
ii_standard = pd.DataFrame(standard_scaler.fit_transform(ii), columns=ii.columns)
ii_robust = pd.DataFrame(robust_scaler.fit_transform(ii), columns=ii.columns)

# 결과 출력
print(&#39;Standard Scaled: \n&#39;, ii_standard.describe())
print()
print(&#39;Robust Scaled: \n&#39;, ii_robust.describe())</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/0c472c7c-b7d6-4559-9bcf-bc60788942d8/image.png" alt=""></p>
<pre><code class="language-python"># 그래프로 확인
# seaborn의 jointplot은 figure의 axes를 지정할 수 없어 subplot을 그리기가 어려움
# patchworklib 패키지를 사용하여 subplot을 그림
import seaborn as sns
import patchworklib as pw
pw.overwrite_axisgrid()

# 첫번째 그래프 
g1 = sns.jointplot(data=ii_standard, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g1 = pw.load_seaborngrid(g1)
g1.set_suptitle(&quot;Standard Scaled&quot;)

# 두번째 그래프 
g2 = sns.jointplot(data=ii_robust, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g2 = pw.load_seaborngrid(g2)
g2.set_suptitle(&quot;Robust Scaled&quot;)

# 그래프 합치기
g12 = (g1|g2)
g12</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/0d9c5172-52cb-4329-89c7-1c956a1221ee/image.png" alt="">
<img src="https://velog.velcdn.com/images/hate_all/post/d6aae245-ef0e-4303-a808-1c6fbd066c62/image.png" alt="">
실행 결과 정리 -&gt; iris 데이터의 수치형 변수만을 골라서 변수 간의 관계에 대하여 시각화 하였다. 그리고 두 스케일러를 사용하여 데이터를 변환한 다음 시각화를 하였다.</p>
<h2 id="45-정규화">4.5 정규화</h2>
<ul>
<li><p>정규화 → 규격화(특정 범위(주로 [0,1]) 로 스케일링)</p>
</li>
<li><p>기본</p>
<pre><code class="language-python">from sklearn.preprocessing import MinMaxScaler, MaxAbsScaler
</code></pre>
</li>
</ul>
<p>minmax_scaler = MinMaxScaler()
maxabs_scaler = MaxAbsScaler()
iris_minmax = pd.DataFrame(minmax_scaler.fit_transform(iris), columns=iris.columns)
iris_maxabs = pd.DataFrame(maxabs_scaler.fit_transform(iris), columns=iris.columns)
print(&#39;MinMax Scaled: \n&#39;, iris_minmax.describe())
print()
print(&#39;MaxAbs Scaled: \n&#39;, iris_maxabs.describe())</p>
<p>g3 = sns.jointplot(data=iris_minmax, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g3 = pw.load_seaborngrid(g3)
g3.set_suptitle(&quot;MinMax Scaled&quot;)
g4 = sns.jointplot(data=iris_maxabs, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g4 = pw.load_seaborngrid(g4)
g4.set_suptitle(&quot;MaxAbs Scaled&quot;)
g34 = (g3|g4)
g34</p>
<pre><code>* 학습
```python
from sklearn.preprocessing import MinMaxScaler, MaxAbsScaler

# Scaler 객체 생성
# MinMaxScaler(): 범위가 [0,1]이 되도록 스케일링
# MaxAbsScaler(): 양수는 [0,1], 음수는 [-1,0], 양수&amp;음수는 [-1,1]이 되도록 스케일링
minmax_scaler = MinMaxScaler()
maxabs_scaler = MaxAbsScaler()

# 데이터 변환 각각 [0,1] [0,1]로
ii_minmax = pd.DataFrame(minmax_scaler.fit_transform(ii), columns=ii.columns)
ii_maxabs = pd.DataFrame(maxabs_scaler.fit_transform(ii), columns=ii.columns)

# 결과 출력
print(&#39;MinMax Scaled: \n&#39;, ii_minmax.describe())
print()
print(&#39;MaxAbs Scaled: \n&#39;, ii_maxabs.describe())</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/d781a6d8-a9c7-4eed-b372-33ecba2ac2bb/image.png" alt=""></p>
<pre><code class="language-python"># 세번째 그래프 
g3 = sns.jointplot(data=ii_minmax, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g3 = pw.load_seaborngrid(g3)
g3.set_suptitle(&quot;MinMax Scaled&quot;)

# 네번째 그래프 
g4 = sns.jointplot(data=ii_maxabs, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g4 = pw.load_seaborngrid(g4)
g4.set_suptitle(&quot;MaxAbs Scaled&quot;)

# 그래프 합치기
g34 = (g3|g4)
g34</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/ba4a3860-7ac3-457d-bf90-ec0acfe6d820/image.png" alt="">
실행 결과 정리 -&gt; 표준화 때와 마찬가지로 두 스케일러를 가지고 그래프로 시각화 하여 두 변수 사이의 관계를 나타냈다.</p>
<h2 id="46-변환">4.6 변환</h2>
<ul>
<li><p>변환(특정한 분포나 모양을 따르도록 스케일링)</p>
</li>
<li><p>기본</p>
<pre><code class="language-python">import numpy as np
from sklearn.preprocessing import PowerTransformer, Normalizer
</code></pre>
</li>
</ul>
<p>power_scaler = PowerTransformer()
normal_scaler = Normalizer()
iris_power = pd.DataFrame(power_scaler.fit_transform(iris), columns=iris.columns)
iris_normal = pd.DataFrame(normal_scaler.fit_transform(iris), columns=iris.columns)
print(&#39;PowerTranformer Scaled: \n&#39;, iris_power.describe())
print()
print(&#39;Normalizer Scaled: \n&#39;, iris_normal.describe())
print(&#39;Euclidian Distance from 0: \n&#39;, np.linalg.norm(iris_normal, axis=1))</p>
<p>g5 = sns.jointplot(data=iris_power, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g5 = pw.load_seaborngrid(g5)
g5.set_suptitle(&quot;PowerTransformer Scaled&quot;)
g6 = sns.jointplot(data=iris_normal, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g6 = pw.load_seaborngrid(g6)
g6.set_suptitle(&quot;Normalizer Scaled&quot;)
g56 = (g5|g6)
g56</p>
<p>from sklearn.preprocessing import QuantileTransformer</p>
<p>gaussian_scaler = QuantileTransformer(output_distribution=&#39;normal&#39;)
uniform_scaler = QuantileTransformer(output_distribution=&#39;uniform&#39;)
iris_gaussian = pd.DataFrame(gaussian_scaler.fit_transform(iris), columns=iris.columns)
iris_uniform = pd.DataFrame(uniform_scaler.fit_transform(iris), columns=iris.columns)
print(&#39;QuantileTranformer_Gaussian Scaled: \n&#39;, iris_gaussian.describe())
print()
print(&#39;QuantileTranformer_Uniform Scaled: \n&#39;, iris_uniform.describe())</p>
<p>g7 = sns.jointplot(data=iris_gaussian, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g7 = pw.load_seaborngrid(g7)
g7.set_suptitle(&quot;QuantileTranformer_Gaussian Scaled&quot;)
g8 = sns.jointplot(data=iris_uniform, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g8 = pw.load_seaborngrid(g8)
g8.set_suptitle(&quot;QuantileTranformer_Uniform Scaled&quot;)
g78 = (g7|g8)
g78
(g1|g2|g3|g4)/(g5|g6|g7|g8)</p>
<pre><code>* 학습
```python
import numpy as np
from sklearn.preprocessing import PowerTransformer, Normalizer

# Scaler 객체 생성
# PowerTransformer(): 정규분포화(정규성 변환)(Box-Cox 변환, Yeo-Johnson 변환)
# Normalizer(): 한 행의 모든 피처들 사이의 유클리드 거리가 1이 되도록 변환
power_scaler = PowerTransformer()
normal_scaler = Normalizer()

# 데이터 변환 각각 (평균=0, 표준편차=1) (각 행의 벡터 크기 1)
ii_power = pd.DataFrame(power_scaler.fit_transform(ii), columns=ii.columns)
ii_normal = pd.DataFrame(normal_scaler.fit_transform(ii), columns=ii.columns)

# 결과 출력
print(&#39;PowerTranformer Scaled: \n&#39;, ii_power.describe())
print()
print(&#39;Normalizer Scaled: \n&#39;, ii_normal.describe())
print(&#39;Euclidian Distance from 0: \n&#39;, np.linalg.norm(ii_normal, axis=1))</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/e05bd2fe-5d15-427a-bd35-a69082a44e88/image.png" alt=""></p>
<pre><code class="language-python"># 다섯번째 그래프
g5 = sns.jointplot(data=ii_power, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g5 = pw.load_seaborngrid(g5)
g5.set_suptitle(&quot;PowerTransformer Scaled&quot;)

# 여섯번째 그래프
g6 = sns.jointplot(data=ii_normal, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g6 = pw.load_seaborngrid(g6)
g6.set_suptitle(&quot;Normalizer Scaled&quot;)

# 그래프 합치기
g56 = (g5|g6)
g56</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/d74cae0e-dc9f-4c13-a340-b600a57dbe3e/image.png" alt=""></p>
<pre><code class="language-python">from sklearn.preprocessing import QuantileTransformer

# Scaler 객체 생성
# QuantileTransformer(): 균일(Uniform)분포 또는 정규(Gaussian)분포로 변환
gaussian_scaler = QuantileTransformer(output_distribution=&#39;normal&#39;)
uniform_scaler = QuantileTransformer(output_distribution=&#39;uniform&#39;)

# 데이터 변환
ii_gaussian = pd.DataFrame(gaussian_scaler.fit_transform(ii), columns=ii.columns)
ii_uniform = pd.DataFrame(uniform_scaler.fit_transform(ii), columns=ii.columns)

# 결과 출력
print(&#39;QuantileTranformer_Gaussian Scaled: \n&#39;, ii_gaussian.describe())
print()
print(&#39;QuantileTranformer_Uniform Scaled: \n&#39;, ii_uniform.describe())</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/0c54adf0-f002-49e4-bbc8-fb2eae899416/image.png" alt=""></p>
<pre><code class="language-python"># 일곱번째 그래프
g7 = sns.jointplot(data=ii_gaussian, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g7 = pw.load_seaborngrid(g7)
g7.set_suptitle(&quot;QuantileTranformer_Gaussian Scaled&quot;)

# 여덟번째 그래프
g8 = sns.jointplot(data=ii_uniform, x=&#39;petal_length&#39;, y=&#39;petal_width&#39;, kind=&#39;reg&#39;)
g8 = pw.load_seaborngrid(g8)
g8.set_suptitle(&quot;QuantileTranformer_Uniform Scaled&quot;)

# 그래프 합치기
g78 = (g7|g8)
g78</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/2f3e09a7-aca7-4664-9a49-86f4c96620d9/image.png" alt=""></p>
<pre><code class="language-python"># 모든 그래프 합치기
(g1|g2|g3|g4)/(g5|g6|g7|g8)</code></pre>
<p><img src="https://velog.velcdn.com/images/hate_all/post/4c81dccb-dc2f-4a59-b4c4-a73ade51f228/image.png" alt=""></p>
<p>실행 결과 정리 -&gt; 마찬가지로 세 스케일러를 통해 데이터를 변환한 후 그래프로 시각화하여 변수간 관계를 나타냈다.</p>
<ul>
<li>응용<pre><code class="language-python">import pandas as pd
import numpy as np
</code></pre>
</li>
</ul>
<p>df = pd.DataFrame({&#39;x1&#39; : np.arange(11), &#39;x2&#39; : np.arange(11) ** 2})
from sklearn.preprocessing import StandardScaler</p>
<p>scaler = StandardScaler()
df_std = scaler.fit_transform(df)</p>
<p>pd.DataFrame(df_std, columns = [&#39;x1_std&#39;, &#39;x2_std&#39;])</p>
<pre><code>![](https://velog.velcdn.com/images/hate_all/post/f345f91e-9a5e-4665-88f5-6c10a198ccd8/image.png)
```python
import pandas as pd
import numpy as np

df = pd.DataFrame({&#39;x1&#39; : np.arange(11), &#39;x2&#39; : np.arange(11) ** 2})
from sklearn.preprocessing import RobustScaler

scaler = RobustScaler()
df_std = scaler.fit_transform(df)

pd.DataFrame(df_std, columns = [&#39;x1_std&#39;, &#39;x2_std&#39;])</code></pre><p><img src="https://velog.velcdn.com/images/hate_all/post/f0a42e53-b6c8-49a3-9104-e40b38bc6f33/image.png" alt="">
실행 결과 정리 -&gt; 간단한 데이터셋(x, x^2)에 대하여 StandardScaler와 RobustScaler를 적용하여 새로운 데이터셋으로 나타내었다. 확실히 후자가 이상치의 영향을 덜 받는다는 것이 납득이 간다.</p>
]]></description>
        </item>
    </channel>
</rss>