>

이 코드는 예측 값과 참 값을 기준으로 진 양성 비율, 오 탐지율, 진 양성 개수, 오 탐지 수를 반환하고 플로팅합니다.

def get_all_stats(y_true , y_pred) : 
    def perf_measure(y_true, y_pred):
        TP = 0
        FP = 0
        TN = 0
        FN = 0
        for i in range(len(y_true)): 
            if y_true[i] == 1 and y_pred[i] == 1:
                TP += 1
            if y_pred[i]==1 and y_true[i]!=y_pred[i]:
                FP += 1
            if y_true[i]== 0 and y_pred[i]==0:
                TN += 1
            if y_pred[i]==0 and y_true[i] != y_pred[i]:
                FN += 1
        if(FP == 0) : 
            FPR = 0;
        else : 
            FPR = FP / (FP + TN)
        if(TP == 0) : 
            TPR = 0
        else : 
            TPR = TP / (TP + FN)
        return(TN , FPR, FN , TPR , TP , FP)
    tn, fpr, fn, tpr, tp , fp = perf_measure(y_true, y_pred)
    return tpr , fpr , tp , fp
tpr1 , fpr1 , tp1 , fp1 = get_all_stats(y_true=[1,1,1] , y_pred=[1,0,0])
tpr2 , fpr2 , tp2 , fp2 = get_all_stats(y_true=[1,0,1] , y_pred=[0,1,0])
tpr3 , fpr3 , tp3 , fp3 = get_all_stats(y_true=[0,0,0] , y_pred=[1,0,0])
plt.figure(figsize=(12,6))
plt.tick_params(labelsize=12)
print(tpr1 , fpr1 , tp1 , fp1)
print(tpr2 , fpr2 , tp2 , fp2)
print(tpr3 , fpr3 , tp3 , fp3)
plt.plot([fpr1,fpr2,fpr3], [tpr1 , tpr2, tpr3], color='blue', label='')
plt.ylabel("TPR",fontsize=16)
plt.xlabel("FPR",fontsize=16)
plt.legend()

결과 ROC 플롯은 다음과 같습니다.

세 개의 서로 다른 위양성 및 진 양성 비율과 다른 임계 값을 모방하기 위해 get_all_stats 함수를 구현하여 이러한 값을 계산합니다.  다른 세 번

tpr1 , fpr1 , tp1 , fp1 = get_all_stats(y_true=[1,1,1] , y_pred=[1,0,0])
tpr2 , fpr2 , tp2 , fp2 = get_all_stats(y_true=[1,0,1] , y_pred=[0,1,0])
tpr3 , fpr3 , tp3 , fp3 = get_all_stats(y_true=[0,0,0] , y_pred=[1,0,0])

진실 값이 다음과 같이 1 또는 0으로 분류되는 9 개의 인스턴스가 있습니다. [1,1,1,1,0,1,0,0,0]

임계 값 1에서 예측 된 값은 [1,0,0] 입니다.  이 임계 값의 실제 값은 [1,1,1] 입니다. .

임계 값 2에서 예측 된 값은 [0,1,0] 입니다.  이 임계 값의 실제 값은 [1,0,1] 입니다. .

임계 값 3에서 예측 된 값은 [1,0,0] 입니다.  이 임계 값의 실제 값은 [0,0,0] 입니다. .

제작 된 분류기의 생성 된 플롯이 '일반적인'ROC 곡선과 다르다는 것을 알 수 있습니다.

처음으로 내려 가면 위양성 및 진 양성 비율이 감소하여 라인이 '뒤로 이동'합니다. ROC 곡선을 올바르게 구현 했습니까? 이 곡선에 대해 AUC를 계산할 수 있습니까?

  • 답변 # 1

    알겠습니다. 담당자가 많기 때문에 동기를 부여했습니다.->많은 사람들을 도왔습니다. 여기로갑니다.

    이 ROC 곡선은 의미가 없습니다. 문제는 다른 임계 값에서 데이터의 하위 집합에 대해서만 FPR/TPR을 계산한다는 것입니다. 각 임계 값에서 데이터의모두를 사용하여 FPR 및 TPR을 계산해야합니다. 따라서 플롯에 3 점이있는 것처럼 보이지만 y_true = [1,1,1,1,0,1,0,0,0] 에 대해 FPR/TPR에 한 점만 있어야합니다  그리고 y_pred = [1,0,0,0,1,0,1,0,0] . 그러나 실제 ROC 곡선을 확보하기 위해 y_pred 를 구성 할 수도 없습니다.  다른 임계 값에서의 값-실제 예측 된 확률에서 나온 다음 적절하게 임계 값을 설정해야합니다. numpy 를 사용하기 때문에 코드를 약간 수정했습니다. ;다음은 ROC 곡선을 계산하는 방법입니다.

    # start with the true labels, as you did
    y_true = np.array([1, 1, 1, 1, 0, 1, 0, 0, 0])
    # and a predicted probability of each being a "1"
    # I just used random numbers for these, but you would get them
    # from your classifier
    predictions = np.array([
        0.07485627, 0.72546085, 0.60287482,
        0.90537829, 0.75789236, 0.01852192,
        0.85425979, 0.36881312, 0.63893516
    ])
    # now define a set of thresholds (the more thresholds, the better
    # the curve will look). There's a smarter way to do this in practice
    # (you can sort the predicted probabilities and just have one threshold
    # between each), but this is just to help with understanding
    thresholds = np.linspace(0, 1, 11) # 0.1, 0.2, ..., 1.0
    fprs = []
    tprs = []
    # we can precompute which inputs are actually 1s/0s and how many of each
    true_1_idx = np.where(y_true == 1)[0]
    true_0_idx = np.where(y_true == 0)[0]
    n_true_1 = len(true_1_idx)
    n_true_0 = len(true_0_idx)
    for threshold in thresholds:
        # now, for each threshold, we use that on the underlying probabilities
        # to get the actual predicted classes
        pred_classes = predictions >= threshold
        # and compute FPR/TPR from those
        tprs.append((pred_classes[true_1_idx] == 1).sum() / n_true_1)
        fprs.append((pred_classes[true_0_idx] == 1).sum() / n_true_0)
    plt.figure(figsize=(12,6))
    plt.tick_params(labelsize=12)
    plt.plot(fprs, tprs, color='blue')
    plt.ylabel("TPR",fontsize=16)
    plt.xlabel("FPR",fontsize=16)
    
    

    FPR (x 축)이 증가함에 따라 ROC 곡선은 항상 TPR (y 축)에서 감소하지 않습니다. 즉, 오른쪽으로 이동하면 올라갑니다. 이는 임계 값 작동 방식에서 분명합니다. 임계 값이 0이면 모든 예측이 "1"이므로 FPR = TPR = 1입니다. 임계 값을 늘리면 "1"에 대한 예측이 줄어들므로 FPR과 TPR은 동일하거나 감소 할 수만 있습니다.

    최적의 임계 값을 사용하더라도 유한 한 양의 데이터가 있기 때문에 여전히 곡선에 점프가 있으므로 유한 한 수의 다른 TPR/FPR 쌍이 임계 값으로 얻을 수 있습니다. 그러나 데이터가 충분하면 원활하게 보이기 시작합니다. 더 부드러운 플롯을 얻기 위해 위 코드에서 몇 줄을 바꿨습니다.

    n_points = 1000
    y_true = np.random.randint(0, 2, size=n_points)
    predictions = np.random.random(n_points)
    thresholds = np.linspace(0, 1, 1000)
    
    

    확실하지 않다면 AUC 0.5가 가장 최악이며, 우리는 이것이 무작위 "예측"으로 얻는 것을 알 수 있습니다. AUC가 0.5보다 나쁜 경우 모든 예측을 0.5보다 나은 것으로 뒤집을 수 있습니다 (그리고 모델/훈련에 문제가있을 수 있습니다).

    실제로 ROC 곡선을 실제로 나타내려면 조금 더 배우기 위해 직접 작성하지 말고 sklearn의 roc_curve 를 사용하십시오. . 그들은 또한 roc_auc_score  당신을 위해 AUC를 얻을 수 있습니다.

  • 이전 c# - xmlserializer - 유형을 반영하는 중에 오류가 발생했습니다
  • 다음 Angular 5 - 각도 5 - 모든 생산 기능을 갖춘 테스트 시스템 구축