https://www.youtube.com/watch?v=J4Wdy0Wc_xQ&t=42s 

 

모든 이미지와 출처는 위영상으로 부터 가져왔다.

 

1. Randomforest란

 

Decision Tree는 overfitting될 가능성이 높다는 약점을 가지고 있다. prune을 통해 트리의 최대 깊이를 설정하여 어느정도 방지할 수 있지만 이 방법으로 overfitting을 해결하기에는 무리가 있다. 

 

Random forest는 여러개의 decision tree를 만들어 예측데이터를 각 트리에 동시에 통과시키고, 각 트리가 분류한 결과에서 투표를 실시하여 가장 많이 득표한 결과를 최종 결과로 선택한다.

 

랜덤 포레스트 중 몇몇개 트리는 overfitting될 수 있지만, 많은 수의 트리를 생성함으로써 overfitting이 예측하는데 있어 큰 영향을 미치지 못 하도록 방지한다. 

 

 

2. Randomforest 만들기

 

decision tree에대한 지식이 부족하다면 이해가 힘들 수 있으니 이전 게시글을 보고오는걸 추천한다.

 

https://gwoolab.tistory.com/24?category=906381 

 

[ML] Decision tree 수학적으로 알아보기 - 분류

1.  트리기반 모델을 자주사용하지만 모델에 대한 이해가 부족한것 같아 하나씩 작성해보려한다. 참조의 대부분은 https://www.youtube.com/watch?v=7VeUPuFGJHk&t=268s 에서 가져왔다. 2-1. decision tree  de..

gwoolab.tistory.com

 

2-1. bootstraped dataset

 

랜덤 포레스트를 만들기 위해서는 부트스트랩 데이터셋을 먼저 생성한다. 

원본데이터와 같은 사이즈의 부트스트랩 데이터를 만들기위해서는 그냥 랜덤으로 오리지날 데이터 셋에서 추출한다.

단 복원추출을 허용하여 데이터를 추출한다. 같은데이터가 두번이상 추출가능하다는 이야기이다.

 

2-2. columns 선택

예를 들어 한 단계마다 두가지의 변수를 선택한다고 가정하자

첫 분기점에서 두가지의 컬럼을 랜덤하게 선택하고 두 지니계수를 비교해 첫 분기점으로 삼는다.

다음 노드들에서도 랜덤하게 두개의 컬럼을 뽑고 그 안에서 질문을 선택한다.

 

이렇게 트리하나가 완성이 되는 것이다..

 

이런 2-1~2-2의 과정을 반복하여 여러가지의 트리를 만들게된다

 

2-3. voting

최종적으로 만들어지 여러트리에 같은 데이터를 통과시켜 결과를 투표를 한 후 높은 표를 받은 결과를 랜덤포레스트의 최종 결과로 반환한다.

 

 

이런 총 과정을 익히들었을

배깅이라고한다.

 

 

3. 정리

디시전트리를 랜덤으로 뽑은 row와 column을 통해 만든다 x n개

 

n개의 트리의 결과를 투표하려 최종 리턴

 

 

몇개의 row와 몇개의 column을 뽑을지는 여러번 반복시행후 성능을보고 결정(하이퍼파라미터튜닝)

 

 

 

 

'ML' 카테고리의 다른 글

[ML] Gradient Boost - Classification  (0) 2022.01.03
[ML] Gradient Boost - regression  (0) 2021.12.30
[ML] Adaboost  (0) 2021.12.29
[ML] Regression Tree  (0) 2021.12.28
[ML] Decision tree  (0) 2021.12.28

https://www.youtube.com/watch?v=g9c66TUylZ4&t=1058s\ 

위 영상을 바탕으로 작성했다..

 

위 와 같이 선형성을 띄는 데이터의 경우 단순선형회귀를 적합하는 것이 옳겠다.

하지만

 

이런 모양의 데이터라면 회귀분석을 고려하기 어려울 것이다. 

물론 다항회귀분석을 고려하는 것은 어떻냐는 질문이 따라오겠지만

 

 

이런식의 범주형데이터가 섞여있거나 많은 변수들이 생긴다면 예측을하기 곤란해질 것이다.

그래서 회귀나무를 사용한다..

앞으로 그 회귀나무가 어떻게 만들어지는지 알아보자

Regression Tree도 일반 decision tree와 같이 어떤 feature를 어떤 threshold를(경계)으로 할 것인지 선택하는 것이 중요하다..

https://gwoolab.tistory.com/24 decision tree에서 수치형 변수를 다루는 방법과 거의 유사하다.

 

 

1. 한가지의 변수만을 고려

설명을 용이하게하기위해 effectuveness와 dosage두가지만을 고려해보자

 

drug dosage변수와 drug effectiveness(target)의 그래프를 보고 가장 낮은 drug dosage값 두가지에 집중해보자

 

두 drug dosage의 평균값은 3이다. 이제 이 3을 기준으로 두 그룹을 나눈다.

좌측편 target의 평균은 0이고 우측의 target평균은 38.8이다.

이제 dosage < 3 이라는 질문의 SSR (sum of squre residuals) 을 계산한다.

 

※ ssr = (참값 - 예측값(여기서는 각 그룹의 평균) )^2

예측값이 참값과 비슷할수록 ssr은 낮고 잘 예측했다고할 수 있다.

 

 

 

이런식으로 dosage변수들 사이의 값을 threshold로 하여 모든 ssr을계산사면 다음과같다 .

 

이중에서 가장 ssr이 작은  14.5를 threshold로 선택한다.

그말인 즉슨 dosage < 14.5라는 질문이 첫번째에 와야한다는 의미이다.

 

이후 다음 노드에서도 

같은 과정을 반복하여 dosage<11.5 라는 질문을 얻었다. 

이 때 no라는 대답의 값이 1개인 경우 그 노드는 리프노드가된다. 즉 더이상 분기할 수 없다.

 

좌측노드를 계속 분기한다면 위와 같은 트리를 얻을 것이다. 위 트리는 주어진 데이터에 있어서 100%를 예측할 수 있다.

하지만 이렇게 계속 분기한다면 엄청난 과적합의 리스크를 안고갈 수 밖에 없다..

 

이런 과적합을 해결하기 위해서는 여러가지 기법이있다. 

가장 간단한방법은 각 노드별 분류하는 row의 갯수의 하한선을 정하는 것이다. 만약에 하한선을 7로 정한다면

 

첫분기점 이후의 좌측노드의 row의 수는 7보다 작기때문에 더이상 분기하지않는다.

 

 

하지만 우측노드는 13개의 row를 가지기때문에 계속해서 분기할 수 있다.

같은 과정으로 계속해서 분기한다면.

 

이렇게 최종 트리를 얻을 수 있다.

 

 

 

 

2. 여러 변수를 고려할 때

범주형 변수일떄는 sex의 경우처럼 , 연속형 변수나 순서형 변수는 1번의 경우처럼 가장 낮은 ssr을 가지는 threshold를 선택하여 변수에 맞는 질문을 만들고 그 질문끼리 가장작은 질문을 우선 순위로하여 트리를 구성하여 트리를 완성한다.

 

'ML' 카테고리의 다른 글

[ML] Gradient Boost - Classification  (0) 2022.01.03
[ML] Gradient Boost - regression  (0) 2021.12.30
[ML] Adaboost  (0) 2021.12.29
[ML] Randomforest  (0) 2021.12.29
[ML] Decision tree  (0) 2021.12.28

1. 순열

import itertools


color_list = ['red','blue','green']

nPr = itertools.permutations(color_list, 2)
print(list(nPr))
[('red', 'blue'), ('red', 'green'), ('blue', 'red'), ('blue', 'green'), ('green', 'red'), ('green', 'blue')]

순서를 고려하여 즉 (a,b)와 (b,a)를 다른 것으로 치고 뽑기 

itertools.permutations(list, n)

list에서 n개를 뽑는경우

 

 

2. 조합

nCr = itertools.combinations(color_list, 2)
print(list(nCr))
[('red', 'blue'), ('red', 'green'), ('red', 'orange'), ('blue', 'green'), ('blue', 'orange'), ('green', 'orange')]

순서를 고려하여 즉 (a,b)와 (b,a)를 같은 것으로 치고 뽑기

itertools.combinations(list, n)

list에서 n개를 뽑는경우

 

 

1. 

 트리기반 모델을 자주사용하지만 모델에 대한 이해가 부족한것 같아 하나씩 작성해보려한다.

참조의 대부분은

https://www.youtube.com/watch?v=7VeUPuFGJHk&t=268s 

 

에서 가져왔다.

 

 

2-1. decision tree 

 decision tree 즉 의사결정나무는 어떤한 데이터를 받았을 떄 ㄷ그 데이터를 바탕으로 질문을 던저 해답을 얻는 과정이다. 쉽게 말하면 스무고개 게임을 하는것이다.

 

 스무고개 게임을 할 때 가장 중요한 점은 질문의 순서일 것이다. 대상을 많이 좁힐 수 있는 질문을 가장 먼저 던지는 것이 답을 구하는데 가장 빠르게 도달할 수 있는 방법일 것이다.

 이런 이유로 의사결정 나무에서도 어떤 질문을 하는지, 즉 어떤 변수를 대상으로 질문을 던지는 것인지를 판단해야한다.

이에 쓰이는 척도가 불순도이다.

 불순도를 나타내는 척도에는 gini, entropy같은 척도가 있는데 이번에는 gini를 기반으로 설명을 진행하겠다.

 

 

2-2. 지니계수

 

위 사진의 경우 다람쥐가 1마리 낙타가 4마리이다.

지니계수를 계산하면 1- (P(다람쥐)^2 + P(낙타)^2) = 1 - ((1/5)^2 + (4/5)^2)  = 0.32 이다. 이 이미지가 얼마나 순수한지를 나타내는 척도라고 이해하면 좋다.

 

위 사진의 경우 다람쥐가 2마리 낙타가 2마리이다.

1- (P(다람쥐)^2 + P(낙타)^2) = 1 - ((1/2)^2 + (1/2)^2)  = 0.5 이다. 데이터가 반반 일시에는 이렇게 지니지수가 항상 반반이 나온다.

 

 

2-3. decision tree 만드는과정 (이진변수)

 

영상의 예시를 들어 지니계수를 계산해보자

 

좌측노드의 지니계수를 계산하면 다음과 같다.

 

 

우측노드의 지니계수를 같은 방법으로 계산하면 0.336이다.

하지만 우리는 이 질문의 지니계수를 구해야한다. 질문의 지니는 두 좌우측노드의 가중평균으로 구한다.

 

좌측노드의 총 데이터 갯수는 144개 우측노드의 갯수는 159개로 

 

 

가중평균하여 chestpain의 질문에 대한 지니계수를 산출한다.  

 

 

같은 방법을 다른 featrue들에도 반복하면  위와 같은 숫자등이 나오게된다. 

세질문중에 불순도 즉 지니계수가 가장낮은 Blood Circulation에 관한 질문을 가장 먼저 물어보는 질문으로 설정한다.

 

같은 과정을 이후에 생긴 노드에도 반복하면 chest pain에 관한 질문을 할것인가 Block Arteries에 대한 질문을 할 것인지 불순도를 계산한다. 위 경우에는 지니계수가 더 낮은 Block Arteries를 선택할것이다.

그리고 그 이후 남은 질문인 chest pain에 관한 질문을 이어나간다.

 

이렇게 가장 좌측가지는 완성이된다.

 

이제 나머지 가지들을 채워나갈 차례다.

만약 질문을 하는것이 분류를 하는데에 오히려 방해가 된다면 질문을 하는것이 유리할까?

그렇지 않다 즉, 가지를 더 뻗어나가지않고 가지를 자르는게 옳다. 그렇다면 이 경우를

숫자로 어떻게 판단을 해야할까?

 

해당 분기점 노드의 불순도와 다음 질문했을 때의 불순도를 비교하여보면된다.

질문을 하지않았을때의 불순도는 yes 13/ no 102로 0.2이고

 

분기점을 나눈이이후의 불순도는 0.29이다. 이 경우 질문을 더이상하지않고 멈추는것이 옳다.

 

이과정을 모든 노드에 반복하면

 

 

이렇게 완성된 트리형태가 나오게된다.

 

 

2-4. 수치형변수에서의 노드분기

 

 

수치변수에서는 임의로 범주형변수로 전환을 하여 지니계수를 계산한다.

위와 같은 데이터가 있다면 선택한 변수를 정렬하고 각 값사이의 평균값을 기준으로 크다 작다를 비교하여 범주형 변수로 변환한 후 각 지니계수를 계산한다.

 167.5를 기준값으로 먼저 지니계수를 구하는 과정이다. 이과정을 모든 기준값에 반복하여

모든 경우에대하여 지니계수를 계산하였으면 가장낮은 0.27이 weight에 대한 지니계수가 되는것이고

다른 변수에대한 지니계수를 비교하여 질문을 선택하게된다.

 

 

2-5. 순서형변수에서의 노드분기

 

순서형변수의 경우 수치형변수의 경우와 비슷하게 지니계수를 계산한다.

만약 [1, 2, 3, 4 ] 가 있다면 위와 같이 세가지 질문의 지니꼐수를 계산하고 가장낮은 것을 취한다.

 

 

2-6. 범주형변수에서의 노드분기

 

[green, blue, red] 세가지 범주가 있다면 3C2 + 3C1총 6가지의 지니계수를 계산하고 가장낮은 것을 취한다.

'ML' 카테고리의 다른 글

[ML] Gradient Boost - Classification  (0) 2022.01.03
[ML] Gradient Boost - regression  (0) 2021.12.30
[ML] Adaboost  (0) 2021.12.29
[ML] Randomforest  (0) 2021.12.29
[ML] Regression Tree  (0) 2021.12.28

 

 

1. 무작위 정수추출 

randint(start, stop)

start 이상 stop 이하 범위의 정수 난수 생성

for i in range(10):
    print(i+1, 'th pick',random.randint(1, 10))
1 th pick 7
2 th pick 4
3 th pick 1
4 th pick 4
5 th pick 2
6 th pick 5
7 th pick 4
8 th pick 9
9 th pick 1
10 th pick 9

randrange(start, stop,step)

start 이상 stop 미만 step간격의 리스트에서 무작위 추출

 

for i in range(10):
    print(i+1, 'th pick',random.randrange(1, 10,3))
1 th pick 7
2 th pick 4
3 th pick 1
4 th pick 1
5 th pick 4
6 th pick 1
7 th pick 1
8 th pick 4
9 th pick 1
10 th pick 7

 

2. 리스트순서 섞기

 

shuffle(list)

리스트의 순서를 무작위로 섞어 반환

abcd = alpha_list[:4]

print(abcd)
for i in range(5):
    random.shuffle(abcd)
    print(i+1, 'th pick',abcd)
['a', 'b', 'c', 'd']
['c', 'a', 'd', 'b']
['d', 'a', 'b', 'c']
['d', 'a', 'c', 'b']
['a', 'c', 'd', 'b']
['b', 'a', 'd', 'c']

3. 리스트에서 무작위 1개 추출

 

choice(list)

print(alpha_list)

for i in range(10):
    print(i+1, 'th pick',random.choice(alpha_list))
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
1 th pick d
2 th pick f
3 th pick g
4 th pick a
5 th pick e
6 th pick f
7 th pick e
8 th pick a
9 th pick g
10 th pick c

가중치까지 부여

 

choices(list, weight_list)

print(alpha_list)
weight = list(range(1,11))

print(weight)
for i in range(10):
    print(i+1, 'th pick',random.choices(alpha_list,range(10)))
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1 th pick ['g']
2 th pick ['j']
3 th pick ['h']
4 th pick ['i']
5 th pick ['c']
6 th pick ['h']
7 th pick ['g']
8 th pick ['f']
9 th pick ['f']
10 th pick ['j']

각각 가중치 부여 뒷쪽 알파벳에 가중치가 높아 뒷쪽이 많이 뽑힘

 

4. 리스트에서 무작위 n개 추출

 

random.sample(list,n)

abcd = alpha_list[:4]

print(abcd)
for i in range(5):
    print(i+1, 'th pick',random.sample(abcd,2))
['a', 'b', 'c', 'd']
['a', 'b']
['c', 'b']
['b', 'a']
['b', 'd']
['b', 'c']

 

코딩테스트를 준비하거나

어떠한 제품에 일련번호를 부여해야할 때 알파벳리스트가 필요할 때가 있다..

 

그럴 떄 string 모듈을 사용하면 용이하다.

print(string.ascii_lowercase)
print(list(string.ascii_lowercase))
print(list(string.ascii_lowercase)[:4])
abcdefghijklmnopqrstuvwxyz
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
['a', 'b', 'c', 'd']

소문자는 lowercase를

 

대문자는 uppercase를 이용한다

print(string.ascii_uppercase)
print(list(string.ascii_uppercase))
print(list(string.ascii_uppercase)[:4])
ABCDEFGHIJKLMNOPQRSTUVWXYZ
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
['A', 'B', 'C', 'D']

변수를 자동으로 생성하고 싶을때

예를 들어 a_1, a_2. a_3 ... 에 순차적으로 원하는 값을 할당하고 싶을 떄 사용

 

for i in range(10):
    globals()[f'a_{i}'] = i
    print(globals()[f'a_{i}'])
    print(globals()[f'a_{i}'] > 4)
    print(globals()[f'a_{i}'] * '원')
0
False

1
False
원
2
False
원원
3
False
원원원
4
False
원원원원
5
True
원원원원원
6
True
원원원원원원
7
True
원원원원원원원
8
True
원원원원원원원원
9
True
원원원원원원원원원
a_8
8

 

 

변수명에 i들이 이쁘게 잘들어갔다.

연산도 그대로 적용된다. 

 

함수또한 마찬가지다

 

for문을 돌리고 하염없이 시간기다리기 싫을 떄

진행상황을 알고 싶다면 사용 

from tqdm.notebook import tqdm
import time
strat_time = time.time()

for i in tqdm(range(50)):
    time.sleep(1)
    
end_time = time.time()

sec = round(end_time - strat_time,1)
min_ =  int(sec//60)
sec = int(sec % 60)

print(f'반복문의 실행은 {min_}분 {sec}초가 걸렸습니다.')
반복문의 실행은 0분 50초가 걸렸습니다.

포문을 실행할 때 반복을 실시할 리스트류에 tqdm 을 씌워주면

진행중에 위와 같은 창이 뜨고 실행되게된다

 

1번은 진행 퍼센테이지

2번은 진행한시간

3번은 남은시간

4번은 한 반복이 걸리는 평균시간을 말한다..

 

tqdm모듈을 사용하면 진행상황과 남은 시간을 예측할 수 있어 시간배분이 효율적일 수 있다.

 

또한 

time 모듈의 time() 함수를 활용하면 현재의 초를 알려준다

 

이에 포문시작과 완료시간을 빼면 총 포문을 실행하는 데에 걸린시간을 알 수 있다,.

데이터 출처 :

https://www.data.go.kr/data/15025602/fileData.do

 

 

import pandas as pd
import numpy as np

df = pd.read_csv('C:\\Users\\user\\Desktop\\티스토리데이터\\수원도시공사_실내공기질 측정 정보_20201211.csv', encoding = 'euc-kr')
df = df[['미세먼지(㎍/㎡)','이산화탄소(ppm)','포름알데히드(㎍/㎡)','일산화탄소(ppm)']]

print(df.shape)

for i in range(5):
    df.iloc[np.random.randint(df.shape[0]),np.random.randint(1,df.shape[1])] = np.nan

print(df.isna().sum())

df.columns = ['미세먼지','이산화탄소','포름알데히드','일산화탄소']
display(df)
(7, 4)
미세먼지(㎍/㎡)      0
이산화탄소(ppm)     1
포름알데히드(㎍/㎡)    2
일산화탄소(ppm)     2
dtype: int64

 


미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.838 NaN
1 33.0 476.5 2.556 3.60
2 40.5 460.0 6.647 3.10
3 54.4 498.7 NaN 4.97
4 41.5 473.0 6.796 2.90
5 56.4 491.5 NaN 3.25
6 63.1 NaN 4.873 NaN

데이터를 가져와 미세먼지열을 제외한 컬럼에 임의로 nan값을 발생시켰다.

 

 

1. dropna()

nan을 포함하는 행을 모두 삭제하는 방법

df.dropna()

미세먼지 이산화탄소 포름알데히드 일산화탄소
1 33.0 476.5 2.556 3.6
2 40.5 460.0 6.647 3.1
4 41.5 473.0 6.796 2.9

2. fillna()

원하는 값으로 채우는 방법

display(df.fillna(0))

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.838 0.00
1 33.0 476.5 2.556 3.60
2 40.5 460.0 6.647 3.10
3 54.4 498.7 0.000 4.97
4 41.5 473.0 6.796 2.90
5 56.4 491.5 0.000 3.25
6 63.1 0.0 4.873 0.00

0으로 채워짐

 

print(df.mean())
display(df.fillna(df.mean()))
미세먼지       48.385714
이산화탄소     485.450000
포름알데히드      4.942000
일산화탄소       3.564000
dtype: float64

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.00 3.838 3.564
1 33.0 476.50 2.556 3.600
2 40.5 460.00 6.647 3.100
3 54.4 498.70 4.942 4.970
4 41.5 473.00 6.796 2.900
5 56.4 491.50 4.942 3.250
6 63.1 485.45 4.873 3.564

각 열의 평균으로 대치가 된다.

같은 방법으로 중앙값, 사분위 수 등의 스칼라로 대체가능하다.

 

df.fillna(method='ffill')

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.838 NaN
1 33.0 476.5 2.556 3.60
2 40.5 460.0 6.647 3.10
3 54.4 498.7 6.647 4.97
4 41.5 473.0 6.796 2.90
5 56.4 491.5 6.796 3.25
6 63.1 491.5 4.873 3.25

각 컬럼의 앞값을 복사한다. 

method를 'bfill'로 넣는다면 뒷값을 복사한다. 일산화탄소 컬럼의 첫 원소는 앞원소가 존재하지않아 nan을 유지한다.

 

3.interpolate()

 

df.interpolate(method='values')

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.0 3.8380 NaN
1 33.0 476.5 2.5560 3.60
2 40.5 460.0 6.6470 3.10
3 54.4 498.7 6.7215 4.97
4 41.5 473.0 6.7960 2.90
5 56.4 491.5 5.8345 3.25
6 63.1 491.5 4.8730 3.25

nan부분을 앞뒤 원소의 선형식으로 보간함

 

4. 다른 값을 통한 예측

 

from sklearn import linear_model 
reg = linear_model.LinearRegression() 

df_dn = df[['미세먼지','이산화탄소']].dropna()
reg.fit(df_dn['미세먼지'].values.reshape(-1,1), df_dn['이산화탄소'])
dust_list = df['미세먼지'].loc[df['이산화탄소'].isna()].tolist()

df['이산화탄소'].loc[df['이산화탄소'].isna()] = list(map(lambda x : reg.predict(np.array(x).reshape(-1,1)), dust_list))

미세먼지 이산화탄소 포름알데히드 일산화탄소
0 49.8 513.000000 3.838 NaN
1 33.0 476.500000 2.556 3.60
2 40.5 460.000000 6.647 3.10
3 54.4 498.700000 NaN 4.97
4 41.5 473.000000 6.796 2.90
5 56.4 491.500000 NaN 3.25
6 63.1 510.048021 4.873 NaN

미세먼지와 이산화탄소 사이의 단순선형회귀 분석을 통해 

이산화탄소의 값을 예측하여 nan값을 채운것

데이터 출처:

https://www.data.go.kr/data/15013192/standard.do

 

전국금연구역표준데이터

금연구역 정보(금연구역 지역, 면적, 위반과태료 등)를 제공합니다. 공공데이터 개방 표준데이터 속성정보(표현형식/단위 등)는 [공공데이터 개방 표준]고시를 참고하시기 바랍니다.(정보공유>

www.data.go.kr

 

 

위 링크의 데이터 목록처럼 데이터 컬럼 형식은 같지만 방대한 데이터의 양 때문에 데이터를 끊어서 제공하는 경우가 있다.

일일이 데이터를 읽고 concat하기에는 시간이 오래 걸리기에 for문과 os, pandas 모듈을 사용하여 concat하는 방법이다.

 

1. os 모듈로 작업위치 확인 및 변경

 

import os
import pandas as pd

os.getcwd()
'C:\\Users\\user'

os.getcwd()는 현재 작업중인 파이썬 폴더를 알려준다.

 

os.chdir("C:\\Users\\user\\Desktop\\티스토리데이터\\os")
os.getcwd()
'C:\\Users\\user\\Desktop\\티스토리데이터\\os'

os.chdir()를 활용하면 폴더를 옮길 수 있다. 

 

폴더의 경로는 폴더내의 빈공간을 마우스 우클릭 후 속성탭에 들어가면 위치를 확인 가능하다.

 

그리고 주피터 노트북내에서 원하는 셀을 누른뒤에 esc를 누르고 f를 누르면 일괄바꾸기 기능이 작동되는데 \를  \\로 바꿔주면 파이썬에서 인식하는 경로의 형식으로 바꾸는게 손쉽게 가능하다.

print(os.listdir())
['chim_df.xlsx', 'corr.csv', 'tb_hb_ind_egnin_m.csv', 'test.csv', 'test_.csv', 'test_cnt.csv', '경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv', '계산을해보자.csv', '상권분석_final.twbx', '성연령별매출 추출_Extract.csv', '청년상권 클러스터링.ipynb']

os.listdir() 을 활용하면 현재 폴더안에 있는 파일들의 이름을 불러와준다.

 

여기서 우리가 가져와야할 데이터는 

경기도_xxx_금연구역_xxxx.csv 

이런 형식의 데이터만 불러와 concat하고자 한다.

 

print(os.listdir())
csv_list = list(filter(lambda x : x.split('.')[-1] == 'csv', os.listdir()))
print(csv_list)
csv_list2 = list(filter(lambda x : '금연구역'in x, csv_list))
print(csv_list2)
['chim_df.xlsx', 'corr.csv', 'tb_hb_ind_egnin_m.csv', 'test.csv', 'test_.csv', 'test_cnt.csv', '경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv', '계산을해보자.csv', '상권분석_final.twbx', '성연령별매출 추출_Extract.csv', '청년상권 클러스터링.ipynb']
['corr.csv', 'tb_hb_ind_egnin_m.csv', 'test.csv', 'test_.csv', 'test_cnt.csv', '경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv', '계산을해보자.csv', '성연령별매출 추출_Extract.csv']
['경기도_가평군_금연구역_20211012_1634033497993_29131.csv', '경기도_고양시_금연구역_20210920_1634617775511_649377.csv', '경기도_남양주시_금연구역_20210930_1634027480812_2270079.csv', '경기도_포천시_금연구역_20210930_1634790042474_958431.csv']

이렇게 파이썬의 내장함수 filter를 활용하면 리스트 중 조건에 만족하는 리스트만을 생성할 수 있다.

https://gwoolab.tistory.com/13

 

[ python 기초 ] lambda, map, filter

lambda 함수를 한줄에 정의하고 사용만 한다.코드의 간결함 메모리의 절약 람다 함수는 정의와 동시에 사용할 수 있음 lambda 매개변수 : 리턴값 print((lambda x : x**2)(2)) 4 제곱을 해주는 함수를 정의하

gwoolab.tistory.com

 

이렇게 타겟하는 파일만을 확인하고 포문으로 빈데이터 프레임에 하나씩 쌀으면 된다

 

df = pd.DataFrame()

for file in csv_list2:
    tmp_df = pd.read_csv(file, encoding = 'euc-kr')
    print(tmp_df.shape)
    df = pd.concat([df,tmp_df])
    print(df.shape)
(131, 15)
(131, 15)
(2572, 15)
(2703, 15)
(10496, 15)
(13199, 15)
(3393, 15)
(16592, 15)

데이터 들이 df라는 데이터에 차례로 쌓이는 것을 확인할 수 있다.

 

 

 

 

+ Recent posts