본문 바로가기
공부/데이터

[데이터정제] apriori 알고리즘을 실행할 수 있게 데이터 변형하기

by demonic_ 2019. 12. 2.
반응형

DBMS에서 바로 데이터를 뽑으면 다음과 같은 행태일 것이다.

TransactionID, ProductName
1	아메리카노
2	카페라떼
2	아메리카노
2	카푸치노
3	아메리카노
3	카푸치노

 

하지만 Apriori 알고리즘을 실행하려면 다음과 같은 데이터구조가 되어야 한다

dataset = [[아메리카노]
, [카페라떼,아메리카노,카푸치노]
, [아메리카노,카푸치노]]

 

 

위와 같은 형태의 데이터를 뽑기 위해서는 2가지 방법이 있다.

 

1) DBMS에서 위와같은 형태로 뽑는다.

2) pandas 를 이용해 데이터를 가공한다.

 

 

# 1번의 경우

MySQL을 이용한다면 다음 함수를 통해 구분자뽑기가 가능하다.

다만 뽑을때 구분자를 콤마로 하면 csv로 저장하여 python에서 로드할때 에러가 발생할 수 있기 때문에 여기서는 '|'를 이용했다

select 
	TransactionID
	, GROUP_CONCAT(ProductName SEPARATOR '|') as ProductName
from [테이블명]
group by TransactionID

결과)

~~~
TransactionID, ProductName
1	아메리카노
2	카페라떼|아메리카노|카푸치노
3	아메리카노|카푸치노
...
~~~

이 상태로 export 하면 된다.

 

 

# 2번의 경우

처음에는 group를 TransactionID 단위로 묶어 인덱스로 지정한 후에 for문을 통해 인덱스에 접근하여 각각의 개체를 목록화하여 리턴하게 하였다. 그런데 시간이 엄청 오래 걸렸다. (100만 건을 처리하는데 1시간 가량 소요)

 

당시 사용했던 코드

df1 = pd.read_csv('파일명.csv')

tmp_1 = df1.set_index('TransactionID')

tmp_keys =tmp_1.index.drop_duplicates()

tmp_keys

> Int64Index([1, 2, 3 ...],
           dtype='int64', name='TransactionID', length=1966436)

tmp_1.loc[tmp_keys[1]]['ProductName'].values

> ['카페라떼', '아메리카노', '카푸치노']

# 제품명을 Series로 추출하여 리스트로 담기
# 너무 오래걸려 폐기. (index로 접근하는데 많은 자원 사용)
dataset = []

for i, key in tqdm_notebook(enumerate(tmp_keys)):
    target = tmp_1.loc[key]['ProductName']
    
    if isinstance(target, str):
        dataset.append(pd.Series(target).values.tolist())
    elif isinstance(target, pd.Series) : 
        dataset.append(target.values.tolist())
    else:
        print('unknown')

 

처음에는 빈 데이터프레임을 만들어줘서 느린줄 알았는데, 로그를 상세히 찍어보니 인덱스에 접근하는데 평균 0.5~1초의 시간이 걸렸다.

그래서 개선된 코드에는 apply를 사용했다.

groupby 로 TransactionID 를 인덱스로 잡은 후, join 명령어를 이용해 데이터를 합쳤고 구분자 ','를 삽입했다.

190만 건을 처리하는데 1분 24초가 소요되었다.

r_1 = df1.groupby(['TransactionID']).progress_apply(lambda x: ','.join(x['ProductName']))

r_2 = pd.DataFrame(r_1).reset_index().rename(columns={0:'item_names'})

r_2
(index) TransactionID, ProductName
0 1 아메리카노
1 2 카페라떼,아메리카노,카푸치노
2 3 아메리카노,카푸치노

반응형

댓글