Conformal Prediction คืออะไร แบบเบื้องต้นสุดๆๆๆๆๆๆ

machine learning

Conformal Prediction คืออะไร ?

alt text ภาพจาก paper UNCERTAINTY SETS FOR IMAGE CLASSIFIERS USING CONFORMAL PREDICTION (link)

ตัวอย่าง Use Case recommendation

Backgound

Solution

ถ้าทำแบบไม่ใช้ conformal prediction

ถ้าเราทำด้วย conformal prediction

คุณสมบัติที่น่าสนใจของ Conformal Prediction

การทำ Conformal Prediction เบื้องต้น

Requirement

Step-by-Step

ในบทความนี้จะยกตัวอย่างเป็นโจทย์ classification ง่าย ๆ แบบ news classification แล้วกันนะครับ โดยเดี๋ยวเราจะทำไปทีละขั้นตอนดังแสดงในภาพด้านล่าง

alt text

  1. load training dataset แล้ว train model กับ training set ไปก่อน

     from sklearn.feature_extraction.text import TfidfVectorizer
     from sklearn.naive_bayes import MultinomialNB
    
     categories = ['alt.atheism', 'talk.religion.misc',
                 'comp.graphics', 'sci.space']
     newsgroups_train = fetch_20newsgroups(subset='train',
                                         categories=categories)
     vectorizer = TfidfVectorizer()
     vectors = vectorizer.fit_transform(newsgroups_train.data)
     clf = MultinomialNB(alpha=.01)
     clf.fit(vectors, newsgroups_train.target)
    
  2. load unseen dataset (dataset ที่โมเดลไม่เคยเห็น) แล้วแบ่งข้อมูลออกมาส่วนนึงเป็น validation set
     VALIDATION_SIZE = 800
     #  Get Unseen Data
     newsgroups_unseen = fetch_20newsgroups(subset='test', categories=categories)
     # TF-IDF
     vectors_unseen = vectorizer.transform(newsgroups_unseen.data)
     # Create validation set
     vectors_validation = vectors_unseen[:VALIDATION_SIZE]
     target_validation = newsgroups_unseen['target'][:VALIDATION_SIZE]
     ''' target_validation
     [1, 3, 1 ,2 , ...]
     '''
    
  3. เอาโมเดลที่เทรนในข้อที่ 1 มาทำนาย probability ของแต่ละ class ของข้อมูลใน validation set
     # Predict on Validation set
     probs = clf.predict_proba(vectors_validation)
     '''probs
     array([ [2.40876175e-06, 7.23547703e-07, 9.99991701e-01, 5.16698113e-06],
             ...,
             [6.21330945e-06, 9.99917854e-01, 7.12575466e-05, 4.67474432e-06]])
     '''
    
  4. คำนวณค่า conformal score (หรือ $s$) ซึ่งจะเป็นค่าที่บอกว่าค่าที่เราทำนายมันห่างจากความเป็นจริงเท่าไหร่ ซึ่งถ้าเป็นโจทย์ประเภท classification ที่ทำนาย probability ออกมา เราก็จะใช้เป็น 1 - probability ของ class ที่ถูกได้เลย ซึ่งถ้าเราจะปรับใช้กับโจทย์อื่น ๆ เราต้อง define เอาว่าตัว score นี้จะคำนวณยังไง เช่น ถ้าหากเป็น regression ก็อาจจะเอา |y_true - y_predict| อะไรแบบนี้ก็ได้
     conformal_scores = 1 - probs[list(range(VALIDATION_SIZE)), target_validation]
    
  5. จากนั้นเราจะหาค่า $\hat{q}$ ซึ่งเป็นค่า quantile ที่ $\frac{\left\lceil (n+1)(1-\alpha) \right\rceil}{n} $ ของ conformal score ใน validation set โดยที่
    • $\alpha$ คือ error rate มีค่าระหว่าง 0 ถึง 1 (ความน่าจะเป็นที่ใน set ที่ทำนายออกมาจะไม่มีค่าจริง) ซึ่งเราจะตั้งค่าเป็น 1%
    • $n$ คือจำนวนข้อมูลใน validation set นั่นเอง
       ALPHA = 0.01 # ต้องการให้ set ที่เป็นผลลัพธ์ของการทำนายมีโอกาสที่จะไม่มีค่าจริงอยู่ในนั้นแค่ 1%
       # Calculate quantile level
       qth = np.ceil((VALIDATION_SIZE+1)*(1-ALPHA))/VALIDATION_SIZE
       # Get value of the quantile 
       qhat = np.quantile(conformal_scores, qth, method='higher')
      
  6. พอเราได้ $\hat{q}$ มาแล้ว เราสามารถนำไปสร้าง set of prediction บน testing set หรือ $\mathcal{C}(X_{\text{test}})$ ได้โดยการ

    \begin{equation} \label{eq:xxx} \mathcal{C}(X_{\text{test}}) = \{ y : s(X_{\text{test}}, y) \leq \hat{q} \} \end{equation}

    ซึ่งก็คือ code ด้านล่าง

     # Create Testing set
     vectors_test = vectors_unseen[VALIDATION_SIZE:]
     target_test = newsgroups_unseen['target'][VALIDATION_SIZE:]
     # Predict (probability of each class)
     probs = clf.predict_proba(vectors_test)
     # Get Prediction Set
     s = (1-probs)
     pred = s < qhat
     ''' pred
     array([ [False, False,  True, False],
             [False, True,  True, True],
             ...,
             [False,  True, False, False]])
     '''
     prediction_set = [list(np.where(row)[0]) for row in pred]
     ''' prediction_set หรือ C(X_test)
     [[2], [1,2,3], ..., [1]]
     '''
    
  7. มาลองหา empirical error rate
     # Test (Calculate empirical Error)
     num_set_contain_actual = 0
     set_size_list = np.array([])
     for actual, pred_set in zip(target_test, prediction_set):
         if actual in pred_set:
             num_set_contain_actual += 1
         set_size_list += []
     print('Empirical Error: ', 1 - num_set_contain_actual/len(target_test))
     '''
     Empirical Error:  0.007233273056057921
     '''
    

    ซึ่งจะเห็นได้ว่าในบรรดาผลการทำนายบน testing set นั้นมีแค่ประมาณ 0.7% เท่านั้นที่ไม่มีค่าจริงอยู่ ซึ่งสอดคล้องกับค่า $\alpha$ ที่เราตั้งไว้ที่ 0.01 หรือ 1% ในข้อ 5

What’s Next

ที่จริง conformal prediction ยังมีท่าอื่น ๆ นี่น่าสนใจมากมาย เช่น

จากบทความนี้ผมคาดหวังว่าอย่างน้อยผู้อ่านน่าจะได้เห็นภาพว่า conformal prediction มันคืออะไรรร ใช้คร่าว ๆ ประมาณไหน ถ้าสนใจเพิ่มเติมและขยันก็อ่านได้ที่ reference ด้านล่าง ผมขอตัวไปอ่านอย่างอื่นต่อ จะได้มีอย่างอื่นมาเขียนให้อ่านกันต่อ (หรือถ้าขยันจะกลับมาเขียนบทความนี้เพิ่มให้ แหะ ๆ)

Reference