멀티 클래스 데이터 세트에서 분류가 잘못되는 불균형 데이터


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 교차 유효성 검사는 클래스 배포도 고려합니다.
Kasra Manshaei

답변:


6

좋은 질문!

일부 비고

불균형 데이터의 경우 다른 접근 방식이 있습니다. 가장 잘 확립 된 것은 리샘플링입니다 (작은 클래스 오버 샘플링 / 큰 클래스 언더 샘플링). 다른 하나는 분류를 계층 적으로 구성하는 것입니다. 즉, 큰 클래스를 다른 클래스와 분류 한 다음 작은 클래스를 두 번째 단계로 분류합니다 (분류자는 동일하지 않아야합니다. 최상의 결과를 얻으려면 모델 선택 전략을 시도하십시오).

실용 답변

데이터를 리샘플링하지 않고 수용 가능한 결과를 얻었습니다! 따라서 다시 시도하지만 나중에 리샘플링 방법을 사용하여 개선하십시오 (통계적으로 A MUST입니다).

TFIDF는 이러한 문제에 적합합니다. 분류자는 모델 선택을 통해 선택해야하지만 내 경험에 따르면 Logistic Regression 및 Random Forest는이 특정 문제에서 잘 작동합니다 (단, 실제 경험 일 뿐임).

간단하게 작동하는 코드를 따라갈 수 있으며 결과를 개선하기 위해 코드를 수정 해 볼 수 있습니다.

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 Methods 제품군의 메타 학습 전략입니다 . 그들은 다른 분류 자로부터 혜택을받습니다. 실제로 실제로 잘 작동 할 때 시도하십시오.

투표 스키마는 단순히 여러 분류기의 결과를 가져와 올바른 가능성이 가장 높은 분류기의 출력을 반환합니다. 독재에 반대하는 민주주의 적 접근 방식;)

그것이 도움이되기를 바랍니다!


어서 오십시오! 직관적 인 리샘플링을 위해 리샘플링을 위해 넣은 링크를 참조 할 수 있습니다. 단계별 지침이 있습니다.
Kasra Manshaei

나는 당신의 해결책을 시도하고 있습니다. 어딘가에 붙어 있거나 의심이있는 경우 의견 섹션에 게시 할 것입니다. 그것이 당신에게 좋을 수 있기를 바랍니다!
outlier

내 친구 야 ... 행운을 빌어!
Kasra Manshaei

1
그것이 효과가 있었다면 당신은 답을 받아 들일 것입니다 :)
Kasra Manshaei

@outlier 답변이 귀하의 문제를 해결 한 이후 친절하게 수락 (및 가능하게 투표)합니다. 답변은 (자원 봉사자) 응답자에게 귀중한 시간이 걸립니다
desertnaut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.