BASEMENT
Python 8주차 - 2 본문
파이썬 실습
1. 다음과 같이 문자열 출력
문자열 입력 : python
n
on
hon
thon
ython
python
string = input("문자열 입력 : ")
n = len(string)
for i in range(n):
for j in range(i,-1,-1):
print(string[n-1-j], end='')
print()
# reversed와 join 사용
string = input("문자열 입력 : ")
r = ''
for i in reversed(string):
r = ''.join(i) + r
print(r)
2. 다음 주어진 숫자들을 작은수에서 큰수의 순서인 오름정렬의 프로그램 작성
- 파이썬 내장함수 sorted, 리스트 메소드 sort 사용하지 말 것
- for 반복문 사용
- 버블정렬
def bubble(data):
for i in range(len(data)):
for j in range(1,len(data)):
if data[j] < data[j-1]:
data[j], data[j-1] = data[j-1], data[j]
return data
data = [90,20,40,3,7,14,76,45,28,38,17,9]
print(bubble(data))
cf) 선택정렬
def selection(data):
for j in range(len(data)-1):
min_ = j
for i in range(j+1, len(data)):
if data[i] < data[min_]:
min_ = i
data[j], data[min_] = data[min_], data[j]
return data
data = [90,20,40,3,7,14,76,45,28,38,17,9]
print(selection(data))
cf) 삽입정렬
def insertion(data):
for i in range(1,len(data)):
for j in range(8,0,-1):
if data[j-1] > data[j]:
data[j-1], data[j] = data[j], data[j-1]
data = [90,20,40,3,7,14,76,45,28,38,17,9]
print(insertion(data))
cf) 쉘정렬
import math
def shell(data):
size = len(data)
gap = size//2
while gap >= 1:
for i in range(gap,size):
target = i
while target>=gap and data[target-gap] > data[target]:
data[target], data[target-gap] = data[target-gap], data[target]
target -= gap
gap //=2
return data
data = [90,20,40,3,7,14,76,45,28,38,17,9]
print(shell(data))
cf) 퀵정렬
선택된 데이터(피벗, pivot)를 기준으로 왼쪽에는 작은값이 오른쪽은 큰값을 배치하는 분할정복법의 정렬 방법
평균적으로 매우 빠른 정렬 방법
불안정한 정렬에 속함
퀵정렬은 전체 리스트를 2개의 부분리스트로 분할하고, 각각의 부분리스트를 다시 퀵정렬로 정렬
비균등 분할하며, 추가적 메모리 공간 필요 없음
정렬된 리스트에 대해서는 수행시간이 더 많이 걸림
많은 언어에서 사용하는 정렬방법으로 2009년에 제안된 dual pivot Quick 정렬 사용
시간복잡도
최상, 평균: O(nlog2n)
최악: O(n2)
import random
def rand_shuffle(data): #Knuth의 random shuffle
N = len(data)
for i in range(N):
temp = random.randint(0,i)
data[i],data[temp] = data[temp],data[i]
def quicksort(data):
if len(data) < 1:
return data
else:
pivot = data[0]
less = [i for i in data[1:] if i <= pivot]
greater = [ i for i in data[1:] if i > pivot]
return quicksort(less) + [pivot] + quicksort(greater)
data = [50,3,8,11,45,70,37,20,8,29,77,65,33]
rand_shuffle(data)
print(data)
print(quicksort(data))
Pandas 기초 활용
1. 예제 - traffic_accident_2020.csv
1-1) 파일에서 데이터 읽어오기
utf-8 인코딩 오류 시, encoding='CP949' 입력
CP949에도 오류면 encoding='latin' 입력 시도
import pandas as pd
import numpy as np
file_path = "traffic_accident_2020.csv"
df = pd.read_csv(file_path, encoding='CP949')
df.info()
df.describe()
# 결과
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3233 entries, 0 to 3232
Data columns (total 23 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 발생년 3233 non-null int64
1 발생년월일시 3233 non-null int64
2 주야 3233 non-null object
3 요일 3233 non-null object
4 사망자수 3233 non-null int64
5 부상자수 3233 non-null int64
6 중상자수 3233 non-null int64
7 경상자수 3233 non-null int64
8 부상신고자수 3233 non-null int64
9 발생지시도 3233 non-null object
10 발생지시군구 3233 non-null object
11 사고유형_대분류 3233 non-null object
12 사고유형_중분류 3233 non-null object
13 사고유형 3233 non-null object
14 가해자법규위반 3233 non-null object
15 도로형태_대분류 3233 non-null object
16 도로형태 3233 non-null object
17 가해자_당사자종별 3233 non-null object
18 피해자_당사자종별 3233 non-null object
19 발생위치X_UTMK 3233 non-null float64
20 발생위치Y_UTMK 3233 non-null float64
21 경도 3233 non-null float64
22 위도 3233 non-null float64
dtypes: float64(4), int64(7), object(12)
memory usage: 581.1+ KB
발생년 발생년월일시 사망자수 부상자수 중상자수 경상자수 부상신고자수 발생위치X_UTMK 발생위치Y_UTMK 경도 위도
count 3233.0 3.233000e+03 3233.00000 3233.000000 3233.000000 3233.000000 3233.000000 3.233000e+03 3.233000e+03 3233.000000 3233.000000
mean 2019.0 2.019068e+09 1.03588 0.548098 0.225178 0.279307 0.043613 1.005579e+06 1.820305e+06 127.559523 36.377054
std 0.0 3.482074e+04 0.22515 1.765558 0.777163 1.090688 0.439696 7.699214e+04 1.174674e+05 0.854347 1.060132
min 2019.0 2.019010e+09 1.00000 0.000000 0.000000 0.000000 0.000000 7.561250e+05 1.470790e+06 124.723794 33.222138
25% 2019.0 2.019041e+09 1.00000 0.000000 0.000000 0.000000 0.000000 9.461720e+05 1.725952e+06 126.896384 35.527055
50% 2019.0 2.019071e+09 1.00000 0.000000 0.000000 0.000000 0.000000 9.753980e+05 1.827462e+06 127.226176 36.443029
75% 2019.0 2.019101e+09 1.00000 0.000000 0.000000 0.000000 0.000000 1.073766e+06 1.932679e+06 128.319218 37.392024
max 2019.0 2.019123e+09 6.00000 34.000000 17.000000 22.000000 15.000000 1.184860e+06 2.048977e+06 129.550265 38.437576
2) column 및 index 명칭 확인
df.columns.values
df.index.values
# 결과
array(['발생년월일시', '주야', '요일', '사망자수', '부상자수', '중상자수', '경상자수', '부상신고자수',
'발생지시도', '발생지시군구', '사고유형_대분류', '사고유형_중분류', '도로형태_대분류', '도로형태',
'가해자_당사자종별', '피해자_당사자종별', '경도', '위도'], dtype=object)
array([ 0, 1, 2, ..., 3230, 3231, 3232], dtype=int64)
3) 불필요한 컬럼 삭제
- drop 함수 사용
- 삭제가 이루어지는 축방향(axis)선정, column 삭제면 1
- inplace = True이면 원본데이터프레임을 수정함
df.drop(['발생년','사고유형','가해자법규위반','발생위치X_UTMK', '발생위치Y_UTMK'], axis=1, inplace=True)
4) 컬럼이름 변경 및 새로운 컬럼 추가
df.rename(columns={'발생년월일시':'월일시','사망자수':'사망','사상자수':'사상','중상자수':'중상', '경상자수':'경상','부상신고자수':'부상','사고유형_대분류':'유형A','사고유형_중분류':'유형B','도로형태_대분류':'도로A','도로형태':'도로B',
'피해자_당사자종별':'피해','가해자_당사자종별':'가해',}, inplace=True)
df.columns.values
df['월']=df['월일시'].astype(str).str[4:6]
df['일']=df['월일시'].astype(str).str[6:8]
df['시']=df['월일시'].astype(str).str[8:]
df.drop(['월일시'], axis=1, inplace=True)
df.head()
# 결과
주야 요일 사망 부상자수 중상 경상 부상 발생지시도 발생지시군구 유형A 유형B 도로A 도로B 가해 피해 경도 위도 월 일 시
0 야 화 1 0 0 0 0 부산 해운대구 차대사람 기타 교차로 교차로내 승용차 보행자 129.152465 35.157884 01 01 00
1 야 화 1 0 0 0 0 경기 안산시 차대차 정면충돌 단일로 기타단일로 승용차 승용차 126.857149 37.288292 01 01 03
2 주 화 1 0 0 0 0 경북 청도군 차대차 측면충돌 교차로 교차로부근 승용차 사륜오토바이(ATV) 128.609230 35.650108 01 01 16
3 야 화 1 0 0 0 0 대전 서구 차대사람 횡단중 교차로 교차로부근 승용차 보행자 127.379560 36.355946 01 01 19
4 야 화 1 0 0 0 0 경북 영천시 차대사람 기타 단일로 기타단일로 승용차 보행자 128.915041 35.899506 01 01 21
5) 결측치 확인
isnull() 사용
missing_df = df.isnull()
missing_type = df[['피해','가해']].isnull()
missing_type.describe()
new_df = df.dropna(subset=['피해'], axis=0)
new_df.head()
# 결과
피해 가해
count 3233 3233
unique 1 1
top False False
freq 3233 3233
주야 요일 사망 부상자수 중상 경상 부상 발생지시도 발생지시군구 유형A 유형B 도로A 도로B 가해 피해 경도 위도 월 일 시
0 야 화 1 0 0 0 0 부산 해운대구 차대사람 기타 교차로 교차로내 승용차 보행자 129.152465 35.157884 01 01 00
1 야 화 1 0 0 0 0 경기 안산시 차대차 정면충돌 단일로 기타단일로 승용차 승용차 126.857149 37.288292 01 01 03
2 주 화 1 0 0 0 0 경북 청도군 차대차 측면충돌 교차로 교차로부근 승용차 사륜오토바이(ATV) 128.609230 35.650108 01 01 16
3 야 화 1 0 0 0 0 대전 서구 차대사람 횡단중 교차로 교차로부근 승용차 보행자 127.379560 36.355946 01 01 19
4 야 화 1 0 0 0 0 경북 영천시 차대사람 기타 단일로 기타단일로 승용차 보행자 128.915041 35.899506 01 01 21
6)
- 중복 없이 unique한 값 출력 및 고유값별로 데이터 개수 계산 : unique(), value_counts()
- 가장 개수가 많은 데이터 고유값 출력 : idxmax 사용
- 새로운 파일로 저장 : to_csv 사용
new_df['피해'].unique()
new_df['피해'].value_counts()
new_df['피해'].value_counts().idxmax()
new_df.to_csv("traffic_accident_pre.csv")
회귀분석 / 시계열 분석
1. 회귀분석 - 예제 : 프로야구선수 다음 해 연봉 예측
1) 데이터 탐색
# -*- coding: utf-8 -*-
%matplotlib inline
import pandas as pd
import numpy as numpy
import matplotlib.pyplot as plt
picher_file_path = 'picher_stats_2017.csv'
batter_file_path = 'batter_stats_2017.csv'
picher = pd.read_csv(picher_file_path)
batter = pd.read_csv(batter_file_path)
picher.columns
picher.head()
# print(picher.shape)
2) 회귀분석에 사용할 피처 탐색
picher_features_df = picher[['승', '패', '홀드', '블론', '경기', '선발', '이닝', '삼진/9', '볼넷/9', '홈런/9', 'BABIP', 'LOB%', 'ERA', 'ERA', 'RA9-WAR', 'FIP', 'kFIP', 'WAR', '연봉(2018)', '연봉(2017)']]
# 피처 각각에 대한 히스토그램 출력
def plot_hist_each_column(df):
plt.rcParams['figure.figsize'] = [20,16]
fig = plt.figure(1)
# df의 열 개수 만큼의 subplot 출력
for i in range(len(df.columns)):
ax = fig.add_subplot(5,5,i+1)
plt.hist(df[df.columns[i]], bins=50)
ax.set_title(df.columns[i])
plt.show()
plot_hist_each_column(picher_features_df)
3) 각 피처 단위간의 정규화 작업
- 표준화 방법 적용 -> Z = ((X) – (X의 평균)) / X의 표준편차
- pd.options.mode.chained_assignment = None -> float 모양으로 출력되게 해주는 코드
- 범주형 피처 정규화 -> get_dummies (원-핫 인코딩) 적용
pd.options.mode.chained_assignment = None
def standard_scaling(df, scale_columns):
for col in scale_columns:
series_mean = df[col].mean()
series_std = df[col].std()
df[col] = df[col].apply(lambda x: (x-series_mean)/series_std)
return df
scale_columns = ['승','패','세','홀드','블론','경기','선발','이닝','삼진/9','볼넷/9','홈런/9','BABIP','LOB%','ERA','RA9-WAR','FIP','kFIP','WAR','연봉(2017)']
picher_df = standard_scaling(picher, scale_columns)
picher_df = picher_df.rename(columns={'연봉(2018)': 'y'})
picher_df.head(5)
원-핫 인코딩
team_encoding = pd.get_dummies(picher_df['팀명'])
picher_df = picher_df.drop('팀명', axis=1)
picher_df = picher_df.join(team_encoding)
team_encoding.head(5)
4) 회귀분석
4-1) 회귀분석을 위한 학습데이터셋, 테스트 데이터셋으로 분리
train_test_split()
from sklearn import linear_model
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from math import sqrt
X = picher_df[picher_df.columns.difference(['선수명','y'])]
y = picher_df['y']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=19)
4-2) 회귀분석 계수 학습 & 학습된 계수 출력
lr = linear_model.LinearRegression()
model = lr.fit(X_train, y_train)
print(lr.coef_)
5) 예측 모델 평가 - 어떤 피처가 가장 영향력이 강한 피처?
- 결정계수(R-squared)와 수정결정계수(Adj.R-squared) 가 회귀분석의 평가 지표
- 1에 가까울수록 데이터를 잘 설명하는 모델
- F 통계량의 p-value의 값이 0.05보다 작게 나오면 유의미한 의미라고 평가함
- P>|t| 는 각 피처의 검정 통계량에 대한 유의미성 평가, 0.05보다 적으면 의미있음
- Coef(계수)는 영향력이 큰 피처를 표현
import statsmodels.api as sm
# statsmodel 라이브러리로 회귀분석 수행
X_train = sm.add_constant(X_train)
model = sm.OLS(y_train, X_train).fit()
model.summary()
6) 어떤 피처가 가장 영향력이 강한 피처일까? - 시각화
import matplotlib as mpl
set(sorted([f.name for f in mpl.font_manager.fontManager.ttflist]))
# 한글 출력을 위한 사전 설정 단계
mpl.rc('font', family='NanumGothicOTF')
plt.rcParams['figure.figsize'] = [20,16]
# 회귀 계수를 리스트로 반환
coefs = model.params.tolist()
coefs_series = pd.Series(coefs)
# 변수명을 리스트로 반환
x_labels = model.params.index.tolist()
# 회귀계수 출력
ax = coefs_series.plot(kind='bar')
ax.set_title('feature_coef_graph')
ax.set_xlabel('x_features')
ax.set_ylabel('coef')
ax.set_xticklabels(x_labels)
7-1) 예측 모델 평가 : R2 score
# 학습 데이터와 테스트 데이터로 분리
X = picher_df[picher_df.columns.difference(['선수명','y'])]
y = picher_df['y']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=19)
# 회귀분석 모델 학습
lr = linear_model.LinearRegression()
model = lr.fit(X_train, y_train)
# 회귀분석 모델 평가
print(model.score(X_train, y_train))
print(model.score(X_test, y_test))
7-2) 예측 모델 평가 : RMSE score - 높을수록 예측이 부정확함
y_predictions = lr.predict(X_train)
print(sqrt(mean_squared_error(y_train, y_predictions))) # train RMSE score 출력
y_predictions = lr.predict(X_test)
print(sqrt(mean_squared_error(y_test, y_predictions))) # test RMSE score 출력
8) 피처들의 상관관계 분석 - heatmap 시각화
import seaborn as sns
# 피처 간의 상관계수 행렬 계산
corr = picher_df[scale_columns].corr(method='pearson')
show_cols = ['win','lose','save','hold','blon','match','start','inning','strike3','ball4','homerun','BABIP','LOB','ERA','RA9-WAR','FIP','kFIP','WAR','2017']
# corr 행렬 히트맵 시각화
plt.rc('font', family='NanumGothicOTF')
sns.set(font_scale=1.5)
hm = sns.heatmap(corr.values,
cbar=True,
annot=True,
square=True,
fmt='.2f',
annot_kws={'size':15},
yticklabels=show_cols,
xticklabels=show_cols)
plt.tight_layout()
plt.show()
9) 회귀분석 예측 성능 높이는 방법 : 다중 공선성 확인
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 피처마다의 VIF 계수 출력
vif = pd.DataFrame()
vif["VIF Factor"] = [ variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
vif["features"] = X.columns
vif.round(1)
10) 분석 결과 시각화
# 2018년 연봉을 예측하여 데이터 프레임의 열로 생성
X = picher_df[['FIP','WAR','볼넷/9','삼진/9','연봉(2017)']]
predict_2018_salary = lr.predict(X)
picher_df['예측연봉(2018)'] = pd.Series(predict_2018_salary)
# 원래의 데이터 프레임을 다시 불러옴
picher = pd.read_csv(picher_file_path)
picher = picher[['선수명', '연봉(2017)']]
# 원래의 데이터 프레임에 2018년 연봉 정보를 합침
result_df = picher_df.sort_values(by=['y'], ascending=False)
result_df.drop(['연봉(2017)'], axis=1, inplace=True, errors='ignore')
result_df = result_df.merge(picher, on=['선수명'], how='left')
result_df = result_df[['선수명', 'y', '예측연봉(2018)', '연봉(2017)']]
result_df.columns = ['선수명', '실제연봉(2018)','예측연봉(2018)','작년연봉(2017)']
# 재계약하여 연봉이 변화한 선수만을 대상으로 관찰
result_df = result_df[result_df['작년연봉(2017)'] != result_df['실제연봉(2018)']]
result_df = result_df.reset_index()
result_df = result_df.ix[:10, :]
result_df.head(10)
11) 선수별 연봉 정보 막대그래프로 출력
mpl.rc('font', family='NanumGothicOTF')
result_df.plot(x='선수명', y=['작년연봉(2017)', '예측연봉(2018)', '실제연봉(2018)'], kind="bar")
2. 시계열 분석
1) 시계열 데이터 (Time Series Data)
시간적 순서를 가지는 데이터로 시간의 흐름에 따라 일정 간격으로 측정된 데이터
데이터의 index가 시간, index간의 시간 간격이 일정함 - 시계열 분석에서 시간의 흐름을 종속변수에 영향을 주는 변수로 취급하기 때문
2) 시계열 데이터 분석 목적
- 미래값 예측
- 시계열 데이터 특성 파악 : 경향, 주기, 계절성, 불규칙성 정상성 등
- 정상성 : 시간 흐름에 영향을 받지 않음, 평균/분산의 안정화, 주기적 변동이 없는 시계열 분포
-> 비정상성 시계열 데이터는 정상화 시켜야 함
3) 시계열 모델의 과정
3-1) Data 확인
- 데이터 시간 확인/ 시간의 format 설정
- 데이터 상태 확인 : 결측치, 반복데이터 등
- 기초 통계 정보 분석 : 트렌드, 계절성 등
3-2) 시계열 모델 제작 (Fit Model)
- 모델 가정 확인 : 정상성, 계절성 확인
- 적합한 모델 조율 선택
3-3) 모델 검증
4) 데이터의 정상성 파악
- 정상성 : Mean, variance이 시간에 걸쳐 일정하고 주기적 변동이 없는 시계열 분포
- 즉, 공분산이 시간 t에 의존하지 않고 오직 시차(시간간격)에만 의존하는 데이터
- 정상성 확인 방법 : 기초통계량의 시각화 / Dickey-Fuller test
3. 시계열 분석 예제1 - 1949~1960년 사이의 비행기 승객 수
1) 데이터 분석
- parse_dates : object 형태의 날짜 데이터를 datetime으로 변경
- index_col : column을 index로 변경
df = pd.read_csv('AirPassengers.csv', parse_dates=['Month'], index_col=['Month'])
plt.xlabel('Date')
plt.ylabel('Num of air Passengers')
plt.plot(df)
2) 정상성 확인
- Rolling statistics : 그래프로 확인
rolling_mean = df.rolling(window=12).mean()
rolling_std = df.rolling(window=12).std()
plt.plot(df, color='blue', label='Original')
plt.plot(rolling_mean, color='red', label='Rolling Mean')
plt.plot(rolling_std, color='black', label='Rolling Std')
plt.legend(loc='best')
plt.title('Rolling Mean & Rolling Standard Deviation')
plt.show()
- Dickey-Fuller Test : p-value < 0.05 정상성이 있음
result = adfuller(df['Passengers'])
print(f'ADF Statistic:{result[0]}')
print(f'p-value: {result[1]}')
print('Critical Values: ')
for key, value in result[4].items():
print(f'\t{key}: {value}')
3) 비정상성 데이터를 정상성화
- 변환 : log함수 사용
df_log = np.log(df)
df_log.plot()
- 차분
def get_stationarity(timeseries):
#discrimination of stationary
rolling_mean = timeseries.rolling(window=12).mean()
rolling_std = timeseries.rolling(window=12).std()
plt.plot(timeseries, color = 'blue',label='Original')
plt.plot(rolling_mean,color='red',label='Rolling Mean')
plt.plot(rolling_std,color='black',label='Rolling Std')
plt.legend(loc='best')
plt.title('Rolling Mean & Rolling Standard Deviation')
plt.show()
result = adfuller(timeseries['Passengers'])
print(f'ADF Statistic:{result[0]}')
print(f'p-value: {result[1]}')
print('Critical Values: ')
for key, value in result[4].items():
print(f'\t{key}: {value}')
rolling_mean = df_log.rolling(window=12).mean()
df_log_minus_mean = df_log - rolling_mean
df_log_minus_mean.dropna(inplace=True)
get_stationarity(df_log_minus_mean)
# 평균 차분 이용
df_log_shift = df_log - df_log.shift()
df_log_shift.dropna(inplace=True)
get_stationarity(df_log_shift)
4) 정상화 이면서 트렌드와 계절성이 있는 데이터
트렌드와 계절성을 파악하고 두 속성만 분석, 또는 두 속성을 제거하고 시계열 분석
#trend와 seasonal effect를 파악
decomposition = seasonal_decompose(df_log)
#result.observed ## observed 데이터 출력
#result.trend ## trend 데이터 출력
#result.seasonal ## seasonal 데이터 출력
#result.residual
decomposition.plot()
5) 전처리한 데이터를 대상으로 ARIMA 생성
model = ARIMA(df_log, order=(2,1,2))
results = model.fit(disp=-1)
plt.plot(df_log_shift)
plt.plot(results.fittedvalues, color='red')
cf) ACF, PACF 구하기
p + q이 2미만
p * q이 0을 포함한 짝수일 경우 좋은 파라미터 조합
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.graphics.tsaplots import plot_pacf
acf_origin = plot_acf(df['Passengers'])
pacf_origin = plot_pacf(df['Passengers'])
acf_log = plot_acf(df_log)
pacf_log = plot_pacf(df_log)
6) 모델 비교
predictions_ARIMA_diff = pd.Series(results.fittedvalues, copy=True)
predictions_ARIMA_diff_cumsum = predictions_ARIMA_diff.cumsum()
predictions_ARIMA_log = pd.Series(df_log['Passengers'].iloc[0], index=df_log.index)
predictions_ARIMA_log = predictions_ARIMA_log.add(predictions_ARIMA_diff_cumsum, fill_value=0)
predictions_ARIMA = np.exp(predictions_ARIMA_log)
plt.plot(df)
plt.plot(predictions_ARIMA)
7) 생성된 ARIMA모델을 사용하여 예측
- 12년간의 승객수에서 향후 10년간의 승객 수를 예측
- 12년 * 12개월 + 10년*12개월 = 264
results.plot_predict(1,264)
4. 시계열 분석 예제2 - 비트코인 시세 예측
1) 데이터 탐색 및 시계열 데이터 확인
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
file_path = 'market-price.csv'
bitcoin_df = pd.read_csv(file_path, names = ['day','price'])
print(bitcoin_df.shape)
print(bitcoin_df.info())
bitcoin_df.tail()
2) to_datetime으로 day 피처를 시계열 피처로 변환
bitcoin_df['day'] = pd.to_datetime(bitcoin_df['day'])
# day 데이터프레임의 index로 설정
bitcoin_df.index = bitcoin_df['day']
bitcoin_df.set_index('day', inplace=True)
bitcoin_df.head()
bitcoin_df.plot()
plt.show()
3) ARIMA 모델
from statsmodels.tsa.arima_model import ARIMA
import statsmodels.api as sm
# (AR=2, 차분=1, MA=2) 파라미터로 ARIMA 모델을 학습
model = ARIMA(bitcoin_df.price.values, order=(2,1,2))
model_fit = model.fit(trend='c', full_output=True, disp=True)
print(model_fit.summary())
4) 모델의 성능 & 예측 결과 시각화
# 학습 데이터에 대한 예측 결과 (첫번째 그래프)
fig = model_fit.plot_predict()
# 잔차의 변동을 시각화 (두번째 그래프)
residuals = pd.DataFrame(model_fit.resid)
residuals.plot()
'Programming > Python' 카테고리의 다른 글
Python 8주차 - 1 (0) | 2020.08.05 |
---|---|
Python 7주차 - 2 (0) | 2020.08.03 |
Python 7주차 - 1 (0) | 2020.07.29 |
Python 6주차 - 2 (0) | 2020.07.26 |
Python 6주차 - 1 (0) | 2020.07.26 |