{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# 使用pandas读取数据\n",
"import pandas as pd\n",
"\n",
"\n",
"data_path = \"./data/adult.data\"\n",
"raw_data = pd.read_csv(data_path)\n",
"## 选取需要使用的列\n",
"cols = [\"workclass\", \"sex\", \"age\", \"education_num\",\n",
" \"capital_gain\", \"capital_loss\", \"hours_per_week\", \"label\"]\n",
"data = raw_data[cols]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" workclass | \n",
" sex | \n",
" age | \n",
" education_num | \n",
" capital_gain | \n",
" capital_loss | \n",
" hours_per_week | \n",
" label | \n",
" label_code | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" State-gov | \n",
" Male | \n",
" 39 | \n",
" 13 | \n",
" 2174 | \n",
" 0 | \n",
" 40 | \n",
" <=50K | \n",
" 0 | \n",
"
\n",
" \n",
" | 1 | \n",
" Self-emp-not-inc | \n",
" Male | \n",
" 50 | \n",
" 13 | \n",
" 0 | \n",
" 0 | \n",
" 13 | \n",
" <=50K | \n",
" 0 | \n",
"
\n",
" \n",
" | 2 | \n",
" Private | \n",
" Male | \n",
" 38 | \n",
" 9 | \n",
" 0 | \n",
" 0 | \n",
" 40 | \n",
" <=50K | \n",
" 0 | \n",
"
\n",
" \n",
" | 3 | \n",
" Private | \n",
" Male | \n",
" 53 | \n",
" 7 | \n",
" 0 | \n",
" 0 | \n",
" 40 | \n",
" <=50K | \n",
" 0 | \n",
"
\n",
" \n",
" | 4 | \n",
" Private | \n",
" Female | \n",
" 28 | \n",
" 13 | \n",
" 0 | \n",
" 0 | \n",
" 40 | \n",
" <=50K | \n",
" 0 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" workclass sex age education_num capital_gain capital_loss \\\n",
"0 State-gov Male 39 13 2174 0 \n",
"1 Self-emp-not-inc Male 50 13 0 0 \n",
"2 Private Male 38 9 0 0 \n",
"3 Private Male 53 7 0 0 \n",
"4 Private Female 28 13 0 0 \n",
"\n",
" hours_per_week label label_code \n",
"0 40 <=50K 0 \n",
"1 13 <=50K 0 \n",
"2 40 <=50K 0 \n",
"3 40 <=50K 0 \n",
"4 40 <=50K 0 "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 将label转换为可以运算的变量\n",
"data.loc[:, \"label_code\"] = pd.Categorical(data.label).codes\n",
"data.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[' Male' ' Female']\n",
"[' State-gov' ' Self-emp-not-inc' ' Private' ' Federal-gov' ' Local-gov'\n",
" ' ?' ' Self-emp-inc' ' Without-pay' ' Never-worked']\n"
]
}
],
"source": [
"print(data[\"sex\"].unique())\n",
"print(data[\"workclass\"].unique())"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"显示sex, label交叉报表:\n",
"sex label \n",
" Female <=50K 9592\n",
" >50K 1179\n",
" Male <=50K 15128\n",
" >50K 6662\n",
"dtype: int64\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# 利用交叉报表,直观了解数据\n",
"import matplotlib.pyplot as plt\n",
"from statsmodels.graphics.mosaicplot import mosaic\n",
"\n",
"\n",
"# 计算sex, label交叉报表\n",
"cross1 = pd.crosstab(data[\"sex\"], data[\"label\"])\n",
"print(\"显示sex, label交叉报表:\")\n",
"print(cross1.stack())\n",
"# 将交叉报表图形化\n",
"props = lambda key: {\"color\": \"0.45\"} if ' >50K' in key else {\"color\": \"#C6E2FF\"}\n",
"mosaic(cross1[[\" >50K\", \" <=50K\"]].stack(), properties=props, axes_label=False)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# 将数据分为训练集和测试集\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"\n",
"train_set, test_set = train_test_split(data, test_size=0.2, random_state=2111)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Warning: Maximum number of iterations has been exceeded.\n",
" Current function value: 0.405259\n",
" Iterations: 35\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/anaconda3/lib/python3.6/site-packages/statsmodels/base/model.py:508: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals\n",
" \"Check mle_retvals\", ConvergenceWarning)\n"
]
}
],
"source": [
"# 训练模型\n",
"import statsmodels.api as sm\n",
"\n",
"\n",
"c_formula = \"label_code ~ C(sex) + C(workclass) + education_num + capital_gain + capital_loss + hours_per_week\"\n",
"c_model = sm.Logit.from_formula(c_formula, data=train_set)\n",
"c_model = c_model.fit()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Logit Regression Results \n",
"==============================================================================\n",
"Dep. Variable: label_code No. Observations: 26048\n",
"Model: Logit Df Residuals: 26034\n",
"Method: MLE Df Model: 13\n",
"Date: Sun, 02 Jun 2019 Pseudo R-squ.: 0.2648\n",
"Time: 20:13:33 Log-Likelihood: -10556.\n",
"converged: False LL-Null: -14359.\n",
" LLR p-value: 0.000\n",
"=====================================================================================================\n",
" coef std err z P>|z| [0.025 0.975]\n",
"-----------------------------------------------------------------------------------------------------\n",
"Intercept -7.6282 0.145 -52.505 0.000 -7.913 -7.343\n",
"C(sex)[T. Male] 1.2558 0.045 27.958 0.000 1.168 1.344\n",
"C(workclass)[T. Federal-gov] 1.0879 0.132 8.223 0.000 0.829 1.347\n",
"C(workclass)[T. Local-gov] 0.6188 0.117 5.288 0.000 0.389 0.848\n",
"C(workclass)[T. Never-worked] -13.7636 1825.543 -0.008 0.994 -3591.762 3564.234\n",
"C(workclass)[T. Private] 0.5003 0.101 4.944 0.000 0.302 0.699\n",
"C(workclass)[T. Self-emp-inc] 1.2942 0.129 10.000 0.000 1.041 1.548\n",
"C(workclass)[T. Self-emp-not-inc] 0.3986 0.116 3.443 0.001 0.172 0.625\n",
"C(workclass)[T. State-gov] 0.4011 0.130 3.084 0.002 0.146 0.656\n",
"C(workclass)[T. Without-pay] -14.3432 1052.727 -0.014 0.989 -2077.649 2048.963\n",
"education_num 0.3286 0.008 41.730 0.000 0.313 0.344\n",
"capital_gain 0.0003 1.08e-05 30.013 0.000 0.000 0.000\n",
"capital_loss 0.0007 3.64e-05 19.958 0.000 0.001 0.001\n",
"hours_per_week 0.0292 0.002 19.288 0.000 0.026 0.032\n",
"=====================================================================================================\n"
]
}
],
"source": [
"# 展示模型结果\n",
"print(c_model.summary())"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0., 0., 0., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 0.],\n",
" [1., 0., 0., 0., 0., 0.],\n",
" [0., 1., 0., 0., 0., 0.],\n",
" [0., 0., 1., 0., 0., 0.],\n",
" [0., 0., 0., 1., 0., 0.],\n",
" [0., 0., 0., 0., 1., 0.],\n",
" [0., 0., 0., 0., 0., 1.]])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 去掉不显著的虚拟变量\n",
"import numpy as np\n",
"\n",
"\n",
"# 定义workclass的类别顺序,数组里的第一个值为基准类别\n",
"l = [\" ?\", \" Never-worked\", \" Without-pay\", \" State-gov\",\n",
" \" Self-emp-not-inc\", \" Private\", \" Federal-gov\",\n",
" \" Local-gov\", \" Self-emp-inc\"]\n",
"# 定义各个类别对应的虚拟变量\n",
"contrast = np.eye(9, 6, k=-3)\n",
"contrast"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"ContrastMatrix(array([[0., 0., 0., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 0.],\n",
" [0., 0., 0., 0., 0., 0.],\n",
" [1., 0., 0., 0., 0., 0.],\n",
" [0., 1., 0., 0., 0., 0.],\n",
" [0., 0., 1., 0., 0., 0.],\n",
" [0., 0., 0., 1., 0., 0.],\n",
" [0., 0., 0., 0., 1., 0.],\n",
" [0., 0., 0., 0., 0., 1.]]),\n",
" [' State-gov',\n",
" ' Self-emp-not-inc',\n",
" ' Private',\n",
" ' Federal-gov',\n",
" ' Local-gov',\n",
" ' Self-emp-inc'])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 为每个虚拟变量命名\n",
"from patsy import ContrastMatrix\n",
"\n",
"\n",
"contrast_mat = ContrastMatrix(contrast, l[3:])\n",
"contrast_mat"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Optimization terminated successfully.\n",
" Current function value: 0.405321\n",
" Iterations 8\n"
]
}
],
"source": [
"# 将不显著的虚拟变量剔除,搭建模型\n",
"m_formula = \"\"\"label_code ~ C(workclass, contrast_mat, levels=l)\n",
" + C(sex) + education_num + capital_gain\n",
" + capital_loss + hours_per_week\"\"\"\n",
"m_model = sm.Logit.from_formula(m_formula, data=train_set)\n",
"m_model = m_model.fit()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Logit Regression Results \n",
"==============================================================================\n",
"Dep. Variable: label_code No. Observations: 26048\n",
"Model: Logit Df Residuals: 26036\n",
"Method: MLE Df Model: 11\n",
"Date: Sun, 02 Jun 2019 Pseudo R-squ.: 0.2647\n",
"Time: 20:13:41 Log-Likelihood: -10558.\n",
"converged: True LL-Null: -14359.\n",
" LLR p-value: 0.000\n",
"=========================================================================================================================\n",
" coef std err z P>|z| [0.025 0.975]\n",
"-------------------------------------------------------------------------------------------------------------------------\n",
"Intercept -7.6422 0.145 -52.624 0.000 -7.927 -7.358\n",
"C(workclass, contrast_mat, levels=l) State-gov 0.4149 0.130 3.193 0.001 0.160 0.670\n",
"C(workclass, contrast_mat, levels=l) Self-emp-not-inc 0.4127 0.116 3.569 0.000 0.186 0.639\n",
"C(workclass, contrast_mat, levels=l) Private 0.5143 0.101 5.090 0.000 0.316 0.712\n",
"C(workclass, contrast_mat, levels=l) Federal-gov 1.1018 0.132 8.335 0.000 0.843 1.361\n",
"C(workclass, contrast_mat, levels=l) Local-gov 0.6327 0.117 5.412 0.000 0.404 0.862\n",
"C(workclass, contrast_mat, levels=l) Self-emp-inc 1.3084 0.129 10.117 0.000 1.055 1.562\n",
"C(sex)[T. Male] 1.2554 0.045 27.948 0.000 1.167 1.343\n",
"education_num 0.3286 0.008 41.738 0.000 0.313 0.344\n",
"capital_gain 0.0003 1.08e-05 30.018 0.000 0.000 0.000\n",
"capital_loss 0.0007 3.64e-05 19.964 0.000 0.001 0.001\n",
"hours_per_week 0.0292 0.002 19.284 0.000 0.026 0.032\n",
"=========================================================================================================================\n"
]
}
],
"source": [
"# 展示模型结果\n",
"print(m_model.summary())"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Optimization terminated successfully.\n",
" Current function value: 0.426517\n",
" Iterations 8\n"
]
}
],
"source": [
"# 搭建不使用类别变量的模型\n",
"b_formula = \"\"\"label_code ~ education_num + capital_gain\n",
" + capital_loss + hours_per_week\"\"\"\n",
"b_model = sm.Logit.from_formula(b_formula, data=train_set)\n",
"b_model = b_model.fit()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" workclass | \n",
" sex | \n",
" age | \n",
" education_num | \n",
" capital_gain | \n",
" capital_loss | \n",
" hours_per_week | \n",
" label | \n",
" label_code | \n",
" b_prob | \n",
" m_prob | \n",
"
\n",
" \n",
" \n",
" \n",
" | 1704 | \n",
" ? | \n",
" Female | \n",
" 22 | \n",
" 10 | \n",
" 0 | \n",
" 0 | \n",
" 35 | \n",
" <=50K | \n",
" 0 | \n",
" 0.127790 | \n",
" 0.034448 | \n",
"
\n",
" \n",
" | 1376 | \n",
" Self-emp-not-inc | \n",
" Male | \n",
" 44 | \n",
" 9 | \n",
" 0 | \n",
" 0 | \n",
" 55 | \n",
" <=50K | \n",
" 0 | \n",
" 0.188333 | \n",
" 0.196298 | \n",
"
\n",
" \n",
" | 14634 | \n",
" Private | \n",
" Female | \n",
" 39 | \n",
" 10 | \n",
" 0 | \n",
" 0 | \n",
" 40 | \n",
" <=50K | \n",
" 0 | \n",
" 0.151123 | \n",
" 0.064593 | \n",
"
\n",
" \n",
" | 21554 | \n",
" Private | \n",
" Female | \n",
" 29 | \n",
" 13 | \n",
" 0 | \n",
" 0 | \n",
" 45 | \n",
" >50K | \n",
" 1 | \n",
" 0.360671 | \n",
" 0.176411 | \n",
"
\n",
" \n",
" | 20959 | \n",
" Private | \n",
" Female | \n",
" 43 | \n",
" 9 | \n",
" 0 | \n",
" 0 | \n",
" 44 | \n",
" <=50K | \n",
" 0 | \n",
" 0.131304 | \n",
" 0.052917 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" workclass sex age education_num capital_gain \\\n",
"1704 ? Female 22 10 0 \n",
"1376 Self-emp-not-inc Male 44 9 0 \n",
"14634 Private Female 39 10 0 \n",
"21554 Private Female 29 13 0 \n",
"20959 Private Female 43 9 0 \n",
"\n",
" capital_loss hours_per_week label label_code b_prob m_prob \n",
"1704 0 35 <=50K 0 0.127790 0.034448 \n",
"1376 0 55 <=50K 0 0.188333 0.196298 \n",
"14634 0 40 <=50K 0 0.151123 0.064593 \n",
"21554 0 45 >50K 1 0.360671 0.176411 \n",
"20959 0 44 <=50K 0 0.131304 0.052917 "
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 得到预测结果\n",
"test_set.loc[:, \"b_prob\"] = b_model.predict(test_set)\n",
"test_set.loc[:, \"m_prob\"] = m_model.predict(test_set)\n",
"test_set.head()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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MsV6XLRoEa1bt8Zms1G5cmWmTp1q7zJFRHIMBVISFi+GrVvhxRfhwQetbWvXrgVg4MCBHDp0CBcX9XiKiGQUDWq4g2vXoEoVa96648ehcGEwTZOKFSvi7u7OkaTWmxARyeU07DuDbdwI58/D2LFWGF26dIkBAwYQFBRE69at7V2eiEiOpDOkJBw+bA333rFjGx07duTixYuULVuWffv2UbhwYXuXJyLikHSGlIGio63H+++HVatW4Ovry8WLF/Hx8VEYiYhkIgXSP/z4I9x7rzWYAWDHDmvF9pEjR7Jjxw6FkYhIJlIg/UN4uDWjt7e39frSpUsAvPDCC/YrSkQkl9A1JKx1jq5csQYwxMWBqyv8+eefVKxYkYIFC3L58mUMw7BbfSIi2YWuIaWDaULNmvD++9bMDK6u1vaAgAAA3njjDYWRiEgWyPVnSCtXQseO1vPTp6FMGeueo0qVKhETE0NwcDDOzs52qU1EJLvRGVI6jB5tPc6fb4URwNatW/nzzz/p0aOHwkhEJIvk6kA6exZ+/90axPDMM7e2L1iwAIBn/rlRREQyVa4OpC1brMcePW5ti46O5uuvv6ZmzZrUrFnTPoWJiORCuTqQ/P2tx549b21bvHgxV65c0dmRiEgWy7WDGmJjoXx5a866hATr/qOEhITEGbzPnDlD6dKls7QmEZHsToMa0mD8eCuMRo+2wmjLli2ULXvrz1BhJCKStXJlIJ05Y83oXaIEDB9ubZs5cyYhISHce++9XLhwwb4FiojkQrm2y27KFChZ0lqaPD4+Htcbd8RGRUXh4eGRpbWIiOQU6emyy3VLnoaHg7s7DB58a5v/jdEN7dq1UxiJiNhJruuy+/RTKFQIDh68te2XX34B4N1337VTVSIikusC6d57oXlza/E9gIsXL7Jo0SJq1apFgwYN7FuciEgulusC6emn4Ycfbk2iumjRIgA6depkx6pERCTXBNKFC9CnD8ycefv2ZcuW4enpybBhw+xTmIiIALkokF55BebOtYLpprNnz7J161bat2+Pp6en3WoTEZFcFEibN1uPb711a9s333yDaZp07drVPkWJiEiiXBFIe/daax35+cE/V5NYtmwZHh4etG/f3n7FiYgIkEsC6cbir7z66q1t586dY/PmzbRr1468efPapzAREUmU4wPJNK1ZGQBq1761ffny5equExFx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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# ROC曲线\n",
"from sklearn import metrics\n",
"\n",
"# 计算b_model的预测效果\n",
"b_fpr, b_tpr, _ = metrics.roc_curve(test_set[\"label_code\"], test_set[\"b_prob\"])\n",
"b_auc = metrics.auc(b_fpr, b_tpr)\n",
"# 计算m_model的预测效果\n",
"m_fpr, m_tpr, _ = metrics.roc_curve(test_set[\"label_code\"], test_set[\"m_prob\"])\n",
"m_auc = metrics.auc(m_fpr, m_tpr)\n",
"# 画图\n",
"fig = plt.figure(figsize=(6, 6), dpi=80)\n",
"# 在图形框里只画一幅图\n",
"ax = fig.add_subplot(1, 1, 1)\n",
"ax.plot(b_fpr, b_tpr, \"k\",\n",
" label=\"%s; %s = %0.4f\" % (\"未使用定性变量的ROC曲线\", \"曲线下面积(AUC)\", b_auc))\n",
"ax.plot(m_fpr, m_tpr, \"b-.\",\n",
" label=\"%s; %s = %0.4f\" % (\"使用定性变量的ROC曲线\", \"曲线下面积(AUC)\", m_auc))\n",
"ax.set_xlim([0, 1])\n",
"ax.set_ylim([0, 1])\n",
"legend = plt.legend(shadow=True)\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}