基尼系数计算的两种方法:python实现 简单高效
使用两种方法,通过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实现 简单高效相关推荐
- DL之DNN:自定义2层神经网络TwoLayerNet模型(计算梯度两种方法)利用MNIST数据集进行训练、预测
DL之DNN:自定义2层神经网络TwoLayerNet模型(计算梯度两种方法)利用MNIST数据集进行训练.预测 导读 利用python的numpy计算库,进行自定义搭建2层神经网络TwoLayerN ...
- QT时间差计算的两种方法代码
QT时间差计算的两种方法 提供两种方法,直接贴出代码供参考,主要用到函数secsTo,toTIme_t(): #include <qdatetime.h>#include <wind ...
- html闰年计算方法,闰年计算的两种方法
说起闰年,估计一些朋友会很糊涂.好像隔个一两年就有闰年,结果闰来闰去,闰得头都快大了.到底什么是闰年?闰年该怎么计算呢? 实际上,闰年是公历的一个计算方式,也就是常说的阳历,或者叫西历也可以.在我国的 ...
- 请描述定时器初值的计算方式_单片机C语言编程中定时器初值计算的两种方法...
单片机C语言编程中,定时器的初值对于初学者真的是比较不好计算,因此我总结了以下几种方法. 第1种方法: #define FOSC 11059200L //晶振的频率 #define TIMS (655 ...
- nn.Dataparallel pytorch 平行计算的两种方法
1. nn.Dataparallel 多GPU加速训练 原理: 模型分别复制到每个卡中,然后把输入切片,分别放入每个卡中计算,然后再用第一块卡进行汇总求loss,反向传播更新参数. 第一块卡占用的内存 ...
- 简历上的照片怎么制作?这两种方法真的很简单
怎么制作简历上的照片呢?简历是每个人在找工作的时候必须要用到的,在简历中,除了填写我们出众的履历和工作技能之外,还有一个很重要的影响因素,那就是我们放在简历中的证件照,一个好的照片可以让面试官一眼记住 ...
- python图片转换成文字的手机软件_手机如何将图片转换成文字?用这两种方法转换很简单...
没有扫描仪怎么将纸质文档变成电子文档?图片上的文字太多想要提取没有好的方法吃苦受累的就是自己!今天分享给大家用手机将图片转换成文字的方法,轻松提取图片文字很简单! 方法一.迅捷文字识别--手机APP ...
- 行列式计算的两种方法
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #d ...
- 多项式计算的两种方法(包含秦九韶公式)
写程序计算给定多项式在定点处的值 普通写法 double f(int n, double a[], double x) {int i;double p = a[0];for(i=1; i<=n; ...
最新文章
- Linux内核网络数据发送(六)——网络设备驱动
- Itext实现导出PDF常用方法说明
- Boost:bind绑定的==,!=,<,<=,>,> =运算符的测试程序
- 最小生成树--prim+优先队列优化模板
- c语言中通过分隔符取字符串,C语言切割多层字符串(strtok_r strtok使用方法)
- 多视角半监督学习:从文本数据中得到不同视角
- java两个return_关于java:调用另一个方法时return语句不起作用
- springMVC学习(10)-上传图片
- linux ruby安装目录,SuseLInux下安装Ruby 及 Rails遇到的问题及解决方法
- 浪涌保护器ant120_ANT120/530/1P浪涌保护器服务周到漳州
- android x86玩和平精英,和平精英iOS和安卓可以一起玩吗 和平精英iOS和安卓数据互通吗...
- Java编程练习题:Demo17-Demo32
- Oracle错误处理机制
- 关于ST的一些库的说明(附标准库下载地址)
- 找一个能随时随地聊天的人很难?不,只是你还不知道Soul App
- 衡量连通图连通性一些指标(r-reachable, r-robust)
- Verilog十大基本功5 (关于verilog中的signed类型)
- VOS3000软交换怎么样,云服务器可以配置吗?
- [POJ1637]SightseeingTour
- 机器人与视觉,基于坐标系的运动偏移