Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Statistical Regression With Python

Mosky Liu
May 11, 2019

Statistical Regression With Python

There are many variables, e.g., the columns in a database, the questions in a survey, etc. If you have a regression model, you can find the relationships out and even predict the future values.

In this talk, I will introduce the correlation analysis, OLS (ordinary least squares), using R formula (an implementation in Python) to build model, covariance types, outliers, other common models, and the most important thing: how to build and interpret a model correctly.

Moreover, all the topics will be introduced with massive Python examples.

The notebooks are available on https://github.com/moskytw/statistical-regression-with-python .

Mosky Liu

May 11, 2019
Tweet

More Decks by Mosky Liu

Other Decks in Research

Transcript

  1. Explain & Predict ➤ ➤ A line. ➤ Explain by

    β, the slope. ➤ Predict by new xi . ➤ “Simple linear regression model” ➤ ➤ A n-dim hyperplane. ➤ β, a slope vector. ➤ New xi , a vector. ➤ “Multiple linear regression model” 4 yi = β0 + β1 xi + εi yi = x i β + εi
  2. Mosky ➤ Python Charmer at Pinkoi. ➤ Has spoken at:

    PyCons in 
 TW, MY, KR, JP , SG, HK,
 COSCUPs, and TEDx, etc. ➤ Countless hours 
 on teaching Python. ➤ Own the Python packages like ZIPCodeTW. ➤ http://mosky.tw/ 6
  3. Outline ➤ The Analysis Steps ➤ Define Assumptions ➤ Validate

    Assumptions ➤ The Dataset: Fair ➤ Correlation Analysis ➤ Ordinary Least Squares ➤ Models & Estimations ➤ Understand
 Regression Result ➤ Model Specification Using the R Formula ➤ Covariance Types ➤ Outliers ➤ Correlation & Causation ➤ More Models & Estimations ➤ Introduction ➤ Logit Model 7
  4. The PDF, Notebooks, and Packages ➤ The PDF and notebooks

    are available on https://github.com/ moskytw/statistical-regression-with-python . ➤ The packages: ➤ $ pip3 install jupyter numpy scipy sympy matplotlib ipython pandas seaborn statsmodels scikit-learn Or: ➤ > conda install jupyter numpy scipy sympy matplotlib ipython pandas seaborn statsmodels scikit-learn 8
  5. Define Assumptions ➤ The regression analysis: ➤ Suitable to measure

    the relationship between variables. ➤ Can model most of the hypothesis testing. [ref] ➤ Can predict. 9
  6. ➤ “The relationship between rates of marriage and affairs?” ➤

    “The relationship between any background and affairs?” 10
  7. Validate Assumptions ➤ Collect data ... ➤ The “Fair” dataset:

    ➤ Fair, Ray. 1978. “A Theory of Extramarital Affairs,” 
 Journal of Political Economy, February, 45-61. ➤ A dataset from 1970s. ➤ Rows: 6,366 ➤ Columns: (next slide) ➤ The full version of the analysis steps: 
 http://bit.ly/analysis-steps . 11
  8. 1. rate_marriage: 1~5; very poor, poor, fair, good, very good.

    2. age 3. yrs_married 4. children: number of children. 5. religious: 1~4; not, mildly, fairly, strongly. 6. educ: 9, 12, 14, 16, 17, 20; grade school, some college, college graduate, some graduate school, advanced degree. 7. occupation: 1, 2, 3, 4, 5, 6; student, farming-like, white- colloar, teacher-like, business- like, professional with advanced degree. 8. occupation_husb 9. affairs: n times of extramarital affairs per year since marriage. 12
  9. Correlation Analysis ➤ Measures “the linear tightness”. ➤ Pearson correlation

    coefficient ➤ For the variables whose distance is meaningful. ➤ df.corr() ➤ Kendall rank correlation coefficient ➤ For the variables whose order is meaningful. ➤ df.corr('kendall') 14
  10. import statsmodels.api as sm import statsmodels.formula.api as smf import seaborn

    as sns print(sm.datasets.fair.SOURCE, sm.datasets.fair.NOTE) # -> Pandas's Dataframe df_fair = sm.datasets.fair.load_pandas().data df = df_fair sns.heatmap(df.corr('kendall'), vmax=1, center=0, vmin=-1, square=True, annot=True, fmt='.2f') 17
  11. Models & Estimations ➤ Models ➤ ➤ Like simple, multiple,

    logit, etc. ➤ Estimations ➤ How to estimate the β̂? For example, OLS: 18 y = Xβ + ε y = X ̂ β S(b) = n ∑ i=1 (yi − xT i b)2 = (y − Xb)T(y − Xb) ̂ β = argminb∈ℝp S(b) = (XTX)−1XTy
  12. affairs ~ rate_marriage ➤ Using the R formula implementation in

    Python, Patsy: 19 y ∼ x ≡ y ∼ 1 + x ≡ y = β0 1 + β1 x + ε
  13. df = df_fair (smf .ols('affairs ~ rate_marriage', df) .fit() .summary())

    df_fair_sample = df_fair.sample( frac=0.1, random_state=20190425 ) df = df_fair_sample sns.regplot(data=df, x='rate_marriage', y='affairs', x_jitter=1/2, y_jitter=20/2) 21
  14. Adj. R-squared ➤ = explained var. by X / var.

    of y and adjusted by no. of X ➤ ∈ [0, 1], usually. ➤ Can be compared among models. ➤ 0.032 is super bad. 22
  15. Prob(F-statistics) ➤ ≈ P(data|all coefs are zero) ➤ Accept the

    model if low enough. ➤ “Low enough” is “< 0.05” in convention. 23
  16. Log-Likelihood ➤ Higher is better. ➤ Negative, usually. ➤ Can

    be compared among models when the datasets are the same. ➤ See also: likelihood-ratio test. 24
  17. Large Sample or Normality ➤ No. Observations: ➤ ≥ 100

    [ref] ➤ Normality of Residuals: ➤ Prob(Omnibus) ≥ 0.05 ➤ and Prob(JB) ≥ 0.05 ➤ To construct interval estimates correctly, e.g., hypothesis tests on coefs, confidence intervals. 25
  18. Cond. No. ➤ Measures the degree of multicollinearity. ➤ Multicollinearity

    increases the std err, 
 i.e., decreases efficiency. ➤ If ≥ 30, check: ➤ Any variable has redundant information? Like fat % and weight. Drop one. ➤ If no, the model is good. ➤ Or other suggestions. 26
  19. P>|t| ➤ = P(data|the coef is zero) ➤ Accept the

    coef if low enough. ➤ Drop the term, otherwise. 27
  20. Coef & Confidence Intervals ➤ “The rate_marriage and affairs have

    a negative relationship, the strength is -0.41, and 95% confidence interval is [-0.46, -0.35].” 28
  21. affairs ~ C(rate_marriage) ➤ y ~ C(x) ➤ If 1,

    affairs is 1.20. ➤ If 5, affairs is 1.20 - 0.85. ➤ 2, 3, 4 are not significant to 1. 30
  22. Code Categorical Variables ➤ The str or bool is treated

    as categorical by default. ➤ The C function: ➤ The x1 is chosen as the reference level automatically. ➤ For example: C(rate_marriage ∈ {1, 2, 3, 4, 5})
 ≡ 1 + rate_marriage_2 ∈ {0, 1} + ... + rate_marriage_5 ∈ {0, 1} 31 y ∼ C(x) ≡ y ∼ 1 + (x1 + x2 + … + xi ) − x1 ≡ y ∼ 1 + x2 + … + xi ≡ y = β0 1 + β2 x2 + … + βi xi + ε
  23. affairs ~ 0 + C(rate_marriage) ➤ y ~ 0 +

    C(x) ➤ Code without a reference. ➤ To calculate the mean of each group. 32
  24. df = df_fair (smf .ols('affairs ~ C(rate_marriage)', df) .fit() .summary())

    df = df_fair (smf .ols('affairs ~ 0 + C(rate_marriage)', df) .fit() .summary()) df = df_fair sns.pointplot(data=df, x='rate_marriage', y='affairs') 34
  25. More Ways to Code Categorical Variables ➤ y ~ C(x,

    Treatment(reference='A')) ➤ Specify the reference level. ➤ affairs ~ 0 + C(rate_marriage, Diff) ➤ Compare each level with the preceding level. ➤ affairs ~ 0 + C(rate_marriage, Sum) ➤ Compare each level with the mean-of-means. ➤ See also: the full reference. 35
  26. Correlation Does Not Imply Causation ➤ y ~ x :=

    “y has association with x” ➤ y ← x := “y because x” ➤ y ~ x may be: ➤ y ← x ➤ y → x ➤ y ← z → x ➤ So y ~ x doesn't implies y ← x. ➤ But usually we want the causation, not only correlation. ➤ Use a good research design to construct a causal inference. 39
  27. Suggested Wording ➤ Can't be wrong: ➤ “Relationship”, any relationship.

    ➤ Correlation: ➤ “Associate” “Association”, relatively conservative. ➤ “Correlate” “Correlation”, usually in correlation analysis. ➤ Causation: ➤ “Predict” “Prediction”. ➤ “Affect” “Influence”, the most strong wording. 40
  28. Interaction ➤ “The low rate_marriage with high religious has a

    lower affairs?” 41 y ∼ x * z ≡ y = β0 1 + β1 x + β2 z + β3 xz + ε
  29. ➤ Hmmm ... ➤ TL;DR by ANOVA. ➤ Looks like

    C(religious) isn't helping to explain. Drop it. ➤ It's interesting since it's significant if we regress affairs on just religious, so we can state “religious is not significant after we control rate_marriage and rate_marriage×religious”. affairs ~ C(rate_marriage)*C(religious) 43
  30. ➤ affairs ~
 C(rate_marriage)*C(religious)
 - C(religious) Or: ➤ affairs ~


    C(rate_marriage)
 + C(religious):C(rate_marriage) ➤ “The low rate_marriage with high religious has a lower affairs?” Yes! 44 y ∼ x : z ≡ y = β0 + β1 xz + ε
  31. df = df_fair (smf .ols('affairs ~ rate_marriage*religious', df) .fit() .summary())

    df = df_fair res = (smf .ols('affairs' '~ C(rate_marriage)*C(religious)', df) .fit()) display(res.summary(), # type III is suitable to unbalanced dataset # ref: http://bit.ly/3typess sm.stats.anova_lm(res, typ=3)) 46
  32. df = df_fair res = (smf .ols('affairs' '~ C(rate_marriage)' '

    + C(rate_marriage):C(religious)', df) .fit()) display(res.summary(), sm.stats.anova_lm(res, typ=3)) df = df_fair sns.pointplot(data=df, x='rate_marriage', y='affairs', hue='religious') 47
  33. More Operators: Transformation & Control Variables ➤ np.log(y) ~ x

    ➤ If y and x have a better linear relationship after transform. ➤ Note that: ➤ log(y) = β̂ 1x1 + β̂ 2x2 ➤ y = exp(β̂ 1x1 + β̂ 2x2 ) ➤ y = exp(β̂ 1x1 )×exp(β̂ 2x2 ) ➤ y ~ I(x*z) ➤ True multiplication. 48
  34. ➤ y ~ z_1 + ... + x_1 + ...

    ➤ The zi and xi are both independent variables. ➤ If we don't interest in zi , but they can carry some effects and clarify the effects of xi , we call zi “control variables”. ➤ For example: ➤ GMV ~ month + group ➤ See also: the full reference. 49
  35. ➤ If spherical errors, the model is good. ➤ If

    not spherical errors, the std errs are wrong. ➤ So the interval estimates are wrong too, including hypothesis tests on coefs, confidence intervals. ➤ Spherical Errors ➤ ≡ Homoscedasticity & no autocorrelation ➤ Heteroscedasticity ≡ no homoscedasticity ➤ Autocorrelation ≡ serial correlation Covariance Types of Errors 50
  36. ➤ Use HC std errs (heteroscedasticity-consistent standard errors) to correct.

    ➤ If N ≤ 250, use HC3. [ref] ➤ If N > 250, consider HC1 
 for the speed. ➤ Also suggest to use by default. ➤ .fit(cov_type='HC3') ← The confidence intervals vary among groups. The heteroscedasticity exists. Heteroscedasticity 52
  37. Autocorrelation ➤ Durbin-Watson ➤ 2 is no autocorrelation. ➤ [0,

    2) 
 is positive autocorrelation. ➤ (2, 4] 
 is negative autocorrelation. ➤ [1.5, 2.5] 
 are relatively normal. [ref] ➤ Use HAC std err. ➤ .fit(cov_type='HAC', cov_kwds=dict(maxlag=tau)) 53
  38. Other Covariance Types ➤ cluster ➤ Assume each group has

    spherical errors. ➤ hac-groupsum ➤ Sum by the time label and then process. ➤ hac-panel ➤ Process by the groups and then aggregate. ➤ See also: the full references. 54
  39. Outliers ➤ An outlier may be the most interesting observation.

    ➤ Consider to include more variables to explain. ➤ Consider the possible non-linear relationship. ➤ Consider the outlier-insensitive models. ➤ Drop observations only when you have a good reason, like: ➤ Typo. ➤ Not representative of the intended study population. ➤ Report fully, including: ➤ The preprocess steps. ➤ The models with and without outliers. 55
  40. ➤ Quantile regression: estimates the median rather than mean. ➤

    Robust regression: robust to outliers, but slower. ➤ Keep middle n%: changes the intended study population. ➤ OLS ➤ Outliner test ➤ Influence report 56
  41. More Models ➤ Discrete Models, like logit model: ➤ y

    ∈ {0, 1} ➤ Mixed Model for estimate both subject and group effect: ➤ ➤ Time Series Models, like autoregressive model: ➤ ➤ See also: all the models that StatsModels supports. 57 y = Xβ + Zu + ε xt = c + φ1 xt−1 + φ2 xt−2 + … + φp xt−p + εt
  42. More Estimations ➤ MLE, Maximum Likelihood Estimation. ← Usually find

    by numerical methods. ➤ TSLS, Two-Stage Least Squares. ➤ y ← (x ← z) ➤ Handle the endogeneity: E[ε|X] ≠ 0. 58
  43. Logit Model ➤ The coef is log-odds. ➤ Use exp(x)/(exp(x)+1)

    to transform back to probability: ➤ 0.6931 → 67% ➤ ″ - 1.6664 → 27% ➤ ″ - 1.3503 → 9% Or: ➤ .predict(dict(
 rate_marriage=[1, 5, 5], religious=[1, 1, 4])) 61
  44. df = df_fair df = df.assign(affairs_yn=(df.affairs > 0).astype(float)) df_fair_2 =

    df df = df_fair_2.sample(frac=0.1, random_state=20190429) sns.regplot(data=df, x='rate_marriage', y='affairs_yn', logistic=True, x_jitter=1/2, y_jitter=0.2/2) df = df_fair_2 (smf .logit('affairs_yn' '~ C(rate_marriage)' ' + C(rate_marriage):C(religious)', df) .fit() .summary()) 62
  45. Recap ➤ The regression analysis finds the relationship, also predicts.

    ➤ The correlation analysis gets an overview. ➤ Plotting, Adj. R-squared, Cond. No., Durbin-Watson, etc. ➤ y ~ C(x) ➤ For categorical variables. ➤ y ~ x*z ➤ For investigating the interaction. ➤ Correlation does not imply causation. ➤ Let's explain and predict efficiently! 63