캠페인에 대한 반응 예측 임계값 최적화

kaggle의 '데이터 세트 대출 캠페인에 대한 응답' 데이터를 사용하여 로지스틱 회귀 모델에서 계산한 예측 확률의 임계값을 최적화합니다.
htps //w w. 꺄gぇ. 코 m / ㈜ shmk 594 / ぉ 안 - m 빠 g

요컨대, 로지스틱 회귀에 적용될 때 계산된 응답 확률이 캠페인의 대상이어야 하는 사용자를 최적화합니다.

데이터 세트를 준비합니다.
df = pd.read_csv('PL_XSELL.csv', index_col = 0)
Y = df.TARGET
x = df.drop('TARGET', axis=1

숫자가 아닌 값을 OneHotEncoding합니다.
from sklearn.preprocessing import OneHotEncoder

enc = OneHotEncoder()
x_gender = pd.DataFrame(enc.fit_transform([[g] for g in x.GENDER]).A, columns=['F', 'M', 'O'], index=x.index)
x_occupation = pd.DataFrame(enc.fit_transform([[oc] for oc in x.OCCUPATION]).A, columns=set(x.OCCUPATION), index=x.index)
x_acc_type = pd.DataFrame(enc.fit_transform([[at] for at in x.ACC_TYPE]).A, columns=set(x.ACC_TYPE), index=x.index)
Account Open Date 를 오늘까지의 경과 일시에 변경합니다.
from datetime import datetime

now = datetime.now()

acc_days = x.ACC_OP_DATE.apply(lambda x : x.replace('-', '/')).apply(lambda x: (now - datetime.strptime(x, '%m/%d/%Y')).days)
x_acc_days = pd.DataFrame(acc_days)
x_acc_days.columns = ['ACC_DAYS']
AGE 열이 있으므로 AGE_BKT 열이 드롭됩니다.
위에서 전처리한 데이터를 맞춥니다.
x_ = x.drop(columns=['GENDER', 'OCCUPATION', 'ACC_TYPE', 'AGE_BKT','ACC_OP_DATE'], axis=1)

new_x = pd.concat([x_, x_gender, x_occupation, x_acc_type, x_acc_days], axis=1)

모델에 적용하기 위해 표준화합니다.
(실제라면 트레이닝 세트·테스트 세트로 나누어야 합니다만, 데모로 행하고 있으므로, 나누지 않고 합니다.)
from sklearn.preprocessing import StandardScaler
std = StandardScaler()
X_std = std.fit_transform(new_x)

로지스틱 회귀를 사용하여 모델을 학습합니다.
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(y=Y, X=X_std)
  • 역치를 변화시켜, confusion matrix 작성.
  • 역치를 넘은 유저를 대상으로 캠페인을 실시하는 것으로, 1인당의 비용(이번은 가정으로 10 )을 곱해 총 비용을 계산.
  • true positive 가 캠페인에 응답하기 때문에, 응답했을 때의 기대치(이번은 가정으로 100 )를 true positive 의 샘플수에 곱해 총 수입을 계산한다.
  • 수입과 비용의 차이가 이익이된다
  • from sklearn.metrics import confusion_matrix
    
    def generate_confusion_matrix(threshold, y_true, y_prob):
        y_pred = [pred[1] for pred in np.where(y_prob > threshold, 1, 0)]
        return confusion_matrix(y_pred=y_pred, y_true=y_true)
    
    def calculate_profit(c_mat, gain, cost):
        sum_gain = gain * c_mat[1,1]
        sum_cost = cost * sum(c_mat[:,1])
        return sum_gain - sum_cost
    
    y_prob = clf.predict_proba(X_std)
    thresholds = np.linspace(0,1)
    profits = []
    gain = 100
    cost = 10
    for threshold in thresholds:
        c_mat = generate_confusion_matrix(threshold, y_true=Y, y_prob=y_prob)
        profit = calculate_profit(c_mat, gain, cost)
        profits.append(profit)
    

    결과를 플롯합니다.
    pd.DataFrame(profits, index=thresholds, columns=['profit']).plot()
    



    대체로 0.1 정도가 최적의 임계치라는 결과가 되었습니다.

    좋은 웹페이지 즐겨찾기