Dynami c If-else в python на основе параметров - PullRequest
0 голосов
/ 22 апреля 2020

Я работаю в процессе сегментации пользователей (сегментация «RFM»), где пользователи классифицируются на основе «сегментов», в которые они входят.

В качестве быстрого примера в качестве примера пользователь может внутри «чемпионов» или «не может проиграть» ведро на основе их активности и покупок (их оценка RFM).

Все это рассчитывается с использованием алгоритма, который объясняется здесь: https://towardsdatascience.com/recency-frequency-monetary-model-with-python-and-how-sephora-uses-it-to-optimize-their-google-d6a0707c5f17

В конце она рассчитывается, как в следующем примере:

if RFM_Score >= 9:
    return "Cannot lose them"
elif ((RFM_Score >= 8) and (RFM_Score < 9)):
    return "Winners"

Теперь я хочу предложить пользователю возможность настроить границы (и имена) сегментов.

Можно ли построить динамическую c структуру if-else, которую можно настроить с помощью параметров?

Я подумал о каком-то словаре, например:

#The first value in the tuple is the lowerbound, the second value is the upperbound.
params={'cannot lose':(9,), 'winners':(8, 9), [...] 'promising':(4, 5)}
def find_class(value):
    for classname, boundaries in params:
         if value >= boundaries[0]:
             if len(boundaries) == 1:
                 return classname
             elif value < boundaries[1]:
                 return classname

Тем не менее, я боюсь, что это сделает алгоритм намного более сложным (представьте, что мы выполняем это с потенциально десятками миллионов записей), хотя я думаю, что простой if / else будет быть быстрым из-за пути * Интерпретатор 1028 * реализован.

Я хотел бы осветить: (1) приемлем ли диктовский подход? Какие возможны спады; (2) это намного медленнее?

1 Ответ

1 голос
/ 22 апреля 2020

Вам следует взглянуть на pandas.cut, который может разделить значения на сегменты и соответствующим образом обозначить их:

import pandas as pd
values = [8,10,6,4,4,1]
labels = pd.cut(values,  bins = [0,4,5,8,10], 
                labels = ["not so promising", "promising", "winners", "cannot lose them"])

Я бы предположил, что это довольно оптимизировано и, вероятно, будет работать по крайней мере не намного хуже, чем Самореализуемая версия, основанная на циклах foor и операторах if else.

По умолчанию бины - это правые закрытые интервалы, поэтому в приведенном выше примере это должно быть ((0,4], (4,5], ( 5, 8], (8, 10]). Это означает, что точка делится на интервал, где она больше, чем левая граница, но не больше, чем правая граница. Это поведение можно адаптировать с аргументами right или include_lowest (см. https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...