귀무가설(영가설, H0) : 변함없는 생각.
대립가설(연구가설, H1) : 귀무가설에 반대하는 새로운 의견. 연구가설.
점추정 : 단일값을 모집단에서 샘플링
구간추정 : 범위를 모집단에서 샘플링. 신뢰도 상승.
가설검증
① 분포표 사용 -> 임계값 산출
임계값이 critical value 왼쪽에 있을 경우 귀무가설 채택/기각.
② p-value 사용(tool에서 산출). 유의확률. (경험적 수치)
p-value > 0.05(a) : 귀무가설 채택. 우연히 발생할 확률이 0.05보다 낮아 연구가설 기각.
p-value < 0.05(a) : 귀무가설 기각. 좋다
p-value < 0.01(a) : 귀무가설 기각. 더 좋다
p-value < 0.001(a) : 귀무가설 기각. 더 더 좋다 => 신뢰 할 수 있다.
척도에 따른 데이터 분석방법
독립변수 x | 종속변수 y | 분석 방법 |
범주형 | 범주형 | 카이제곱 검정(교차분석) |
범주형 | 연속형 | T 검정(범주형 값 2개 : 집단 2개 이하), ANOVA(범주형 값 3개 : 집단 2개 이상) |
연속형 | 범주형 | 로지스틱 회귀 분석 |
연속형 | 연속형 | 회귀분석, 구조 방정식 |
1종 오류 : 귀무가설이 채택(참)인데, 이를 기각.
2종 오류 : 귀무가설이 기각(거짓)인데, 이를 채택.
분산(표준편차)의 중요도 - 데이터의 분포
* temp.py
import scipy.stats as stats
import numpy as np
import matplotlib.pyplot as plt
centers = [1, 1.5, 2] # 3개 집단
col = 'rgb'
data = []
std = 0.01 # 표준편차 - 작으면 작을 수록 응집도가 높다.
for i in range(len(centers)):
data.append(stats.norm(centers[i], std).rvs(100)) # norm() : 가우시안 정규분포. rvs(100) : 랜덤값 생성.
plt.plot(np.arange(100) + i * 100, data[i], color=col[i]) # 그래프
plt.scatter(np.arange(100) + i * 100, data[i], color=col[i]) # 산포도
plt.show()
print(data)
import scipy.stats as stats
stats.norm(평균, 표준편차).rvs(size=크기, random_state=seed) : 가우시안 정규 분포 랜덤 값 생성.
import matplotlib.pyplot as plt
plt.plot(x, y) : 그래프 출력.
교차분석 (카이제곱) 가설 검정
- 데이터나 집단의 분산을 추정하고 검정할때 사용
- 독립변수, 종속변수 : 범주형
- 일원 카이제곱 : 변수 단수. 적합성(선호도) 검정. 교차분할표 사용하지않음.
- 이원 카이제곱 : 변수 복수. 독립성(동질성) 검정. 교차분할표 사용.
- 절차 : 가설 설정 -> 유의 수준 결정 -> 검정통계량 계산 -> 귀무가설 채택여부 판단 -> 검정결과 진술
- 수식 : sum((관찰빈도 - 기대빈도)^2 / 기대빈도)
수식에 따른 카이제곱 검정
* chi1.py
import pandas as pd
data = pd.read_csv('../testdata/pass_cross.csv', encoding='euc-kr') # csv 파일 읽기
print(data.head(3))
'''
공부함 공부안함 합격 불합격
0 1 0 1 0
1 1 0 1 0
2 0 1 0 1
'''
print(data.shape) # (행, 열) : (50, 4)
귀무가설 : 벼락치기와 합격여부는 관계가 없다.
대립가설 : 벼락치기와 합격여부는 관계가 있다.
print(data[(data['공부함'] == 1) & (data['합격'] == 1)].shape[0]) # 18 - 공부하고 합격
print(data[(data['공부함'] == 1) & (data['불합격'] == 1)].shape[0]) # 7 - 공부하고 불합격
빈도표
data2 = pd.crosstab(index=data['공부안함'], columns=data['불합격'], margins=True)
'''
불합격 0 1
공부안함
0 18 7
1 12 13
'''
data2.columns = ['합격', '불합격', '행 합']
data2.index = ['공부함', '공부안함', '열 합']
print(data2)
'''
합격 불합격 행 합
공부함 18 7 25
공부안함 12 13 25
열 합 30 20 50
'''
기대도수 = 각 행 합 * 각 열 합 / 총합
'''
합격 불합격 행 합
공부함 15 10 25
공부안함 15 10 25
열 합 30 20 50
'''
카이제곱
ch2 = ((18 - 15) ** 2 / 15) + ((7 - 10) ** 2 / 10) + ((12 - 15) ** 2 / 15) + ((13 - 10) ** 2 / 10)
print('카이제곱 :', ch2) # 3.0
자유도(df) = (행 개수 - 1) * (열 개수 - 1) = (2-1) * (2-1) = 1
카이제곱 분포표에서 확인한 임계치 : 3.84
카이제곱분포표 보는 법
카이제곱분포는 t분포와 마찬가지로 확률을 구할 때 사용하는 분포가 아니라, 나중에 신뢰구간이랑 가설검정에서 사용하는 분포다. 그래서 카이제곱분포표는 “t분포표 보는 법”과 얼추 비슷
math100.tistory.com
# 결론1 : 카이제곱 3 < 유의수준 3.84 => 귀무가설 채택 내에서 존재하여 귀무가설 채택.
( 귀무가설 : 벼락치기와 합격여부는 관계가 없다. )
전문가 제공 모듈 사용(chi2_contingency())
import scipy.stats as stats
chi2, p, ddof, expected = stats.chi2_contingency(data2)
print('chi2\t:', chi2)
print('p\t:', p)
print('ddof\t:', ddof)
print('expected :\n', expected)
'''
chi2 : 3.0
p : 0.5578254003710748
ddof : 4
expected :
[[15. 10. 25.]
[15. 10. 25.]
[30. 20. 50.]]
'''
# 결론2 : 유의확률(p-value) 0.5578 > 유의수준 0.05 => 귀무가설 채택.
( 귀무가설 : 벼락치기와 합격여부는 관계가 없다. )
stats.chi2_contigency(데이터) : 이원카이제곱 함수
일원카이제곱(chisquare())
: 관찰도수가 기대도수와 일치하는 지를 검정하는 방법
: 종류 적합도 선호도 검정 - 범주형 변수가 한 가지로 관찰도수가 기대도수에 일치하는지 검정한다
적합도검정
: 자연현상이나 각종 실험을 통해 관찰되는 도수들이 귀무가설 하의 분포 범주형 자료의 각 수준별 비율 에 얼마나 일치하는 가에 대한 분석을 적합도 검정이라 한다
: 관측값들이 어떤 이론적 분포를 따르고 있는지를 검정으로 한 개의 요인을 대상으로 함
<실습 : 적합도 검정>
주사위를 60 회 던져서 나온 관측도수 기대도수가 아래와 같이 나온 경우에 이 주사위는 적합한 주사위가 맞는가를 일원카이제곱 검정
으로 분석하자
주사위 눈금 | 1 | 2 | 3 | 4 | 5 | 6 |
관측도수 | 4 | 6 | 17 | 16 | 8 | 9 |
기대도수 | 10 | 10 | 10 | 10 | 10 | 10 |
귀무가설(영가설, H0) : 기대빈도와 관찰빈도는 차이가 없다. 현재 주사위는 평범한 주사위다.
대립가설(연구가설, H1) : 기대빈도와 관찰빈도는 차이가 있다. 현재 주사위는 평범하지않은 주사위다.
변수 1개 : 주사위를 던진 횟수. 기대빈도와 관찰빈도의 차이를 확인. stats.chisquare(관찰빈도, 기대빈도)
* chi2.py
import pandas as pd
import scipy.stats as stats
data = [4, 6, 17, 16, 8, 9] # 관찰빈도
result = stats.chisquare(data)
print(result)
# Power_divergenceResult(statistic=14.200000000000001, pvalue=0.014387678176921308)
data2 = [10, 10, 10, 10, 10, 10] # 기대빈도
result2 = stats.chisquare(data, data2)
print(result2)
print('통계량(x2) : %.5f, p-value : %.5f'%result)
# 통계량(x2) : 14.20000, p-value : 0.01439
# 통계량과 p-value는 반비례 관계.
# 결론 1 : p-value 0.01439 < 0.05 이므로 유의미한 수준(a=0.05)에서 귀무 가설 기각. 연구가설 채택.
( 대립가설 : 기대빈도와 관찰빈도는 차이가 있다. 현재 주사위는 평범하지않은 주사위다. )
# 결론 2 : df 5(N-1), 임계값 : 카이제곱 분포표를 참고시 11.07
statistic(x2) 14.200 > 임계값 11.07 이므로 귀무 가설 기각. 연구가설 채택.
( 대립가설 : 기대빈도와 관찰빈도는 차이가 있다. 현재 주사위는 평범하지않은 주사위다. )
관찰빈도와 기대빈도 사이에 유의한 차이가 있는 지 일원 카이제곱을 사용하여 검정
stats.chisquare(데이터) : 일원카이제곱 함수
<실습 : 선호도 분석>
5개의 스포츠 음료에 대한 선호도에 차이가 있는지 검정하기
귀무 가설 : 스포츠 음료에 대한 선호도 차이가 없다.
대립 가설 : 스포츠 음료에 대한 선호도 차이가 있다.
import numpy as np
data3 = pd.read_csv('../testdata/drinkdata.csv')
print(data3, ' ', sum(data3['관측도수']))
'''
음료종류 관측도수
0 s1 41
1 s2 30
2 s3 51
3 s4 71
4 s5 61 254
'''
print(stats.chisquare(data3['관측도수']))
# Power_divergenceResult(statistic=20.488188976377952, pvalue=0.00039991784008227264)
# 결론 : pvalue 0.00039 < 유의수준 0.05 이기 때문에 귀무가설 기각. 대립가설 채택.
( 대립 가설 : 스포츠 음료에 대한 선호도 차이가 있다. 향후 작업에 대한 참조자료로 이용. )
이원카이제곱 - 교차분할표 이용
: 두 개 이상의 변인 집단 또는 범주 을 대상으로 검정을 수행한다
분석대상의 집단 수에 의해서 독립성 검정과 동질성 검정으로 나뉜다
독립성 검정 : 두 변인의 관계가 독립인지 검정
동질성 검정 : 두 변인 간의 비율이 서로 동일한지를 검정
독립성 (관련성) 검정
- 동일 집단의 두 변인 학력수준과 대학진학 여부 을 대상으로 관련성이 있는가 없는가
- 독립성 검정은 두 변수 사이의 연관성을 검정한다
<실습 : 교육수준과 흡연율 간의 관련성 분석>
집단 2개 : 교육수준, 흡연율
귀무가설 : 교육수준과 흡연율 간에 관련이 없다. (독립이다)
대립가설 : 교육수준과 흡연율 간에 관련이 있다. (독립이 아니다)
*chi3.py
import pandas as pd
import scipy.stats as stats
data = pd.read_csv('../testdata/smoke.csv')
print(data)
'''
education smoking
0 1 1
1 1 1
2 1 1
3 1 1
4 1 1
.. ... ...
350 3 3
351 3 3
352 3 3
353 3 3
354 3 3
'''
print(data['education'].unique()) # [1 2 3]
print(data['smoking'].unique()) # [1 2 3]
교육 수준, 흡연인원를 이용한 교차표 작성
# education : 독립변수, smoking : 종속변수
ctab = pd.crosstab(index = data['education'], columns = data['smoking']) # 빈도수.
ctab = pd.crosstab(index = data['education'], columns = data['smoking'], normalize=True) # normalize : 비율
ctab.index = ['대학원졸', '대졸', '고졸']
ctab.columns = ['골초', '보통', '노담']
print(ctab)
'''
골초 보통 노담
대학원졸 51 92 68
대졸 22 21 9
고졸 43 28 21
'''
pd.crosstab(index=, columns=) : 교차 테이블
이원 카이 제곱을 지원하는 함수
chi_result = [ctab.loc['대학원졸'], ctab.loc['대졸'], ctab.loc['고졸']]
chi, p, _, _ = stats.chi2_contingency(chi_result)
chi, p, _, _ = stats.chi2_contingency(ctab)
print('chi :', chi) # chi : 18.910915739853955
print('p-value :', p) # p-value : 0.0008182572832162924
# 결론 : p-value 0.0008 < 0.05 이므로 귀무가설 기각.
( 대립가설 : 교육수준과 흡연율 간에 관련이 있다. (독립이 아니다) )
stats.chi2_contigency(데이터) : 이원카이제곱 함수
야트보정
분할표의 자유도가 1인 경우는 x^2값이 약간 높게 계산된다. 그러므로 이에 하기 식으로 야트보정이라 한다.
x^2=∑(|O-E|-0.5)^2/E
=> 상기 함수는 자동으로 야트보정이 이루어진다.
<실습 : 국가전체와 지역에 대한 인종 간 인원수로 독립성 검정 실습>
두 집단 국가전체 national, 특정지역 la) 의 인종 간 인원수의 분포가 관련이 있는가
귀무가설 : 국가전체와 지역에 대한 인종 간 인원수는 관련이 없다. 독립적.
대립가설 : 국가전체와 지역에 대한 인종 간 인원수는 관련이 있다. 독립적이지 않다.
national = pd.DataFrame(["white"] * 100000 + ["hispanic"] * 60000 +
["black"] * 50000 + ["asian"] * 15000 +["other"] * 35000)
la = pd.DataFrame(["white"] * 600 + ["hispanic"] * 300 + ["black"] * 250 +
["asian"] * 75 + ["other"] * 150)
print(national) # [260000 rows x 1 columns]
print(la) # [1375 rows x 1 columns]
na_table = pd.crosstab(index = national[0], columns = 'count')
la_table = pd.crosstab(index = la[0], columns = 'count')
print(la_table)
'''
col_0 count
0
asian 75
black 250
hispanic 300
other 150
white 600
'''
na_table['count_la'] = la_table['count'] # 칼럼 추가
print(na_table)
'''
col_0 count count_la
0
asian 15000 75
black 50000 250
hispanic 60000 300
other 35000 150
white 100000 600
'''
chi, p, _, _ = stats.chi2_contingency(na_table)
print('chi :', chi) # chi : 18.099524243141698
print('p-value :', p) # p-value : 0.0011800326671747886
# 결론 : p-value : 0.0011 < 0.05 이므로 귀무가설 기각.
( 대립가설 : 국가전체와 지역에 대한 인종 간 인원수는 관련이 있다. 독립적이지 않다.)
이원카이제곱
동질성 검정
- 두 집단의 분포가 동일한가 다른 분포인가 를 검증하는 방법이다 두 집단 이상에서 각 범주 집단 간의 비율이 서로 동일한가를 검정하게 된다 두 개 이상의 범주형 자료가 동일한 분포를 갖는 모집단에서 추출된 것인지 검정하는 방법이다
<실습 1 : 교육방법에 따른 교육생들의 만족도 분석 - 동질성 검정>
귀무가설 : 교육방법에 따른 교육생들의 만족도에 차이가 없다.
대립가설 : 교육방법에 따른 교육생들의 만족도에 차이가 있다.
* chi4.py
import pandas as pd
import scipy.stats as stats
data = pd.read_csv("../testdata/survey_method.csv")
print(data.head(6))
'''
no method survey
0 1 1 1
1 2 2 2
2 3 3 3
3 4 1 4
4 5 2 5
5 6 3 2
'''
print(data['survey'].unique()) # [1 2 3 4 5] - survey 데이터 종류
print(data['method'].unique()) # [1 2 3] - method 데이터 종류
# 교차표 작성
ctab = pd.crosstab(index=data['method'], columns=data['survey'])
ctab.columns = ['매우만족', '만족', '보통', '불만족', '매우불만족']
ctab.index = ['방법1', '방법2', '방법3']
print(ctab)
'''
매우만족 만족 보통 불만족 매우불만족
방법1 5 8 15 16 6
방법2 8 14 11 11 6
방법3 8 7 11 15 9
'''
# 카이제곱
chi, p, df, ex = stats.chi2_contingency(ctab)
msg = "chi2 : {}, p-value:{}, df:{}"
print(msg.format(chi, p, df))
# chi2 : 6.544667820529891, p-value:0.5864574374550608, df:8
# 결론 : p-value 0.586 > 0.05 이므로 귀무가설 채택.
( 귀무가설 : 교육방법에 따른 교육생들의 만족도에 차이가 없다. )
<실습 : 연령대별 sns 이용률의 동질성 검정>
20대에서 40 대까지 연령대별로 서로 조금씩 그 특성이 다른 SNS 서비스들에 대해 이용 현황을 조사한 자료를 바탕으로 연령대별로 홍보 전략을 세우고자 한다. 연령대별로 이용 현황이 서로 동일한지 검정해 보도록 하자
귀무가설 : 연령대별로 SNS 서비스 이용 현황에 차이가 없다(동질이다).
대립가설 : 연령대별로 SNS 서비스 이용 현황에 차이가 있다(동질이 없다).
import pandas as pd
import scipy.stats as stats
data2 = pd.read_csv("../testdata/snsbyage.csv")
print(data2.head(), ' ', data2.shape)
'''
age service
0 1 F
1 1 F
2 1 F
3 1 F
4 1 F (1439, 2)
'''
print(data2['age'].unique()) # [1 2 3]
print(data2['service'].unique()) # ['F' 'T' 'K' 'C' 'E']
# 교차표 작성
ctab2 = pd.crosstab(index = data2['age'], columns = data2['service'])
print(ctab2)
'''
service C E F K T
age
1 81 16 207 111 117
2 109 15 107 236 104
3 32 17 78 133 76
'''
# 카이제곱
chi, p, df, ex = stats.chi2_contingency(ctab2)
msg2 = "chi2 : {}, p-value:{}, df:{}"
print(msg2.format(chi, p, df))
# chi2 : 102.75202494484225, p-value:1.1679064204212775e-18, df:8
# 결론 : p-value 1.1679064204212775e-18 < 0.05 이므로 귀무가설 기각.
( 대립가설 : 연령대별로 SNS 서비스 이용 현황에 차이가 있다(동질이 없다) )
# 참고 : 상기 데이터가 모집단이었다면 샘플링을 진행하여 샘플링 데이터로 작업 진행.
sample_data = data2.sample(500, replace=True)
카이제곱 + Django
= django_use02_chi(PyDev Django Project)
Create application - coffesurvey
* settings
...
INSTALLED_APPS = [
...
'coffeesurvey',
]
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'coffeedb', # DB명 : db는 미리 작성되어 있어야 함.
'USER': 'root', # 계정명
'PASSWORD': '123', # 계정 암호
'HOST': '127.0.0.1', # DB가 설치된 컴의 ip
'PORT': '3306', # DBMS의 port 번호
}
}
* MariaDB
create database coffeedb;
use coffeedb;
create table survey(rnum int primary key auto_increment, gender varchar(4),age int(3),co_survey varchar(10));
insert into survey (gender,age,co_survey) values ('남',10,'스타벅스');
insert into survey (gender,age,co_survey) values ('여',20,'스타벅스');
* anaconda prompt
cd C:\work\psou\django_use02_chi
python manage.py inspectdb > aaa.py
* models
from django.db import models
# Create your models here.
class Survey(models.Model):
rnum = models.AutoField(primary_key=True)
gender = models.CharField(max_length=4, blank=True, null=True)
age = models.IntegerField(blank=True, null=True)
co_survey = models.CharField(max_length=10, blank=True, null=True)
class Meta:
managed = False
db_table = 'survey'
Make migrations - coffeesurvey
Migrate
* urls(django_use02_chi)
from django.contrib import admin
from django.urls import path
from coffeesurvey import views
from django.urls.conf import include
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.Main), # url 없을 경우
path('coffee/', include('coffeesurvey.urls')), # 위임
]
* views
from django.shortcuts import render
from coffeesurvey.models import Survey
# Create your views here.
def Main(request):
return render(request, 'main.html')
...
* main.html
<body>
<h2>메인</h2>
<ul>
<li>메뉴</li>
<li>신제품</li>
<li><a href="coffee/survey">설문조사</a></li>
</ul>
</body>
* urls(coffeesurvey)
from django.urls import path
from coffeesurvey import views
urlpatterns = [
path('survey', views.SurveyView),
path('surveyprocess', views.SurveyProcess),
]
* views
...
def SurveyView(request):
return render(request, 'survey.html')
* survey.html
<body>
<h2>* 커피전문점에 대한 소비자 인식조사 *</h2>
<form action="/coffee/surveyprocess" method="post">{% csrf_token %}
<table>
<tr>
<td>귀하의 성별은?</td>
<td>
<label for="genM">남</label>
<input type="radio" id="genM" name="gender" value="남" checked="checked">
 
<label for="genF">여</label>
<input type="radio" id="genF" name="gender" value="여">
</td>
</tr>
<tr>
<td>귀하의 나이는?</td>
<td>
<label for="age10">10대</label>
<input type="radio" id="age10" name="age" value="10" checked="checked">
 
<label for="age20">20대</label>
<input type="radio" id="age20" name="age" value="20">
 
<label for="age10">30대</label>
<input type="radio" id="age30" name="age" value="30">
 
<label for="age40">40대</label>
<input type="radio" id="age40" name="age" value="40">
 
<label for="age50">50대</label>
<input type="radio" id="age50" name="age" value="50">
</td>
</tr>
<tr>
<td>선호하는 커피전문점은?</td>
<td>
<label for="startbucks">스타벅스</label>
<input type="radio" id="genM" name="co_survey" value="스타벅스" checked="checked">
 
<label for="coffeebean">커피빈</label>
<input type="radio" id="coffeebean" name="co_survey" value="커피빈">
 
<label for="ediya">이디아</label>
<input type="radio" id="ediya" name="co_survey" value="이디아">
 
<label for="tomntoms">탐앤탐스</label>
<input type="radio" id="tomntoms" name="co_survey" value="탐앤탐스">
</td>
</tr>
<tr>
<td colspan="2">
<br>
<input type="submit" value="설문완료">
<input type="reset" value="초기화">
</tr>
</table>
</form>
</body>
* views
...
import pandas as pd
import scipy.stats as stats
import matplotlib.pyplot as plt
plt.rc('font', family="malgun gothic")
def SurveyProcess(request):
InsertData(request)
rdata = list(Survey.objects.all().values())
# print(rdata) # [{'rnum': 1, 'gender': '남', 'age': 10, 'co_survey': '스타벅스'}, ...
df, crossTab, results = Analysis(rdata)
# 시각화
fig = plt.gcf()
gen_group = df['co_survey'].groupby(df['coNum']).count()
gen_group.index = ['스타벅스', '커피빈', '이디아', '탐앤탐스']
gen_group.plot.bar(subplots=True, color=['red', 'blue'], width=0.5)
plt.xlabel('커피샵')
plt.ylabel('선호도 건수')
plt.title('커피샵 별 선호건수')
fig.savefig('django_use02_chi/coffeesurvey/static/images/co.png')
return render(request, 'list.html', {'df':df.to_html(index=False), \
'crossTab':crossTab.to_html(), 'results':results})
def InsertData(request): # 입력자료 DB에 저장
if request.method == 'POST':
Survey(
gender = request.POST.get('gender'),
age = request.POST.get('age'),
co_survey = request.POST.get('co_survey')
).save()
# 또는 SQL문을 직접 사용해도 무관.
def Analysis(rdata): # 분석
df = pd.DataFrame(rdata)
df.dropna() # 결측치 처리가 필요한 경우에는 진행. 이상치도 처리.
df['genNum'] = df['gender'].apply(lambda g:1 if g =='남' else 2)
df['coNum'] = df['co_survey'].apply(lambda c:1 if c =='스타벅스' \
else 2 if c =='커피빈' else 3 if c =='이디아' else 4)
print(df)
'''
rnum gender age co_survey genNum coNum
0 1 남 10 스타벅스 1 1
1 2 여 20 스타벅스 2 1
2 3 남 10 스타벅스 1 1
3 4 남 10 스타벅스 1 1
4 5 남 10 탐앤탐스 1 4
5 6 남 40 커피빈 1 2
6 7 남 10 스타벅스 1 1
7 8 남 10 스타벅스 1 1
8 9 남 10 스타벅스 1 1
9 10 남 10 스타벅스 1 1
10 11 남 10 스타벅스 1 1
11 12 남 10 스타벅스 1 1
'''
# 교차 빈도표
crossTab = pd.crosstab(index=df['gender'], columns=df['co_survey'])
#crossTab = pd.crosstab(index=df['genNum'], columns=df['coNum'])
print(crossTab)
chi, pv, _, _ = stats.chi2_contingency(crossTab)
if pv > 0.05:
results = 'p값이 {}이므로 유의수준 0.05 <b>이상</b>의 값을 가지므로 <br> "
+"성별에 따라 선호하는 커피브랜드에는 <b>차이가 없다.</b> (귀무가설 채택)'.format(pv)
else:
results = 'p값이 {}이므로 유의수준 0.05 <b>이하</b>의 값을 가지므로 <br> "
+"성별에 따라 선호하는 커피브랜드에는 <b>차이가 있다.</b> (연구가설 채택)'.format(pv)
return df, crossTab, results
* list.html
<body>
<h2>* 커피전문점에 대한 소비자 인식 조사 결과 *</h2>
<a href="/">메인화면</a><br>
<a href="/coffee/survey">다시 설문조사 하기</a><br>
{% if df %}
{{df|safe}}
{% endif %}<br>
{% if crossTab %}
{{crossTab|safe}}
{% endif %}<br>
{% if results %}
{{results|safe}}
{% endif %}<br>
<img src="/static/images/co.png" width="400" />
</body>
'BACK END > Deep Learning' 카테고리의 다른 글
[딥러닝] 선형회귀 (0) | 2021.03.10 |
---|---|
[딥러닝] 공분산, 상관계수 (0) | 2021.03.10 |
[딥러닝] 이항검정 (0) | 2021.03.10 |
[딥러닝] ANOVA (0) | 2021.03.08 |
[딥러닝] T 검정 (0) | 2021.03.05 |