マルチクラスデータセットで誤った分類を引き起こす不均衡なデータ


9

39のカテゴリ/クラスと850万件のレコードがあるテキスト分類に取り組んでいます。(将来的にはデータとカテゴリーが増えるでしょう)。

私のデータの構造またはフォーマットは次のとおりです。

----------------------------------------------------------------------------------------
| product_title          | Key_value_pairs                               | taxonomy_id |
----------------------------------------------------------------------------------------
  Samsung S7 Edge        | Color:black,Display Size:5.5 inch,Internal    | 211 
                          Storage:128 GB, RAM:4 GB,Primary Camera:12 MP  

  Case cover Honor 8     | Color:transparent,Height:15 mm,width:22 mm    | 212 

  Ruggers Men's T-Shirt  | Size:L,ideal for:men,fit:regular,             | 111
                          sleeve:half sleeve

  Optimum Nutrition Gold | Flavor:chocolate,form:powder,size:34 gm       | 311
  Standard Whey Protein  

データの分布は正常ではありません。それは非常に不均衡です:

-------------------------
| taxonomy_id |   count |
-------------------------
          111 |  851750 
          112 |  355592
          113 |  379433
          114 |   23138
          115 |  117735
          116 |  145757
          117 | 1339471
          121 |  394026
          122 |  193433
          123 |   78299
          124 |  111962
          131 |    1776
          132 |    4425
          133 |     908
          134 |   23062
          141 |   22713
          142 |   42073
          211 |    7892
          212 | 1574744
          221 |    1047
          222 |  397515
          223 |   53009
          231 |    1227
          232 |    7683
          251 |     739
          252 |     327
          253 |   38974
          254 |      25
          311 |    2901
          321 |    7126
          412 |     856
          421 |  697802
          422 |  414855
          423 |   17750
          425 |    1240
          427 |     658
          429 |    1058
          431 |   20760
          441 |     257       

ご覧のとおり、それらは非常に不均衡であり、誤分類につながっています。

これまでに実行した手順

1)product_titleとkey_value_pairs列をマージし、ストップワードと特殊文字を削除してステミングを実行します。

2)TFIDFvectorizer()、LinearSVC()にパイプラインを使用しました

vectorizerPipe = Pipeline([
                 ('tfidf', TfidfVectorizer(lowercase=True, stop_words='english')),
                 ('classification', OneVsRestClassifier(LinearSVC(penalty='l2', loss='hinge'))),
                 ])

この後、パイプラインを適合させ、分類器をピクルスに格納しました

prd = vectorizerPipe.fit(df.loc[:, 'description'], df.loc[:, 'taxonomy_id'])

テスト側では、上記のようにステップ1を繰り返し、次にピクルスをロードして予測関数を使用しました

pd = cl.predict([testData])

私が直面している問題

  1. 多くの製品が他のいくつかのカテゴリに誤って分類されています

    例:Ultimate Nutrition Prostar 100%ホエイプロテインはカテゴリ311に分類する必要がありますが、私の分類子はそれを222として分類していますが、これは完全に間違っています。

  2. TFidfVectorizer()とHashingvectorizer()のどちらを使用するかわからないのですが、パラメーターと一緒にこれを選択するのを手伝っていただけますか?

  3. 私が使用しているアルゴリズムはLinearSVCですが、大量のデータを含むマルチクラス分類問題に適していますか?または、別のアルゴリズムを使用する必要がありますか?

  4. 私のデータは非常に不均衡なので、ランダムアンダーサンプリングを試しました。結果は改善されましたが、まだ基準に達していませんでした。また、これがランダムアンダーサンプリングを実行する適切なアプローチであるかどうかもわかりません。

    pipe = make_pipeline_imb(
        HashingVectorizer(lowercase=True),
        RandomUnderSampler(ratio={111: 405805, 112: 170431, 113: 241709, 114: 8341, 115: 50328, 116: 89445, 117: 650020, 121: 320803, 122: 162557, 123: 66156, 124: 36276, 131: 1196, 132: 3365, 133: 818, 134: 15001, 141: 6145, 142: 31783, 211: 24728, 212: 100000, 221: 791, 222: 8000, 223: 35406, 231: 785, 232: 3000, 251: 477, 252: 127, 253: 29563, 254: 33, 311: 2072, 321: 5370, 412: 652, 421: 520973, 422: 99171, 423: 16786, 425: 730, 427: 198, 429: 1249, 431: 13793, 441: 160},random_state=1), 
        OneVsRestClassifier(LinearSVC(penalty='l2', loss='hinge')))
  5. 私は機械学習の初心者なので、この方法をテキスト分類に使用しました。私のアプローチが間違っている場合は、正しい方法で修正してください。

(私がよりよく理解するのに役立つので、例を挙げて提案や解決策を提供してくれると素晴らしいでしょう)

***編集-1 ****

RndmFrst = RandomForestClassifier(n_estimators=100, max_depth=20, max_features=5000,n_jobs=-1)
LogReg = LogisticRegression()
voting = VotingClassifier(estimators=[('LogReg ', LogReg), ('RndmFrst', RndmFrst)], voting='soft', n_jobs=-1)

pipe = Pipeline([('tfidf', TfidfVectorizer(ngram_range=(1,4), max_features=50000)), ('clf', voting)])

pipe = pipe.fit(df.loc[:,'description'], df.loc[:,'taxonomy_id'])
Preds = pipe.predict(test_data)

アンダーサンプリングを試してみたのを見ました。ちなみに、Sci-Kit LearnのStartified K-fold cross validationでは、クラスの分布も考慮されています。
Kasra Manshaei、2018

回答:


6

いい質問だ!

いくつかの備考

不均衡なデータについては、さまざまなアプローチがあります。最もよく確立されているのはリサンプリングです(小さなクラスのオーバーサンプリング /大きなクラスのアンダーサンプリング)。もう1つは、分類を階層化することです。つまり、大きなクラスを他のクラスすべてに対して分類し、次に2番目のステップで小さなクラスを分類します(分類子は同じであるとは限りません。最適なものを見つけるためにモデル選択戦略を試してください)。

実用的な答え

データをリサンプリングせずに許容できる結果が得られました!試してみてくださいが、後でリサンプリングメソッドを使用して改善してください(統計的には、これらは一種の必須条件です)。

TFIDFはこのような問題に適しています。分類子はモデルの選択を通じて選択する必要がありますが、私の経験では、ロジスティック回帰とランダムフォレストがこの特定の問題にうまく機能することが示されています(ただし、実際の経験にすぎません)。

以下のコードをたどることで簡単に機能し、結果を改善するためにコードを変更してみることができます。

train = pd.read_csv(...)
test = pd.read_csv(...)    

# TFIDF Bag Of Words Model For Text Curpos. Up to 4-grams and 50k Features
vec = TfidfVectorizer(ngram_range=(1,4), max_features=50000)
TrainX = vec.fit_transform(train)
TestX = vec.transform(test)


# Initializing Base Estimators
clf1 = LogisticRegression()
clf2 = RandomForestClassifier(n_estimators=100, max_depth=20, max_features=5000,n_jobs=-1)

# Soft Voting Classifier For Each Column
clf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2)], voting='soft', n_jobs=-1)
clf = clf.fit(TrainX, TrainY)
preds = clf.predict_proba(TestX)[:,1]

コードは抽象的であるため、TianX、TrainY、TestXなどを適切に定義する必要があることに注意してください。

ヒント

StopWordとは何かに注意してください。実質的に多くの人々(私を含む!)は、事前定義されたリストに従ってストップワードを削除するためにこの間違いを犯しました。それはあってない!

ストップワードはコーパスの影響を受けやすいので、情報理論の概念に従ってストップワードを削除する必要があります(簡単にするために、TFIDFがコーパス固有のストップワードを無視することを知っている必要があります。詳細な説明が必要な場合は、回答を更新してください。) 。

VotingClassifierは、Ensembleメソッドファミリーのメタ学習戦略です。さまざまな分類子を利用します。それらは実際にはかなりうまくいくので試してみてください。

投票スキーマは、単に異なる分類子の結果を取得し、正しい可能性が最も高い分類子の出力を返します。だから、独裁に対する民主的なアプローチの一種です;)

それが役に立てば幸い!


ようこそ!直感的なリサンプリングについては、リサンプリングのために置いたリンクを参照してください。ステップバイステップの説明があります。
Kasra Manshaei、2018

私はあなたの解決策を試しています、私がどこかで動けなくなったり、疑問がある場合はコメント欄に投稿します。よろしくお願いします!
外れ値

友達よ…頑張ってね!
Kasra Manshaei、2018

1
それがうまくいったなら、あなたは答えを受け入れるかもしれません:)
Kasra Manshaei 2018

@outlier回答があなたの問題に対処したので、親切に受け入れて(そしておそらく賛成票を投じて)ください。(ボランティア)回答者にとって回答は貴重な時間を
費やす
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.