파이썬에서 ROC 곡선을 그리는 방법
로지스틱 회귀 패키지를 사용하여 Python에서 개발한 예측 모델의 정확성을 평가하기 위해 ROC 곡선을 작성하려고 합니다.실제 양성률과 거짓 양성률을 계산했지만, 다음을 사용하여 정확하게 플롯하는 방법을 찾을 수 없습니다.matplotlib
AUC 값을 계산합니다.내가 어떻게 그럴 수 있을까?
다음과 같은 두 가지 방법을 시도할 수 있습니다.model
질문 학습 예측 변수입니다.
import sklearn.metrics as metrics
# calculate the fpr and tpr for all thresholds of the classification
probs = model.predict_proba(X_test)
preds = probs[:,1]
fpr, tpr, threshold = metrics.roc_curve(y_test, preds)
roc_auc = metrics.auc(fpr, tpr)
# method I: plt
import matplotlib.pyplot as plt
plt.title('Receiver Operating Characteristic')
plt.plot(fpr, tpr, 'b', label = 'AUC = %0.2f' % roc_auc)
plt.legend(loc = 'lower right')
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0, 1])
plt.ylim([0, 1])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()
# method II: ggplot
from ggplot import *
df = pd.DataFrame(dict(fpr = fpr, tpr = tpr))
ggplot(df, aes(x = 'fpr', y = 'tpr')) + geom_line() + geom_abline(linetype = 'dashed')
또는 시도
ggplot(df, aes(x = 'fpr', ymin = 0, ymax = 'tpr')) + geom_line(aes(y = 'tpr')) + geom_area(alpha = 0.2) + ggtitle("ROC Curve w/ AUC = %s" % str(roc_auc))
이것은 일련의 실측값 레이블과 예측 확률을 고려할 때 ROC 곡선을 표시하는 가장 간단한 방법입니다.가장 좋은 점은 모든 클래스에 대한 ROC 곡선을 표시하기 때문에 여러 개의 깔끔한 곡선도 얻을 수 있다는 것입니다.
import scikitplot as skplt
import matplotlib.pyplot as plt
y_true = # ground truth labels
y_probas = # predicted probabilities generated by sklearn classifier
skplt.metrics.plot_roc_curve(y_true, y_probas)
plt.show()
다음은 plot_roc_curve에 의해 생성된 샘플 곡선입니다.저는 scikit-learn의 샘플 숫자 데이터 세트를 사용하여 10개의 클래스가 있습니다.각 클래스에 대해 하나의 ROC 곡선이 표시됩니다.
고지 사항:이것은 제가 만든 스크킷 플롯 라이브러리를 사용합니다.
matplotlib을 사용한 이항 분류에 대한 AUC 곡선
from sklearn import svm, datasets
from sklearn import metrics
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
import matplotlib.pyplot as plt
유방암 데이터 세트 로드
breast_cancer = load_breast_cancer()
X = breast_cancer.data
y = breast_cancer.target
데이터 집합 분할
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.33, random_state=44)
모델
clf = LogisticRegression(penalty='l2', C=0.1)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
정확성.
print("Accuracy", metrics.accuracy_score(y_test, y_pred))
AUC 곡선
y_pred_proba = clf.predict_proba(X_test)[::,1]
fpr, tpr, _ = metrics.roc_curve(y_test, y_pred_proba)
auc = metrics.roc_auc_score(y_test, y_pred_proba)
plt.plot(fpr,tpr,label="data 1, auc="+str(auc))
plt.legend(loc=4)
plt.show()
여기서 문제가 무엇인지 전혀 명확하지 않지만 배열이 있는 경우true_positive_rate
배열과false_positive_rate
그런 다음 ROC 곡선을 표시하고 AUC를 얻는 것은 다음과 같이 간단합니다.
import matplotlib.pyplot as plt
import numpy as np
x = # false_positive_rate
y = # true_positive_rate
# This is the ROC curve
plt.plot(x,y)
plt.show()
# This is the AUC
auc = np.trapz(y,x)
ROC 곡선을 계산하기 위한 파이썬 코드는 다음과 같습니다(산란 플롯으로).
import matplotlib.pyplot as plt
import numpy as np
score = np.array([0.9, 0.8, 0.7, 0.6, 0.55, 0.54, 0.53, 0.52, 0.51, 0.505, 0.4, 0.39, 0.38, 0.37, 0.36, 0.35, 0.34, 0.33, 0.30, 0.1])
y = np.array([1,1,0, 1, 1, 1, 0, 0, 1, 0, 1,0, 1, 0, 0, 0, 1 , 0, 1, 0])
# false positive rate
fpr = []
# true positive rate
tpr = []
# Iterate thresholds from 0.0, 0.01, ... 1.0
thresholds = np.arange(0.0, 1.01, .01)
# get number of positive and negative examples in the dataset
P = sum(y)
N = len(y) - P
# iterate through all thresholds and determine fraction of true positives
# and false positives found at this threshold
for thresh in thresholds:
FP=0
TP=0
for i in range(len(score)):
if (score[i] > thresh):
if y[i] == 1:
TP = TP + 1
if y[i] == 0:
FP = FP + 1
fpr.append(FP/float(N))
tpr.append(TP/float(P))
plt.scatter(fpr, tpr)
plt.show()
from sklearn import metrics
import numpy as np
import matplotlib.pyplot as plt
y_true = # true labels
y_probas = # predicted results
fpr, tpr, thresholds = metrics.roc_curve(y_true, y_probas, pos_label=0)
# Print ROC curve
plt.plot(fpr,tpr)
plt.show()
# Print AUC
auc = np.trapz(tpr,fpr)
print('AUC:', auc)
스택 오버플로, 스크킷 학습 문서 등의 여러 주석을 기반으로 정말 간단한 방법으로 ROC 곡선(및 기타 메트릭)을 플롯하기 위해 파이썬 패키지를 만들었습니다.
패키지 설치하기pip install plot-metric
(자세한 내용은 게시물 끝에 있음)
ROC 곡선을 플롯하려면(예: 설명서 참조):
이진 분류
간단한 데이터 세트를 로드하고 트레인 및 테스트 세트를 만듭니다.
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
X, y = make_classification(n_samples=1000, n_classes=2, weights=[1,1], random_state=1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=2)
분류기 및 예측 테스트 세트 교육:
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=50, random_state=23)
model = clf.fit(X_train, y_train)
# Use predict_proba to predict probability of the class
y_pred = clf.predict_proba(X_test)[:,1]
이제 plot_metric을 사용하여 ROC 곡선을 플롯할 수 있습니다.
from plot_metric.functions import BinaryClassification
# Visualisation with plot_metric
bc = BinaryClassification(y_test, y_pred, labels=["Class 1", "Class 2"])
# Figures
plt.figure(figsize=(5,5))
bc.plot_roc_curve()
plt.show()
결과:
패키지의 Github 및 설명서에서 더 많은 예제를 찾을 수 있습니다.
- Github : https://github.com/yohann84L/plot_metric
- 설명서: https://plot-metric.readthedocs.io/en/latest/
앞의 답변에서는 실제로 TP/센서를 계산했다고 가정합니다.수동으로 이 작업을 수행하는 것은 좋지 않습니다. 계산 과정에서 실수하기 쉬우므로 라이브러리 기능을 사용하는 것이 좋습니다.
scikit_dll의 plot_roc 함수는 http://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html 에서 필요한 작업을 정확히 수행합니다.
코드의 중요한 부분은 다음과 같습니다.
for i in range(n_classes):
fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
roc_auc[i] = auc(fpr[i], tpr[i])
metriculous라는 라이브러리가 있습니다.
$ pip install metriculous
먼저 몇 가지 데이터를 모의 실험해 보겠습니다. 이는 일반적으로 테스트 데이터 세트와 모델에서 가져온 것입니다.
import numpy as np
def normalize(array2d: np.ndarray) -> np.ndarray:
return array2d / array2d.sum(axis=1, keepdims=True)
class_names = ["Cat", "Dog", "Pig"]
num_classes = len(class_names)
num_samples = 500
# Mock ground truth
ground_truth = np.random.choice(range(num_classes), size=num_samples, p=[0.5, 0.4, 0.1])
# Mock model predictions
perfect_model = np.eye(num_classes)[ground_truth]
noisy_model = normalize(
perfect_model + 2 * np.random.random((num_samples, num_classes))
)
random_model = normalize(np.random.random((num_samples, num_classes)))
이제 미터법을 사용하여 ROC 곡선을 포함한 다양한 메트릭과 다이어그램이 있는 표를 생성할 수 있습니다.
import metriculous
metriculous.compare_classifiers(
ground_truth=ground_truth,
model_predictions=[perfect_model, noisy_model, random_model],
model_names=["Perfect Model", "Noisy Model", "Random Model"],
class_names=class_names,
one_vs_all_figures=True, # This line is important to include ROC curves in the output
).save_html("model_comparison.html").display()
ROC 곡선은 출력에서 다음과 같습니다.
플롯은 확대/축소 및 드래그가 가능하며, 플롯 위에 마우스를 올려 놓으면 다음과 같은 세부 정보를 볼 수 있습니다.
공식 문서 양식 스크킷을 따를 수도 있습니다.
ROC 곡선 패키지에 포함된 간단한 기능을 만들었습니다.저는 이제 막 기계 학습 연습을 시작했는데 혹시 이 코드에 문제가 있으면 알려주세요!
자세한 내용은 github readme 파일을 보세요! :)
https://github.com/bc123456/ROC
from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score, roc_curve
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
def plot_ROC(y_train_true, y_train_prob, y_test_true, y_test_prob):
'''
a funciton to plot the ROC curve for train labels and test labels.
Use the best threshold found in train set to classify items in test set.
'''
fpr_train, tpr_train, thresholds_train = roc_curve(y_train_true, y_train_prob, pos_label =True)
sum_sensitivity_specificity_train = tpr_train + (1-fpr_train)
best_threshold_id_train = np.argmax(sum_sensitivity_specificity_train)
best_threshold = thresholds_train[best_threshold_id_train]
best_fpr_train = fpr_train[best_threshold_id_train]
best_tpr_train = tpr_train[best_threshold_id_train]
y_train = y_train_prob > best_threshold
cm_train = confusion_matrix(y_train_true, y_train)
acc_train = accuracy_score(y_train_true, y_train)
auc_train = roc_auc_score(y_train_true, y_train)
print 'Train Accuracy: %s ' %acc_train
print 'Train AUC: %s ' %auc_train
print 'Train Confusion Matrix:'
print cm_train
fig = plt.figure(figsize=(10,5))
ax = fig.add_subplot(121)
curve1 = ax.plot(fpr_train, tpr_train)
curve2 = ax.plot([0, 1], [0, 1], color='navy', linestyle='--')
dot = ax.plot(best_fpr_train, best_tpr_train, marker='o', color='black')
ax.text(best_fpr_train, best_tpr_train, s = '(%.3f,%.3f)' %(best_fpr_train, best_tpr_train))
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC curve (Train), AUC = %.4f'%auc_train)
fpr_test, tpr_test, thresholds_test = roc_curve(y_test_true, y_test_prob, pos_label =True)
y_test = y_test_prob > best_threshold
cm_test = confusion_matrix(y_test_true, y_test)
acc_test = accuracy_score(y_test_true, y_test)
auc_test = roc_auc_score(y_test_true, y_test)
print 'Test Accuracy: %s ' %acc_test
print 'Test AUC: %s ' %auc_test
print 'Test Confusion Matrix:'
print cm_test
tpr_score = float(cm_test[1][1])/(cm_test[1][1] + cm_test[1][0])
fpr_score = float(cm_test[0][1])/(cm_test[0][0]+ cm_test[0][1])
ax2 = fig.add_subplot(122)
curve1 = ax2.plot(fpr_test, tpr_test)
curve2 = ax2.plot([0, 1], [0, 1], color='navy', linestyle='--')
dot = ax2.plot(fpr_score, tpr_score, marker='o', color='black')
ax2.text(fpr_score, tpr_score, s = '(%.3f,%.3f)' %(fpr_score, tpr_score))
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC curve (Test), AUC = %.4f'%auc_test)
plt.savefig('ROC', dpi = 500)
plt.show()
return best_threshold
확률이 필요할 때도...다음은 AUC 값을 가져와 한 번의 샷으로 모두 표시합니다.
from sklearn.metrics import plot_roc_curve
plot_roc_curve(m,xs,y)
가능성이 있을 때...auc 값과 플롯을 한 번에 얻을 수 없습니다.다음을 수행합니다.
from sklearn.metrics import roc_curve
fpr,tpr,_ = roc_curve(y,y_probas)
plt.plot(fpr,tpr, label='AUC = ' + str(round(roc_auc_score(y,m.oob_decision_function_[:,1]), 2)))
plt.legend(loc='lower right')
제 코드에서는 X_train과 y_train이 있고 클래스는 0과 1입니다.clf.predict_proba()
방법은 모든 데이터 점에 대한 두 클래스의 확률을 계산합니다.저는 임계값이 다른 클래스 1의 확률을 비교합니다.
probability = clf.predict_proba(X_train)
def plot_roc(y_train, probability):
threshold_values = np.linspace(0,1,100) #Threshold values range from 0 to 1
FPR_list = []
TPR_list = []
for threshold in threshold_values: #For every value of threshold
y_pred = [] #Classify every data point in the test set
#prob is an array consisting of 2 values - Probability of datapoint in Class0 and Class1.
for prob in probability:
if ((prob[1])<threshold): #Prob of class1 (positive class)
y_pred.append(0)
continue
elif ((prob[1])>=threshold): y_pred.append(1)
#Plot Confusion Matrix and Obtain values of TP, FP, TN, FN
c_m = confusion_matrix(y, y_pred)
TN = c_m[0][0]
FP = c_m[0][1]
FN = c_m[1][0]
TP = c_m[1][1]
FPR = FP/(FP + TN) #Obtain False Positive Rate
TPR = TP/(TP + FN) #Obtain True Positive Rate
FPR_list.append(FPR)
TPR_list.append(TPR)
fig = plt.figure()
plt.plot(FPR_list, TPR_list)
plt.ylabel('TPR')
plt.xlabel('FPR')
plt.show()
제가 관리하는 새로운 오픈 소스는 모델 성능을 테스트할 수 있는 여러 가지 방법이 있습니다.ROC 곡선을 보려면 다음을 수행할 수 있습니다.
from deepchecks.checks import RocReport
from deepchecks import Dataset
RocReport().run(Dataset(df, label='target'), model)
결과는 다음과 같습니다. RocReport의 더 정교한 예는 여기에서 찾을 수 있습니다.
ROC 곡선은 이진 분류에만 사용되므로 데이터 이진화 및 레이블링을 사용합니다.
# Binarize data for getting AUC
y_test_bin = label_binarize(y_test, classes=range(y_train.min() , y_train.max()))
y_pred_bin = label_binarize(Predicted_result, classes=range(y_train.min() , y_train.max()))
# Calculate FP , TP rate
fpr, tpr, _ = roc_curve(y_test_bin.ravel(), y_pred_bin.ravel() )
# Get AUC ,
auc = roc_auc_score(y_test_bin, y_pred_bin, average='micro', multi_class='ovr')
#create ROC curve
plt.plot(fpr,tpr , label= f"AUC = {auc}" , )
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.title('ROC')
plt.legend(loc=7)
plt.figure(figsize = [])
plt.show()
여기 w3Schools에 기록된 바와 같이:
import matplotlib.pyplot as plt def plot_roc_curve(true_y, y_prob): """ plots the roc curve based of the probabilities """ fpr, tpr, thresholds = roc_curve(true_y, y_prob) plt.plot(fpr, tpr) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plot_roc_curve(y, y_proba) print(f'model AUC score: {roc_auc_score(y, y_proba)}')
언급URL : https://stackoverflow.com/questions/25009284/how-to-plot-roc-curve-in-python
'it-source' 카테고리의 다른 글
CSS/HTML: 입력 필드 주위에 빛나는 테두리 만들기 (0) | 2023.09.03 |
---|---|
Powershell - 리소스 부족으로 인해 테스트-연결 실패 (0) | 2023.09.03 |
MariaDB 열에서 중첩된 JSON 값을 가져오는 방법은 무엇입니까? (0) | 2023.09.03 |
내 Git 저장소가 왜 그렇게 큰가요? (0) | 2023.09.03 |
Excel VBA에서 사용자에게 범위 선택 도구/유틸리티 제공 (0) | 2023.09.03 |