Skip to main content

N维迭代比例拟合,用于python

项目描述

迭代比例拟合是一种用于许多不同领域(如经济学或社会科学)的算法,用于改变结果,使沿一个或多个维度的聚合与已知的边际(或沿这些相同维度的聚合)匹配。

该算法有 2 个版本:

  • numpy 版本,目前最快

  • pandas 版本,比 numpy 版本更慢但更易于使用

该算法识别输入变量类型并使用适当的版本来解决问题。要安装软件包:

  • 点安装ipfn

  • pip install git+http://github.com/dirguis/ipfn@master

有关更多信息和示例,请访问:


如果要测试包,请克隆 repo 并从主文件夹中运行:

  • py.test –verbose –color=yes 测试/tests.py


该项目类似于可用于 R 的 ipfp 包,并且已运行测试以确保相同的结果。


输入变量:
  • 原始:numpy darray 矩阵或数据帧来执行 ipfn。

  • 聚合:numpy 数组或 darray 或 pandas 数据帧/系列的列表。聚合与边际相同。

当沿一个或多个轴聚合时,它们是我们想要沿一个或多个轴的目标值。
  • 维度:如果使用 numpy 对象,则为整数列表列表,如果使用 pandas 对象,则为列名。

保留维度,我们沿着这些维度求和以获得相应的聚合。
  • 收敛率:如果有很多聚合/边际,放宽收敛标准可能很有用。

  • 最大迭代:整数。允许的最大迭代次数。

  • 详细:整数 0、1 或 2。每个案例编号包括先前案例编号的输出。

    • 0:返回更新的矩阵。

    • 1:带有输出状态的标志(0 表示失败,1 表示成功)。

    • 2:在所有步骤中具有迭代次数和收敛速度信息的数据帧。

  • rate_tolerance:浮点值。如果高于 0.0,如 0.001,则一旦 2 次连续迭代的 conv_rate 变量之间的差异低于该指定值,算法将停止。

使用 Numpy 的维基百科示例:

为了说明迭代比例拟合,维基百科在这里使用了一个示例

以下是使用 IPFN 解决的示例:

import numpy as np
from ipfn import ipfn

m = [[40, 30, 20, 10], [35, 50, 100, 75], [30, 80, 70, 120], [20, 30, 40, 50]]
m = np.array(m)
xip = np.array([150, 300, 400, 150])
xpj = np.array([200, 300, 400, 100])

aggregates = [xip, xpj]
dimensions = [[0], [1]]

IPF = ipfn.ipfn(m, aggregates, dimensions, convergence_rate=1e-6)
m = IPF.iteration()
print(m)

算法的 numpy 版本的示例:

请按照以下示例运行该软件包。ipfn.py 脚本中列出了除了下面列出的示例之外的其他几个示例。此示例取自http://www.demog.berkeley.edu/~eddieh/IPFDescription/AKDOLWDIPFTHREED.pdf

首先,让我们定义一个 N=3 维的矩阵,该矩阵的特定大小为 2*4*3,并用一些值填充该矩阵

from ipfn import ipfn
import numpy as np
import pandas as pd

m = np.zeros((2,4,3))
m[0,0,0] = 1
m[0,0,1] = 2
m[0,0,2] = 1
m[0,1,0] = 3
m[0,1,1] = 5
m[0,1,2] = 5
m[0,2,0] = 6
m[0,2,1] = 2
m[0,2,2] = 2
m[0,3,0] = 1
m[0,3,1] = 7
m[0,3,2] = 2
m[1,0,0] = 5
m[1,0,1] = 4
m[1,0,2] = 2
m[1,1,0] = 5
m[1,1,1] = 5
m[1,1,2] = 5
m[1,2,0] = 3
m[1,2,1] = 8
m[1,2,2] = 7
m[1,3,0] = 2
m[1,3,1] = 7
m[1,3,2] = 6

现在,让我们定义一些边际:

xipp = np.array([52, 48])
xpjp = np.array([20, 30, 35, 15])
xppk = np.array([35, 40, 25])
xijp = np.array([[9, 17, 19, 7], [11, 13, 16, 8]])
xpjk = np.array([[7, 9, 4], [8, 12, 10], [15, 12, 8], [5, 7, 3]])

我用字母 p 来表示被求和的维度

对于这个具体的例子,它们都必须小于 N=3 维并且与列联表 m 的维数一致。例如,沿第一个维度的边缘将由 2 个元素组成。我们希望维度 2 和维度 3 的 m 中元素的总和等于边际:

m[0,:,:].sum() == xipp[0]
m[1,:,:].sum() == xipp[1]

定义聚合列表和相应的维度列表,以指示算法对每个聚合求和的维度:

aggregates = [xipp, xpjp, xppk, xijp, xpjk]
dimensions = [[0], [1], [2], [0, 1], [1, 2]]

最后,运行算法:

IPF = ipfn.ipfn(m, aggregates, dimensions)
m = IPF.iteration()
print(xijp[0,0])
print(m[0, 0, :].sum())

算法的熊猫版本示例:

以同样的方式,我们可以运行一个类似的例子,但是使用一个数据框:

from ipfn import ipfn
import numpy as np
import pandas as pd

m      = np.array([1., 2., 1., 3., 5., 5., 6., 2., 2., 1., 7., 2.,
               5., 4., 2., 5., 5., 5., 3., 8., 7., 2., 7., 6.], )
dma_l  = [501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501,
          502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502]
size_l = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,
          1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]

age_l  = ['20-25','30-35','40-45',
          '20-25','30-35','40-45',
          '20-25','30-35','40-45',
          '20-25','30-35','40-45',
          '20-25','30-35','40-45',
          '20-25','30-35','40-45',
          '20-25','30-35','40-45',
          '20-25','30-35','40-45']

df = pd.DataFrame()
df['dma'] = dma_l
df['size'] = size_l
df['age'] = age_l
df['total'] = m

xipp = df.groupby('dma')['total'].sum()
xpjp = df.groupby('size')['total'].sum()
xppk = df.groupby('age')['total'].sum()
xijp = df.groupby(['dma', 'size'])['total'].sum()
xpjk = df.groupby(['size', 'age'])['total'].sum()
# xppk = df.groupby('age')['total'].sum()

xipp.loc[501] = 52
xipp.loc[502] = 48

xpjp.loc[1] = 20
xpjp.loc[2] = 30
xpjp.loc[3] = 35
xpjp.loc[4] = 15

xppk.loc['20-25'] = 35
xppk.loc['30-35'] = 40
xppk.loc['40-45'] = 25

xijp.loc[501] = [9, 17, 19, 7]
xijp.loc[502] = [11, 13, 16, 8]

xpjk.loc[1] = [7, 9, 4]
xpjk.loc[2] = [8, 12, 10]
xpjk.loc[3] = [15, 12, 8]
xpjk.loc[4] = [5, 7, 3]

aggregates = [xipp, xpjp, xppk, xijp, xpjk]
dimensions = [['dma'], ['size'], ['age'], ['dma', 'size'], ['size', 'age']]

IPF = ipfn.ipfn(df, aggregates, dimensions)
df = IPF.iteration()

print(df)
print(df.groupby('size')['total'].sum(), xpjp)

添加注释:

要在程序中调用算法,请执行:

from ipfn import ipfn

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

ipfn-1.4.4.tar.gz (10.9 kB 查看哈希

已上传 source

内置分布

ipfn-1.4.4-py2.py3-none-any.whl (7.4 kB 查看哈希

已上传 py2 py3