Data AnalyticsMachine LearningCustomer ScorePython

Customer Score คืออะไร และวิธีการพัฒนาด้วย Machine Learning

By Aoddy15 min read

Customer Score คืออะไร และวิธีการพัฒนาด้วย Machine Learning

Customer Score นั้นก็คือ การเอาข้อมูลลูกค้า ไม่ว่าจะเป็นด้าน Profile ข้อมูลการใช้งาน (Historical Data) และอาจจะรวมไปถึง ข้อมูล 3rd Parties อื่นๆ (แน่นอนข้อมูลที่เอามาใช้ต้องผ่าน consent) เข้ามาใช้ในการ ตัดเกรดหรือ จัดกลุ่มลูกค้า เพื่อให้ ทางฝั่ง Business Unit สามารถนำไป Score เหล่านี้ ไปวางแผนในเชิงกลยุทธ์ จัด Campaign กับลูกค้า ได้อย่างเหมาะสม

Customer Score

Photo by Blake Wisz on Unsplash

ประเภทของ Customer Score

Customer Score นั้นมีการนำไปใช้ได้หลากหลายรูปแบบ เช่น

1. Churn Score

คือ Score ที่ออกแบบให้จัดกลุ่มลูกค้า ที่มีโอกาสที่จะ Churn หรือ หลุดจากธุรกิจของเรา คนในแต่ละกลุ่มทาง Business Unit ก็จะมี ขั้นตอน/กลยุทธ์ ในการ Approach ลูกค้าแตกต่างกัน

2. Credit Risk Score

คือ Score ที่เอามาช่วยจัดเกรด ความเสี่ยงให้กับลูกค้า ว่าลูกค้าคนไหนมีความเสี่ยงสูง ซึ่งคนไหน สูงเราก็อาจจะไม่ปล่อยกู้ เป็นต้น

3. Propensity to buy Score

คือ Score ที่ช่วยบอกว่า ลูกค้ามี "โอกาส" ที่จะซื้อสินค้าของเรามากน้อยแค่ไหน คนกลุ่มไหนมี "โอกาซื้อสูง" ทาง BU ก็อาจจะนำเสนอ Promotion หรือ Offer ให้ "แรง"กว่าลูกค้าที่มีโอกาซื้อต่ำ เป็นต้น

ประโยชน์ของ Customer Score

ดังนั้น ประโยชน์ของการทำ Customer Score นั้นนอกจากจะช่วยจัดกลุ่มลูกค้าแล้ว ประโยชน์ที่ตามมานั้นมหาศาลจริงๆ ไม่ว่าจะเป็น ในกรณีที่ BU มีทรัพยากร ที่จำกัด เช่น:

  • จำนวน Offer จำกัด
  • สินค้าจำกัด
  • Budget จำกัด
  • พนักงานที่จะเข้าไปนำเสนอก็มีจำกัด

Score เหล่านี้จะถูกนำมาใช้ได้ทันที เพราะ Customer Score เหล่านี้จะช่วย "ชี้เป้า" ให้กับทาง BU ว่าคนไหนกลุ่มไหน ควร "ดำเนินการ/Approach" อย่างไร ทำให้ลดต้นทุนทั้ง ค่าใช้จ่ายและเวลา ได้อย่างมหาศาลอีกด้วย

Customer Score มีกี่แบบ

ถ้าจะให้ผมแบ่ง ทุกวันนี้เท่าที่ผมเห็น จะมีอยู่ด้วยกัน 2 แบบคือ

1. By Expert Judgment

โดยใช้ Business Logic หรือคนที่มีความเข้าใจในธุรกิจ เอามาช่วยในการทำ มีการนำข้อมูลทั้ง Profile หรือ การใช้งานของลูกค้ามาช่วยในการจัดกลุ่ม Score เช่น ลูกค้ามีรายได้ 30,000-50,000 บาท/เดือน และ มีการใช้ สินค้าหรือบริการของเรา อยู่เดือนละ 1,000-3,000 บาท เราจะจัดลูกค้ากลุ่มนี้เป็น ลูกค้า Grade A เป็นต้น ทั้งนี้เราอาจจะใช้ ข้อมูลใน 'มิติ' อื่นๆ ของลูกค้ามาช่วยเสริมด้วยก็เป็นได้

2. By Machine Learning

คือ การเอาข้อมูลของลูกค้า หรือ ผู้ใช้บริการ ในหลายๆ มิติมาเข้า Model แล้วให้ตัว Model ดำเนินการสร้างค่า "ความน่าจะเป็น" ที่จะเกิดเหตุการณ์ที่เราสนใจนั้นๆๆ ออกมา แล้วเราค่อยเอา "ค่าความน่าจะเป็นนั้น" มาดำเนินการจัดกลุ่มอีกที

ในการใช้งานจริง เราก็มักจะทำ Score ด้วยใช้ ML ขึ้นมาก่อน แล้ว เอา Expert Judgment มาครอบตอนใช้งานจริงอีกที แต่ในบทความนี้จะทำ Customer Score โดยใช้ Machine Learning ครับ

ขั้นตอนการพัฒนา Customer Score Model

ในการพัฒนา Model นั้นก็จะมี Methodologies และ Framework ที่เป็น มาตรฐาน ที่เราสามารถ Follow ตามขั้นตอนเหล่านั้นได้เช่น SEMMA, CRISP-DM, KDD เป็นต้น ซึ่งโดยทั่วไปก็จะมีหลักการใกล้เคียงกัน แต่ ที่เป็นที่นิยมก็คือ CRISP-DM ซึ่งจะมีทั้งหมด 6 ขั้นตอนหลักๆ คือ

1. Business Understanding

เข้าใจว่าคนที่จะเอา Model เราไปใช้นี้เค้าจะเอาไปใช้ทำอะไร เป้าหมายของเค้าคืออะไร เราจะได้ออกแบบ Model ได้ถูกต้อง และที่สำคัญที่สุดในขั้นตอนนี้ คือ Target ที่ทาง BU ต้องการนั้นคือ อะไร ซึ่งโดยส่วนใหญ่ ก็มักจะเป็น Target ที่มีเป้าหมาย เพียงอย่างเดียวเช่น:

  • เสี่ยง/ไม่เสี่ยง (เสี่ยงมากเสี่ยงน้อยเดี๋ยวเราจะไปทำตอนจัดกลุ่ม Score)
  • ซื้อ/ไม่ซื้อ
  • Churn / Unchurn เป็นต้น

2. Data Understanding

เข้าใจข้อมูลที่จะเอามาใช้ และ ต้องรู้ว่าจะเอาข้อมูลนั้นมาอย่างไร ในขั้นตอนนี้ สิ่งที่เราจะต้องได้คือ "Data Source และ Data Timeframe" เราต้องรู้ว่า เราจะใช้ข้อมูลอะไรและไปเอาข้อมูลที่ไหน และที่สำคัญไปกว่านั้น ก็คือ Data Timeframe หรือ กรอบของเวลาของข้อมูลที่เราจะเอาไปใช้

เช่น BU บอกว่าต้องใช้ข้อมูลลูกค้า ที่เพิ่งเข้ามาในธุรกิจ 3 เดือนล่าสุด (หรือเป็นทางเราที่แนะนำให้กับ BU ก็เป็นได้) และ Target ที่สนใจคือ ลูกค้าเหล่านี้(ที่เพิ่งเข้ามาได้ 3 เดือน) คนไหนที่มี หลุด/ออก ไปจากธุรกิจในเดือนที่ 4ถึง5

Data Timeframe Data Timeframe Visualization

3. Data Preparation

หลังจากที่เราทราบ Target และ เข้าใจแล้วว่า ข้อมูลที่เราจะใช้นั้นไปเอามาจากที่ไหน ขั้นตอนนี้ก็จะเป็นการเอาข้อมูลเหล่านั้นมาผ่านขั้นตอนย่อยต่างๆๆ เช่น:

  • การเลือกข้อมูลว่าอันไหนจะใช้ไม่ใช้
  • Cleaning Data
  • การเปลี่ยนรูปแบบข้อมูลให้เหมาะสม
  • การทำ Binning ซึ่งเราจะใช้ Library ที่ชื่อว่า OptBinning มาช่วยเราทำนั่นเอง

และข้อมูลที่ผมจะเอามาใช้ในการพัฒนา Credit Scorecard Model ก็คือข้อมูล 'Home Credit Default Risk' จากเว็บ Kaggle นั่นเอง

4. Modelling

ปกติก่อนเริ่มพัฒนา Model ผมมักจะเช็คก่อนว่า Baseline ของ Model ที่เราจะพัฒนานี้มี Natural Rate หรือ Baseline อยู่ที่เท่าไหร่

Natural Rate คือ % Target ในข้อมูลที่เราสนใจจะเอามาทำ Model ตัวเลขนี้ BU หรือ คนให้ Requirement เค้าก็มักจะมีตัวเลขคร่าวๆ มาให้เรา แต่ ตัวเราก็ต้องมา Double Check อีกรอบว่าเท่าไหร่

ปกติผมจะมีตัวเลข 2 ตัวในใจคือ:

  • Natural Rate / Baseline ที่มากกว่า 8%
  • Datapoint สำหรับทำ Model ต้องมากกว่า 20,000 Datapoints

ถ้าผ่านตัวเลข 2 ตัวนี้ แสดงว่า Model นี้ก็น่าจะ 'มีโอกาสพัฒนาแล้วได้ผลลัพธ์ที่ดี'

4.1 โหลดข้อมูลและเช็ค Baseline

import pandas as pd
import numpy as np
import xgboost as xgb
import pickle

from optbinning import BinningProcess
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report
from sklearn import metrics

df = pd.read_csv('dataset/application_train.csv.zip', low_memory=True)

# Check Datapoint
df.TARGET.value_counts()
#0    282686
#1     24825
#Name: TARGET, dtype: int64

# Check Baseline
print('Baseline : {:.5f}%'.format(df[df['TARGET']==1]['TARGET'].count()/ df.shape[0]*100))

# Result
# Baseline : 8.07288%

df.set_index('SK_ID_CURR', inplace=True)
# Split the dataset into train and test
df_train, df_test, y_train, y_test = train_test_split(df, df.TARGET, test_size=0.2, random_state=5456)

จากข้างบนเราจะเห็นได้ว่า ข้อมูลที่เรา Load มาจาก Kaggle มี Baseline สูงกว่า 8% และ จำนวน datapoint มากกว่า 20,000

# List of features
x_all_features = df_train.drop(columns=['TARGET']).columns.values

# List categorical features
x_categorical = df_train.select_dtypes(include=['object', 'category']).columns.values

4.2 สร้าง Criteria และ BinningProcess

# Create criteria for BinningProcess
selection_criteria = {"iv": {"min": 0.005, 'max':0.85, "strategy": "highest"}}

# Instantiate BinningProcess
binning_process = BinningProcess(
    categorical_variables=x_categorical,
    variable_names=x_all_features,
    selection_criteria=selection_criteria,
    min_n_bins = 2,
    max_n_prebins =9
)

ตัว Criteria จะเป็นตัวที่เราใช้กำหนดว่า Feature ที่จะใช้ในการทำ Model นั้น ค่า IV จะต้องมากกว่า 0.005 และสูงสุด ไม่เกิน 0.85 ส่วนตัว strategy จะมีได้ 2 ค่า คือ 'highest' และ 'lowest' ในที่นี้เราเลือก 'highest'

binning_process.fit(df_train, y_train)

binning_process เมื่อเราทำการ fit แล้วจำเป็นต้องเก็บค่านี้ไว้ด้วยนะครับ เพราะตอนเราไปใช้ Production เราก็จะเอา Binning ชุดนี้ไป Transform กับข้อมูลชุดใหม่ทุกครั้ง

binning_process.summary().head(20)

Review Data

4.3 สร้าง Pipeline และ Models

MD1 = Pipeline(steps=[('binning_process', binning_process),
                       ('xgb_model', xgb.XGBClassifier())])
MD2 = Pipeline(steps=[('binning_process', binning_process),
                      ('classifier', LogisticRegression(solver="lbfgs"))])

MD1.fit(df_train, y_train)
MD2.fit(df_train, y_train)

5. Evaluation

หลังจากที่เราทำการ Fit Model มาแล้ว เราก็จะเอา Model ทั้ง 2 อันมาเปรียบเทียบดูว่า อันไหนให้ค่าที่ดีมากกว่ากัน โดยค่า ที่เราจะดูก็จะมีทั้ง AUC, Precision, Recall, F1-Score เป็นต้น

y_pred = MD1.predict(df_test)
print(classification_report(y_test, y_pred))

              precision    recall  f1-score   support

           0       0.92      1.00      0.96     56505
           1       0.49      0.03      0.05      4998

    accuracy                           0.92     61503
   macro avg       0.70      0.51      0.50     61503
weighted avg       0.89      0.92      0.88     61503


y_pred = MD2.predict(df_test)
print(classification_report(y_test, y_pred))

              precision    recall  f1-score   support

           0       0.92      1.00      0.96     56505
           1       0.54      0.01      0.02      4998

    accuracy                           0.92     61503
   macro avg       0.73      0.51      0.49     61503
weighted avg       0.89      0.92      0.88     61503

5.1 คำนวณหา ROC_AUC

import matplotlib.pyplot as plt

probs = MD1.predict_proba(df_test)
preds = probs[:,1]
fpr1, tpr1, threshold = metrics.roc_curve(y_test, preds)
roc_auc1 = metrics.auc(fpr1, tpr1)

probs = MD2.predict_proba(df_test)
preds = probs[:,1]
fpr2, tpr2, threshold = metrics.roc_curve(y_test, preds)
roc_auc2 = metrics.auc(fpr2, tpr2)

plt.title('Receiver Operating Characteristic')
plt.plot(fpr1, tpr1, 'b', label='Binning+XGB: AUC = {0:.2f}'.format(roc_auc1))
plt.plot(fpr2, tpr2, 'black', label='Binning+LR: AUC = {0:.2f}'.format(roc_auc2))
plt.legend(loc='lower right')
plt.plot([0, 1], [0, 1],'k--')
plt.xlim([0, 1])
plt.ylim([0, 1])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()

ROC_AUC

จากกราฟด้านบนก็จแสดงให้เห็นว่า เราควรจะเลือก ML2 เพื่อค่า ROC_AUC สูงกว่า ML1 นั่นเอง ทั้งนี้ขั้นตอนถัดไปก็ถือว่าเป็นขั้นตอนที่สำคัญมาก ก็คือ ขั้นตอนการ Export ทั้งในส่วนของ Model และ Binning_Process มาเก็บเป็นไฟล์ไว้ เพื่อที่เราจะนำ ไฟล์นี้ไปใช้อีกครั้งตอน Deployment ขึ้น Production ครับ

5.2 Save Model

ในการ Save Model นั้น ปกติผมจะเอาทั้ง Model, Binning_Process และ ค่าที่สำคัญอื่นๆๆ ประกาศรวมกันไว้ในตัวแปล Tuple

tuple_objects_monitoring = (x_all_features, binning_process, model)
# To pickle a Scorecard object
with open('models/CREDIT_SCORE_202212.pickle', 'wb') as pfile:
    pickle.dump(tuple_objects_monitoring, pfile)

จะเห็นว่า ผมมีการนำ x_all_features ใส่เข้ามาด้วย เพื่อตอนที่ Run Predict จริงๆ ตัว Model จะได้รู้ว่าเราใช้ Features อะไรในการเอาเข้า Model บ้าง

6. Deployment

สำหรับการ Deployment เป็นขั้นตอนที่มี DS หลายๆคน พลาดที่จุดนี้ คือ ทำ Model มาแล้ว Deploy ไม่ได้ หรือ ถ้า Deploy ได้ก็อาจจะ Deploy ผิด แล้วจะผิดพลาดได้ที่จุดไหนได้บ้าง

ข้อควรระวัง:

  1. ผิดที่ขั้นตอนการเตรียมข้อมูล - ตอนเราทำ Model เรารู้ 'คำตอบ' หรือ มี Target ครบอยู่แล้ว แต่ ตอนขึ้น Production จริง เราจะยังไม่มี 'คำตอบ'

  2. Transform ต้องเหมือนกัน - ตอน Train Data ยังไง ตอนขึ้น Production ก็ต้อง Transform ตาม Step เหมือนตอน Train เป๊ะๆ

  3. ห้าม Fit ข้อมูลใหม่ - ที่สำคัญที่สุดคือ "ห้าม Fit" ข้อมูลใหม่เพื่อทำ Model เด็ดขาด

6.1 Load Model & Configuration

x_all_features, binning_process, model = pickle.load(open("models/CREDIT_SCORE_202212.pickle", 'rb'))

# นำค่าที่ Load ได้มาใช้งาน
oper_df = pd.read_csv('data/production_data.csv')
y_pred = model.predict(binning_process.transform(oper_df[x_all_features]))
y_pred_score = model.predict_proba(binning_process.transform(oper_df[x_all_features]))[:,1]

มาถึงตอนนี้เราก็จะมี Score ให้กับลูกค้าของเราทั้งหมดละครับ

แต่ก็อย่างที่บอกเรา Gen Score ออกมาเป็นค่า Probability ที่มีค่า 0-1 แต่เวลาที่หน้าบ้าน หรือ Business Unit เอาไปใช้งานจริงๆ เรามีความจำเป็นจะต้องทำการจัดกลุ่ม Score เหล่านี้เพื่อให้ทาง User หรือ BU เอาไปใช้งานได้ง่าย และ ที่สำคัญไปกว่านั้น คือ เราจะเอาการจัดกลุ่มนี้ มาเป็น 1 ในตัวชี้วัด Performance ของ Model ของเราด้วยครับ หรือ ที่เรียกว่า Rank Ordering

สรุป

การพัฒนา Customer Score ด้วย Machine Learning นั้นเป็นเครื่องมือที่ทรงพลังสำหรับธุรกิจในการจัดการลูกค้าอย่างมีประสิทธิภาพ การใช้ CRISP-DM Framework ช่วยให้เราสามารถพัฒนา Model ได้อย่างเป็นระบบและลดความเสี่ยงในการ Deploy

ซึ่งเรื่องการจัดกลุ่ม Score นี้เดี๋ยวผมจะขอเอาไปเล่าในบทความถัดๆๆไป ครับ เพราะตอนนี้ บทความนี้จะเริ่มยาวมากๆๆละ

ขอให้สนุกกับการพัฒนา Model นะครับ


Reference


หากคุณสนใจเรื่อง Data Analytics และ Machine Learning เพิ่มเติม สามารถติดตามบทความอื่นๆ ได้ที่ Blog หรือติดต่อสอบถามได้ที่ Contact

Aoddy avatar

Aoddy

Lifelong learning | Data Analytics | Algorithmic Trading | Quantmania | Wife Lover

www.aoddy.com
Loading views...