scikit-learn의 class_weight 매개 변수는 어떻게 작동합니까?
나는 어떻게 그것을 이해하는 것에 많은 어려움을 겪고 있습니다.class_weightoperates.skikit-learn's operating.skikit-learn's 로지모의 ▁in▁parameter▁sc작다모동합가니▁reg수지로sk스s▁operateslearns
상황
로지스틱 회귀 분석을 사용하여 매우 불균형한 데이터 집합에 대해 이항 분류를 수행하려고 합니다.클래스는 0(음성) 및 1(양성)으로 표시되며, 관측된 데이터는 약 19:1의 비율이며 대부분의 샘플은 음성 결과를 갖습니다.
첫 번째 시도: 교육 데이터 수동 준비
제가 가지고 있던 데이터를 교육 및 테스트를 위해 분리된 세트로 분할했습니다(약 80/20).그런 다음 19:1 -> 16:1의 비율로 교육 데이터를 얻기 위해 손으로 무작위로 교육 데이터를 샘플링했습니다.
그런 다음 이러한 서로 다른 훈련 데이터 하위 집합에 대한 로지스틱 회귀 분석을 훈련하고 서로 다른 훈련 비율의 함수로 호출(= TP/(TP+FN))을 표시했습니다.물론, 리콜은 관찰된 비율이 19:1인 분리된 TEST 샘플에 대해 계산되었습니다.참고로, 저는 다른 훈련 데이터에 대해 다른 모델을 훈련했지만, 동일한 (분리된) 테스트 데이터에 대한 모든 모델에 대한 리콜을 계산했습니다.
결과는 예상대로였습니다. 리콜은 2:1 훈련 비율로 약 60%였고 16:1에 도달할 때쯤에는 다소 빠르게 감소했습니다.리콜이 5% 이상인 비율은 2:1 -> 6:1이었습니다.
두 번째 시도: 그리드 검색
저는 다양한 하여 GridSearchCV의 .C 변수 및 개변수및class_weight매개 변수내 n:m 비율의 음: 양성 훈련 샘플을 사전 언어로 변환하려면class_weight다음과 같이 몇 개의 사전을 지정하면 된다고 생각했습니다.
{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 } #expected 4:1
그리고 나는 또한 포함시켰습니다.None그리고.auto.
이번에는 결과가 완전히 엉망이 되었습니다.의 모든 제 리 모 콜 은 모 값 든 아 대 작 은 주 나 습 났 니 타 것 다 로 으 든 해 에 < ) ▁all < 니 ▁0 습 ▁0 ▁out ) ▁tiny ▁value ▁for ▁came ▁of ▁every 제 다 ▁recalls 05 ▁my 났 나 타 모 든 리class_weight외하고를 auto그래서 나는 단지 어떻게 설정하는지에 대한 나의 이해가class_weight사전이 잘못되었습니다. 미롭게도그흥, 그▁interest롭.class_weight에서 '값은 그드검색 'auto'의 약였습니다.C1?1:1로 ?
내 질문
을 어떻게 합니까?
class_weight교육 데이터에서 실제 제공하는 것과 다른 균형을 달성하는 것?구체적으로 어떤 사전에 전달해야 합니까?class_weight음: 양성 훈련 샘플의 n:m 비율을 사용하려면?여러 가지를 통과하면,
class_weight그리드서치CV에 대한 사전, 교차 검증 중에 사전에 따라 교육용 접기 데이터를 재조정하지만 시험 접기에서 내 채점 함수를 계산하기 위해 실제 주어진 샘플 비율을 사용합니까?모든 메트릭은 관측된 비율의 데이터에서 가져온 경우에만 유용하기 때문에 이는 매우 중요합니다.입니까?
auto의 값class_weight비율만큼 합니까?설명서를 읽어보니 "데이터의 주파수에 반비례하여 균형을 유지한다"는 것은 1:1이 된다는 것을 의미하는 것 같습니다.이거 맞는건가요?만약 그렇지 않다면, 누가 명확히 할 수 있습니까?
우선, 리콜만으로 진행하는 것은 좋지 않을 수 있습니다.모든 것을 양의 클래스로 분류하면 100%의 리콜을 달성할 수 있습니다.일반적으로 AUC를 사용하여 매개 변수를 선택한 다음 관심 있는 작동 지점(예: 지정된 정밀도 수준)의 임계값을 찾는 것이 좋습니다.
ㅠㅠㅠclass_weight작업: 샘플의 실수를 처벌합니다.class[i]와 함께class_weight[i]1 에 에 신▁means▁class 더 높은 계급 가중치는 더을 의미합니다.그래서 더 높은 계급 비중은 여러분이 계급에 더 중점을 두고 싶어한다는 것을 의미합니다.당신의 말을 들어보면 0반이 1반보다 19배나 더 많은 것 같습니다.그래서 당신은 그것을 증가시켜야 합니다.class_weight클래스 0을 기준으로 클래스 1의 {0:.1, 1:.9}을 입력합니다.에 약에만.class_weight합계가 1이 아니라 기본적으로 정규화 매개 변수가 변경됩니다.
ㅠㅠㅠclass_weight="auto"작동합니다. 이 토론을 볼 수 있습니다.개발 버전에서 사용할 수 있습니다.class_weight="balanced"이는 더 이해하기 쉽습니다. 기본적으로 더 작은 클래스를 더 큰 클래스와 같은 수의 샘플이 있을 때까지 복제하는 것을 의미하지만 암묵적인 방식으로 복제하는 것을 의미합니다.
첫 번째 답은 그것이 어떻게 작동하는지 이해하는 데 좋습니다.하지만 실제로 어떻게 사용해야 하는지 알고 싶었습니다.
불균형 사용 - 학습
불균형 데이터의 경우 불균형 학습의 방법은 클래스 가중치 매개 변수를 사용하는 것보다 샘플 내 및 특히 샘플 외부에서 더 나은 결과를 생성합니다.
요약
- 노이즈가 없는 중간 정도의 불균형 데이터의 경우 클래스 가중치를 적용하는 데 큰 차이가 없습니다.
- 노이즈와 강한 불균형이 있는 중간 정도의 불균형 데이터의 경우 클래스 가중치를 적용하는 것이 좋습니다.
- .
class_weight="balanced"으로 최적화하려는 합니다. - 와 함께
class_weight="balanced"더 많은 실제 이벤트(TRUE 리콜 증가)를 캡처하지만 잘못된 경고(TRUE 정밀도 감소)를 수신할 가능성이 더 높습니다.- 결과적으로 모든 잘못된 긍정 때문에 총 % TRUE가 실제보다 높을 수 있습니다.
- 잘못된 경보가 문제인 경우 AUC가 잘못 안내할 수 있습니다.
- 의사결정 임계값을 불균형 %로 변경할 필요 없음, 강한 불균형의 경우에도 0.5를 유지하는 것이 좋습니다(또는 필요한 사항에 따라 그 주변 어딘가).
NB
RF 또는 GBM을 사용할 경우 결과가 다를 수 있습니다.sklearn에는 없습니다. class_weight="balanced"GBM용이지만 lightgbm은LGBMClassifier(is_unbalance=False)
코드
# scikit-learn==0.21.3
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, classification_report
import numpy as np
import pandas as pd
# case: moderate imbalance
X, y = datasets.make_classification(n_samples=50*15, n_features=5, n_informative=2, n_redundant=0, random_state=1, weights=[0.8]) #,flip_y=0.1,class_sep=0.5)
np.mean(y) # 0.2
LogisticRegression(C=1e9).fit(X,y).predict(X).mean() # 0.184
(LogisticRegression(C=1e9).fit(X,y).predict_proba(X)[:,1]>0.5).mean() # 0.184 => same as first
LogisticRegression(C=1e9,class_weight={0:0.5,1:0.5}).fit(X,y).predict(X).mean() # 0.184 => same as first
LogisticRegression(C=1e9,class_weight={0:2,1:8}).fit(X,y).predict(X).mean() # 0.296 => seems to make things worse?
LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X).mean() # 0.292 => seems to make things worse?
roc_auc_score(y,LogisticRegression(C=1e9).fit(X,y).predict(X)) # 0.83
roc_auc_score(y,LogisticRegression(C=1e9,class_weight={0:2,1:8}).fit(X,y).predict(X)) # 0.86 => about the same
roc_auc_score(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X)) # 0.86 => about the same
# case: strong imbalance
X, y = datasets.make_classification(n_samples=50*15, n_features=5, n_informative=2, n_redundant=0, random_state=1, weights=[0.95])
np.mean(y) # 0.06
LogisticRegression(C=1e9).fit(X,y).predict(X).mean() # 0.02
(LogisticRegression(C=1e9).fit(X,y).predict_proba(X)[:,1]>0.5).mean() # 0.02 => same as first
LogisticRegression(C=1e9,class_weight={0:0.5,1:0.5}).fit(X,y).predict(X).mean() # 0.02 => same as first
LogisticRegression(C=1e9,class_weight={0:1,1:20}).fit(X,y).predict(X).mean() # 0.25 => huh??
LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X).mean() # 0.22 => huh??
(LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict_proba(X)[:,1]>0.5).mean() # same as last
roc_auc_score(y,LogisticRegression(C=1e9).fit(X,y).predict(X)) # 0.64
roc_auc_score(y,LogisticRegression(C=1e9,class_weight={0:1,1:20}).fit(X,y).predict(X)) # 0.84 => much better
roc_auc_score(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X)) # 0.85 => similar to manual
roc_auc_score(y,(LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict_proba(X)[:,1]>0.5).astype(int)) # same as last
print(classification_report(y,LogisticRegression(C=1e9).fit(X,y).predict(X)))
pd.crosstab(y,LogisticRegression(C=1e9).fit(X,y).predict(X),margins=True)
pd.crosstab(y,LogisticRegression(C=1e9).fit(X,y).predict(X),margins=True,normalize='index') # few prediced TRUE with only 28% TRUE recall and 86% TRUE precision so 6%*28%~=2%
print(classification_report(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X)))
pd.crosstab(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X),margins=True)
pd.crosstab(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X),margins=True,normalize='index') # 88% TRUE recall but also lot of false positives with only 23% TRUE precision, making total predicted % TRUE > actual % TRUE
언급URL : https://stackoverflow.com/questions/30972029/how-does-the-class-weight-parameter-in-scikit-learn-work
'programing' 카테고리의 다른 글
| 파이어베이스의 블레이즈 계획을 제한할 방법이 있습니까? (0) | 2023.06.07 |
|---|---|
| 엑셀 공식을 읽을 수 있는 방식으로 다시 쓰는 방법은? (0) | 2023.06.07 |
| Visual Studio Code에서 로컬 웹 서버를 설정하는 방법 (0) | 2023.06.07 |
| excelLibrary로 생성된 excel 파일을 열 수 없습니다. (0) | 2023.06.07 |
| ASP.NET MVC에서 HTML 문자열을 렌더링하는 방법은 무엇입니까? (0) | 2023.06.07 |