adp 실기
[Python] Adp 실기 모의고사 1회 2번 파이썬 풀이(데이터에듀 교재)
ㅅ ㅜ ㅔ ㅇ
2022. 3. 19. 20:19
728x90
2. 통계분석(사용데이터: FIFA)
FIFA 데이터는 가상의 온라인 축구게임에 등장하는 축구 선수의 주요 특징과 신체 정보에 대한 데이터이며, 변수 설명은 아래와 같다.
변수 | 데이터형태 |
ID | 수치형 |
Age | 수치형 |
Nationality | 범주형 |
Overall | 수치형 |
Club | 범주형 |
Preferred Foot | 범주형 |
Work Rate | 범주형 |
Position | 범주형 |
Jersey Number | 수치형 |
Contract Valid Until | 수치형 |
Height | 문자형 |
Weight_lb | 수치형 |
Release_Clause | 수치형 |
Value | 수치형 |
Wage | 수치형 |
1. FIFA 데이터에서 각 선수의 키는 Height변수에 피트와 인치로 입력되어 있습니다. 이를 cm로 변환하여 새로운 변수 Height_cm을 생성하시오.(" ' " 앞의 숫자는 피트이며, 뒤의 숫자는 인치, 1피트 = 30cm, 1인치 = 2.5cm)
- 데이터 불러오기
import pandas as pd
import numpy as np
data = pd.read_csv("FIFA.csv")
data.head()
- 새로운 변수 'Height_cm' 생성
data['Height_cm'] = pd.to_numeric(data['Height'].str[:1])*30 + pd.to_numeric(data['Height'].str[2:])*2.5
data.head()
2. 포지션을 의미하는 Position변수를 아래 표를 참고하여 "Forward", "Midfielder", "Defender", "GoalKeeper" 로 재범주화하고, factor형으로 변환하여 Position_Class라는 변수를 생성하고 저장하시오.
Forward | LS, ST, RS, LW, LF, CF, RF, RW |
Midfielder | LAM, CAM, RAM, LM, LCM, CM, RCM, RM |
Defender | LWB, LDM, CDM, RDM, RWB, LB, LCB, CB, RCB, RB |
GoalKeeper | GK |
- 변수 생성
data["Position_Class"] = ""
Forward = ['LS','ST','RS','LW','LF','CF','RF','RW']
MidFielder = ['LAM','CAM','RAM','LM','LCM','CM','RCM','RM']
Defender = ['LWB','LDM','CDM','RDM','RWB','LB','LCB','CB','RCB','RB']
GoalKeeper = ['GK']
for i in range(len(data)):
if data['Position'][i] in Forward:
data["Position_Class"][i] = 'Forward'
elif data['Position'][i] in MidFielder:
data["Position_Class"][i] = 'MidFielder'
elif data['Position'][i] in Defender:
data["Position_Class"][i] = 'Defender'
elif data['Position'][i] in GoalKeeper:
data["Position_Class"][i] = 'GoalKeeper'
data.head()
data['Position_Class'].value_counts()
3. 새로 생성한 Position_Class 변수의 각 범주에 따른 Value 변수 평균값의 차이를 비교하는 일원배치 분산분석을 수행하고 결과를 해석하시오. (데이터는 등분산성을 만족한다고 가정) 그리고 평균값의 차이가 통계적으로 유의하다면 사후검정을 수행하고 설명하시오.
- 귀무가설 : k개의 집단 간 모평균에는 차이가 없다.
- 대립가설 : K개의 집단 간 모평균이 모두 같다고는 할 수 없다.
- 일원배치 분산분석
import statsmodels.formula.api as smf
import statsmodels.api as sm
from statsmodels.stats.anova import AnovaRM
from scipy import stats
anova = smf.ols(formula = 'Value~Position_Class',data = data)
anova_fit = anova.fit()
anova_table = sm.stats.anova_lm(anova_fit,typ=2)
print(anova_table)
p-value값이 0.05보다 작아 귀무가설 기각 -> 사후검정 필요
- 사후검정(투키의 HSD)
from statsmodels.sandbox.stats.multicomp import MultiComparison
import scipy.stats
#투키의 HSD (유의미한 차이 분석)
from statsmodels.stats.multicomp import pairwise_tukeyhsd
hsd = pairwise_tukeyhsd(data['Value'],data['Position_Class'],alpha=0.05)
print(hsd.summary())
Forward-MidFielder의 P-value값만이 0.5609로 크게 나옴 -> 유의미한 차이x
Forward-MidFielder를 제외한 모든 변수들에 유의미한 차이가 존재한다고 판단
- 사후검정(봉페로니 교정)
#봉페로니 교정
comp = MultiComparison(data.Value,data.Position_Class)
result = comp.allpairtest(scipy.stats.ttest_ind, method = 'bonf')
print(result[0])
본페로니 방법: 유의수준 0.05를 비교하는 개수로 나누어 줍니다.
가령 3개의 그룹을 비교한다면 3개의 짝이 만들어지게 됩니다.
0.05/3=약 0.017
따라서 검정을 할 때 각 군에 대해서 유의수준 0.017을 기준으로 하게 됩니다.
Forward-MidFielder의 P-value값만이 0.2784로 크게 나옴 -> 유의미한 차이x
4. Preferred Foot과 Position_Class 변수에 따라 Value의 차이가 있는지를 알아보기 위해 이원 배치 분산 분석을 수행하고, 결과를 해석하시오.
귀무가설
- Preferred Foot 변수에 따른 Value 값 에는 차이가 없다.
- Position_Class 변수에 따른 Value 값에는 차이가 없다.
- Preferred Foot과 Position_Class변수의 상호작용 효과가 없다.
대립가설
- Preferred Foot 변수에 따른 Value 값에는 차이가 있다.
- Position_Class 변수에 따른 Value 값에는 차이가 있다.
- Preferred Foot과 Position_Class변수의 상호작용 효과가 있다.
anova2 = smf.ols(formula='Value~Preferred_Foot*Position_Class',data = data).fit()
sm.stats.anova_lm(anova2)
- Preferred_Foot의 p-value값은 매우 작게 나와 귀무가설 기각 -> Value값에 영향을 미친다고 판단
- Position_Value의 p-value값은 매우 작게 나와 귀무가설 기각 -> Value값에 영향을 미친다고 판단
- Preferred_Foot:Position_Class의 p-value값 또한 매우 작게 나와 귀무가설 기각 -> 두 변수는 각 변수가 Value에 끼치는 영향도의 크기에 상호 영향을 미친다고 판단
5. Age, Overall, Wage, Height_cm, Weight_lb가 Value에 영향을 미치는지 알아보는 회귀분석을 단계적 선택법을 사용하여 수행하고 결과를 해석하시오.
variables = data[['Age','Overall','Wage','Height_cm','Weight_lb']].columns.tolist()
y = data['Value']
#선택된 변수들
selected_variables = []
sl_enter = 0.05
sl_remove = 0.05
#각 스텝별 선택 변수
sv_per_step = []
#수정된 결정계수
adjusted_r_squared = []
#스텝
steps = []
step = 0
while len(variables)>0:
remainder = list(set(variables) - set(selected_variables))
pval = pd.Series(index=remainder) ## 변수의 p-value
## 기존에 포함된 변수와 새로운 변수 하나씩 돌아가면서
## 선형 모형을 적합한다.
for col in remainder:
X = data[selected_variables+[col]]
X = sm.add_constant(X)
model = sm.OLS(y,X).fit()
pval[col] = model.pvalues[col]
min_pval = pval.min()
if min_pval < sl_enter: ## 최소 p-value 값이 기준 값보다 작으면 포함
selected_variables.append(pval.idxmin())
## 선택된 변수들에대해서
## 어떤 변수를 제거할지 고른다.
while len(selected_variables) > 0:
selected_X = data[selected_variables]
selected_X = sm.add_constant(selected_X)
selected_pval = sm.OLS(y,selected_X).fit().pvalues[1:] ## 절편항의 p-value는 뺀다
max_pval = selected_pval.max()
if max_pval >= sl_remove: ## 최대 p-value값이 기준값보다 크거나 같으면 제외
remove_variable = selected_pval.idxmax()
selected_variables.remove(remove_variable)
else:
break
step += 1
steps.append(step)
adj_r_squared = sm.OLS(y,sm.add_constant(data[selected_variables])).fit().rsquared_adj
adjusted_r_squared.append(adj_r_squared)
sv_per_step.append(selected_variables.copy())
else:
break
selected_variables
- 선택된 변수로 회귀모델 재생성
from statsmodels.stats.anova import anova_lm
reg = smf.ols('Value~Overall+Age+Wage+Height_cm',data=data).fit()
anova_lm(reg)
reg.summary2()
- 시각화
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(10,10))
fig.set_facecolor('white')
font_size = 15
plt.xticks(steps,[f'step {s}\n'+'\n'.join(sv_per_step[i]) for i,s in enumerate(steps)], fontsize=12)
plt.plot(steps,adjusted_r_squared, marker='o')
plt.ylabel('Adjusted R Squared',fontsize=font_size)
plt.grid(True)
plt.show()
y = 241.345Overall - 202.1603Age + 184.184*Wage - 8.445Height_cm 이고, R-square값은 0.791이다. 즉 회귀식은 전체 데이터의 약 79.1%를 설명하고 있으며 F통계량이 0.05보다 작아 모형이 통계적으로 유의미하다고 판단할 수 있다.
회귀분석은 무조건 R로 해야겠다...ㅎㅎ
728x90