강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

jhy242님의 프로필 이미지
jhy242

작성한 질문수

[개정판] 파이썬 머신러닝 완벽 가이드

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 문의하기를 이용해주세요.
 
 
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

권 철민님의 프로필 이미지
권 철민
지식공유자

안녕하십니까, 

올리신 코드를 제가 알아볼수가 없습니다. 

어떤것을 변경했는지 알수 없기에 원본 실습 코드를 다시 다운로드 받으셔서(만약 원본 소스코드를 수정하셨다면) 다시 실습 해보시기 바랍니다. 

감사합니다. 

jhy242님의 프로필 이미지
jhy242

작성한 질문수

질문하기