在分析账号登陆异常的阈值分布取舍时,例如同phone每日登录次数分布,假定有1%、0.1%异常坏人,需要找个阈值切割点。
之前看到pandas的DataFrame有summary(),然后看spark的DataFrame也有,本以为可以很好的使用。
但是发现了一个问题,就是异常点的用户数都很小,造成条数很多,对ip_cnt的个数用阈值取0.1% 1% 5% 都是 ip_cnt=1,而且我也按 95%等,把数据弄到excel中进行累加分析,发现并不是累加的算出正好加到那个数值占总的百分比。
样例数据如下(登录多少次得ip有多少个):
time | login_cnt | ip_cnt |
---|---|---|
190315 | 1 | 56422 |
190315 | 2 | 49422 |
190315 | 3 | 36422 |
190315 | 4 | 22422 |
…… | …… | …… |
190315 | 200 | 22 |
…… | …… | …… |
190315 | 400 | 2 |
…… | …… | …… |
190315 | 600 | 1 |
…… | …… | …… |
首先发现,pyspark中 sumary调用的而_jdf.summary(),而spark官网并没有看到源码,搜索到一个stackOverFlow https://stackoverflow.com/questions/50793165/pyspark-how-are-dataframe-describe-and-summary-implemented 里看到使用的StatFunctions调用
针对 1%这样百分比 调用 new ApproximatePercentile(child, Literal.create(percentiles)).toAggregateExpression()
找到 ApproximatePercentile.scala
可惜源码也看不懂,不过大致知道是求的近似值,而且这里的k%百分比,是指的排序之后第k%的值,所以因为后面异常点很多都是1,有几十条,总记录也就三百来条,所以最终10%之内的值都是1。
而并不是当初设想的累加后值到达sum(col)的k%对应的值,所以需要自己实现了,可惜暂时不会,方向也就只有复制一列进行累加求出百分比,然后filter筛选出来,可惜难在累加这一块了。