我正在尝试计算一组数字的基尼系数。基尼系数是平均绝对差值的一半。也就是说,对于列表中的每一对可能的数字,我需要采取它们的绝对差异并将这些差异加在一起(以及其他一些东西)。这是我的代码
to-report calc-Gini [list-Values]
let sumdiff 0
foreach list-Values
[ foreach list-Values
[ set sumdiff sumdiff + abs ( ?1 - ?2 )
]
]
report 0.5 * sumdiff / (mean list-Values * (length list-Values) ^ 2)
end
当我测试它时(例如show calc-Gini (list 1 2 3)
)我在第二个foreach
上收到错误“任务预期2个输入,但只有1个”。
我认为问题是NetLogo想要同时运行foreach循环。因此,如果列表长度为N,则它仅创建N对(即list1中的第一项和list2中的第一项,然后是每个列表中的第二项等),这是对等长列表的要求来自的地方。但是我需要它来处理通过越过列表获得的N ^ 2对。
如何让嵌套的foreach
做我想要的和/或更合适的其他原语?
答案 0 :(得分:2)
NetLogo没有将?1
和?2
绑定到外部和内部任务的机制。当它在您的代码中看到?1
和?2
时,它希望两个输入都来自内部任务。由于内部foreach
只提供一个输入,NetLogo会抱怨。
您可以通过简单地将外部foreach
的输入分配给局部变量来解决该问题:
to-report calc-Gini [list-Values]
let sumdiff 0
foreach list-Values
[ let v ?
foreach list-Values
[ set sumdiff sumdiff + abs ( v - ? )
]
]
report 0.5 * sumdiff / (mean list-Values * (length list-Values) ^ 2)
end
话虽如此,这是另一种实现方式:
to-report calc-gini [ xs ]
report 0.5 * sum map [ sum-diff ? xs ] xs / (mean xs * (length xs) ^ 2)
end
to-report sum-diff [ x xs ]
report sum map [ abs (x - ?) ] xs
end
答案 1 :(得分:1)
我无法解决您的嵌套foreach
方法,但这可能是另一种计算方法:
如果你使用有序数据,你可以使用这个等式计算基尼系数(给定一个向量$ y $,带有$ y_i $,$ i = 1,...,n $)
$$ G(y)= \ frac {1} {n}(n + 1 - 2 * \ frac {\ sum_ {i = 1} ^ {n}(n + 1 - i)y_ {i} } {\ sum_ {i = 1} ^ {n} y_i} $$
以下记者应该在NetLogo中提供结果:
to-report calc-Gini [list-Values]
let values sort list-Values ; making sure values are in a non-decreasing order
let n length values
let i 1
let numerator []
foreach values
[ set numerator lput ( (n + 1 - i) * ? ) numerator
set i i + 1
]
report 1 / n * ( n + 1 - 2 * (sum(numerator) / sum(values)) )
end