안녕하세요. 보랏입니다.
오늘은 머신러닝 금융 데이터 활용 데이터 분석을 진행하였으며
Django를 활용한 웹 페이지를 구축하였습니다.
복습 시작하겠습니다.
1. 머신러닝 - 금융 데이터 활용 디폴트 찾기 (출처 : 금융 파이썬 쿡북)
- 사용되는 데이터 셋은 2005년 10월 대만 은행에서 수집한 것으로 '과거 상환 내역과 함께 고객에 대한 몇 가지 기본정보 (성별, 연령 교육 수준)을 사용해 디폴트 가능성이 높은 사람을 예측
- 6개월의 상환내역 (2005년 4월 ~9월)을 사용해 고객이 2005년에 10월에 디폴트를 할지 말지 여부 예측
데이터 읽기 및 유형 관리 (메모리 최적화 가능)
- separator 문자는 무엇인가?
- 별도 처리해야 하는 특수 문자가 존재하는가?
- 누락된 값(결측치)이 있는가? 그렇다면 어떻게 처리해야하나?
- 파일에 있는 변수 유형(float, integer, string)은 무엇인가?
df = pd.read_csv('credit_card_default.csv', index_col=0, na_values='')
print(f'The DataFrame has {len(df)} rows and {df.shape[1]} columns.')
df.head()
- Target(y값) 추출
X = df.copy()
y = X.pop('default_payment_next_month')
X.columns
- 메모리 사용량 확인하기
- type이 object인 컬럼을 대상으로 category(범주형) 데이터 타입으로 변경하여 메모리 절약 가능
# 실제로 메모리를 얼마나 사용중인가 확인하는 함수
def get_df_memory_usage(df, top_columns=5):
'''
Function for quick analysis of a pandas DataFrame's memory usage.
It prints the top `top_columns` columns in terms of memory usage
and the total usage of the DataFrame.
Parameters
------------
df : pd.DataFrame
DataFrame to be inspected
top_columns : int
Number of top columns (in terms of memory used) to display
'''
print('Memory usage ----')
memory_per_column = df.memory_usage(deep=True) / 1024 ** 2
print(f'Top {top_columns} columns by memory (MB):')
print(memory_per_column.sort_values(ascending=False) \
.head(top_columns))
print(f'Total size: {memory_per_column.sum():.4f} MB')
get_df_memory_usage(df, 5)
df_cat = df.copy()
object_columns = df_cat.select_dtypes(include='object').columns
df_cat[object_columns] = df_cat[object_columns].astype('category')
get_df_memory_usage(df_cat, 5)
탐색적 데이터 분석 (Exploratory Data Analysis)
- 실제로 어떤 종류의 데이터를 갖고 있으며 다른 유형을 어떻게 다뤄야 하는가?
- 변수의 분포는 무엇인가?
- 데이터에 특이값이 있는가? 어떻게 처리할 수 있는가?
- 변환이 필요한가? 예를 들어, 일부 모델은 정규 분포 변수와 더 잘 작동하거나 로그 변환과 같은 기술을 사용할 수 있다.
- 분포는 그룹마다 다른가?(예: 성별 또는 교육 수준)
- 데이터가 누락된 경우가 있는가?
- 얼마나 빈번하고 어떤 변수에 있는가?
- 일부 변수 간에 선형(상관) 관계가 있는가?
- 기존 변수 집합을 사용해 새 특징을 생성할 수 있는가?
- 타임 스탬프에서 시간/분, 날짜에서 요일 등을 예로 들수 있다
- 분석과 관련이 없기 때문에 제거할 수 있는 변수가 있는가?
- 무작위로 생성된 고객 식별자를 예로 들 수 있다.
수치형 데이터 기술 통계값
- describe()를 사용하여 수치형 데이터의 개수, 평균, 최소/최대 및 사분위수와 같은 요약 통계 출력
- 이러한 지표를 검사해 특정 특징의 값 범위 또는 분포가 왜곡됐는지 평균값과 중앙값의 차이를 확인해 추정 가능.
- 음수나 매우 작은 연령 등 가능한 범위를 벗어난 값을 쉽게 발견 가능
df.describe().transpose().round(2)
범주형 변수에 대한 기술 통계량
- include 매개변수에 'object'인수를 추가하면 범주 특징을 개별적으로 출력 가능
df.describe(include='object').transpose()
데이터 시각화
- 나이 분포를 도식화하여 추가적으로 성별로 분할하기
- 단일 특징의 분포를 검사하는 보편적인 방법중 하나
- hist = True를 사용하면 히스토그램을 만들수 있음
import matplotlib.pyplot as plt
import warnings
plt.style.use('seaborn')
plt.rcParams['figure.figsize'] = [8, 4.5]
plt.rcParams['figure.dpi'] = 300
warnings.simplefilter(action='ignore', category=FutureWarning)
fig, ax = plt.subplots()
sns.distplot(df.loc[df.sex=='Male', 'age'].dropna(),
hist=False, color='green',
kde_kws={'shade': True},
ax=ax, label='Male')
sns.distplot(df.loc[df.sex=='Female', 'age'].dropna(),
hist=False, color='blue',
kde_kws={'shade': True},
ax=ax, label='Female')
ax.set_title('Distribution of age')
ax.legend(title='Gender:')
plt.tight_layout()
# plt.savefig('images/ch8_im5.png')
plt.show()
선택된 변수에 대해 pairplot을 도식화
- 대각선은 일변량 히스토그램을 나타내고, 비대각은 두 변수의 산점도를 나타낸다.
- 이 방법으로 두 변수 간에 관계가 있는지 확인할 수 있다.
pair_plot = sns.pairplot(df[['age', 'limit_bal', 'previous_payment_sep']])
pair_plot.fig.suptitle('Pairplot of selected variables', y=1.05)
plt.tight_layout()
# plt.savefig('images/ch8_im6.png', bbox_inches='tight')
plt.show()
상관관계 히트맵(heatmap)을 그리는 함수를 정의하고 실행
def plot_correlation_matrix(corr_mat):
'''
Function for plotting the correlation heatmap. It masks the irrelevant fields.
Parameters
----------
corr_mat : pd.DataFrame
Correlation matrix of the features.
'''
# temporarily change style
sns.set(style='white')
# mask the upper triangle
mask = np.zeros_like(corr_mat, dtype=bool)
mask[np.triu_indices_from(mask)] = True
# set up the matplotlib figure
fig, ax = plt.subplots()
# set up custom diverging colormap
cmap = sns.diverging_palette(240, 10, n=9, as_cmap=True)
# plot the heatmap
sns.heatmap(corr_mat, mask=mask, cmap=cmap, vmax=.3, center=0,
square=True, linewidths=.5,
cbar_kws={'shrink': .5}, ax=ax)
ax.set_title('Correlation Matrix', fontsize=16)
# change back to darkgrid style
sns.set(style='darkgrid')
corr_mat = df.select_dtypes(include='number').corr()
plot_correlation_matrix(corr_mat)
plt.tight_layout()
#plt.savefig('images/ch8_im7.png')
plt.show()
df.select_dtypes(include='number').corr()[['default_payment_next_month']]
- 이렇게 EDA를 따로 시행하는 방법도 있지만 EDA를 한 번에 해주는 라이브러리가 pandas_profiling 라이브러리를 사용하여 단 한줄의 코드로 HTML보고서 형식으로 데이터셋에 대한 포괄적인 요약을 생성함
pip install pandas_profiling
import pandas_profiling
df.profile_report()
2. Django 웹 페이지 구축 및 CSS활용
- 어제 만든 Answer, Question 클래스(DB)를 활용하여 홈페이지 제작을 추가로 진행하였습니다.
- admin.py에 Question 클래스 (DB) 등록
- views.py에 Question의 objects 컬럼을 불러오는 함수 생성
- q_list 는 Qusetion의 objects컬럼을 create_date를 내림차순으로 정렬
- pybo폴더에 question_list.html 파일에서 question_list라는 key값을 입력하여 q_list 값을 호출
- pybo폴더 아래 question_list.html 파일 생성 후 question_list를 불러오는 함수 생성 필요
- 이 때, html 파일은 무수히 많아질 수가 있어 같은 pybo폴더에서 관리하기 보다 새롭게 폴더를 만들어 전용 템플릿(html) 관리하는 것이 좋음
- 상위폴더에 templates라는 폴더를 생성하고 그 안에 새롭게 pybo라는 폴더 생성
- setting.py -> base.py 파일 접속 후 TEMPLATES 에서 DIRS 를 [BASE_DIR / 'templates'] 로 수정 후 저장
- templates --> pybo폴더 아래 question_list.html 파일 생성 후 아래 코드 입력
{% if question_list %} ## question_List 가 있다면
<ul>
{% for question in question_list %} # question값(views.py의 index함수의 q_list값을 반복하여)
<li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li> # 주소값을 pybo/question_id 값으로 하고/question.subject값을 불러오기
{% endfor %}
</ul>
{% else %}
<p>질문이 없습니다.</p> #question_list 가 없으면 질문이 없습니다. 출력
{% endif %}
- 이제 질문을 입력하였으니 그에 대한 대답을 응답할 수 있는 페이지를 생성하려고 합니다.
- views.py에서 대답 시 응답하는 함수를 생성
- request 값과 question에 FK로 응답할 수 있도록 입력값을 'request', 'question_id'를 입력 변수로 받기
- get_object_or_404 라이브러리를 활용하여 유효 값일 시 object를 출력하고 아닐 시 404포트 페이지를 출력
- detail함수를 호출할 수 있는 html파일 생성
- question.subject를 <h1>로 question.content를 <div> 로 지정하여 html파일 생성
- 현재 question_list.html 에서 url을 호출하는 링크명이 <a href="/pybo/{{ question.id }}/"> 으로 되어 있는데 이러한 url링크는 수정될 가능성이 있어 향후 사용한 url들을 일일히 찾아가며 수정해야 하는 리스크가 발생함--> 이러한 문제점을 해결하기 위해서는 해당 url에 대한 실제 링크 대신 링크의 주소를 1:1로 매칭 시켜주는 별칭 생성 필요
- pybo / urls.py에 name 값 지정 필요
- views.detail 함수에 name 을 'detail'로 지정
- question_detail.html 파일에서 아래코드 입력
- 질문 상세 템플릿에 답변을 저장할 수 있는 폼(form)추가
- 답변의 내용을 입력할 수 있는 텍스트창(textarea)과 답변을 저장할 수 있는 '답변등록'버튼 추가
- 답변 저장을 위한 url은 form태그의 action속성에 {% url 'pybo:answer_create' question.id%} 로 지정
- form 태그 밑에 있는 {% csrf_token %} 은 보안에 관련된 항목으로 form으로 전송한 데이터가 실제 웹 페이지에서 작성한 데이터인지를 판단하는 가늠하는 역할 진행 (ex : 해커가 서버에서 발행한 csrf_token값과 해커가 보낸 token값이 불일치 할 시 블록킹)
- question_detail.html 파일에 answer_create <form>을 생성하였으니 이제 이를 접속할 수 있는 url.py과 views.py 생성 필요
- answer_create 별칭에 해당하는 url매칭 규칙을 등록하여 www.localhost:8000/pybo/answer/create/1/ 과 같이 입력 시 views.answer_create 함수를 호출
- pk는 question_id를 넘겨받고, request는 form 의 textarea에 입력된 답변 내용을 넘겨받음, 여기서 해당 텍스트 내용만을 추출하기 위한 코드가 request.POST.get('content')
- Question모델을 통해 Answer 모델 데이터를 생성하기 위해 question.answer_set.create 라는 ORM 생성
- redirect('pybo : detail', question_id = question_id)를 통해 question_detail.html파일로 이동
- 이제 부트스트랩 CSS파일을 활용해서 question_list.html 파일을 꾸미도록 하겠습니다.
- pybo 폴더 밑에 static이라는 폴더를 생성한 뒤 강사님께서 제공해주신 부트스트랩 css파일을 저장하였습니다.
- settings.py에 base.py에 접속하여 아래 코드로 내용 수정
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
- 이제 question_list.html을 아래 코드로 변경하였습니다.
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'bootstrap.min.css' %}">
<div class="container my-3">
<table class="table">
<thead>
<tr class="table-dark">
<th>번호</th>
<th>제목</th>
<th>작성일시</th>
</tr>
</thead>
<tbody>
{% if question_list %}
{% for question in question_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>
<a href="{% url 'pybo:detail' question.id %}">{{ question.subject }}</a>
</td>
<td>{{ question.create_date }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="3">질문이 없습니다.</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
이렇게 오늘 복습도 마무리 하겠습니다.
감사합니다.
'DB 공부하기' 카테고리의 다른 글
230418_DB복습 (0) | 2023.04.18 |
---|---|
230417_DB복습 (0) | 2023.04.17 |
230410_DB복습 (0) | 2023.04.10 |
230406_DB복습 (0) | 2023.04.07 |
230405_DB복습 (0) | 2023.04.05 |