使用两种方法,通过python计算基尼系数。

在sql中如何计算基尼系数,可以查看我的另一篇文章。两篇文章取数相同,可以结合去看。

文章中方法1的代码来自于:(加入了一些注释,方便理解)。为精确计算。

如果对于基尼系数概念不太清楚,可以看原文的第一部分。

基尼系数计算方法 - longwind09 - 博客园

方法2和3借鉴资料:方法2和3是近似算法。其中方法3:只适用于一些特殊情况。

http://www.360doc.com/content/14/0911/13/87990_408644530.shtml

-------------------------------------------------------------------------------------------------

方法一:

#方法1import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plfrom scipy.integrate import odeintdef gini():# 计算数组累计值,从 0 开始wealths = [346,  559,  198,  420,  39,  709,  225,  731,  708,  369,  519,46,  48,  446,  117,  127,  905,  652,  528,  832,  217,  536, 942,  608,  37,  802,  422,  884,  746,  959,  759,  397,  245, 83,  542,  907,  128,  933,  740,  506,  458,  830,  874,  570,914,  592,  585,  574,  636,  462,  86,  321,  174,  238,  670, 690,  456,  918,  70,  801,  695,  908,  57,  497,  605,  334,  265,  255,  235,  199,  739,  81,  131,  68,  229,  602,  390, 571,  733,  440,  528,  409,  222,  55,  876,  606,  906,  549, 487,  552,  796,  454,  301,  914,  635,  304,  503,  688,  631,705]# 一共是100个数字
#    wealths = [1.5, 2, 3.5, 10, 4.2, 2.1, 1.1, 2.2, 3.1, 5.1, 9.5, 9.7, 1.7, 2.3, 3.8, 1.7, 2.3, 5, 4.7, 2.3, 4.3, 12]cum_wealths = np.cumsum(sorted(np.append(wealths, 0)))#加上0,再排序,再计算cumsum# 取最后一个,也就是原数组的和sum_wealths = cum_wealths[-1]#倒数第一个# 人数的累积占比#就是每个点都会产生一个横坐标xarray = np.array(range(0, len(cum_wealths))) / np.float(len(cum_wealths) - 1)# 均衡收入曲线#就是45度曲线upper = xarray# 收入累积占比yarray = cum_wealths / sum_wealths#cumsum的占比# 绘制基尼系数对应的洛伦兹曲线pl.plot(xarray, yarray)pl.plot(xarray, upper)# 上面画的是45度线#ax.plot(xarray, yarray)#ax.plot(xarray, upper)#ax.set_xlabel(u'人数累积占比')#ax.set_ylabel(u'收入累积占比')#pl.show()# 计算曲线下面积的通用方法B = np.trapz(yarray, x=xarray)# 总面积 0.5A = 0.5 - BG = A / (A + B)print (G)# 执行函数输出结果
gini()
# 结果为
0.3109641735512392

画出来的图:

方法二:

近似的求上图中的面积,将其分割成多个梯形,通过近似计算多个梯形面积,将其加和得到蓝色线条线条下面的面积。

通过简化推到多个梯形面积求和公式,得到一个比较简单的公式,就是链接2中结尾的公式。

如果分组的数量跟样本数量相同,就可以得到精确的数字,计算出来的基尼系数跟上面方法1的结果相等。

如果分组数量降低,获得的基尼系数将稍低于准确的基尼系数,因为更多的将非直线的曲线假设成了直线,即梯形的一边。

# 第二个方法
# 接着上面的定义
# 可能会出现样本数量不能被分组数量均分的情况,所以需要借助python自己包含的分布数组pd.cut# 分成n个组
n = 100
m = pd.cut(pd.Series(range(1, len(cum_wealths))), bins = n, labels = False)
# 将1到样本数量的整数,分成‘均匀’的n个组
# labels = false生成一些组数,表示这个位置原来的值属于1到n的哪个组
y = m.groupby(by = m).size().cumsum()
# 得到每个分组中的最后一个数的位置在哪里
# size表示每个组里面有多少个元素
# cumsum之后显示每个组里面最后一个元素的位置
#就是图中分为点的位置
t = yarray[y[:]]
#取得在yarray上的值
#就是图中w0 w1 w2等的值
g = 1 - (1/n)*(2*(sum(t)-1)+1)
# 跟文档中的有一点不一样,在最后的计算中减去了1
# 但其实是一致的,文档中分成了5组,w1到w5,求和的是4个y轴值的和,即为w1-w4,是到n-1的和
# 所以可改写成(不要刻意减去1,按照公式,加总到n-1)
g = 1 - (1/n)*(2*(sum(t[0:n-1]))+1)
g
# 结果为
0.3109641735512395# 相同的计算,只是起始位置稍有不同
# 上面是从1开始,这里是从0开始
# 如果是从0开始,如果第一组中有6个元素,需要取第6个元素,在python中的index是5,所以需要减去1
n = 100
m = pd.cut(pd.Series(range(0, len(cum_wealths))), bins = n, labels = False)
y = m.groupby(by = m).size().cumsum() - 1
t = yarray[y[:]]
g = 1 - (1/n)*(2*(sum(t)-1)+1)
#或者是
g = 1 - (1/n)*(2*(sum(t[0:n-1]))+1)
g# 结果为
0.3109641735512395n = 19
m = pd.cut(pd.Series(range(1, len(cum_wealths))), bins = n, labels = False)
y = m.groupby(by = m).size().cumsum()t = yarray[y[:]]
g = 1 - (1/n)*(2*(sum(t)-1)+1)
g# 结果为
0.3133532456894873n = 9
m = pd.cut(pd.Series(range(1, len(cum_wealths))), bins = n, labels = False)
y = m.groupby(by = m).size().cumsum()t = yarray[y[:]]
g = 1 - (1/n)*(2*(sum(t)-1)+1)
g#结果为
0.300356286353766n = 20
m = pd.cut(pd.Series(range(1, len(cum_wealths))), bins = n, labels = False)
y = m.groupby(by = m).size().cumsum()t = yarray[y[:]]
g = 1 - (1/n)*(2*(sum(t[0:n-1]))+1)
g#结果为
0.31025484587225693

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

最初开始计算时候做的比较简单的思路,但是并不适用于样本数量不能被分组数整除的情况。但可能有助于对基尼系数近似计算的理解,所以放在了这里。

方法三

样本数量能够被分组数均匀分配的情况(仅适用于这个情况),更好的方法详见方法二。

数据的精确度可能还会受样本量和分组量的关系。本文中采用的100个样本和分成100/20/50都是可均匀分配的情况。如果不能均匀分配,可能取m的方式需要优化,应该采取python内含的最大力度均匀分组的函数。

# 第二个方法
#只适用于样本数量能够被分组数量整除的情况
# 接着上面的定义n = 100
#分成100个组,100个数据分成100个组,每个点和点之间的梯形都计算其面积,‘最精确的近似‘
m = round(len(wealths) / n)
#每个组之间的距离
y = yarray[range(0, len(wealths), m)]
#在y轴上选择那些矩形底部x轴相对应的y轴值
g = 1 - (1/100)*(2*sum(y)+1)
g# 结果为
0.3109641735512395
#与上面计算的图形下面的面积相等# 分成20个组
n = 20
m = round(len(wealths) / n)
# 每个组的距离
y = yarray[range(0, len(wealths), m)]
# 这些点的y坐标
g = 1 - (1/n)*(2*sum(y)+1)
g# 结果为
0.31025484587225693n = 50
m = round(len(wealths) / n)
y = yarray[range(0, len(wealths), m)]
g = 1 - (1/n)*(2*sum(y)+1)
g
# 结果为
0.3108691564481606# 当样本量不能被分组数量均匀分配,会出现比较大的偏差。需优化,见方法3。
n = 40
m = round(len(wealths) / n)
y = yarray[range(0, len(wealths), m)]
g = 1 - (1/n)*(2*sum(y)+1)
g
# 结果为
0.13858644556020072# 不准确
n = 9
m = round(len(wealths) / n)
y = yarray[range(0, len(wealths), m)]
g = 1 - (1/n)*(2*sum(y)+1)
g
# 结果为
0.1003202798725994

基尼系数计算的两种方法:python实现 简单高效相关推荐

  1. DL之DNN:自定义2层神经网络TwoLayerNet模型(计算梯度两种方法)利用MNIST数据集进行训练、预测

    DL之DNN:自定义2层神经网络TwoLayerNet模型(计算梯度两种方法)利用MNIST数据集进行训练.预测 导读 利用python的numpy计算库,进行自定义搭建2层神经网络TwoLayerN ...

  2. QT时间差计算的两种方法代码

    QT时间差计算的两种方法 提供两种方法,直接贴出代码供参考,主要用到函数secsTo,toTIme_t(): #include <qdatetime.h>#include <wind ...

  3. html闰年计算方法,闰年计算的两种方法

    说起闰年,估计一些朋友会很糊涂.好像隔个一两年就有闰年,结果闰来闰去,闰得头都快大了.到底什么是闰年?闰年该怎么计算呢? 实际上,闰年是公历的一个计算方式,也就是常说的阳历,或者叫西历也可以.在我国的 ...

  4. 请描述定时器初值的计算方式_单片机C语言编程中定时器初值计算的两种方法...

    单片机C语言编程中,定时器的初值对于初学者真的是比较不好计算,因此我总结了以下几种方法. 第1种方法: #define FOSC 11059200L //晶振的频率 #define TIMS (655 ...

  5. nn.Dataparallel pytorch 平行计算的两种方法

    1. nn.Dataparallel 多GPU加速训练 原理: 模型分别复制到每个卡中,然后把输入切片,分别放入每个卡中计算,然后再用第一块卡进行汇总求loss,反向传播更新参数. 第一块卡占用的内存 ...

  6. 简历上的照片怎么制作?这两种方法真的很简单

    怎么制作简历上的照片呢?简历是每个人在找工作的时候必须要用到的,在简历中,除了填写我们出众的履历和工作技能之外,还有一个很重要的影响因素,那就是我们放在简历中的证件照,一个好的照片可以让面试官一眼记住 ...

  7. python图片转换成文字的手机软件_手机如何将图片转换成文字?用这两种方法转换很简单...

    没有扫描仪怎么将纸质文档变成电子文档?图片上的文字太多想要提取没有好的方法吃苦受累的就是自己!今天分享给大家用手机将图片转换成文字的方法,轻松提取图片文字很简单! 方法一.迅捷文字识别--手机APP ...

  8. 行列式计算的两种方法

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #d ...

  9. 多项式计算的两种方法(包含秦九韶公式)

    写程序计算给定多项式在定点处的值 普通写法 double f(int n, double a[], double x) {int i;double p = a[0];for(i=1; i<=n; ...

最新文章

  1. Linux内核网络数据发送(六)——网络设备驱动
  2. Itext实现导出PDF常用方法说明
  3. Boost:bind绑定的==,!=,<,<=,>,> =运算符的测试程序
  4. 最小生成树--prim+优先队列优化模板
  5. c语言中通过分隔符取字符串,C语言切割多层字符串(strtok_r strtok使用方法)
  6. 多视角半监督学习:从文本数据中得到不同视角
  7. java两个return_关于java:调用另一个方法时return语句不起作用
  8. springMVC学习(10)-上传图片
  9. linux ruby安装目录,SuseLInux下安装Ruby 及 Rails遇到的问题及解决方法
  10. 浪涌保护器ant120_ANT120/530/1P浪涌保护器服务周到漳州
  11. android x86玩和平精英,和平精英iOS和安卓可以一起玩吗 和平精英iOS和安卓数据互通吗...
  12. Java编程练习题:Demo17-Demo32
  13. Oracle错误处理机制
  14. 关于ST的一些库的说明(附标准库下载地址)
  15. 找一个能随时随地聊天的人很难?不,只是你还不知道Soul App
  16. 衡量连通图连通性一些指标(r-reachable, r-robust)
  17. Verilog十大基本功5 (关于verilog中的signed类型)
  18. VOS3000软交换怎么样,云服务器可以配置吗?
  19. [POJ1637]SightseeingTour
  20. 机器人与视觉,基于坐标系的运动偏移

热门文章

  1. css动画效果transtion,transform,animation
  2. npm基本操作及命令详解
  3. WordPress站点健康提示REST API遇到了错误
  4. 菜鸟后端开发之接口请求方式
  5. 云计算安全参考架构 概述
  6. openvpn (用户名密码模式)
  7. 奥的斯服务器显示,教你奥的斯服务器怎么看故障!
  8. 使用 Java的继承关系来描述动物世界的特征和关系
  9. web练习一——qq注册面开发(四)源码
  10. 关于ActivityThread