인프런 커뮤니티 질문&답변
ValueError: x and y must have same first dimension, but have shapes (53,) and (144,) 와 Input contains NaN, infinity or a value too large for dtype('float64'). 에러 두 가지
작성
·
512
0
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 강의 내용을 질문할 경우 몇분 몇초의 내용에 대한 것인지 반드시 기재 부탁드립니다.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 강의 내용을 질문할 경우 몇분 몇초의 내용에 대한 것인지 반드시 기재 부탁드립니다.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
3장 평가 부분 공부하면서 두 가지 에러가 나서 문의합니다.
개념부분 설명하며 코드 작성할 때는 잘 되었는데, 당뇨병 데이터 가지고 실습 예제하는 중에는
빨갛게 표시된 부분에 해당 에러가 발생합니다. 전체 코드를 올리니 답변 부탁드립니다! ^^
# 분류의 성능 평가지표 - 이진 분류: 긍정/부정과 같은 2개의 결괏값만을 가짐(아래의 성능 지표는 이진 분류에서 특히 중요하게 강조하는 지표임) - 멀티 분류: 여러 개의 결정 클래스 값을 가짐 ## 정확도 accuracy ## 오차행렬 confusion matrix ## 정밀도, 재현율 precision, recall ## F1 score ## ROC AUC ## 1. 정확도 : 실제 데이터에서 예측 데이터가 얼마나 같은지 판단하는 지표 예측 결과가 동일한 데이터 건수/전체 예측 데이터 건수 왜곡이 발생할 수 있음 from sklearn.base import BaseEstimator class MyDummyClassifier(BaseEstimator): # 학습하지 않은 경우에도 높은 확률을 보일 수 있다! 주의!! def fit(self, X, y=None): pass def predict(self, X): pred=np.zeros((X.shape[0], 1)) for i in range(X.shape[0]): if X['Sex'].iloc[i] == 1: pred[i]=0 else: pred[i]=1 return pred import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn import preprocessing titanic_df= pd.read_csv('./train.csv') def encode_features(dataDF): features=['Cabin', 'Sex', 'Embarked'] for feature in features: le = preprocessing.LabelEncoder() le = le.fit(dataDF[feature]) dataDF[feature] = le.transform(dataDF[feature]) return dataDF titanic_df = encode_features(titanic_df) titanic_df.head() def fillna(df): df['Age'].fillna(df['Age'].mean(), inplace=True) df['Cabin'].fillna('N', inplace=True) df['Embarked'].fillna('N', inplace =True) df['Fare'].fillna(0, inplace=True) return df def drop_features(df): df.drop(['PassengerId', 'Name', 'Ticket'], axis=1, inplace=True) return df def format_features(df): df['Cabin'] = df['Cabin'].str[:1] features=['Cabin', 'Sex', 'Embarked'] for feature in features: le = LabelEncoder() le=le.fit(df[feature]) df[feature] = le.transform(df[feature]) return df def transform_features(df): df=fillna(df) df= drop_features(df) df= format_features(df) return df titanic_df = pd.read_csv('./train.csv') y_titanic_df = titanic_df['Survived'] X_titanic_df = titanic_df.drop('Survived', axis=1) X_titanic_df X_titanic_df= transform_features(X_titanic_df) X_titanic_df X_train, X_test, y_train, y_test = train_test_split(X_titanic_df, y_titanic_df, test_size=0.2, random_state=0) myclf= MyDummyClassifier() myclf.fit(X_train, y_train) mypredictions= myclf.predict(X_test) print(accuracy_score(y_test, mypredictions)) from sklearn.datasets import load_digits from sklearn.model_selection import train_test_split from sklearn.base import BaseEstimator from sklearn.metrics import accuracy_score import numpy as np import pandas as pd class MyFakeClassifier(BaseEstimator): def fit(self, X, y): pass def predict(self, X): return np.zeros((len(X), 1), dtype=bool) digits= load_digits() y=(digits.target==7).astype(int)#True라면 astype(int)로 1로 변환, 아니면 False니 0으로 변환 X_train, X_test, y_train, y_test = train_test_split(digits.data, y, random_state=11) print(y_test.shape) print(pd.Series(y_test).value_counts()) fakeclf= MyFakeClassifier() fakeclf.fit(X_train, y_train) fakepred= fakeclf.predict(X_test) print(accuracy_score(y_test, fakepred)) # 따라서 불균형한 lableSets에서는 평가수치로 사용돼서는 안 된다!!!! # 2. 오차행렬 confusion matrix - 학습된 분류 모델이 예측을 수행하면서 얼마나 헷갈리고 있는지 함께 보여주는 지표다 - 이진 분류의 예측 오류 얼마인지? + 어떠한 유형의 예측 오류가 발생하고 있는지? - TN FP - FN TP ## 정확도 * (TN+ TP)/(TN+FP+FN+TP) * 불균형한 레이블 세트에서는 * 매우 적은 수의 결과값에 positive를 설정해 1값을 부여하고, 그렇지 않은 경우는 negative로 0값을 부여하는 경우가 많다. ## 정밀도 * TP / (FP+TP) * 예측을 Positive로 한 대상 중 예측과 실제 값이 Positive로 일치한 데이터의 비율 * Positive 예측 성능을 더욱 정밀하게 측정하기 위한 평가 지표 * 양성 예측도 * 언제 중요한가? 실제 nagative 데이터를 positive데이터로 판단하면 안되는 경우 (가짠데 진짜라고 판단하면 안되는 경우) * FP 낮추는 데 초점을 둔다!!!!!! ## 재현율 recalls * TP/(FN+TP) * 실제값이 Positive인 대상 중 * 예측과 실제 값이 Positive로 일치한 데이터의 비율 * 민감도 Sensitivity 또는 TPR True positive rate * 언제 중요하는가? 실제 positive 양성 데이터를 nagative로 잘못 판단하면 안되는 경우 (진짠데 가짜라고 판단하면 안되는 경우) * FN 낮추는데 초점을 둔다!!!!!!!! ### Trade-off - 분류의 결정 임곗값 Threshold를 조정해 정밀도 또는 재현율의 수치를 높일 수 있다. - 그런데 이들은 상호 보완적인 평가 지표라서 어느 한쪽을 강제로 높이면, 다른 하나의 수치는 떨어진다. # 정확도 from sklearn.metrics import confusion_matrix confusion_matrix(y_test, fakepred) # 정밀도, 재현율 from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix def get_clf_eval(y_test, pred): confusion= confusion_matrix(y_test, pred) accuracy= accuracy_score(y_test, pred) precision= precision_score(y_test, pred) recall= recall_score(y_test, pred) print(confusion) print(f"정확도:{accuracy}, 정밀도:{precision}, 재현율:{recall}") import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression titanic_df = pd.read_csv('./train.csv') y_titanic_df = titanic_df['Survived'] X_titanic_df = titanic_df.drop('Survived', axis=1) X_titanic_df = transform_features(X_titanic_df) X_train, X_test, y_train, y_test = train_test_split(X_titanic_df, y_titanic_df, test_size= 0.20, random_state = 11) lr_clf= LogisticRegression() lr_clf.fit(X_train, y_train) pred = lr_clf.predict(X_test) print(y_test.shape) print(pred.shape) get_clf_eval(y_test, pred) # trade-off # predict_proba() 반환결과: 예측 확률 결과 # predict() 반환 결과: 예측 결과 클래스값 pred_proba = lr_clf.predict_proba(X_test) pred = lr_clf.predict(X_test) print(pred_proba.shape) print(pred_proba[:3]) pred_proba_result = np.concatenate([pred_proba, pred.reshape(-1, 1)], axis=1) print(pred_proba_result[:3]) from sklearn.preprocessing import Binarizer X=[[1, -1, 2], [2,1,4], [2,2,-2]] binarizer= Binarizer(threshold=1.1) print(binarizer.fit_transform(X)) custom_threshold= 0.5 pred_proba_1 = pred_proba[:, 1].reshape(-1,1) binarizer = Binarizer(threshold=custom_threshold).fit(pred_proba_1) custom_predict = binarizer.transform(pred_proba_1) get_clf_eval(y_test, custom_predict) custom_threshold= 0.3 pred_proba_1 = pred_proba[:, 1].reshape(-1,1) binarizer = Binarizer(threshold=custom_threshold).fit(pred_proba_1) custom_predict = binarizer.transform(pred_proba_1) get_clf_eval(y_test, custom_predict) # 잘모르겠는 부분 임곗값에 따라 정밀도와 재현율이 달라지는 이유?가 잘 이해가 안됨! thresholds= [0.4, 0.5, 0.6, 0.7] def get_eval_by_threshold(y_test, pred_proba_c1, thresholds): for custom_threshold in thresholds: binarizer= Binarizer(threshold = custom_threshold).fit(pred_proba_c1) custom_predict= binarizer.transform(pred_proba_c1) print(custom_threshold) get_clf_eval(y_test, custom_predict) get_eval_by_threshold(y_test, pred_proba[:, 1].reshape(-1,1), thresholds) # precision_recall_curve() from sklearn.metrics import precision_recall_curve pred_proba_class1 = lr_clf.predict_proba(X_test)[:,1] precisions, recalls, thresholds = precision_recall_curve(y_test, pred_proba_class1) print(thresholds.shape) thr_index = np.arange(0, thresholds.shape[0], 15) print(thr_index) print(np.round(thresholds[thr_index], 2)) print(f"정밀도{np.round(precisions[thr_index], 3)}") print(f"재현율{np.round(recalls[thr_index], 3)}") import matplotlib.pyplot as plt import matplotlib.ticker as ticker %matplotlib inline def precision_recall_curve_plot(y_test, pred_proba_c1): precision, recalls, threshold = precision_recall_curve(y_test, pred_proba_c1) plt.figure(figsize=(8,6)) threshold_boundary = threshold.shape[0] plt.plot(thresholds, precisions[0:threshold_boundary], linestyle='--', label='precision') plt.plot(thresholds, recalls[0:threshold_boundary], label='recall') start, end = plt.xlim() plt.xticks(np.round(np.arange(start, end, 0.1),2)) plt.xlabel('Threshold value') plt.ylabel('Precision and recall value') plt.legend() plt.grid() plt.show() precision_recall_curve_plot(y_test, lr_clf.predict_proba(X_test)[:, 1]) # F1 스코어 - F1 score는 정밀도와 재현율을 결합한 지표로서 둘이 어느 한 쪽으로 치우치지 않는 수치를 나타낼 때 상대적으로 높은 값을 가짐 #F1 score from sklearn.metrics import f1_score f1 = f1_score(y_test, pred) print(f1) def get_clf_eval(y_test, pred): confusion = confusion_matrix(y_test, pred) accuracy = accuracy_score(y_test, pred) precision= precision_score(y_test, pred) recall = recall_score(y_test, pred) f1= f1_score(y_test, pred) print(confusion) print(accuracy, precision, recall, f1) thresholds = [0.4, 0.45, 0.50, 0.55, 0.60] pred_proba = lr_clf.predict_proba(X_test) get_eval_by_threshold(y_test, pred_proba[:,1].reshape(-1, 1), thresholds) # ROC곡선 - 이진 분류의 예측 성능 측정에서 중요하게 사용되는 지표 - Receiver Operation characteristic curve 수신자 판단 곡선 - FPR False Positive Rate 이 변할 때, TPR 재현율=민감도 True Positive Rate이 어떻게 변하는지 나타내는 곡선 - TPR <-> TNR 특이성 Specificity True Negative Rate, - FPR= 1-TNR, 1-특이성 from sklearn.metrics import roc_curve pred_proba_class1 = lr_clf.predict_proba(X_test)[:,1] fprs, tprs, thresholds = roc_curve(y_test, pred_proba_class1) print(thresholds) #thresholds[0]은 max예측확률+1로 임의 설정된다. 이를 제외하기 위해 np.arange는 1부터 시작한다. thr_index=np.arange(1, thresholds.shape[0],5) print(thr_index) print(np.round(thresholds[thr_index],2)) def roc_curve_plot(y_test, pred_proba_c1): fprs, tprs, thrsholds = roc_curve(y_test, pred_proba_c1) plt.plot(fprs, tprs, label = 'ROC') plt.plot([0,1], [0,1], 'k--', label='Random') start, end= plt.xlim() plt.xticks(np.round(np.arange(start, end, 0.1),2)) plt.xlim(0,1) plt.ylim(0,1) plt.xlabel('FPR(1-Sensitivity)') plt.ylabel('TPR(recall)') plt.legend() roc_curve_plot(y_test, pred_proba[:,1]) # AUC - ROC 곡선 자체는 FPR과 TPR의 변화 값을 보는 데 이용하며 분류의 성능 지표로 사용되는 것은 ROC 곡선 면적에 기반한 AUC값으로 결정한다. AUC 값은 ROC 곡선 밑의 면적을 구한 것으로 일반적으로 1에 가까울 수록 좋은 수치다. -Area Under Curve - AUC 수치가 커지려면 FPR이 작은 상태에서 얼마나 큰 TPR을 얻을 수 있느냐가 관건이다. 직사각형에 가까운 곡선! from sklearn.metrics import roc_auc_score pred_proba = lr_clf.predict_proba(X_test)[:,1] roc_score = roc_auc_score(y_test, pred_proba) print(roc_score) def get_clf_eval(y_test, pred=None, pred_proba= None): confusion = confusion_matrix(y_test, pred) accuracy = accuracy_score(y_test, pred) precision= precision_score(y_test, pred) recall = recall_score(y_test, pred) f1= f1_score(y_test, pred) roc_auc= roc_auc_score(y_test, pred_proba) print(confusion) print(accuracy, precision, recall, f1, roc_auc) get_clf_eval(y_test, pred, pred_proba) #prediction about pima inidans diabetes #inline: 브라우저 내부(inline)에 바로 그려지도록 해주는 코드 import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_auc_score from sklearn.metrics import f1_score, confusion_matrix, precision_recall_curve, roc_curve from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression diabetes_data = pd.read_csv('diabetes.csv') print(diabetes_data['Outcome'].value_counts()) diabetes_data.head(3) diabetes_data.info() X= diabetes_data.iloc[:, :-1] X y= diabetes_data.iloc[:, -1] y X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = 156, stratify=y) #stratify(층을 이룬다) : 지정한 Data의 비율을 유지한다. 예를 들어, Label Set인 Y가 25%의 0과 75%의 1로 이루어진 Binary Set일 때, # stratify=Y로 설정하면 나누어진 데이터셋들도 0과 1을 각각 25%, 75%로 유지한 채 분할된다. lr_clf = LogisticRegression() lr_clf.fit(X_train, y_train) pred = lr_clf.predict(X_test) pred_proba = lr_clf.predict_proba(X_test)[:, 1] get_clf_eval(y_test, pred, pred_proba) pred_proba_c1 = lr_clf.predict_proba(X_test)[:, -1] print(pred_proba_c1.shape) print(y_test.shape) precision_recall_curve_plot(y_test, pred_proba_c1) ValueError: x and y must have same first dimension, but have shapes (53,) and (144, diabetes_data.describe() # bins 파라미터는 히스토그램의 가로축 구간의 개수를 지정 # cumulative는 누적히스토그램 plt.hist(diabetes_data['Glucose'], cumulative=False, bins=10) plt.hist(diabetes_data['Glucose'], bins=15) zero_features = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI'] total_count = diabetes_data['Glucose'].count() for feature in zero_features: zero_count = diabetes_data[diabetes_data[feature]==0][feature].count() print(feature) print(zero_count) print(f'{feature}은 0인 데이터 계수가 {zero_count}이므로 퍼센트는 {100*zero_count/total_count}') mean_zero_features=diabetes_data[zero_features].mean() mean_zero_features diabetes_data[zero_features]= diabetes_data[zero_features].replace(0, mean_zero_features) diabetes_data[zero_features].head(10) X=diabetes_data.iloc[:, :-1] y = diabetes_data.iloc[:, -1] scaler=StandardScaler() X_scaled = scaler.fit_transform(X) X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state= 156, stratify=y) lr_clf= LogisticRegression() lr_clf.fit(X_train, y_train) pred= lr_clf.predict(X_test) pred_proba = lr_clf.predict_proba(X_test)[:, 1] get_clf_eval(y_test, pred, pred_proba) precision_recall_curve_plot(y_test, pred_proba)
ValueError: x and y must have same first dimension, but have shapes (53,) and (144,)
thresholds=[0.3, 0.33, 0.36, 0.39, 0.42, 0.45] pred_proba = lr_clf.predict_proba(X_test) def get_eval_by_threshold(y_test, pred_proba_c1, thresholds): for custom_threshold in thresholds: binarizer= Binarizer(threshold = custom_threshold).fit(pred_proba_c1) custom_predict= binarizer.transform(pred_proba_c1) print(custom_threshold) get_clf_eval(y_test, custom_predict) get_eval_by_threshold(y_test, pred_proba[:, 1].reshape(-1,1), thresholds)
Input contains NaN, infinity or a value too large for dtype('float64').
binarizer=Binarizer(threshold=0.48) pred_th_048=binarizer.fit_transform(pred_proba[:, 1].reshape(-1,1)) get_clf_eval(y_test, pred_th_048, pred_proba[:, 1])
답변 1
0
권 철민
지식공유자
안녕하십니까,
올리신 코드를 제가 알아볼수가 없습니다.
어떤것을 변경했는지 알수 없기에 원본 실습 코드를 다시 다운로드 받으셔서(만약 원본 소스코드를 수정하셨다면) 다시 실습 해보시기 바랍니다.
감사합니다.





