การพัฒนา Customer Score Model ด้วย OptBinning Aoddy, December 5, 2022January 22, 2023 Customer Score คืออะไร Customer Score นั้นก็คือ การเอาข้อมูลลูกค้า ไม่ว่าจะเป็นด้าน Profile ข้อมูลการใช้งาน (Historical Data) และอาจจะรวมไปถึง ข้อมูล 3rd Parties อื่นๆ (แน่นอนข้อมูลที่เอามาใช้ต้องผ่าน consent) เข้ามาใช้ในการ ตัดเกรดหรือ จัดกลุ่มลูกค้า เพื่อให้ ทางฝั่ง Business Unit สามารถนำไป Score เหล่านี้ ไปวางแผนในเชิงกลยุทธิ์ จัด Campaign กับลูกค้า ได้อย่างเหมาะสม Photo by Blake Wisz on Unsplash Customer Score นั้นมีการนำไปใช้ได้หลากหลายรูปแบบ เช่น Churn Score คือ Score ที่ออกแบบให้จัดกลุ่มลูกค้า ที่มีโอกาสที่จะ Churn หรือ หลุดจากธุรกิจของเรา คนในแต่ละกลุ่มทาง Business Unit ก็จะมี ขั้นตอน/กลยุทธ์ ในการ Approch ลูกค้าแตกต่างกัน Credit Risk Score คือ Score ที่เอามาช่วยจัดเกรด ความเสี่ยงให้กับลูกค้า ว่าลูกค้าคนไหนมีความเสี่ยงสูง ซึ่งคนไหน สูงเราก็อาจจะไม่ปล่อยกู้ เป็นต้น Propensity to buy Score คือ Score ที่ช่วยบอกว่า ลูกค้ามี “โอกาส” ที่จะซื้อสินค้าของเรามากน้อยแค่ไหน คนกลุ่มไหนมี “โอกาสซื้อสูง” ทาง BU ก็อาจจะนำเสนอ Promotion หรือ Offer ให้ “แรง”กว่าลูกค้าที่มีโอกาสซื้อต่ำ เป็นต้น ดังนั้น ประโยชน์ของการทำ Customer Score นั้นนอกจากจะช่วยจัดกลุ่มลูกค้าแล้ว ประโยชน์ที่ตามมานั้นมหาศาลจริงๆ ไม่ว่าจะเป็น ในกรณีที่ BU มีทรัพยากร ที่จำกัด เช่น จำนวน Offer จำกัด / สินค้าจำกัด / Budget จำกัด หรือแม้แต่ พนักงานที่จะเข้าไปนำเสนอก็มีจำกัด Score เหล่านี้จะถูกนำมาใช้ได้ทันที เพราะ Customer Score เหล่านี้จะช่วย “ชี้เป้า” ให้กับทาง BU ว่าคนไหนกลุ่มไหน ควร “ดำเนินการ/Approch” อย่างไร ทำให้ลดต้นทุนทั้ง ค่าใช้จ่ายและเวลา ได้อย่างมหาศาลอีกด้วย Customer Score มีกี่แบบ ถ้าจะให้ผมแบ่ง ทุกวันนี้เท่าที่ผมเห็น จะมีอยู่ด้วยกัน 2 แบบคือ By Export Justment โดยใช้ Business Logic หรือคนที่มีความเข้าใจในธุรกิจ เอามาช่วยในการทำ มีการนำข้อมูลทั้ง Profile หรือ การใช้งานของลูกค้ามาช่วยในการจัดกลุ่ม Score เช่น ลูกค้ามีรายได้ 30,000-50,000 บาท/เดือน และ มีการใช้ สินค้าหรือบริการของเรา อยู่เดือนละ 1,000-3,000 บาท เราจะจัดลูกค้ากลุ่มนี้เป็น ลูกค้า Grade A เป็นต้น ทั้งนี้เราอาจจะใช้ ข้อมูลใน ‘มิติ‘ อื่นๆ ของลูกค้ามาช่วยเสริมด้วยก็เป็นได้ By Machine Learning คือ การเอาข้อมูลของลูกค้า หรือ ผู้ใช้บริการ ในหลายๆ มิติมาเข้า Model แล้วให้ตัว Model ดำเนินการสร้างค่า “ความน่าจะเป็น” ที่จะเกิดเหตุการณ์ที่เราสนใจนั้นๆๆ ออกมา แล้วเราค่อยเอา “ค่าความน่าจะเป็นนั้น” มาดำเนินการจัดกลุ่มอีกที ในการใช้งานจริง เราก็มักจะทำ Score ด้วยใช้ ML ขึ้นมาก่อน แล้ว เอา Export Justment มาครอบตอนใช้งานจริงอีกที แต่ในบทความนี้จะทำ Customer Score โดยใช้ Machine Learning ครับ ว่าแล้วเราก็มาเริ่มกันเลย ขั้นตอนการพัฒนา Customer Score Model ในการพัฒนา Model นั้นก็จะมี Methodologies และ Framework ที่เป็น มาตรฐาน ที่เราสามารถ Follow ตามขั้นตอนเหล่านั้นได้เช่น SEMMA, CRISP-DM, KDD เป็นต้น ซึ่งโดยทั่วไปก็จะมีหลักการใกล้เคียงกัน แต่ ที่เป็นที่นิยมก็คือ CRISP-DM ซึ่งจะมีทั้งหมด 6 ขั้นตอนหลักๆ คือ 1. Business Understand เข้าใจว่าคนที่จะเอา Model เราไปใช้นี้เค้าจะเอาไปใช้ทำอะไร เป้าหมายของเค้าคืออะไร เราจะได้ออกแบบ Model ได้ถูกต้อง และที่สำคัญที่สุดในขั้นตอนนี้ คือ Target ที่ทาง BU ต้องการนั้นคือ อะไร ซึ่งโดยส่วนใหญ่ ก็มักจะเป็น Target ที่มีเป้าหมาย เพียงอย่างเดียวเช่น เสี่ยง/ไม่เสี่ยง (เสี่ยงมากเสี่ยงน้อยเดี๋ยวเราจะไปทำตอนจัดกลุ่ม Score) , ซื้อ/ไม่ซื้อ , Churn / Unchurn เป็นต้น 2. Data Understanding เข้าใจข้อมูลที่จะเอามาใช้ และ ต้องรู้ว่าจะเอาข้อมูลนั้นมาอย่างไร ในขั้นตอนนี้ สิ่งที่เราจะต้องได้คือ “Data Source และ Data Timeframe” เราต้องรู้ว่า เราจะใช้ข้อมูลอะไรและไปเอาข้อมูลที่ไหน และที่สำคัญไปกว่านั้น ก็คือ Data Timeframe หรือ กรอบของเวลาของข้อมูลที่เราจะเอาไปใช้ เช่น BU บอกว่าต้องใช้ข้อมูลลูกค้า ที่เพิ่งเข้ามาในธุรกิจ 3 เดือนล่าสุด (หรือเป็นทางเราที่แนะนำให้กับ BU ก็เป็นได้) และ Target ที่สนใจคือ ลูกค้าเหล่านี้(ที่เพิ่งเข้ามาได้ 3 เดือน) คนไหนที่มี หลุด/ออก ไปจากธุรกิจในเดือนที่ 4ถึง5 พอมาถึงตรงนี้ผมก็มักจะได้ ER Diagram กับภาพ Data Timeframe ง่ายๆๆ ออกมา เพื่อใช้ตลอดของการพัฒนาและลากยาวไปถึงตอน Deployment Model Data Timeframe 3. Data Preparation หลังจากที่เราทราบ Target และ เข้าใจแล้วว่า ข้อมูลที่เราจะใช้นั้นไปเอามาจากที่ไหน ขั้นตอนนี้ก็จะเป็นการเอาข้อมูลเหล่านั้นมาผ่านขั้นตอนย่อยต่างๆๆ เช่น การเลือกข้อมูลว่าอันไหนจะใช้ไม่ใช้ , Cleaning Data , การเปลี่ยนรูปแบบข้อมูลให้เหมาะสม รวมไปถึงการทำ Binning ซึ่งเราจะใช้ Library ที่ชื่อว่า OptBinning มาช่วยเราทำนั่นเอง และข้อมูลที่ผมจะเอามาใช้ในการพัฒนา Credit Scorecard Model ก็คือข้อมูล ‘Home Credit Default Risk‘ จากเว็บ Kaggle นั่นเอง โดยบทความนี้ผมคงไม่ได้ลงลึกไปถึงเรื่อง Feature Engineering เท่าไหร่ แต่ผมอาจจะดึงบาง Feature ของข้อมูลออกมาทำเป็น Model เพื่อให้เห็น Concept การทำ Model และการนำไปใช้งานจริง โดย Features ที่ผมจะเลือก ก็จะมีทั้งที่เป็น Categorical และ Numerical เพื่อจะเอามาแสดงให้เห็นว่า เวลาเราใช้ OptBinning แล้วเราควรทำอย่างไรกับข้อมูลเหล่านี้ 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 นี้ก็น่าจะ ‘มีโอกาสพัฒนาแล้วได้ผลลัพธ์ที่ดี‘ เพราะถ้าตัวเลข 2 ตัวนี้ไม่ผ่าน (จำนวนน้อยกว่า) โอกาสที่ Model ที่เราจะพัฒนาแล้ว ‘ไม่แม่น‘ มีสูงมาก Aoddy 4.1 โหลดข้อมูลและเช็ค Baseline ## Load data 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 ทำการดึง Features ออกมา โดยแยกออกมาเก็บไว้ที่ ตัวแปร 2 ตัว สำหรับเก็บ Features ทั้งหมด และตัวแปรที่เก็บเฉพาะ Features ที่มีชนิดเป็น ‘Object’ และ ‘Category’ # 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 ดำเนินการสร้าง Criteria และ BinningProcess # Crelate criteria for BinningProcess selection_criteria = {"iv": {"min": 0.005, 'max':0.85, "strategy": "highest"}} # Instatiate 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 ) ตัว Creteria จะเป็นตัวที่เราใช้กำหนดว่า Feature ที่จะใช้ในการทำ Model นั้น ค่า IV จะต้องมากกว่า 0.005 และสูงสุด ไม่เกิน 0.85 ส่วนตัว strategy จะมีได้ 2 ค่า คือ ‘highest’ และ ‘lowest’ ในที่นี้เราเลือก ‘highest’ ส่วนตัว BinningProcess ก็จะมีการกำหนดโดยจะทำการบอกให้ Binning รู้ว่า Feature ทั้งหมดมีอะไรบ้าง และ Feature ไหนเป็น Object/Category (ที่เหลือเป็นตัวเลข) หลังจากนั้นก็ดำเนินการสั่ง fit ข้อมูล Binning binning_process.fit(df_train, y_train) binning_process เมื่อเราทำการ fit แล้วจำเป็นต้องเก็บค่านี้ไว้ด้วยนะครับ (เดี๋ยวจะมาเล่าว่าเก็บยังไง) เพราะตอนเราไปใช้ Production เราก็จะเอา Binning ชุดนี้ไป Transform กับข้อมูลชุดใหม่ทุกครั้ง เราสามารถเช็ค Binning Table คร่าวๆ ได้ว่า ค่า Feature ไหนผ่าน Criteria, มีค่า gini / iv เท่าไหร่ และ มีจำนวน bin ที่ได้กี่ Bin ในแต่ Features มีอะไรบ้าง ด้วย command binning_process.summary().head(20) 4.3 สร้าง Pipeline และ Models พอเราได้ Binning Data เราก็จะเอาข้อมูลนี้ไป fit กับ Model ผ่านตัว Pipeline โดยเราจะสร้าง Model ขึ้นมา 2 อันเพื่อเปรียบเทียบระหว่าง XGBoost กับ LogisticRegression MD1 = Pipeline(steps=[('binning_process', binning_process), ('xgb_model', xgb.XGBClassifier())]) MD2 = Pipeline(steps=[('binning_process', binning_process), ('classifier', LogisticRegression(solver="lbfgs"))]) เอา Pipeline ที่เพิ่งสร้างขึ้นมา นำไป Fit กับข้อมูลที่จะใช้ Train Data 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 คำนวณหา ROC_AUC แล้วเอาไปลอง Plot Graph เพื่อเปรียบเทียบ 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() จากกราฟด้านบนก็จแสดงให้เห็นว่า เราควรจะเลือก ML2 เพื่อค่า ROC_AUC สูงกว่า ML1 นั่นเอง ทั้งนี้ขั้นตอนถัดไปก็ถือว่าเป็นขั้นตอนที่สำคัญมาก ก็คือ ขั้นตอนการ Export ทั้งในส่วนของ Model และ Binning_Process มาเก็บเป็นไฟล์ไว้ เพื่อที่เราจะนำ ไฟล์นี้ไปใช้อีกครั้งตอน Deployment ขึ้น Production ครับ 5.1 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 ผิด แล้วจะผิดพลาดได้ที่จุดไหนได้บ้าง ผิดที่ขั้นตอนการเตรียมข้อมูล อย่างที่เรารูักันว่า ตอนเราทำ Model เรารู้ ‘คำตอบ’ หรือ มี Target ครบอยู่แล้ว แต่ ตอนขึ้น Production จริง เราจะยังไม่มี ‘คำตอบ’ ดังนั้นเพื่อป้องกันความสับสนสำหรับการเตรียมข้อมูล ให้กลับไปดูรูป ที่ข้อ 2 ให้ดีๆ ว่า จริงๆแล้ว ตอน Production เราอยู่ ณ จุดไหนของช่วงเวลา Transform ตอน Train Data ยังไง ตอนขึ้น Production ก็ต้อง Transform ตาม Step เหมือนตอน Train เป๊ะๆ และ ที่สำคัญที่สุดคือ “ห้าม Fit” ข้อมูลใหม่เพื่อทำ Model เด็ดขาด ซึ่งขั้นตอนที่สำคัญในการ Deployment ก็คือ การ Load Model & Configuration Data ต่างๆ x_all_features, binning_process, model = pickle.load(open("models/CREDIT_SCORE_202212.pickle", 'rb')) นำค่าที่ Load ได้มาใช้งาน oper_df = pd.load_csv('data/production_data.csv'); y_pred = model.predict(binning_process.transform(oper_df[x_all_features])) y_pred_score = y_back_probs[:,1] มาถึงตอนนี้เราก็จะมี Score ให้กับลูกค้าของเราทั้งหมดละครับ แต่ก็อย่างที่บอกเรา Gen Score ออกมาเป็นค่า Probability ที่มีค่า 0-1 แต่เวลาที่หน้าบ้าน หรือ Business Unit เอาไปใช้งานจริงๆ เรามีความจำเป็นจะต้องทำการจัดกลุ่ม Score เหล่านี้เพื่อให้ทาง User หรือ BU เอาไปใช้งานได้ง่าย และ ที่สำคัญไปกว่านั้น คือ เราจะเอาการจัดกลุ่มนี้ มาเป็น 1 ในตัวชี้วัด Performance ของ Model ของเราด้วยครับ หรือ ที่เรียกว่า Rank Ordering ซึ่งเรื่องการจัดกลุ่ม Score นี้เดี๋ยวผมจะขอเอาไปเล่าในบทความถัดๆๆไป ครับ เพราะตอนนี้ บทความนี้จะเริ่มยาวมากๆๆละ ขอให้สนุกกับการพัฒนา Model นะครับ Reference https://towardsdatascience.com/developing-scorecards-in-python-using-optbinning-ab9a205e1f69 http://gnpalencia.org/optbinning/ AoddyLifelong learning | Data Analytics | Algorithmic Trading | Quantmania | Wife Lover www.aoddy.com Post Views: 1,729 Data Science Machine Leaning Credit ScoreMachine Learning