提交 7155a2fb 编写于 作者: Font Tian's avatar Font Tian

创建项目,准备开始翻译活动

上级
Release Notes
=============
The list of changes for each statsmodels release can be found [here](https://www.statsmodels.org/devel/release/index.html). Full details are available in the [commit logs](https://github.com/statsmodels/statsmodels).
Contributing guidelines
=======================
This page explains how you can contribute to the development of `statsmodels`
by submitting patches, statistical tests, new models, or examples.
`statsmodels` is developed on `Github <https://github.com/statsmodels/statsmodels>`_
using the `Git <http://git-scm.com/>`_ version control system.
Submitting a Bug Report
~~~~~~~~~~~~~~~~~~~~~~~
- Include a short, self-contained code snippet that reproduces the problem
- Specify the statsmodels version used. You can do this with ``sm.version.full_version``
- If the issue looks to involve other dependencies, also include the output of ``sm.show_versions()``
Making Changes to the Code
~~~~~~~~~~~~~~~~~~~~~~~~~~
For a pull request to be accepted, you must meet the below requirements. This greatly helps in keeping the job of maintaining and releasing the software a shared effort.
- **One branch. One feature.** Branches are cheap and github makes it easy to merge and delete branches with a few clicks. Avoid the temptation to lump in a bunch of unrelated changes when working on a feature, if possible. This helps us keep track of what has changed when preparing a release.
- Commit messages should be clear and concise. This means a subject line of less than 80 characters, and, if necessary, a blank line followed by a commit message body. We have an `informal commit format standard <https://www.statsmodels.org/devel/dev/maintainer_notes.html#commit-comments>`_ that we try to adhere to. You can see what this looks like in practice by ``git log --oneline -n 10``. If your commit references or closes a specific issue, you can close it by mentioning it in the `commit message <https://help.github.com/articles/closing-issues-via-commit-messages>`_. (*For maintainers*: These suggestions go for Merge commit comments too. These are partially the record for release notes.)
- Code submissions must always include tests. See our `notes on testing <https://www.statsmodels.org/devel/dev/test_notes.html>`_.
- Each function, class, method, and attribute needs to be documented using docstrings. We conform to the `numpy docstring standard <https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#docstring-standard>`_.
- If you are adding new functionality, you need to add it to the documentation by editing (or creating) the appropriate file in ``docs/source``.
- Make sure your documentation changes parse correctly. Change into the top-level ``docs/`` directory and type::
make clean
make html
Check that the build output does not have *any* warnings due to your changes.
- Finally, please add your changes to the release notes. Open the ``docs/source/release/versionX.X.rst`` file that has the version number of the next release and add your changes to the appropriate section.
How to Submit a Pull Request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So you want to submit a patch to `statsmodels` but aren't too familiar with github? Here are the steps you need to take.
1. `Fork <https://help.github.com/articles/fork-a-repo>`_ the `statsmodels repository <https://github.com/statsmodels/statsmodels>`_ on Github.
2. `Create a new feature branch <http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging>`_. Each branch must be self-contained, with a single new feature or bugfix.
3. Make sure the test suite passes. This includes testing on Python 3. The easiest way to do this is to either enable `Travis-CI <https://travis-ci.org/>`_ on your fork, or to make a pull request and check there.
4. Document your changes by editing the appropriate file in ``docs/source/``. If it is a big, new feature add a note and an example to the latest ``docs/source/release/versionX.X.rst`` file. See older versions for examples. If it's a minor change, it will be included automatically in our relase notes.
5. Add an example. If it is a big, new feature please submit an example notebook by following `these instructions <https://www.statsmodels.org/devel/dev/examples.html>`_.
6. `Submit a pull request <https://help.github.com/articles/using-pull-requests>`_
Mailing List
~~~~~~~~~~~~
Conversations about development take place on the `statsmodels mailing list <http://groups.google.com/group/pystatsmodels?hl=en>`__.
Learn More
~~~~~~~~~~
The ``statsmodels`` documentation's `developer page <https://www.statsmodels.org/stable/dev/index.html>`_
offers much more detailed information about the process.
License
~~~~~~~
Statsmodels is released under the
`Modified (3-clause) BSD license <http://www.opensource.org/licenses/BSD-3-Clause>`_.
The license of statsmodels can be found in LICENSE.txt
statsmodels contains code or derivative code from several other
packages. Some modules also note the author of individual contributions, or
author of code that formed the basis for the derived or translated code.
The copyright statements for the datasets are attached to the individual
datasets, most datasets are in public domain, and we don't claim any copyright
on any of them.
In the following, we collect copyright statements of code from other packages,
all of which are either a version of BSD or MIT licensed:
numpy
scipy
pandas
matplotlib
scikit-learn
qsturng-py http://code.google.com/p/qsturng-py/
numpy (statsmodels.compatnp contains copy of entire model)
----------------------------------------------------------
Copyright (c) 2005-2009, NumPy Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the NumPy Developers nor the names of any
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------
scipy
-----
Copyright (c) 2001, 2002 Enthought, Inc.
All rights reserved.
Copyright (c) 2003-2009 SciPy Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
a. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
b. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
c. Neither the name of the Enthought nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
---------------------------------------------------------------------------
pandas
------
Copyright (c) 2008-2009 AQR Capital Management, LLC
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the copyright holder nor the names of any
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
matplotlib (copied from license.py)
-----------------------------------
LICENSE AGREEMENT FOR MATPLOTLIB %(version)s
--------------------------------------
1. This LICENSE AGREEMENT is between John D. Hunter ("JDH"), and the
Individual or Organization ("Licensee") accessing and otherwise using
matplotlib software in source or binary form and its associated
documentation.
2. Subject to the terms and conditions of this License Agreement, JDH
hereby grants Licensee a nonexclusive, royalty-free, world-wide license
to reproduce, analyze, test, perform and/or display publicly, prepare
derivative works, distribute, and otherwise use matplotlib %(version)s
alone or in any derivative version, provided, however, that JDH's
License Agreement and JDH's notice of copyright, i.e., "Copyright (c)
2002-%(year)d John D. Hunter; All Rights Reserved" are retained in
matplotlib %(version)s alone or in any derivative version prepared by
Licensee.
3. In the event Licensee prepares a derivative work that is based on or
incorporates matplotlib %(version)s or any part thereof, and wants to
make the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to matplotlib %(version)s.
4. JDH is making matplotlib %(version)s available to Licensee on an "AS
IS" basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB %(version)s
WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
%(version)s FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
MATPLOTLIB %(version)s, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between JDH and
Licensee. This License Agreement does not grant permission to use JDH
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using matplotlib %(version)s,
Licensee agrees to be bound by the terms and conditions of this License
Agreement.
--------------------------------------------------------------------------
scikits-learn
-------------
New BSD License
Copyright (c) 2007 - 2010 Scikit-Learn Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
a. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
b. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
c. Neither the name of the Scikit-learn Developers nor the names of
its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
---------------------------------------------------------------------------
qsturng-py (code included in statsmodels.stats.libqsturng)
--------------------------------------------------------------
Copyright (c) 2011, Roger Lew [see LICENSE.txt]
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the organizations affiliated with the
contributors or the names of its contributors themselves may be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------
Dependencies
------------
python >= 2.7
www.python.org
numpy >= 1.11
www.numpy.org
scipy >= 0.18
www.scipy.org
pandas >= 0.19
pandas.pydata.org
patsy >= 0.4.0
patsy.readthedocs.org
cython >= 0.24
http://cython.org/
Cython is required if you are building the source from github. However,
if you have are building from source distribution archive then the
generated C files are included and Cython is not necessary. If you are
building for Python 3.4, then you must use Cython >= 0.24. Earlier
versions may be ok for earlier versions of Python.
Optional Dependencies
---------------------
X-12-ARIMA or X-13ARIMA-SEATS
http://www.census.gov/srd/www/x13as/
If available, time-series analysis can be conducted using either
X-12-ARIMA or the newer X-13ARIMA-SEATS. You should place the
appropriate executable on your PATH or set the X12PATH or X13PATH
environmental variable to take advantage.
matplotlib >= 1.5
http://matplotlib.org/
Matplotlib is needed for plotting functionality and running many of the
examples.
sphinx >= 1.3
http://sphinx.pocoo.org/
Sphinx is used to build the documentation.
pytest >= 3.0
http://readthedocs.org/docs/pytest/en/latest/
Pytest is needed to run the tests.
IPython >= 3.0
Needed to build the docs.
Installing
----------
To get the latest release using pip
pip install statsmodels --upgrade-strategy only-if-needed
The additional parameter pip --upgrade-strategy only-if-needed will ensure
that dependencies, e.g. NumPy or pandas, are not upgraded unless required.
Ubuntu/Debian
-------------
On Ubuntu you can get dependencies through:
sudo apt-get install python python-dev python-setuptools python-numpy python-scipy
pip install cython pandas
Alternatively, you can install from the NeuroDebian repository:
http://neuro.debian.net
Installing from Source
----------------------
Download and extract the source distribution from PyPI or github
http://pypi.python.org/pypi/statsmodels
https://github.com/statsmodels/statsmodels/tags
Or clone the bleeding edge code from our repository on github at
git clone git://github.com/statsmodels/statsmodels.git
In the statsmodels directory do (with proper permissions)
python setup.py install
You will need a C compiler installed.
Installing from Source on Windows
---------------------------------
See https://www.statsmodels.org/devel/install.html#windows.
Documentation
-------------
You may find more information about the project and installation in our
documentation
https://www.statsmodels.org/devel/install.html
Copyright (C) 2006, Jonathan E. Taylor
All rights reserved.
Copyright (c) 2006-2008 Scipy Developers.
All rights reserved.
Copyright (c) 2009-2018 Statsmodels Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
a. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
b. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
c. Neither the name of Statsmodels nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL STATSMODELS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
## 这是什么?
这是由ApacheCN翻译的Statsmodels的中文文档
## Statsmodels是什么?
Statsmodels是一个Python包,为统计计算的scipy提供补充,包括描述性统计和统计模型的估计和推断。
### 英文文档
最新的稳定版文档位于
[https://www.statsmodels.org/stable/](https://www.statsmodels.org/stable/)
开发版文档位于
[https://www.statsmodels.org/dev/](https://www.statsmodels.org/dev/)
Recent improvements are highlighted in the release notes
[https://www.statsmodels.org/stable/release/version0.9.html](https://www.statsmodels.org/stable/release/version0.9.html)
有关文档的备份请访问-[https://statsmodels.github.io/stable/](https://statsmodels.github.io/stable/)
[https://statsmodels.github.io/dev/](https://statsmodels.github.io/dev/).
### 主要内容
- 线性回归模型:
- 普通最小二乘
- 广义最小二乘法
- 加权最小二乘法
- 具有自回归误差的最小二乘法
- 分位数回归
- 递归最小二乘法
- 具有混合效应和方差分量的混合线性模型
- GLM:支持所有单参数指数族分布的广义线性模型
- 用于二项式和泊松的贝叶斯混合GLM
- GEE:单向聚类或纵向数据的广义估计方程
- 离散模型:
- Logit和Probit
- 多项logit(MNLogit)
- 泊松和广义Poisson回归
- 负二项式回归
- 零膨胀计数模型
- RLM:强大的线性模型,支持多个M估计器。
- 时间序列分析:时间序列分析模型
- 完成StateSpace建模框架
- 季节性ARIMA和ARIMAX模型
- VARMA和VARMAX型号
- 动态因子模型
- 未观察到的组件模型
- 马尔可夫切换模型(MSAR),也称为隐马尔可夫模型(HMM)
- 单变量时间序列分析:AR,ARIMA
- 矢量自回归模型,VAR和结构VAR
- 矢量误差修正模型,VECM
- 指数平滑,Holt-Winters
- 时间序列的假设检验:单位根,协整等
- 时间序列分析的描述性统计和过程模型
- 生存分析:
- 比例风险回归(Cox模型)
- 幸存者函数估计(Kaplan-Meier)
- 累积发生率函数估计
- 多因素:
- 缺少数据的主成分分析
- 旋转因子分析
- MANOVA
- 典型相关
- 非参数统计:单变量和多变量核密度估计
- 数据集:用于示例和测试的数据集
- 统计:广泛的统计测试
- 诊断和规范测试
- 拟合优度和正态性测试
- 用于多个测试的功能
- 各种额外的统计测试
- MICE估算,秩序统计回归和高斯插补
- 调解分析
- 图形包括用于数据和模型结果的可视分析的绘图功能
- I / O
- 用于读取Stata .dta文件的工具,但是pandas具有更新版本
- 表输出为ascii,latex和html
- Miscellaneous models(各种各样的模型)
- Sandbox:statsmodels包含一个沙箱文件夹,其中的代码处于开发和测试的各个阶段,不被视为“生产就绪”。这包括其中之一
- 广义矩量法(GMM)估计量
- 核回归
- scipy.stats.distributions的各种扩展
- 面板数据模型
- 信息理论措施
## ApacheCN是什么?
* 主页:[apachecn.org](http://www.apachecn.org)
* Github:[@ApacheCN](https://github.com/apachecn)
* 社区:[community.apachecn.org](http://community.apachecn.org)
* 知识库:[cwiki.apachecn.org](http://cwiki.apachecn.org/)
* 自媒体平台:
* [微博:@ApacheCN](https://weibo.com/u/6326715527)
* [知乎:@ApacheCN](https://www.zhihu.com/people/apachecn)
* [CSDN](https://blog.csdn.net/wizardforcel/article/category/8437073)[简书](https://www.jianshu.com/c/4ee721d0c474)[OSChina](https://my.oschina.net/repine/)[博客园](https://www.cnblogs.com/wizardforcel/category/1352397.html)
* **我们不是 Apache 的官方组织/机构/团体,只是 Apache 技术栈(以及 AI)的爱好者!**
* 如有侵权,请联系邮箱:【片刻】<jiang-s@163.com>(如果需要合作,也可以私聊我)
## 参与翻译 & 发现错误
1. 在 github 上 fork 该 repository.
2. 翻译 doc/zh/source 或者根目录 下面的 rst或txt 文件即可, 例如, gettingstarted.rst.
3. 然后, 在你的 github 发起 New pull request 请求.
## 角色分配
目前有如下可分配的角色:
* 翻译: 负责文章内容的翻译.
* 校验: 负责文章内容的校验, 比如格式, 正确度之类的.
* 负责人: 负责整个 Projcet
有兴趣参与的朋友, 可以看看最后的联系方式.
## Statsmodels负责人
* [@FontTian](https://github.com/FontTian)(Font Tian)
## 贡献者
贡献者可自行编辑如下内容(排名不分先后).
### Statsmodels-0.9
**翻译者(人人皆大佬~):**
* [@FontTian](https://github.com/FontTian)(Font Tian)
## 联系方式
有任何建议反馈, 或想参与文档翻译, 麻烦联系下面的企鹅:
* 企鹅: 2404846224((FontTian)
## 其它中文文档
1. [sklearn 中文文档](https://github.com/apachecn/scikit-learn-doc-zh)
2. [pytorch 0.3 中文文档](https://github.com/apachecn/pytorch-doc-zh)
3. [TensorFlow R1.2 中文文档](http://cwiki.apachecn.org/pages/viewpage.action?pageId=10030122)
4. [xgboost 中文文档](https://github.com/apachecn/xgboost-doc-zh)
5. [lightgbm 中文文档](https://github.com/apachecn/lightgbm-doc-zh)
6. [fasttext 中文文档](https://github.com/apachecn/fasttext-doc-zh)
7. [gensim 中文文档](https://github.com/apachecn/gensim-doc-zh)
1. [Spark 中文文档](https://github.com/apachecn/spark-doc-zh)
2. [Storm 中文文档](https://github.com/apachecn/storm-doc-zh)
3. [Kafka 中文文档](https://github.com/apachecn/kafka-doc-zh)
4. [Flink 中文文档](https://github.com/apachecn/flink-doc-zh)
5. [Beam 中文文档](https://github.com/apachecn/beam-site-zh)
6. [Zeppelin 0.7.2 中文文档](https://github.com/apachecn/zeppelin-doc-zh)
7. [Elasticsearch 5.4 中文文档](https://github.com/apachecn/elasticsearch-doc-zh)
8. [Kibana 5.2 中文文档](https://github.com/apachecn/kibana-doc-zh)
9. [Kudu 1.4.0 中文文档](https://github.com/apachecn/kudu-doc-zh)
0. [Spring Boot 1.5.2 中文文档](https://github.com/apachecn/spring-boot-doc-zh)
1. [Airflow 中文文档](https://github.com/apachecn/airflow-doc-zh)
1. [Solidity 中文文档](https://github.com/apachecn/solidity-doc-zh)
1. [numpy 中文文档](https://github.com/apachecn/numpy-ref-zh)
1. [pandas 中文文档](https://github.com/apachecn/pandas-doc-zh)
1. [matplotlib 中文文档](https://github.com/apachecn/matplotlib-user-guide-zh)
1. 等等
\ No newline at end of file
|Travis Build Status| |Appveyor Build Status| |Coveralls Coverage|
About Statsmodels
=================
Statsmodels is a Python package that provides a complement to scipy for
statistical computations including descriptive statistics and estimation
and inference for statistical models.
Documentation
=============
The documentation for the latest release is at
https://www.statsmodels.org/stable/
The documentation for the development version is at
https://www.statsmodels.org/dev/
Recent improvements are highlighted in the release notes
https://www.statsmodels.org/stable/release/version0.9.html
Backups of documentation are available at https://statsmodels.github.io/stable/
and https://statsmodels.github.io/dev/.
Main Features
=============
* Linear regression models:
- Ordinary least squares
- Generalized least squares
- Weighted least squares
- Least squares with autoregressive errors
- Quantile regression
- Recursive least squares
* Mixed Linear Model with mixed effects and variance components
* GLM: Generalized linear models with support for all of the one-parameter
exponential family distributions
* Bayesian Mixed GLM for Binomial and Poisson
* GEE: Generalized Estimating Equations for one-way clustered or longitudinal data
* Discrete models:
- Logit and Probit
- Multinomial logit (MNLogit)
- Poisson and Generalized Poisson regression
- Negative Binomial regression
- Zero-Inflated Count models
* RLM: Robust linear models with support for several M-estimators.
* Time Series Analysis: models for time series analysis
- Complete StateSpace modeling framework
- Seasonal ARIMA and ARIMAX models
- VARMA and VARMAX models
- Dynamic Factor models
- Unobserved Component models
- Markov switching models (MSAR), also known as Hidden Markov Models (HMM)
- Univariate time series analysis: AR, ARIMA
- Vector autoregressive models, VAR and structural VAR
- Vector error correction modle, VECM
- exponential smoothing, Holt-Winters
- Hypothesis tests for time series: unit root, cointegration and others
- Descriptive statistics and process models for time series analysis
* Survival analysis:
- Proportional hazards regression (Cox models)
- Survivor function estimation (Kaplan-Meier)
- Cumulative incidence function estimation
* Multivariate:
- Principal Component Analysis with missing data
- Factor Analysis with rotation
- MANOVA
- Canonical Correlation
* Nonparametric statistics: Univariate and multivariate kernel density estimators
* Datasets: Datasets used for examples and in testing
* Statistics: a wide range of statistical tests
- diagnostics and specification tests
- goodness-of-fit and normality tests
- functions for multiple testing
- various additional statistical tests
* Imputation with MICE, regression on order statistic and Gaussian imputation
* Mediation analysis
* Graphics includes plot functions for visual analysis of data and model results
* I/O
- Tools for reading Stata .dta files, but pandas has a more recent version
- Table output to ascii, latex, and html
* Miscellaneous models
* Sandbox: statsmodels contains a sandbox folder with code in various stages of
developement and testing which is not considered "production ready". This covers
among others
- Generalized method of moments (GMM) estimators
- Kernel regression
- Various extensions to scipy.stats.distributions
- Panel data models
- Information theoretic measures
How to get it
=============
The master branch on GitHub is the most up to date code
https://www.github.com/statsmodels/statsmodels
Source download of release tags are available on GitHub
https://github.com/statsmodels/statsmodels/tags
Binaries and source distributions are available from PyPi
https://pypi.org/project/statsmodels/
Binaries can be installed in Anaconda
conda install statsmodels
Installing from sources
=======================
See INSTALL.txt for requirements or see the documentation
https://statsmodels.github.io/dev/install.html
License
=======
Modified BSD (3-clause)
Discussion and Development
==========================
Discussions take place on our mailing list.
http://groups.google.com/group/pystatsmodels
We are very interested in feedback about usability and suggestions for
improvements.
Bug Reports
===========
Bug reports can be submitted to the issue tracker at
https://github.com/statsmodels/statsmodels/issues
.. |Travis Build Status| image:: https://travis-ci.org/statsmodels/statsmodels.svg?branch=master
:target: https://travis-ci.org/statsmodels/statsmodels
.. |Appveyor Build Status| image:: https://ci.appveyor.com/api/projects/status/gx18sd2wc63mfcuc/branch/master?svg=true
:target: https://ci.appveyor.com/project/josef-pkt/statsmodels/branch/master
.. |Coveralls Coverage| image:: https://coveralls.io/repos/github/statsmodels/statsmodels/badge.svg?branch=master
:target: https://coveralls.io/github/statsmodels/statsmodels?branch=master
What the l1 addition is
=======================
A slight modification that allows l1 regularized LikelihoodModel.
Regularization is handled by a fit_regularized method.
Main Files
==========
l1_demo/demo.py
$ python demo.py --get_l1_slsqp_results logit
does a quick demo of the regularization using logistic regression.
l1_demo/sklearn_compare.py
$ python sklearn_compare.py
Plots a comparison of regularization paths. Modify the source to use
different datasets.
statsmodels/base/l1_cvxopt.py
fit_l1_cvxopt_cp()
Fit likelihood model using l1 regularization. Use the CVXOPT package.
Lots of small functions supporting fit_l1_cvxopt_cp
statsmodels/base/l1_slsqp.py
fit_l1_slsqp()
Fit likelihood model using l1 regularization. Use scipy.optimize
Lots of small functions supporting fit_l1_slsqp
statsmodels/base/l1_solvers_common.py
Common methods used by l1 solvers
statsmodels/base/model.py
Likelihoodmodel.fit()
3 lines modified to allow for importing and calling of l1 fitting functions
statsmodels/discrete/discrete_model.py
L1MultinomialResults class
Child of MultinomialResults
MultinomialModel.fit()
3 lines re-directing l1 fit results to the L1MultinomialResults class
此差异已折叠。
文件已添加
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = statsmodels
SOURCEDIR = source
BUILDDIR = build
PAPER =
TOOLSPATH = ../tools/
DATASETBUILD = dataset_rst.py
EXAMPLEBUILD = examples_rst.py
NOTEBOOKBUILD = nbgenerate.py
FOLDTOC = fold_toc.py
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(ALLSPHINXOPTS) $(O)
.PHONY: help Makefile
cleanall:
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(ALLSPHINXOPTS) $(O)
-rm source/examples/generated/*
-rm -rf source/examples/notebooks/generated/*
-rm -rf ../tools/hash_dict.pickle
-rm -rf source/datasets/generated/*
notebooks:
@echo "Generating notebooks from examples/notebooks folder"
$(TOOLSPATH)$(NOTEBOOKBUILD) --execute=True --allow_errors=True
html:
# make directories for images
@echo "Make static directory for images"
mkdir -p $(BUILDDIR)/html/_static
# generate the examples rst files
@echo "Generating reST from examples folder"
#$(TOOLSPATH)$(EXAMPLEBUILD)
@echo "Generating datasets from installed statsmodels.datasets"
$(TOOLSPATH)$(DATASETBUILD)
@echo "Generating notebooks from examples/notebooks folder"
$(TOOLSPATH)$(NOTEBOOKBUILD) --parallel --report-errors --skip-existing
@echo "Running sphinx-build"
@echo @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(ALLSPHINXOPTS) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(ALLSPHINXOPTS) $(O)
@echo "Copying rendered example notebooks"
mkdir -p $(BUILDDIR)/html/examples/notebooks/generated
cp source/examples/notebooks/generated/*html $(BUILDDIR)/html/examples/notebooks/generated
@echo $(TOOLSPATH)$(FOLDTOC) $(BUILDDIR)/html/index.html
$(TOOLSPATH)$(FOLDTOC) $(BUILDDIR)/html/index.html
@echo $(TOOLSPATH)$(FOLDTOC) $(BUILDDIR)/html/dev/index.html ../_static
$(TOOLSPATH)$(FOLDTOC) $(BUILDDIR)/html/dev/index.html ../_static
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(ALLSPHINXOPTS) $(O)
# Documentation Documentation
We use a combination of sphinx and Jupyter notebooks for the documentation.
Jupyter notebooks should be used for longer, self-contained examples demonstrating
a topic.
Sphinx is nice because we get the tables of contents and API documentation.
## Build Process
Building the docs requires a few additional dependencies. You can get most
of these with
```bash
pip install -e .[docs]
```
From the root of the project.
Some of the examples rely on `rpy2` to execute R code from the notebooks.
It's not included in the setup requires since it's known to be difficult to
install.
To generate the HTML docs, run ``make html`` from the ``docs`` directory.
This executes a few distinct builds
1. datasets
2. notebooks
3. sphinx
# Notebook Builds
We're using `nbconvert` to execute the notebooks, and then convert them
to HTML. The conversion is handled by `statsmodels/tools/nbgenerate.py`.
The default python kernel (embedded in the notebook) is `python3`.
You need at least `nbconvert==4.2.0` to specify a non-default kernel,
which can be passed in the Makefile.
#!/usr/bin/env python
import sys
import os
BUILDDIR = sys.argv[-1]
read_file_path = os.path.join(BUILDDIR,'latex','statsmodels.tex')
write_file_path = os.path.join(BUILDDIR, 'latex','statsmodels_tmp.tex')
read_file = open(read_file_path,'r')
write_file = open(write_file_path, 'w')
for line in read_file:
if 'longtable}{LL' in line:
line = line.replace('longtable}{LL', 'longtable}{|l|l|')
write_file.write(line)
read_file.close()
write_file.close()
os.remove(read_file_path)
os.rename(write_file_path, read_file_path)
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
set SPHINXPROJ=statsmodels
set SPHINXOPTS=-j auto
set TOOLSPATH=../tools
set DATASETBUILD=dataset_rst.py
set NOTEBOOKBUILD=nbgenerate.py
set FOLDTOC=fold_toc.py
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
if "%1" == "html" (
echo mkdir %BUILDDIR%\html\_static
mkdir %BUILDDIR%\html\_static
echo python %TOOLSPATH%/%NOTEBOOKBUILD% --parallel --report-errors --skip-existing
python %TOOLSPATH%/%NOTEBOOKBUILD% --parallel --report-errors --skip-existing
echo python %TOOLSPATH%/%DATASETBUILD%
python %TOOLSPATH%/%DATASETBUILD%
)
echo %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
if errorlevel 1 exit /b 1
if "%1" == "html" (
echo xcopy /s source/examples/notebooks/generated/*.html %BUILDDIR%/html/examples/notebooks/generated
xcopy /s source/examples/notebooks/generated/*.html %BUILDDIR%/html/examples/notebooks/generated
echo python %TOOLSPATH%/%FOLDTOC% %BUILDDIR%/html/index.html
python %TOOLSPATH%/%FOLDTOC% %BUILDDIR%/html/index.html
echo python %TOOLSPATH%/%FOLDTOC% %BUILDDIR%/html/examples/index.html ../_static
python %TOOLSPATH%/%FOLDTOC% %BUILDDIR%/html/examples/index.html ../_static
echo python %TOOLSPATH%/%FOLDTOC% %BUILDDIR%/html/dev/index.html ../_static
python %TOOLSPATH%/%FOLDTOC% %BUILDDIR%/html/dev/index.html ../_static
if NOT EXIST %BUILDDIR%/html/examples/notebooks/generated mkdir %BUILDDIR%\html\examples\notebooks\generated
)
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
.examples-page {
/*override div.body padding of 30px */
margin-left: -30px;
margin-right: -30px;
}
.examples-page .padleft {
padding-left: 30px;
}
.examples-page h1, .examples-page h2, .examples-page h3 {
padding-left: 30px; /* to make up for margin above */
}
.examples-page .toclist {
list-style:none;
margin-bottom:0px;
margin-top:0px;
}
/* Marketing section of Overview
-------------------------------------------------- */
.marketing p {
margin-right: 10px;
}
/* Eaxmples page
------------------------- */
.thumbnail {
margin-bottom: 9px;
background-color: #fff;
}
/* Example sites showcase */
.example-sites img {
max-width: 100%;
margin: 0 auto;
}
.marketing-byline {
font-size: 18px;
font-weight: 300;
line-height: 24px;
color: #999;
text-align: center;
}
/* From bootstrap.css */
.thumbnails {
margin-left: -20px;
list-style: none;
*zoom: 1;
}
.thumbnails:before,
.thumbnails:after {
display: table;
line-height: 0;
content: "";
}
.thumbnails:after {
clear: both;
}
.row-fluid .thumbnails {
margin-left: 0;
}
.thumbnails > li {
float: left;
margin-bottom: 20px;
margin-left: 20px;
}
.thumbnail {
display: block;
padding: 4px;
line-height: 20px;
border: 1px solid #ddd;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
a.thumbnail:hover,
a.thumbnail:focus {
border-color: #0088cc;
-webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
-moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
}
.thumbnail > img {
display: block;
width: 360px;
max-width: 100%;
height: auto;
margin-right: auto;
margin-left: auto;
}
.thumbnail .caption {
padding: 9px;
color: #555555;
}
#facebox {
position: absolute;
top: 0;
left: 0;
z-index: 100;
text-align: left;
}
#facebox .popup{
position:relative;
border:3px solid rgba(0,0,0,0);
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius:5px;
-webkit-box-shadow:0 0 18px rgba(0,0,0,0.4);
-moz-box-shadow:0 0 18px rgba(0,0,0,0.4);
box-shadow:0 0 18px rgba(0,0,0,0.4);
}
#facebox .content {
display:table;
width: 370px;
padding: 10px;
background: #fff;
-webkit-border-radius:4px;
-moz-border-radius:4px;
border-radius:4px;
}
#facebox .content > p:first-child{
margin-top:0;
}
#facebox .content > p:last-child{
margin-bottom:0;
}
#facebox .close{
position:absolute;
top:5px;
right:5px;
padding:2px;
background:#fff;
}
#facebox .close img{
opacity:0.3;
}
#facebox .close:hover img{
opacity:1.0;
}
#facebox .loading {
text-align: center;
}
#facebox .image {
text-align: center;
}
#facebox img {
border: 0;
margin: 0;
}
#facebox_overlay {
position: fixed;
top: 0px;
left: 0px;
height:100%;
width:100%;
}
.facebox_hide {
z-index:-100;
}
.facebox_overlayBG {
background-color: #000;
z-index: 99;
}
\ No newline at end of file
/*
* Facebox (for jQuery)
* version: 1.3
* @requires jQuery v1.2 or later
* @homepage https://github.com/defunkt/facebox
*
* Licensed under the MIT:
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright Forever Chris Wanstrath, Kyle Neath
*
* Usage:
*
* jQuery(document).ready(function() {
* jQuery('a[rel*=facebox]').facebox()
* })
*
* <a href="#terms" rel="facebox">Terms</a>
* Loads the #terms div in the box
*
* <a href="terms.html" rel="facebox">Terms</a>
* Loads the terms.html page in the box
*
* <a href="terms.png" rel="facebox">Terms</a>
* Loads the terms.png image in the box
*
*
* You can also use it programmatically:
*
* jQuery.facebox('some html')
* jQuery.facebox('some html', 'my-groovy-style')
*
* The above will open a facebox with "some html" as the content.
*
* jQuery.facebox(function($) {
* $.get('blah.html', function(data) { $.facebox(data) })
* })
*
* The above will show a loading screen before the passed function is called,
* allowing for a better ajaxy experience.
*
* The facebox function can also display an ajax page, an image, or the contents of a div:
*
* jQuery.facebox({ ajax: 'remote.html' })
* jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
* jQuery.facebox({ image: 'stairs.jpg' })
* jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
* jQuery.facebox({ div: '#box' })
* jQuery.facebox({ div: '#box' }, 'my-groovy-style')
*
* Want to close the facebox? Trigger the 'close.facebox' document event:
*
* jQuery(document).trigger('close.facebox')
*
* Facebox also has a bunch of other hooks:
*
* loading.facebox
* beforeReveal.facebox
* reveal.facebox (aliased as 'afterReveal.facebox')
* init.facebox
* afterClose.facebox
*
* Simply bind a function to any of these hooks:
*
* $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
*
*/
(function($) {
$.facebox = function(data, klass) {
$.facebox.loading(data.settings || [])
if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
else if (data.image) fillFaceboxFromImage(data.image, klass)
else if (data.div) fillFaceboxFromHref(data.div, klass)
else if ($.isFunction(data)) data.call($)
else $.facebox.reveal(data, klass)
}
/*
* Public, $.facebox methods
*/
$.extend($.facebox, {
settings: {
opacity : 0.2,
overlay : true,
loadingImage : '/facebox/loading.gif',
closeImage : '/facebox/closelabel.png',
imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ],
faceboxHtml : '\
<div id="facebox" style="display:none;"> \
<div class="popup"> \
<div class="content"> \
</div> \
<a href="#" class="close"></a> \
</div> \
</div>'
},
loading: function() {
init()
if ($('#facebox .loading').length == 1) return true
showOverlay()
$('#facebox .content').empty().
append('<div class="loading"><img src="'+$.facebox.settings.loadingImage+'"/></div>')
$('#facebox').show().css({
top: getPageScroll()[1] + (getPageHeight() / 10),
left: $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2)
})
$(document).bind('keydown.facebox', function(e) {
if (e.keyCode == 27) $.facebox.close()
return true
})
$(document).trigger('loading.facebox')
},
reveal: function(data, klass) {
$(document).trigger('beforeReveal.facebox')
if (klass) $('#facebox .content').addClass(klass)
$('#facebox .content').empty().append(data)
$('#facebox .popup').children().fadeIn('normal')
$('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2))
$(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
},
close: function() {
$(document).trigger('close.facebox')
return false
}
})
/*
* Public, $.fn methods
*/
$.fn.facebox = function(settings) {
if ($(this).length == 0) return
init(settings)
function clickHandler() {
$.facebox.loading(true)
// support for rel="facebox.inline_popup" syntax, to add a class
// also supports deprecated "facebox[.inline_popup]" syntax
var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
if (klass) klass = klass[1]
fillFaceboxFromHref(this.href, klass)
return false
}
return this.bind('click.facebox', clickHandler)
}
/*
* Private methods
*/
// called one time to setup facebox on this page
function init(settings) {
if ($.facebox.settings.inited) return true
else $.facebox.settings.inited = true
$(document).trigger('init.facebox')
makeCompatible()
var imageTypes = $.facebox.settings.imageTypes.join('|')
$.facebox.settings.imageTypesRegexp = new RegExp('\\.(' + imageTypes + ')(\\?.*)?$', 'i')
if (settings) $.extend($.facebox.settings, settings)
$('body').append($.facebox.settings.faceboxHtml)
var preload = [ new Image(), new Image() ]
preload[0].src = $.facebox.settings.closeImage
preload[1].src = $.facebox.settings.loadingImage
$('#facebox').find('.b:first, .bl').each(function() {
preload.push(new Image())
preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
})
$('#facebox .close')
.click($.facebox.close)
.append('<img src="'
+ $.facebox.settings.closeImage
+ '" class="close_image" title="close">')
}
// getPageScroll() by quirksmode.com
function getPageScroll() {
var xScroll, yScroll;
if (self.pageYOffset) {
yScroll = self.pageYOffset;
xScroll = self.pageXOffset;
} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
yScroll = document.documentElement.scrollTop;
xScroll = document.documentElement.scrollLeft;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
xScroll = document.body.scrollLeft;
}
return new Array(xScroll,yScroll)
}
// Adapted from getPageSize() by quirksmode.com
function getPageHeight() {
var windowHeight
if (self.innerHeight) { // all except Explorer
windowHeight = self.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
windowHeight = document.documentElement.clientHeight;
} else if (document.body) { // other Explorers
windowHeight = document.body.clientHeight;
}
return windowHeight
}
// Backwards compatibility
function makeCompatible() {
var $s = $.facebox.settings
$s.loadingImage = $s.loading_image || $s.loadingImage
$s.closeImage = $s.close_image || $s.closeImage
$s.imageTypes = $s.image_types || $s.imageTypes
$s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
}
// Figures out what you want to display and displays it
// formats are:
// div: #id
// image: blah.extension
// ajax: anything else
function fillFaceboxFromHref(href, klass) {
// div
if (href.match(/#/)) {
var url = window.location.href.split('#')[0]
var target = href.replace(url,'')
if (target == '#') return
$.facebox.reveal($(target).html(), klass)
// image
} else if (href.match($.facebox.settings.imageTypesRegexp)) {
fillFaceboxFromImage(href, klass)
// ajax
} else {
fillFaceboxFromAjax(href, klass)
}
}
function fillFaceboxFromImage(href, klass) {
var image = new Image()
image.onload = function() {
$.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
}
image.src = href
}
function fillFaceboxFromAjax(href, klass) {
$.facebox.jqxhr = $.get(href, function(data) { $.facebox.reveal(data, klass) })
}
function skipOverlay() {
return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
}
function showOverlay() {
if (skipOverlay()) return
if ($('#facebox_overlay').length == 0)
$("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')
$('#facebox_overlay').hide().addClass("facebox_overlayBG")
.css('opacity', $.facebox.settings.opacity)
.click(function() { $(document).trigger('close.facebox') })
.fadeIn(200)
return false
}
function hideOverlay() {
if (skipOverlay()) return
$('#facebox_overlay').fadeOut(200, function(){
$("#facebox_overlay").removeClass("facebox_overlayBG")
$("#facebox_overlay").addClass("facebox_hide")
$("#facebox_overlay").remove()
})
return false
}
/*
* Bindings
*/
$(document).bind('close.facebox', function() {
if ($.facebox.jqxhr) {
$.facebox.jqxhr.abort()
$.facebox.jqxhr = null
}
$(document).unbind('keydown.facebox')
$('#facebox').fadeOut(function() {
$('#facebox .content').removeClass().addClass('content')
$('#facebox .loading').remove()
$(document).trigger('afterClose.facebox')
})
hideOverlay()
})
})(jQuery);
此差异已折叠。
/* Put this inside a @media qualifier so Netscape 4 ignores it */
@media screen, print {
/* Turn off list bullets */
ul.mktree li { list-style: none; }
/* Control how "spaced out" the tree is */
ul.mktree, ul.mktree ul , ul.mktree li { margin-left:10px; padding:0px; }
/* Provide space for our own "bullet" inside the LI */
ul.mktree li .bullet { padding-left: 15px; }
/* Show "bullets" in the links, depending on the class of the LI that the link's in */
ul.mktree li.liOpen .bullet { cursor: pointer; background: url(minus.gif) center left no-repeat; }
ul.mktree li.liClosed .bullet { cursor: pointer; background: url(plus.gif) center left no-repeat; }
ul.mktree li.liBullet .bullet { cursor: default; background: url(bullet.gif) center left no-repeat; }
/* Sublists are visible or not based on class of parent LI */
ul.mktree li.liOpen ul { display: block; }
ul.mktree li.liClosed ul { display: none; }
/* Format menu items differently depending on what level of the tree they are in */
/* Uncomment this if you want your fonts to decrease in size the deeper they are in the tree */
/*
ul.mktree li ul li { font-size: 90% }
*/
}
/**
* Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
*
* Dual licensed under the MIT and GPL licenses.
* This basically means you can use this code however you want for
* free, but don't claim to have written it yourself!
* Donations always accepted: http://www.JavascriptToolbox.com/donate/
*
* Please do not link to the .js files on javascripttoolbox.com from
* your site. Copy the files locally to your server instead.
*
*/
/*
This code is inspired by and extended from Stuart Langridge's aqlist code:
http://www.kryogenix.org/code/browser/aqlists/
Stuart Langridge, November 2002
sil@kryogenix.org
Inspired by Aaron's labels.js (http://youngpup.net/demos/labels/)
and Dave Lindquist's menuDropDown.js (http://www.gazingus.org/dhtml/?id=109)
*/
// Automatically attach a listener to the window onload, to convert the trees
addEvent(window,"load",convertTrees);
// Utility function to add an event listener
function addEvent(o,e,f){
if (o.addEventListener){ o.addEventListener(e,f,false); return true; }
else if (o.attachEvent){ return o.attachEvent("on"+e,f); }
else { return false; }
}
// utility function to set a global variable if it is not already set
function setDefault(name,val) {
if (typeof(window[name])=="undefined" || window[name]==null) {
window[name]=val;
}
}
// Full expands a tree with a given ID
function expandTree(treeId) {
var ul = document.getElementById(treeId);
if (ul == null) { return false; }
expandCollapseList(ul,nodeOpenClass);
}
// Fully collapses a tree with a given ID
function collapseTree(treeId) {
var ul = document.getElementById(treeId);
if (ul == null) { return false; }
expandCollapseList(ul,nodeClosedClass);
}
// Expands enough nodes to expose an LI with a given ID
function expandToItem(treeId,itemId) {
var ul = document.getElementById(treeId);
if (ul == null) { return false; }
var ret = expandCollapseList(ul,nodeOpenClass,itemId);
if (ret) {
var o = document.getElementById(itemId);
if (o.scrollIntoView) {
o.scrollIntoView(false);
}
}
}
// Performs 3 functions:
// a) Expand all nodes
// b) Collapse all nodes
// c) Expand all nodes to reach a certain ID
function expandCollapseList(ul,cName,itemId) {
if (!ul.childNodes || ul.childNodes.length==0) { return false; }
// Iterate LIs
for (var itemi=0;itemi<ul.childNodes.length;itemi++) {
var item = ul.childNodes[itemi];
if (itemId!=null && item.id==itemId) { return true; }
if (item.nodeName == "LI") {
// Iterate things in this LI
var subLists = false;
for (var sitemi=0;sitemi<item.childNodes.length;sitemi++) {
var sitem = item.childNodes[sitemi];
if (sitem.nodeName=="UL") {
subLists = true;
var ret = expandCollapseList(sitem,cName,itemId);
if (itemId!=null && ret) {
item.className=cName;
return true;
}
}
}
if (subLists && itemId==null) {
item.className = cName;
}
}
}
}
// Search the document for UL elements with the correct CLASS name, then process them
function convertTrees() {
setDefault("treeClass","mktree");
setDefault("nodeClosedClass","liClosed");
setDefault("nodeOpenClass","liOpen");
setDefault("nodeBulletClass","liBullet");
setDefault("nodeLinkClass","bullet");
setDefault("preProcessTrees",true);
if (preProcessTrees) {
if (!document.createElement) { return; } // Without createElement, we can't do anything
var uls = document.getElementsByTagName("ul");
if (uls==null) { return; }
var uls_length = uls.length;
for (var uli=0;uli<uls_length;uli++) {
var ul=uls[uli];
if (ul.nodeName=="UL" && ul.className==treeClass) {
processList(ul);
}
}
}
}
function treeNodeOnclick() {
this.parentNode.className = (this.parentNode.className==nodeOpenClass) ? nodeClosedClass : nodeOpenClass;
return false;
}
function retFalse() {
return false;
}
// Process a UL tag and all its children, to convert to a tree
function processList(ul) {
if (!ul.childNodes || ul.childNodes.length==0) { return; }
// Iterate LIs
var childNodesLength = ul.childNodes.length;
for (var itemi=0;itemi<childNodesLength;itemi++) {
var item = ul.childNodes[itemi];
if (item.nodeName == "LI") {
// Iterate things in this LI
var subLists = false;
var itemChildNodesLength = item.childNodes.length;
for (var sitemi=0;sitemi<itemChildNodesLength;sitemi++) {
var sitem = item.childNodes[sitemi];
if (sitem.nodeName=="UL") {
subLists = true;
processList(sitem);
}
}
var s= document.createElement("SPAN");
var t= '\u00A0'; // &nbsp;
s.className = nodeLinkClass;
if (subLists) {
// This LI has UL's in it, so it's a +/- node
if (item.className==null || item.className=="") {
item.className = nodeClosedClass;
}
// If it's just text, make the text work as the link also
if (item.firstChild.nodeName=="#text") {
t = t+item.firstChild.nodeValue;
item.removeChild(item.firstChild);
}
s.onclick = treeNodeOnclick;
}
else {
// No sublists, so it's just a bullet node
item.className = nodeBulletClass;
s.onclick = retFalse;
}
s.appendChild(document.createTextNode(t));
item.insertBefore(s,item.firstChild);
}
}
}
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #808080 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #7D9029 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.highlight .no { color: #880000 } /* Name.Constant */
.highlight .nd { color: #AA22FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0000FF } /* Name.Function */
.highlight .nl { color: #A0A000 } /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #666666 } /* Literal.Number.Float */
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
\ No newline at end of file
function cleanUpText(codebox){
/// Not currently used
/// Strips a whole IPython session of input and output prompts
//escape quotation marks
codebox = codebox.replace(/"/g, "\'");
// newlines
codebox = codebox.replace(/[\r\n|\r|\n]$/g, ""); // remove at end
codebox = codebox.replace(/[\r\n|\r|\n]+/g, "\\n");
// prompts
codebox = codebox.replace(/In \[\d+\]: /g, "");
codebox = codebox.replace(/Out \[\d+\]: /g, "");
return codebox;
}
function htmlescape(text){
return (text.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;"))
}
function scrapeText(codebox){
/// Returns input lines cleaned of prompt1 and prompt2
var lines = codebox.split('\n');
var newlines = new Array();
$.each(lines, function() {
if (this.match(/^In \[\d+]: /)){
newlines.push(this.replace(/^(\s)*In \[\d+]: /,""));
}
else if (this.match(/^(\s)*\.+:/)){
newlines.push(this.replace(/^(\s)*\.+: /,""));
}
}
);
return newlines.join('\\n');
}
$(document).ready(
function() {
// grab all code boxes
var ipythoncode = $(".highlight-ipython");
$.each(ipythoncode, function() {
var codebox = scrapeText($(this).text());
// give them a facebox pop-up with plain text code
$(this).append('<span style="text-align:left; display:block; margin-top:-10px; margin-left:10px; font-size:75%"><a href="javascript: jQuery.facebox(\'<textarea cols=80 rows=10 readonly style=margin:5px onmouseover=javascript:this.select();>'+htmlescape(htmlescape(codebox))+'</textarea>\');">View Code</a></span>');
$(this,"textarea").select();
});
});
{{ fullname }}
{{ underline }}
.. currentmodule:: {{ module }}
.. autoclass:: {{ objname }}
{% block methods %}
{% if methods %}
.. rubric:: Methods
.. autosummary::
:toctree:
{% for item in methods %}
{% if item != '__init__' %}
~{{ name }}.{{ item }}
{% endif %}
{%- endfor %}
{% endif %}
{% endblock %}
{% block attributes %}
{% if attributes %}
.. rubric:: Attributes
.. autosummary::
{% for item in attributes %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{{ fullname }}
{{ underline }}
.. currentmodule:: {{ module }}
.. autoclass:: {{ objname }}
{% block methods %}
{% if methods %}
.. rubric:: Methods
.. autosummary::
:toctree:
{% for item in methods %}
{% if item != '__init__' %}
~{{ name }}.{{ item }}
{% endif %}
{%- endfor %}
{% endif %}
{% endblock %}
.. module:: statsmodels
:synopsis: Statistical analysis in Python
.. currentmodule:: statsmodels
*****************
About Statsmodels
*****************
Background
----------
The ``models`` module of ``scipy.stats`` was originally written by Jonathan
Taylor. For some time it was part of scipy but was later removed. During
the Google Summer of Code 2009, ``statsmodels`` was corrected, tested,
improved and released as a new package. Since then, the statsmodels
development team has continued to add new models, plotting tools, and statistical methods.
Testing
-------
Most results have been verified with at least one other statistical package:
R, Stata or SAS. The guiding principle for the initial rewrite and for
continued development is that all numbers have to be verified. Some
statistical methods are tested with Monte Carlo studies. While we strive to
follow this test driven approach, there is no guarantee that the code is
bug-free and always works. Some auxiliary function are still insufficiently
tested, some edge cases might not be correctly taken into account, and the
possibility of numerical problems is inherent to many of the statistical
models. We especially appreciate any help and reports for these kind of
problems so we can keep improving the existing models.
Code Stability
~~~~~~~~~~~~~~
The existing models are mostly settled in their user interface and we do not
expect many large changes going forward. For the existing code, although
there is no guarantee yet on API stability, we have long deprecation periods
in all but very special cases, and we try to keep changes that require
adjustments by existing users to a minimal level. For newer models we might
adjust the user interface as we gain more experience and obtain feedback.
These changes will always be noted in our release notes available in the
documentation.
Financial Support
-----------------
We are grateful for the financial support that we obtained for the
development of statsmodels:
Google `www.google.com <https://www.google.com/>`_ : Google Summer of Code
(GSOC) 2009-2017.
AQR `www.aqr.com <https://www.aqr.com/>`_ : financial sponsor for the work on
Vector Autoregressive Models (VAR) by Wes McKinney
We would also like to thank our hosting providers, `github
<https://github.com/>`_ for the public code repository, `github.io
<https://www.statsmodels.org/stable/index.html>`_ for hosting our documentation and `python.org
<https://www.python.org/>`_ for making our downloads available on PyPi.
We also thank our continuous integration providers,
`Travis CI <https://travis-ci.org/>`_ and `AppVeyor <https://ci.appveyor.com>`_ for
unit testing, and `Codecov <https://codecov.io>`_ and `Coveralls <https://coveralls.io>`_ for
code coverage.
.. currentmodule:: statsmodels.stats.anova
.. _anova:
ANOVA
=====
Analysis of Variance models containing anova_lm for ANOVA analysis with a
linear OLSModel, and AnovaRM for repeated measures ANOVA, within ANOVA for
balanced data.
Examples
--------
.. ipython:: python
import statsmodels.api as sm
from statsmodels.formula.api import ols
moore = sm.datasets.get_rdataset("Moore", "carData",
cache=True) # load data
data = moore.data
data = data.rename(columns={"partner.status":
"partner_status"}) # make name pythonic
moore_lm = ols('conformity ~ C(fcategory, Sum)*C(partner_status, Sum)',
data=data).fit()
table = sm.stats.anova_lm(moore_lm, typ=2) # Type 2 ANOVA DataFrame
print(table)
A more detailed example for `anova_lm` can be found here:
* `ANOVA <examples/notebooks/generated/interactions_anova.html>`__
Module Reference
----------------
.. module:: statsmodels.stats.anova
:synopsis: Analysis of Variance
.. autosummary::
:toctree: generated/
anova_lm
AnovaRM
# -*- coding: utf-8 -*-
#
# statsmodels documentation build configuration file, created by
# sphinx-quickstart on Sat Jan 22 11:17:58 2011.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../sphinxext'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.mathjax', # One of mathjax or imgmath
# 'sphinx.ext.imgmath',
'sphinx.ext.viewcode',
'sphinx.ext.autosummary',
'sphinx.ext.inheritance_diagram',
'matplotlib.sphinxext.plot_directive',
'IPython.sphinxext.ipython_console_highlighting',
'IPython.sphinxext.ipython_directive',
'github', # for GitHub links,
# 'numpydoc', # numpydoc or napoleon, but not both
'sphinx.ext.napoleon'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'statsmodels'
copyright = u'2009-2017, Josef Perktold, Skipper Seabold, Jonathan Taylor, statsmodels-developers'
autosummary_generate = True
autoclass_content = 'class'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from statsmodels import __version__
release = __version__
# The full version, including dev tag.
version = __version__
# set inheritance_graph_attrs
# you need graphviz installed to use this
# see: http://sphinx.pocoo.org/ext/inheritance.html
# and graphviz dot documentation http://www.graphviz.org/content/attrs
#NOTE: giving the empty string to size allows graphviz to figure out
# the size
inheritance_graph_attrs = dict(size='""', ratio="compress", fontsize=14,
rankdir="LR")
#inheritance_node_attrs = dict(shape='ellipse', fontsize=14, height=0.75,
# color='dodgerblue1', style='filled')
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['*/autosummary/class.rst', '*/autosummary/glmfamilies.rst']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
add_function_parentheses = False
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#html_theme = 'default'
if 'htmlhelp' in sys.argv:
#html_theme = 'statsmodels_htmlhelp' #doesn't look nice yet
html_theme = 'default'
print('################# using statsmodels_htmlhelp ############')
else:
html_theme = 'statsmodels'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ['../themes']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = 'images/statsmodels_hybi_banner.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = 'images/statsmodels_hybi_favico.ico'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
html_sidebars = {'index' : ['indexsidebar.html','searchbox.html','sidelinks.html']}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'statsmodelsdoc'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'statsmodels.tex', u'statsmodels Documentation',
u'Josef Perktold, Skipper Seabold', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# imgmath options
imgmath_image_format = 'png'
imgmath_latex_preamble = r'\usepackage[active]{preview}'
imgmath_use_preview = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'statsmodels', u'statsmodels Documentation',
[u'Josef Perktold, Skipper Seabold, Jonathan Taylor'], 1)
]
# -- Options for Epub output ---------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u'statsmodels'
epub_author = u'Josef Perktold, Skipper Seabold'
epub_publisher = u'Josef Perktold, Skipper Seabold'
epub_copyright = u'2009-2017, Josef Perktold, Skipper Seabold, Jonathan Taylor, statsmodels-developers'
# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''
# A unique identification for the text.
#epub_uid = ''
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []
# A list of files that should not be packed into the epub file.
#epub_exclude_files = []
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'python': ('https://docs.python.org/3/', None),
'pydagogue': ('https://matthew-brett.github.io/pydagogue/', None),
'patsy': ('https://patsy.readthedocs.io/en/latest/', None),
'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None),
}
from os.path import dirname, abspath, join
plot_basedir = join(dirname(dirname(os.path.abspath(__file__))), 'source')
# ghissue config
github_project_url = "https://github.com/statsmodels/statsmodels"
# for the examples landing page
import json
example_context = json.load(open('examples/landing.json'))
html_context = {'examples': example_context }
# --------------- DOCTEST -------------------
doctest_global_setup = """
import statsmodels.api as sm
import statsmodels.formula.api as smf
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import pandas as pd
"""
.. currentmodule:: statsmodels.stats.contingency_tables
.. _contingency_tables:
Contingency tables
==================
Statsmodels supports a variety of approaches for analyzing contingency
tables, including methods for assessing independence, symmetry,
homogeneity, and methods for working with collections of tables from a
stratified population.
The methods described here are mainly for two-way tables. Multi-way
tables can be analyzed using log-linear models. Statsmodels does not
currently have a dedicated API for loglinear modeling, but Poisson
regression in :class:`statsmodels.genmod.GLM` can be used for this
purpose.
A contingency table is a multi-way table that describes a data set in
which each observation belongs to one category for each of several
variables. For example, if there are two variables, one with
:math:`r` levels and one with :math:`c` levels, then we have a
:math:`r \times c` contingency table. The table can be described in
terms of the number of observations that fall into a given cell of the
table, e.g. :math:`T_{ij}` is the number of observations that have
level :math:`i` for the first variable and level :math:`j` for the
second variable. Note that each variable must have a finite number of
levels (or categories), which can be either ordered or unordered. In
different contexts, the variables defining the axes of a contingency
table may be called **categorical variables** or **factor variables**.
They may be either **nominal** (if their levels are unordered) or
**ordinal** (if their levels are ordered).
The underlying population for a contingency table is described by a
**distribution table** :math:`P_{i, j}`. The elements of :math:`P`
are probabilities, and the sum of all elements in :math:`P` is 1.
Methods for analyzing contingency tables use the data in :math:`T` to
learn about properties of :math:`P`.
The :class:`statsmodels.stats.Table` is the most basic class for
working with contingency tables. We can create a ``Table`` object
directly from any rectangular array-like object containing the
contingency table cell counts:
.. ipython:: python
import numpy as np
import pandas as pd
import statsmodels.api as sm
df = sm.datasets.get_rdataset("Arthritis", "vcd").data
tab = pd.crosstab(df['Treatment'], df['Improved'])
tab = tab.loc[:, ["None", "Some", "Marked"]]
table = sm.stats.Table(tab)
Alternatively, we can pass the raw data and let the Table class
construct the array of cell counts for us:
.. ipython:: python
data = df[["Treatment", "Improved"]]
table = sm.stats.Table.from_data(data)
Independence
------------
**Independence** is the property that the row and column factors occur
independently. **Association** is the lack of independence. If the
joint distribution is independent, it can be written as the outer
product of the row and column marginal distributions:
.. math::
P_{ij} = \sum_k P_{ij} \cdot \sum_k P_{kj} \forall i, j
We can obtain the best-fitting independent distribution for our
observed data, and then view residuals which identify particular cells
that most strongly violate independence:
.. ipython:: python
print(table.table_orig)
print(table.fittedvalues)
print(table.resid_pearson)
In this example, compared to a sample from a population in which the
rows and columns are independent, we have too many observations in the
placebo/no improvement and treatment/marked improvement cells, and too
few observations in the placebo/marked improvement and treated/no
improvement cells. This reflects the apparent benefits of the
treatment.
If the rows and columns of a table are unordered (i.e. are nominal
factors), then the most common approach for formally assessing
independence is using Pearson's :math:`\chi^2` statistic. It's often
useful to look at the cell-wise contributions to the :math:`\chi^2`
statistic to see where the evidence for dependence is coming from.
.. ipython:: python
rslt = table.test_nominal_association()
print(rslt.pvalue)
print(table.chi2_contribs)
For tables with ordered row and column factors, we can us the **linear
by linear** association test to obtain more power against alternative
hypotheses that respect the ordering. The test statistic for the
linear by linear association test is
.. math::
\sum_k r_i c_j T_{ij}
where :math:`r_i` and :math:`c_j` are row and column scores. Often
these scores are set to the sequences 0, 1, .... This gives the
'Cochran-Armitage trend test'.
.. ipython:: python
rslt = table.test_ordinal_association()
print(rslt.pvalue)
We can assess the association in a :math:`r\times x` table by
constructing a series of :math:`2\times 2` tables and calculating
their odds ratios. There are two ways to do this. The **local odds
ratios** construct :math:`2\times 2` tables from adjacent row and
column categories.
.. ipython:: python
print(table.local_oddsratios)
taloc = sm.stats.Table2x2(np.asarray([[7, 29], [21, 13]]))
print(taloc.oddsratio)
taloc = sm.stats.Table2x2(np.asarray([[29, 7], [13, 7]]))
print(taloc.oddsratio)
The **cumulative odds ratios** construct :math:`2\times 2` tables by
dichotomizing the row and column factors at each possible point.
.. ipython:: python
print(table.cumulative_oddsratios)
tab1 = np.asarray([[7, 29 + 7], [21, 13 + 7]])
tacum = sm.stats.Table2x2(tab1)
print(tacum.oddsratio)
tab1 = np.asarray([[7 + 29, 7], [21 + 13, 7]])
tacum = sm.stats.Table2x2(tab1)
print(tacum.oddsratio)
A mosaic plot is a graphical approach to informally assessing
dependence in two-way tables.
.. ipython:: python
from statsmodels.graphics.mosaicplot import mosaic
fig, _ = mosaic(data, index=["Treatment", "Improved"])
Symmetry and homogeneity
------------------------
**Symmetry** is the property that :math:`P_{i, j} = P_{j, i}` for
every :math:`i` and :math:`j`. **Homogeneity** is the property that
the marginal distribution of the row factor and the column factor are
identical, meaning that
.. math::
\sum_j P_{ij} = \sum_j P_{ji} \forall i
Note that for these properties to be applicable the table :math:`P`
(and :math:`T`) must be square, and the row and column categories must
be identical and must occur in the same order.
To illustrate, we load a data set, create a contingency table, and
calculate the row and column margins. The :class:`Table` class
contains methods for analyzing :math:`r \times c` contingency tables.
The data set loaded below contains assessments of visual acuity in
people's left and right eyes. We first load the data and create a
contingency table.
.. ipython:: python
df = sm.datasets.get_rdataset("VisualAcuity", "vcd").data
df = df.loc[df.gender == "female", :]
tab = df.set_index(['left', 'right'])
del tab["gender"]
tab = tab.unstack()
tab.columns = tab.columns.get_level_values(1)
print(tab)
Next we create a :class:`SquareTable` object from the contingency
table.
.. ipython:: python
sqtab = sm.stats.SquareTable(tab)
row, col = sqtab.marginal_probabilities
print(row)
print(col)
The ``summary`` method prints results for the symmetry and homogeneity
testing procedures.
.. ipython:: python
print(sqtab.summary())
If we had the individual case records in a dataframe called ``data``,
we could also perform the same analysis by passing the raw data using
the ``SquareTable.from_data`` class method.
::
sqtab = sm.stats.SquareTable.from_data(data[['left', 'right']])
print(sqtab.summary())
A single 2x2 table
------------------
Several methods for working with individual 2x2 tables are provided in
the :class:`sm.stats.Table2x2` class. The ``summary`` method displays
several measures of association between the rows and columns of the
table.
.. ipython:: python
table = np.asarray([[35, 21], [25, 58]])
t22 = sm.stats.Table2x2(table)
print(t22.summary())
Note that the risk ratio is not symmetric so different results will be
obtained if the transposed table is analyzed.
.. ipython:: python
table = np.asarray([[35, 21], [25, 58]])
t22 = sm.stats.Table2x2(table.T)
print(t22.summary())
Stratified 2x2 tables
---------------------
Stratification occurs when we have a collection of contingency tables
defined by the same row and column factors. In the example below, we
have a collection of 2x2 tables reflecting the joint distribution of
smoking and lung cancer in each of several regions of China. It is
possible that the tables all have a common odds ratio, even while the
marginal probabilities vary among the strata. The 'Breslow-Day'
procedure tests whether the data are consistent with a common odds
ratio. It appears below as the `Test of constant OR`. The
Mantel-Haenszel procedure tests whether this common odds ratio is
equal to one. It appears below as the `Test of OR=1`. It is also
possible to estimate the common odds and risk ratios and obtain
confidence intervals for them. The ``summary`` method displays all of
these results. Individual results can be obtained from the class
methods and attributes.
.. ipython:: python
data = sm.datasets.china_smoking.load_pandas()
mat = np.asarray(data.data)
tables = [np.reshape(x.tolist(), (2, 2)) for x in mat]
st = sm.stats.StratifiedTable(tables)
print(st.summary())
Module Reference
----------------
.. module:: statsmodels.stats.contingency_tables
:synopsis: Contingency table analysis
.. currentmodule:: statsmodels.stats.contingency_tables
.. autosummary::
:toctree: generated/
Table
Table2x2
SquareTable
StratifiedTable
mcnemar
cochrans_q
See also
--------
Scipy_ has several functions for analyzing contingency tables,
including Fisher's exact test which is not currently in Statsmodels.
.. _Scipy: https://docs.scipy.org/doc/scipy-0.18.0/reference/stats.html#contingency-table-functions
:orphan:
Patsy: Contrast Coding Systems for categorical variables
===========================================================
.. note:: This document is based heavily on `this excellent resource from UCLA <http://www.ats.ucla.edu/stat/r/library/contrast_coding.htm>`__.
A categorical variable of K categories, or levels, usually enters a regression as a sequence of K-1 dummy variables. This amounts to a linear hypothesis on the level means. That is, each test statistic for these variables amounts to testing whether the mean for that level is statistically significantly different from the mean of the base category. This dummy coding is called Treatment coding in R parlance, and we will follow this convention. There are, however, different coding methods that amount to different sets of linear hypotheses.
In fact, the dummy coding is not technically a contrast coding. This is because the dummy variables add to one and are not functionally independent of the model's intercept. On the other hand, a set of *contrasts* for a categorical variable with `k` levels is a set of `k-1` functionally independent linear combinations of the factor level means that are also independent of the sum of the dummy variables. The dummy coding isn't wrong *per se*. It captures all of the coefficients, but it complicates matters when the model assumes independence of the coefficients such as in ANOVA. Linear regression models do not assume independence of the coefficients and thus dummy coding is often the only coding that is taught in this context.
To have a look at the contrast matrices in Patsy, we will use data from UCLA ATS. First let's load the data.
.. ipython:: python
:suppress:
import numpy as np
np.set_printoptions(precision=4, suppress=True)
from patsy.contrasts import ContrastMatrix
def _name_levels(prefix, levels):
return ["[%s%s]" % (prefix, level) for level in levels]
class Simple(object):
def _simple_contrast(self, levels):
nlevels = len(levels)
contr = -1./nlevels * np.ones((nlevels, nlevels-1))
contr[1:][np.diag_indices(nlevels-1)] = (nlevels-1.)/nlevels
return contr
def code_with_intercept(self, levels):
contrast = np.column_stack((np.ones(len(levels)),
self._simple_contrast(levels)))
return ContrastMatrix(contrast, _name_levels("Simp.", levels))
def code_without_intercept(self, levels):
contrast = self._simple_contrast(levels)
return ContrastMatrix(contrast, _name_levels("Simp.", levels[:-1]))
Example Data
------------
.. ipython:: python
import pandas
url = 'https://stats.idre.ucla.edu/stat/data/hsb2.csv'
hsb2 = pandas.read_csv(url)
It will be instructive to look at the mean of the dependent variable, write, for each level of race ((1 = Hispanic, 2 = Asian, 3 = African American and 4 = Caucasian)).
.. ipython::
hsb2.groupby('race')['write'].mean()
Treatment (Dummy) Coding
------------------------
Dummy coding is likely the most well known coding scheme. It compares each level of the categorical variable to a base reference level. The base reference level is the value of the intercept. It is the default contrast in Patsy for unordered categorical factors. The Treatment contrast matrix for race would be
.. ipython:: python
from patsy.contrasts import Treatment
levels = [1,2,3,4]
contrast = Treatment(reference=0).code_without_intercept(levels)
print(contrast.matrix)
Here we used `reference=0`, which implies that the first level, Hispanic, is the reference category against which the other level effects are measured. As mentioned above, the columns do not sum to zero and are thus not independent of the intercept. To be explicit, let's look at how this would encode the `race` variable.
.. ipython:: python
contrast.matrix[hsb2.race-1, :][:20]
This is a bit of a trick, as the `race` category conveniently maps to zero-based indices. If it does not, this conversion happens under the hood, so this won't work in general but nonetheless is a useful exercise to fix ideas. The below illustrates the output using the three contrasts above
.. ipython:: python
from statsmodels.formula.api import ols
mod = ols("write ~ C(race, Treatment)", data=hsb2)
res = mod.fit()
print(res.summary())
We explicitly gave the contrast for race; however, since Treatment is the default, we could have omitted this.
Simple Coding
-------------
Like Treatment Coding, Simple Coding compares each level to a fixed reference level. However, with simple coding, the intercept is the grand mean of all the levels of the factors. See :ref:`user-defined` for how to implement the Simple contrast.
.. ipython:: python
contrast = Simple().code_without_intercept(levels)
print(contrast.matrix)
mod = ols("write ~ C(race, Simple)", data=hsb2)
res = mod.fit()
print(res.summary())
Sum (Deviation) Coding
----------------------
Sum coding compares the mean of the dependent variable for a given level to the overall mean of the dependent variable over all the levels. That is, it uses contrasts between each of the first k-1 levels and level k In this example, level 1 is compared to all the others, level 2 to all the others, and level 3 to all the others.
.. ipython:: python
from patsy.contrasts import Sum
contrast = Sum().code_without_intercept(levels)
print(contrast.matrix)
mod = ols("write ~ C(race, Sum)", data=hsb2)
res = mod.fit()
print(res.summary())
This correspons to a parameterization that forces all the coefficients to sum to zero. Notice that the intercept here is the grand mean where the grand mean is the mean of means of the dependent variable by each level.
.. ipython:: python
hsb2.groupby('race')['write'].mean().mean()
Backward Difference Coding
--------------------------
In backward difference coding, the mean of the dependent variable for a level is compared with the mean of the dependent variable for the prior level. This type of coding may be useful for a nominal or an ordinal variable.
.. ipython:: python
from patsy.contrasts import Diff
contrast = Diff().code_without_intercept(levels)
print(contrast.matrix)
mod = ols("write ~ C(race, Diff)", data=hsb2)
res = mod.fit()
print(res.summary())
For example, here the coefficient on level 1 is the mean of `write` at level 2 compared with the mean at level 1. Ie.,
.. ipython:: python
res.params["C(race, Diff)[D.1]"]
hsb2.groupby('race').mean()["write"][2] - \
hsb2.groupby('race').mean()["write"][1]
Helmert Coding
--------------
Our version of Helmert coding is sometimes referred to as Reverse Helmert Coding. The mean of the dependent variable for a level is compared to the mean of the dependent variable over all previous levels. Hence, the name 'reverse' being sometimes applied to differentiate from forward Helmert coding. This comparison does not make much sense for a nominal variable such as race, but we would use the Helmert contrast like so:
.. ipython:: python
from patsy.contrasts import Helmert
contrast = Helmert().code_without_intercept(levels)
print(contrast.matrix)
mod = ols("write ~ C(race, Helmert)", data=hsb2)
res = mod.fit()
print(res.summary())
To illustrate, the comparison on level 4 is the mean of the dependent variable at the previous three levels taken from the mean at level 4
.. ipython:: python
grouped = hsb2.groupby('race')
grouped.mean()["write"][4] - grouped.mean()["write"][:3].mean()
As you can see, these are only equal up to a constant. Other versions of the Helmert contrast give the actual difference in means. Regardless, the hypothesis tests are the same.
.. ipython:: python
k = 4
1./k * (grouped.mean()["write"][k] - grouped.mean()["write"][:k-1].mean())
k = 3
1./k * (grouped.mean()["write"][k] - grouped.mean()["write"][:k-1].mean())
Orthogonal Polynomial Coding
----------------------------
The coefficients taken on by polynomial coding for `k=4` levels are the linear, quadratic, and cubic trends in the categorical variable. The categorical variable here is assumed to be represented by an underlying, equally spaced numeric variable. Therefore, this type of encoding is used only for ordered categorical variables with equal spacing. In general, the polynomial contrast produces polynomials of order `k-1`. Since `race` is not an ordered factor variable let's use `read` as an example. First we need to create an ordered categorical from `read`.
.. ipython:: python
_, bins = np.histogram(hsb2.read, 3)
try: # requires numpy master
readcat = np.digitize(hsb2.read, bins, True)
except:
readcat = np.digitize(hsb2.read, bins)
hsb2['readcat'] = readcat
hsb2.groupby('readcat').mean()['write']
.. ipython:: python
from patsy.contrasts import Poly
levels = hsb2.readcat.unique().tolist()
contrast = Poly().code_without_intercept(levels)
print(contrast.matrix)
mod = ols("write ~ C(readcat, Poly)", data=hsb2)
res = mod.fit()
print(res.summary())
As you can see, readcat has a significant linear effect on the dependent variable `write` but not a significant quadratic or cubic effect.
.. _user-defined:
User-Defined Coding
-------------------
If you want to use your own coding, you must do so by writing a coding class that contains a code_with_intercept and a code_without_intercept method that return a `patsy.contrast.ContrastMatrix` instance.
.. ipython:: python
from patsy.contrasts import ContrastMatrix
def _name_levels(prefix, levels):
return ["[%s%s]" % (prefix, level) for level in levels]
class Simple(object):
def _simple_contrast(self, levels):
nlevels = len(levels)
contr = -1./nlevels * np.ones((nlevels, nlevels-1))
contr[1:][np.diag_indices(nlevels-1)] = (nlevels-1.)/nlevels
return contr
def code_with_intercept(self, levels):
contrast = np.column_stack((np.ones(len(levels)),
self._simple_contrast(levels)))
return ContrastMatrix(contrast, _name_levels("Simp.", levels))
def code_without_intercept(self, levels):
contrast = self._simple_contrast(levels)
return ContrastMatrix(contrast, _name_levels("Simp.", levels[:-1]))
mod = ols("write ~ C(race, Simple)", data=hsb2)
res = mod.fit()
:orphan:
.. _dataset_proposal:
Dataset for statmodels: design proposal
===============================================
One of the thing numpy/scipy is missing now is a set of datasets, available for
demo, courses, etc. For example, R has a set of dataset available at the core.
The expected usage of the datasets are the following:
- examples, tutorials for model usage
- testing of model usage vs. other statistical packages
That is, a dataset is not only data, but also some meta-data. The goal of this
proposal is to propose common practices for organizing the data, in a way which
is both straightforward, and does not prevent specific usage of the data.
Background
----------
This proposal was adapted from David Cournapeau's original proposal for a
datasets package for scipy and the learn scikit. It has been adapted for use
in the statsmodels scikit. The structure of the datasets itself, while
specific to statsmodels, should be general enough such that it might be used
for other types of data (e.g., in the learn scikit or scipy itself).
Organization
------------
Each dataset is a directory in the `datasets` directory and defines a python
package (e.g. has the __init__.py file). Each package is expected to define the
function load, returning the corresponding data. For example, to access datasets
data1, you should be able to do::
>>> from statsmodels.datasets.data1 import load
>>> d = load() # -> d is a Dataset object, see below
The `load` function is expected to return the `Dataset` object, which has certain
common attributes that make it readily usable in tests and examples. Load can do
whatever it wants: fetching data from a file (python script, csv file, etc...),
from the internet, etc. However, it is strongly recommended that each dataset
directory contain a csv file with the dataset and its variables in the same form
as returned by load so that the dataset can easily be loaded into other
statistical packages. In addition, an optional (though recommended) sub-directory
src should contain the dataset in its original form if it was "cleaned" (ie.,
variable transformations) in order to put it into the format needed for statsmodels.
Some special variables must be defined for each package, containing a Python string:
- COPYRIGHT: copyright informations
- SOURCE: where the data are coming from
- DESCHOSRT: short description
- DESCLONG: long description
- NOTE: some notes on the datasets.
See `datasets/data_template.py` for more information.
Format of the data
------------------
This is strongly suggested a practice for the `Dataset` object returned by the
load function. Instead of using classes to provide meta-data, the Bunch pattern
is used.
::
class Bunch(dict):
def __init__(self,**kw):
dict.__init__(self,kw)
self.__dict__ = self
See this `Reference <http://code.activestate.com/recipes/52308-the-simple-but-handy-collector-of-a-bunch-of-named/>`_
In practice, you can use ::
>>> from statsmodels.datasets import Dataset
as the default collector as in `datasets/data_template.py`.
The advantage of the Bunch pattern is that it preserves look-up by attribute.
The key goals are:
- For people who just want the data, there is no extra burden
- For people who need more, they can easily extract what they need from
the returned values. Higher level abstractions can be built easily
from this model.
- All possible datasets should fit into this model.
For the datasets to be useful in statsmodels the Dataset object
returned by load has the following conventions and attributes:
- Calling the object itself returns the plain ndarray of the full dataset.
- `data`: A recarray containing the actual data. It is assumed
that all of the data can safely be cast to a float at this point.
- `raw_data`: This is the plain ndarray version of 'data'.
- `names`: this returns data.dtype.names so that name[i] is the i-th
column in 'raw_data'.
- `endog`: this value is provided for convenience in tests and examples
- `exog`: this value is provided for convenience in tests and examples
- `endog_name`: the name of the endog attribute
- `exog_name`: the names of the exog attribute
This contains enough information to get all useful information through
introspection and simple functions. Further, attributes are easily added that
may be useful for other packages.
Adding a dataset
----------------
See the :ref:`notes on adding a dataset <add_data>`.
Example Usage
-------------
::
>>> from statsmodels import datasets
>>> data = datasets.longley.load()
Remaining problems:
-------------------
- If the dataset is big and cannot fit into memory, what kind of API do
we want to avoid loading all the data in memory ? Can we use memory
mapped arrays ?
- Missing data: I thought about subclassing both record arrays and
masked arrays classes, but I don't know if this is feasable, or even
makes sense. I have the feeling that some Data mining software use
Nan (for example, weka seems to use float internally), but this
prevents them from representing integer data.
- What to do with non-float data, i.e., strings or categorical variables?
Current implementation
----------------------
An implementation following the above design is available in `statsmodels`.
Note
----
Although the datasets package emerged from the learn package, we try to keep it
independant from everything else, that is once we agree on the remaining
problems and where the package should go, it can easily be put elsewhere
without too much trouble. If there is interest in re-using the datasets package,
please contact the developers on the `mailing list <https://groups.google.com/forum/?hl=en#!forum/pystatsmodels>`_.
.. _datasets:
.. currentmodule:: statsmodels.datasets
.. ipython:: python
:suppress:
import numpy as np
np.set_printoptions(suppress=True)
The Datasets Package
====================
``statsmodels`` provides data sets (i.e. data *and* meta-data) for use in
examples, tutorials, model testing, etc.
Using Datasets from Stata
-------------------------
.. autosummary::
:toctree: ./
webuse
Using Datasets from R
---------------------
The `Rdatasets project <https://vincentarelbundock.github.io/Rdatasets/>`__ gives access to the datasets available in R's core datasets package and many other common R packages. All of these datasets are available to statsmodels by using the :func:`get_rdataset` function. The actual data is accessible by the ``data`` attribute. For example:
.. ipython:: python
import statsmodels.api as sm
duncan_prestige = sm.datasets.get_rdataset("Duncan", "carData")
print(duncan_prestige.__doc__)
duncan_prestige.data.head(5)
R Datasets Function Reference
-----------------------------
.. autosummary::
:toctree: ./
get_rdataset
get_data_home
clear_data_home
Available Datasets
------------------
.. toctree::
:maxdepth: 1
:glob:
generated/*
Usage
-----
Load a dataset:
.. ipython:: python
import statsmodels.api as sm
data = sm.datasets.longley.load(as_pandas=False)
The `Dataset` object follows the bunch pattern explained in :ref:`proposal <dataset_proposal>`. The full dataset is available in the ``data`` attribute.
.. ipython:: python
data.data
Most datasets hold convenient representations of the data in the attributes `endog` and `exog`:
.. ipython:: python
data.endog[:5]
data.exog[:5,:]
Univariate datasets, however, do not have an `exog` attribute.
Variable names can be obtained by typing:
.. ipython:: python
data.endog_name
data.exog_name
If the dataset does not have a clear interpretation of what should be an
`endog` and `exog`, then you can always access the `data` or `raw_data`
attributes. This is the case for the `macrodata` dataset, which is a collection
of US macroeconomic data rather than a dataset with a specific example in mind.
The `data` attribute contains a record array of the full dataset and the
`raw_data` attribute contains an ndarray with the names of the columns given
by the `names` attribute.
.. ipython:: python
type(data.data)
type(data.raw_data)
data.names
Loading data as pandas objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For many users it may be preferable to get the datasets as a pandas DataFrame or
Series object. Each of the dataset modules is equipped with a ``load_pandas``
method which returns a ``Dataset`` instance with the data readily available as pandas objects:
.. ipython:: python
data = sm.datasets.longley.load_pandas()
data.exog
data.endog
The full DataFrame is available in the ``data`` attribute of the Dataset object
.. ipython:: python
data.data
With pandas integration in the estimation classes, the metadata will be attached
to model results:
.. ipython:: python,okwarning
y, x = data.endog, data.exog
res = sm.OLS(y, x).fit()
res.params
res.summary()
Extra Information
^^^^^^^^^^^^^^^^^
If you want to know more about the dataset itself, you can access the
following, again using the Longley dataset as an example ::
>>> dir(sm.datasets.longley)[:6]
['COPYRIGHT', 'DESCRLONG', 'DESCRSHORT', 'NOTE', 'SOURCE', 'TITLE']
Additional information
----------------------
* The idea for a datasets package was originally proposed by David Cournapeau and can be found :ref:`here <dataset_proposal>` with updates by Skipper Seabold.
* To add datasets, see the :ref:`notes on adding a dataset <add_data>`.
.. _add_data:
Datasets
========
For a list of currently available datasets and usage instructions, see the
:ref:`datasets page <datasets>`.
License
-------
To be considered for inclusion in `statsmodels`, a dataset must be in the
public domain, distributed under a BSD-compatible license, or we must obtain
permission from the original author.
Adding a dataset: An example
----------------------------
The Nile River data measures the volume of the discharge of the Nile River at
Aswan for the years 1871 to 1970. The data are copied from the paper of Cobb
(1978).
**Step 1**: Create a directory `datasets/nile/`
**Step 2**: Add `datasets/nile/nile.csv` and a new file `datasets/__init__.py` which contains ::
from data import *
**Step 3**: If `nile.csv` is a transformed/cleaned version of the original data, create a `nile/src` directory and include the original raw data there. In the `nile` case, this step is not necessary.
**Step 4**: Copy `datasets/template_data.py` to `nile/data.py`. Edit `nile/data.py` by filling-in strings for COPYRIGHT, TITLE, SOURCE, DESCRSHORT, DESCLONG, and NOTE. ::
COPYRIGHT = """This is public domain."""
TITLE = """Nile River Data"""
SOURCE = """
Cobb, G.W. 1978. The Problem of the Nile: Conditional Solution to a Changepoint
Problem. Biometrika. 65.2, 243-251,
"""
DESCRSHORT = """Annual Nile River Volume at Aswan, 1871-1970""
DESCRLONG = """AAnnual Nile River Volume at Aswan, 1871-1970. The units of
measurement are 1e9 m^{3}, and there is an apparent changepoint near 1898."""
NOTE = """
Number of observations: 100
Number of variables: 2
Variable name definitions:
year - Year of observation
volume - Nile River volume at Aswan
The data were originally used in Cobb (1987, See SOURCE). The author
acknowledges that the data were originally compiled from various sources by
Dr. Barbara Bell, Center for Astrophysics, Cambridge, Massachusetts. The data
set is also used as an example in many textbooks and software packages.
"""
**Step 5:** Edit the docstring of the `load` function in `data.py` to specify
which dataset will be loaded. Also edit the path and the indices for the
`endog` and `exog` attributes. In the `nile` case, there is no `exog`, so
everything referencing `exog` is not used. The `year` variable is also not
used.
**Step 6:** Edit the `datasets/__init__.py` to import the directory.
That's it! The result can be found `here
<https://github.com/statsmodels/statsmodels/tree/master/statsmodels/datasets/nile>`_
for reference.
.. _examples:
Examples
========
Examples are invaluable for new users who hope to get up and running quickly
with `statsmodels`, and they are extremely useful to those who wish to explore
new features of `statsmodels`. We hope to provide documentation and tutorials
for as many models and use-cases as possible! Please consider submitting an example with any PR that introduces new functionality.
User-contributed examples/tutorials/recipes can be placed on the
`statsmodels examples wiki page <https://github.com/statsmodels/statsmodels/wiki/Examples>`_
That wiki page is freely editable. Please post your cool tricks,
examples, and recipes on there!
If you would rather have your example file officially accepted to the
`statsmodels` distribution and posted on this website, you will need to go
through the normal `patch submission process <index.html#submitting-a-patch>`_ and follow the instructions that follow.
File Format
~~~~~~~~~~~
Examples are best contributed as IPython notebooks. Save your notebook with all output cells cleared in ``examples/notebooks``. From the notebook save the pure Python output to ``examples/python``. The first line of the Notebook *must* be a header cell that contains a title for the notebook, if you want the notebook to be included in the documentation.
The Example Gallery
~~~~~~~~~~~~~~~~~~~
We have a gallery of example notebooks available `here <https://www.statsmodels.org/devel/examples/index.html>`_. If you would like your example to show up in this gallery, add a link to the notebook in ``docs/source/examples/landing.json``. For the thumbnail, take a screenshot of what you think is the best "hook" for the notebook. The image will be displayed at 360 x 225 (W x H). It's best to save the image as a PNG with a resolution that is some multiple of 360 x 225 (720 x 450 is preferred).
Before submitting a PR
~~~~~~~~~~~~~~~~~~~~~~
To save you some time and to make the new examples nicely fit into the existing
ones consider the following points.
**Look at examples source code** to get a feel for how statsmodels examples should look like.
**Build the docs** by running `make html` from the docs directory to see how your example looks in the fully rendered html pages.
Get Involved
============
Where to Start?
---------------
Use grep or download a tool like `grin <https://pypi.python.org/pypi/grin>`__ to search the code for TODO notes::
grin -i -I "*.py*" todo
This shows almost 700 TODOs in the code base right now. Feel free to inquire on the mailing list about any of these.
Sandbox
-------
We currently have a large amount code in the :ref:`sandbox`. The medium term goal is to move much of this to feature branches as it gets worked on and remove the sandbox folder. Many of these models and functions are close to done, however, and we welcome any and all contributions to complete them, including refactoring, documentation, and tests. These models include generalized additive models (GAM), information theoretic models such as maximum entropy, survival models, systems of equation models, restricted least squares, panel data models, and time series models such as (G)ARCH.
.. .. toctree::
.. :maxdepth: 4
..
.. ../sandbox
Contribute an Example
---------------------
Contribute an :ref:`example <examples>`, add some technical documentation, or contribute a statistics tutorial.
Working with the Statsmodels Code
=================================
Github
------
The `statsmodels` code base is hosted on `Github <https://github.com/statsmodels/statsmodels>`_. To
contribute you will need to `sign up for a free Github account <https://github.com/>`_.
Version Control and Git
-----------------------
We use the `Git <http://git-scm.com/>`_ version control system for development.
Git allows many people to work together on the same project. In a nutshell, it
allows you to make changes to the code independent of others who may also be
working on the code and allows you to easily contribute your changes to the
codebase. It also keeps a complete history of all changes to the code, so you
can easily undo changes or see when a change was made, by whom, and why.
To install and configure Git, and to setup SSH keys, see
`setting up git <https://help.github.com/articles/set-up-git/>`_.
To learn more about Git, you may want to visit:
+ `Git documentation (book and videos) <https://git-scm.com/documentation>`_
+ `Github help pages <https://help.github.com/>`_
+ `NumPy documentation <https://docs.scipy.org/doc/numpy/dev/index.html>`_
+ `Matthew Brett's Pydagogue <http://matthew-brett.github.io/pydagogue/>`_
Below, we describe the bare minimum git commands you need to contribute to
`statsmodels`.
Statsmodels Git/Github Workflow
-------------------------------
Forking and cloning
~~~~~~~~~~~~~~~~~~~
After setting up git, you need to fork the main `statsmodels` repository. To do
this, visit the `statsmodels project page
<https://github.com/statsmodels/statsmodels>`_ and hit the fork button (see
instructions for
`forking a repo <https://help.github.com/articles/fork-a-repo/>`_ for details).
This should take you to your fork's page.
Then, you want to clone the fork to your machine::
git clone https://github.com/your-user-name/statsmodels
cd statsmodels
git remote add upstream https://github.com/statsmodels/statsmodels
git fetch --all
The third line sets-up a read-only connection to the upstream statsmodels
repository. This will allow you to periodically update your local code with
changes in the upstream. The final command fetches both your repository and
the upstream statsmodels repository.
Create a Branch
~~~~~~~~~~~~~~~
All changes to the code should be made in a feature branch. To create a branch, type::
git checkout master
git rebase upstream/master
git checkout -b shiny-new-feature
The first two lines ensure you are starting from an up-to-date version of the upstream
statsmodels repository. The third creates and checkout a new branch.
Doing::
git branch
will give something like::
* shiny-new-feature
master
to indicate that you are now on the `shiny-new-feature` branch.
Making changes
~~~~~~~~~~~~~~
Hack away! Make any changes that you want, but please keep the work in your
branch completely confined to one specific topic, bugfix, or feature
implementation. You can work across multiple files and have many commits, but
the changes should all be related to the feature of the feature branch,
whatever that may be.
Now imagine that you changed the file `foo.py`. You can see your changes by
typing::
git status
This will print something like::
# On branch shiny-new-feature
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: relative/path/to/foo.py
#
no changes added to commit (use "git add" and/or "git commit -a")
Before you can commit these changes, you have to `add`, or `stage`, the
changes. You can do this by typing::
git add path/to/foo.py
Then check the status to make sure your commit looks okay::
git status
should give something like::
# On branch shiny-new-feature
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: /relative/path/to/foo.py
#
Pushing your changes
~~~~~~~~~~~~~~~~~~~~
At any time you can push your feature branch (and any changes) to your github
(fork) repository by::
git push
although the first time you will need to run
git push --set-upstream origin shiny-new-feature
to instruct git to set the current branch to track its corresponding branch in
your github repository.
You can see the remote repositories by::
git remote -v
If you added the upstream repository as described above you will see something
like::
origin https://github.com/yourname/statsmodels.git (fetch)
origin https://github.com/yourname/statsmodels.git (push)
upstream https://github.com/statsmodels/statsmodels.git (fetch)
upstream https://github.com/statsmodels/statsmodels.git (push)
Before you push any commits, however, it is *highly* recommended that you make
sure what you are pushing makes sense and looks clean. You can review your
change history by::
git log --oneline --graph
It pays to take care of things locally before you push them to github. So when
in doubt, don't push. Also see the advice on keeping your history clean in
:ref:`merge-vs-rebase`.
.. _pull-requests:
Pull Requests
~~~~~~~~~~~~~
When you are ready to ask for a code review, we recommend that you file a pull
request. Before you do so you should check your changeset yourself. You can do
this by using `compare view
<https://github.com/blog/612-introducing-github-compare-view>`__ on github.
#. Navigate to your repository on github.
#. Click on `Branch List`
#. Click on the `Compare` button for your feature branch, `shiny-new-feature`.
#. Select the `base` and `compare` branches, if necessary. This will be `master` and
`shiny-new-feature`, respectively.
#. From here you will see a nice overview of your changes. If anything is amiss, you can fix it.
If everything looks good you are read to make a `pull request <https://help.github.com/articles/about-pull-requests/>`__.
#. Navigate to your repository on github.
#. Click on the `Pull Request` button.
#. You can then click on `Commits` and `Files Changed` to make sure everything looks okay one last time.
#. Write a description of your changes in the `Preview Discussion` tab.
#. Click `Send Pull Request`.
Your request will then be reviewed. If you need to go back and make more
changes, you can make them in your branch and push them to github and the pull
request will be automatically updated.
One last thing to note. If there has been a lot of work in upstream/master
since you started your patch, you might want to rebase. However, you can
probably get away with not rebasing if these changes are unrelated to the work
you have done in the `shiny-new-feature` branch. If you can avoid it, then
don't rebase. If you have to, try to do it once and when you are at the end of
your changes. Read on for some notes on :ref:`merge-vs-rebase`.
Advanced Topics
---------------
.. _merge-vs-rebase:
Merging vs. Rebasing
~~~~~~~~~~~~~~~~~~~~
This is a topic that has been discussed at great length and with considerable
more expertise than we can offer here. This section will provide some resources
for further reading and some advice. The focus, though, will be for those who
wish to submit pull requests for a feature branch. For these cases rebase
should be preferred.
A rebase replays commits from one branch on top of another branch to preserve a
linear history. Recall that your commits were tested against a (possibly) older
version of master from which you started your branch, so if you rebase, you
could introduce bugs. However, if you have only a few commits, this might not
be such a concern. One great place to start learning about rebase is
:ref:`rebasing without tears <pydagogue:actual-rebase>`. In particular, `heed
the warnings
<http://matthew-brett.github.io/pydagogue/rebase_without_tears.html#safety>`__.
Namely, **always make a new branch before doing a rebase**. This is good
general advice for working with git. I would also add **never use rebase on
work that has already been published**. If another developer is using your
work, don't rebase!!
As for merging, **never merge from trunk into your feature branch**. You will,
however, want to check that your work will merge cleanly into trunk. This will
help out the reviewers. You can do this in your local repository by merging
your work into your master (or any branch that tracks remote master) and
:ref:`run-tests`.
Deleting Branches
~~~~~~~~~~~~~~~~~
Once your feature branch is accepted into upstream, you might want to get rid
of it. First you'll want to merge upstream master into your branch. That way
git will know that it can safely delete your branch::
git fetch upstream
git checkout master
git merge upstream/master
Then you can just do::
git branch -d shiny-new-feature
Make sure you use a lower-case -d. That way, git will complain if your feature
branch has not actually been merged. The branch will still exist on github
however. To delete the branch on github, do::
git push origin :shiny-new-feature branch
.. Squashing with Rebase
.. ^^^^^^^^^^^^^^^^^^^^^
.. You've made a bunch of incremental commits, but you think they might be better off together as one
.. commit. You can do this with an interactive rebase. As usual, **only do this when you have local
.. commits. Do not edit the history of changes that have been pushed.**
.. see this reference http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Testing on Build Machines
-------------------------
There are currently several places that statsmodels is automatically built and tested against different dependency and Python versions and architectures. Check these logs periodically, make sure everything looks okay, and fix any failures.:
* `Travis CI <https://travis-ci.org/statsmodels/statsmodels/builds>`_
* `Daily testing on Ubuntu via Python(x,y) <https://code.launchpad.net/~pythonxy/+recipe/statsmodels-daily-current>`_
* `NiPy testing on SPARC Boxes <http://nipy.bic.berkeley.edu/waterfall?category=statsmodels>`_
The test coverage pages are here.
* `Coveralls <https://coveralls.io/github/statsmodels/statsmodels>`_
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册