import numpy as np
import first
live, firsts, others = first.MakeFrames()
df = live[live.prglngth>30]

"""
Explanation: 통계적 사고 (2판) 연습문제 (thinkstats2.com, think-stat.xwmooc.org)<br>
Allen Downey / 이광춘(xwMOOC)
연습문제 11.1
동료중 한명이 출산이 예정되어 있고, 출생일을 예측하는 사무실 내기게임에 참여한다고 가정하자. 임신 30주차에 내기를 건다고 가정하자. 가장 최선의 예측을 하는데 어떤 변수를 사용하면 될까? 출생전에 알려진 변수로 한정해야하고, 내기에 참여한 사람들에게 이용가능해야할 것 같다.
연습문제 11.2
트리버스-윌라드(Trivers-Willard) 가설은 많은 포유류에 있어, 성비는 “어머니 상태(maternal condition)”에 달려있다고 제시한다; 즉, 산모 연령, 크기, 건강, 사회적 지위 같은 요인. https://en.wikipedia.org/wiki/Trivers-Willard_hypothesis 참조한다.
일부 연구는 사람사이에 이런 효과를 보여주고 있지만, 결과는 혼재한다. 이번 장에서, 이런 요인과 연관된 일부 변수를 검정하지만, 성비에 통계적으로 유의적인 효과를 갖는 어떤 변수도 발견하지 못했다.
연습으로, 데이터 마이닝 접근법을 사용해서 임신파일과 응답자파일에서 다른 변수를 검정하라. 실질적인 효과를 갖는 다른 요인을 발견할 수 있는가?
연습문제 11.3
예측하고자 하는 수량(quantity)이 갯수(count)라면, 포아송 회귀를 사용할 수 있다. StatModels에 poisson 함수로 구현되어 있다. ols 나 logit 과 동일한 방식으로 작동한다. 연습으로, 이것을 사용해서 한 여성에 대해서 얼마나 많은 아기가 태어나는지 예측한다; NSFG 데이터셋에서, 이 변수는 numbabes로 불린다..
나이가 35세, 흑인, 연가구소득이 $75,000을 넘는 대학을 졸업한 여성을 가정해보자. 그녀가 얼마나 많은 자녀를 출산할 것으로 예상되는가?
연습문제 11.4
만약 예측하고자 하는 수량이 범주형이라면, 다항 로지스틱 회귀를 사용한다. StatModels에서 mnlogit 함수로 구현되어 있다. 연습으로, 이를 사용해서, 한 여성이 혼인상태, 동거상태, 과부상태, 이혼상태, 별거상태, 미혼인지 추측해본다; NSFG 데이터셋에서, 혼인상태는 변수명 rmarital로 부호화되어 있다.
연령이 25세, 백인, 연가구소득이 약 $45,000 달러인 고졸 여성을 만났다고 가정해보자. 그녀가 혼인, 동거, 등일 확률은 얼마나 될까?
End of explanation
"""


import statsmodels.formula.api as smf
model = smf.ols('prglngth ~ birthord==1 + race==2 + nbrnaliv>1', data=df)
results = model.fit()
results.summary()

"""
Explanation: 아래에 저자가 발견한 임신기간에 통계적으로 유의적인 변수만 나와있다.
End of explanation
"""


import regression
join = regression.JoinFemResp(live)

def GoMining(df):
    """Searches for variables that predict birth weight.

    df: DataFrame of pregnancy records

    returns: list of (rsquared, variable name) pairs
    """
    df['boy'] = (df.babysex==1).astype(int)
    variables = []
    for name in df.columns:
        try:
            if df[name].var() < 1e-7:
                continue

            formula='boy ~ agepreg + ' + name
            model = smf.logit(formula, data=df)
            nobs = len(model.endog)
            if nobs < len(df)/2:
                continue

            results = model.fit()
        except:
            continue

        variables.append((results.prsquared, name))

    return variables

variables = GoMining(join)

"""
Explanation: 성비를 예측하는 변수에 대해서 좀더 깊게 살펴보자.
End of explanation
"""


regression.MiningReport(variables)

"""
Explanation: 가장 높은 유사-$R^2$(pseudo-$R^2$) 값을 이끌어 내는 변수가 30개 있다.
End of explanation
"""


formula='boy ~ agepreg + fmarout5==5 + infever==1'
model = smf.logit(formula, data=join)
results = model.fit()
results.summary() 

"""
Explanation: 임신기간 동안 알려지지 않은 변수와 다양한 사유로 수상한 냄새가 나는 변수를 제거하고 나서, 저자가 찾은 가장 최적의 모형이 다음에 나와있다:
End of explanation
"""


join.numbabes.replace([97], np.nan, inplace=True)
join['age2'] = join.age_r**2
join['age3'] = join.age_r**3

formula='numbabes ~ age_r + age2 + age3 + C(race) + totincr + educat'
model = smf.poisson(formula, data=join)
results = model.fit()
results.summary() 

"""
Explanation: 응답자 자녀숫자를 예측하는 모형을 만들어보자. 연령에 대해 비선형모형을 사용했다. age3 항이 지나칠 수 있지만, 저자 생각에는 엉뚱한 선택은 아니라고 본다. 예측에 그다지 효과는 없다.
End of explanation
"""


import pandas
columns = ['age_r', 'age2', 'age3', 'race', 'totincr', 'educat']
new = pandas.DataFrame([[35, 35**2, 35**3, 1, 14, 16]], columns=columns)
results.predict(new)

"""
Explanation: 이제, 35세, 흑인, 대학졸업하고 연간 가구소등이 $75,000을 넘는 여성에 대한 자녀수를 예측할 수 있다.
End of explanation
"""


formula='rmarital ~ age_r + age2 + C(race) + totincr + educat'
model = smf.mnlogit(formula, data=join)
results = model.fit()
results.summary() 

"""
Explanation: 혼인상태를 예측하기 위하는데, 저자가 찾은 가장 최적의 모형이 다음에 나와 있다:
End of explanation
"""


columns = ['age_r', 'age2', 'race', 'totincr', 'educat']
new = pandas.DataFrame([[25, 25**2, 2, 11, 12]], columns=columns)
results.predict(new)

"""
Explanation: 25세, 백인, 고등학교 졸업, 연간 가구소득이 $45,000인 여성에 대한 예측이 다음에 나와있다.
End of explanation
"""


