<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用分類權(quán)重解決數(shù)據(jù)不平衡的問題

          共 3830字,需瀏覽 8分鐘

           ·

          2022-08-11 19:59

          推薦關注↓

          在分類任務中,不平衡數(shù)據(jù)集是指數(shù)據(jù)集中的分類不平均的情況,會有一個或多個類比其他類多的多或者少的多。

          在我們的日常生活中,不平衡的數(shù)據(jù)是非常常見的比如本篇文章將使用一個最常見的例子,信用卡欺詐檢測來介紹,在我們的日常使用中欺詐的數(shù)量要遠比正常使用的數(shù)量少很多,對于我們來說這就是數(shù)據(jù)不平衡的問題。

          我們使用kaggle上的信用卡交易數(shù)據(jù)集作為本文的數(shù)據(jù)集。數(shù)據(jù)的細節(jié)不是特別重要。因為為了進行脫敏,這個數(shù)據(jù)集的特征是經(jīng)過PCA降維后輸出的,所以討論這些特征代表什么沒有任何意義。除了PCA輸出的特征以外,這個數(shù)據(jù)集還包括與每筆交易相關的美元金額、以秒為單位的連續(xù)時間索引,以及一個表示存在或不存在欺詐的二進制目標。對于時間索引,我們考慮到某些特征工程,它可能會很有用,但這不是本文的重點。對于我們真實可見的數(shù)據(jù)只有金額一項,這個很重要!

          我們再看看目標,在284,807行數(shù)據(jù)中只有0.173%的行是欺詐案例,這絕對是不平衡數(shù)據(jù)的樣例,這種數(shù)據(jù)的分布會使建模和預測欺詐行為變得有非常的棘手。

          性能指標

          在不平衡數(shù)據(jù)時,可以使用幾個有價值的性能指標來了解模型的性能。通常情況下,指標的選擇很大程度上取決于應用以及與正負相關的結(jié)果。單獨的一種方法不能適用于所有人。

          在信用卡欺詐的背景下,我們不會對產(chǎn)生高準確度分數(shù)的模型感興趣。因為數(shù)據(jù)集非常不平衡欺詐的數(shù)據(jù)很少,如果我們將所有樣本分類為不存在欺詐,那么準確率還是很高。但是我們對準確預測信用卡交易何時不存在欺詐不感興趣,我們關心的是信用卡是否存在欺詐,也就是樣本量少的分類是否能夠被判斷出來。

          最簡單的辦法就是召回分數(shù)作為模型性能的主要指標。召回是衡量有多少正面案例被模型準確預測的指標。在我們的特定用例中,更高的召回分數(shù)意味著我們檢測到更多的欺詐案例。

          在本文中,我們除了使用召回以外還將分類與最后的財務指標相結(jié)合,還記得我們前面提到的數(shù)據(jù)集的包含交易的美元金額嗎?我們也將把它納入績效評估,稱之為“財務召回”。我們將在下面詳細介紹。

          數(shù)據(jù)準備

          首先,讓我們讀入數(shù)據(jù),并將其分成訓練集和測試集:

          import pandas as pdfrom sklearn.model_selection import train_test_split
          df = pd.read_csv('creditcard.csv')
          # enumerate the feature columnsfeats = [col for col in df.columns if 'V' in col]
          # Split datax = df[feats + ['Amount']]y = df['Class']
          X_train, X_test, y_train, y_test = train_test_split( x, y, test_size=.2, stratify=y, random_state=41)

          如果以前沒有在train_test_split中使用過stratify參數(shù),那么在處理不平衡數(shù)據(jù)時應該使用該參數(shù),train_test_split分割后欺詐案例的比例會根據(jù)傳遞列的比例進行分配(具體使用方法可以查看sklearn的文檔),我們的目標是為了確保我們在訓練集和測試集中保持相同比例類別分布。

          基類模型

          我們將創(chuàng)建并訓練一個基本的邏輯回歸模型作為基線。但在此之前我們先創(chuàng)建一個小函數(shù),將每筆交易的金額納入性能評估。

          因為關心的是能夠正確分類的欺詐案件的數(shù)量,并且我們也關心(可能更關心)將欺詐損失的美元保持在最低限度。這就是我們之前討論的“財務召回”。讓我們創(chuàng)建一個函數(shù)來計算正確識別的欺詐金額:

          from sklearn.metrics import recall_score
          def assess_test_set_performance(model): # create predictions yhat = model.predict(X_test[feats]) # evaluate performance using counts model_recall = recall_score(y_test, yhat)*100 print("Classification Test Performance:") print(f"Recall: {model_recall:.2f}%") # calculate financial performance using the dollar amount associated with each transaction performance_df = pd.DataFrame({'Amount':X_test['Amount'], 'Actual':y_test, 'Pred':yhat}) performance_df['fraud_amount'] = performance_df['Amount']*performance_df['Actual'] performance_df['fraud_prevented'] = performance_df['fraud_amount']*performance_df['Pred'] performance_df['fraud_realized'] = performance_df['fraud_amount'] - performance_df['fraud_prevented'] financial_recall = (performance_df['fraud_prevented'].sum() / (performance_df['fraud_prevented'].sum() + performance_df['fraud_realized'].sum()))*100
          print() print("Financial Test Performance:") print(f"Financial Recall: {financial_recall:.2f}%")

          現(xiàn)在我們已經(jīng)確定了評估函數(shù),讓我們訓練基線模型并評估它的性能:

          from sklearn.linear_model import LogisticRegression
          baseline_model = LogisticRegression()baseline_model.fit(X_train[feats], y_train)
          assess_test_set_performance(baseline_model)

          我們的基線模型實現(xiàn)了59%的召回和61%的財務召回,這實際上比預期的要好。但是這在實際使用時肯定不好,所以其實我們可以做的更好。

          改進模型加入類權(quán)重

          基線模型將兩個類設置成同等重要,因為模型不知道我們更關心欺詐的情況,所以我們需要重新定義我們的損失函數(shù)。sklearn API提供了讓模型知道對正確識別欺詐的偏好:class_weight參數(shù)。

          當使用class_weight時,模型接收一個字典,每個類都有一個鍵,其中的值是該類的權(quán)重。我們有兩類,為了說明這個例子,我們假設欺詐案的重要性是前者的10倍。在這種情況下,我們可以像這樣向class_weight傳遞一個字典:

          fraud_class_weights = {0:1, 1:10}

          但是sklearn API實際上使這個過程更容易。class_weight參數(shù)也可以取'balanced'的值。我們需要做的是使用下面的公式建立一個字典,其中權(quán)重與數(shù)據(jù)中的類分布成比例:

          len(X_train) / (2 * numpy.bincount(y_train))

          將上面的公式應用到我們的數(shù)據(jù)中,我們估計正情況實際上比負情況重要575倍。

          當我們把這個新的代碼放到邏輯回歸模型中時,它將更專注于正確地對我們的欺詐交易進行分類。這正是我們想要的結(jié)果!

          讓我們設置它,然后研究性能:

          lr_class_weights = LogisticRegression(class_weight='balanced')lr_class_weights.fit(X_train[feats], y_train)
          assess_test_set_performance(lr_class_weights)

          這個簡單的改變將使我們的召回率提高到90%和93% !因為現(xiàn)在對欺詐更加敏感,比使用基線模型準確地識別更多的欺詐案例。

          總結(jié)

          在模型中使用class_weight肯定會幫助從模型中獲得更多相關的性能。并且它很容易設置,至少值得試一試。本文中介紹的方法是解決分類不平衡問題的一種過簡單的方法,在這個領域中還有許多其他的方法可以討論,但是為分類設置權(quán)重是一個非常好的開始。

          長按或掃描下方二維碼,后臺回復:加群,即可申請入群。一定要備注:來源+研究方向+學校/公司,否則不拉入群中,見諒!

          長按三秒,進入后臺


          推薦閱讀

          瀏覽 37
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆国产原创 | 91爱搞 | 久热中文在线观看精品视频 | 做aAAAAA免费视频 | a看一级免费视频 |