728x90
범주형 변수를 모델링을 하기 위해서는 더미변수를 만들어 모델링한다. 문자 그대로는 모델링 할 수 없기 때문이다.
from bs4 import BeautifulSoup
import pandas as pd
import requests
from io import BytesIO
from zipfile import ZipFile
import json
def get_company_code(api_key):
url = 'https://opendart.fss.or.kr/api/corpCode.xml?crtfc_key=%s' % api_key
response = requests.get(url)
zip_file = ZipFile(BytesIO(response.content))
files = zip_file.namelist()
soup = ''
with zip_file.open(files[0]) as csvfile:
soup = BeautifulSoup(csvfile.read(), 'lxml')
soup = soup.findAll('list')
data = []
for company in soup:
data.append({
'corp_code': company.corp_code.text,
'corp_name': company.corp_name.text,
'stock_code': company.stock_code.text,
'modify_date': company.modify_date.text
})
return pd.DataFrame(data)
def get_multi_account(api_key, code, year, report_code):
fullUrl = 'https://opendart.fss.or.kr/api/fnlttMultiAcnt.json?crtfc_key=%s&corp_code=%s&' \
'bsns_year=%s&reprt_code=%s' % (api_key, code, year, report_code)
response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
result = response.text
result = json.loads(result)
if result['status'] == '000':
data = pd.DataFrame(result['list'])
return data
if __name__ == '__main__':
api_key = '*'
company_code = get_company_code(api_key)
cmpy = ['005930', '005380', '000660','035720', '035420', '093050', '051910', '207940', '051900']
code = ','.join(company_code[company_code['stock_code'].isin(cmpy)]['corp_code'].tolist())
year = '2020'
report_code = '11011'
multi_account = get_multi_account(api_key, code, year, report_code)
multi_account = multi_account[['stock_code', 'fs_nm', 'account_nm', 'thstrm_dt', 'thstrm_amount']]
multi_account = multi_account[(multi_account['fs_nm']=='연결재무제표') & (multi_account['account_nm']=='당기순이익')]
multi_account['thstrm_amount'] = multi_account['thstrm_amount'].str.replace(',', '').astype(float) / 100000000
multi_account = multi_account.merge(company_code[['stock_code', 'corp_name']], how='left', on='stock_code')
multi_account['thstrm_dt'] = multi_account['thstrm_dt'].str.split('~', expand=True)[1].str.strip().str.replace('.', '-')
cap = pd.DataFrame([
{'stock_code': '005930', 'cap': 4835524},
{'stock_code': '005380', 'cap': 511735},
{'stock_code': '000660', 'cap': 910003},
{'stock_code': '035720', 'cap': 701409},
{'stock_code': '035420', 'cap': 675944},
{'stock_code': '093050', 'cap': 5980},
{'stock_code': '051910', 'cap': 592270},
{'stock_code': '207940', 'cap': 559756},
{'stock_code': '051900', 'cap': 274412},
])
multi_account = multi_account.merge(cap, how='left', on='stock_code')
multi_account['PER'] = multi_account['cap'] / multi_account['thstrm_amount']
multi_account['1/PER'] = 1 / multi_account['PER']
multi_account['bin'] = pd.cut(x=multi_account['1/PER'], bins=[multi_account['1/PER'].quantile(0), multi_account['1/PER'].quantile(0.33), multi_account['1/PER'].quantile(0.66), multi_account['1/PER'].quantile(1)], labels=['고PER','평균PER','저PER'], include_lowest=True)
print(pd.concat([multi_account[['stock_code', 'corp_name', '1/PER', 'bin']], pd.get_dummies(multi_account['bin'], prefix='dummy', drop_first=True)], axis=1))
print(pd.concat([multi_account[['stock_code', 'corp_name', '1/PER', 'bin']], pd.get_dummies(multi_account['bin'], prefix='dummy', drop_first=False)], axis=1))
결과 값
stock_code corp_name 1/PER bin dummy_평균PER dummy_저PER
0 005930 삼성전자 0.054612 저PER 0 1
1 000660 SK하이닉스 0.052296 저PER 0 1
2 035720 카카오 0.002472 고PER 0 0
3 035420 NAVER 0.012501 평균PER 1 0
4 051910 LG화학 0.011522 고PER 0 0
5 051900 LG생활건강 0.029631 평균PER 1 0
6 093050 LF 0.047819 저PER 0 1
7 207940 삼성바이오로직스 0.004305 고PER 0 0
stock_code corp_name 1/PER bin dummy_고PER dummy_평균PER dummy_저PER
0 005930 삼성전자 0.054612 저PER 0 0 1
1 000660 SK하이닉스 0.052296 저PER 0 0 1
2 035720 카카오 0.002472 고PER 1 0 0
3 035420 NAVER 0.012501 평균PER 0 1 0
4 051910 LG화학 0.011522 고PER 1 0 0
5 051900 LG생활건강 0.029631 평균PER 0 1 0
6 093050 LF 0.047819 저PER 0 0 1
7 207940 삼성바이오로직스 0.004305 고PER 1 0 0
예시를 들기 위해 1/PER의 데이터를 고PER, 평균PER, 저PER로 나눈 범주형변수로 변환하였다. 실제로는 연속형변수가 더욱 설명력이 높을 수 있으니 변환은 테스트를 통해서 신중히 결정해야 한다. 비슷한 수준의 1/PER은 그 속에선 유의미한 차이가 없다면 범주형 변수로의 변환을 고려해볼 수 있다. 업종 데이터를 이용하는 것이 일반적이다.
더미변수로 변환하면 각 값을 0, 1으로 변환한 조합으로 각 값을 설명한다. 즉, 고PER은 고PER, 평균PER, 저PER의 조합이 1, 0, 0 이다. 더미변수로의 변환은 크게 두 가지가 있다 고PER, 평균PER, 저PER 모두 사용하는 경우와 평균PER, 저PER 두 가지만 사용하는 경우이다. 후자의 경우는 평균PER과 저PER의 값이 모두 0일 때 고PER을 의미한다.
728x90
'Data Science > Data Preprocessing' 카테고리의 다른 글
[04. Feature Sampling] 001. Simple Random Sampling (0) | 2021.07.20 |
---|---|
[03. Feature Engineering] 006. Dimensionality Reduction (0) | 2021.07.20 |
[03. Feature Engineering] 004. Transform (0) | 2021.06.29 |
[03. Feature Engineering] 003. Binning (0) | 2021.06.29 |
[03. Feature Engineering] 002. Scaling (0) | 2021.06.24 |