본문 바로가기
IT,SW,Data,Cloud,코딩/Python

20230615 머신러닝 공부, 시험환경 꿀팁 등

by 착실하게 2023. 6. 15.
반응형

predict() 와 predict_proba() 함수. 

함수에 대해 잘 몰라서 구글링함.

다음의 링크를 참고하여 메모함. https://www.inflearn.com/questions/680910/predict-%EC%99%80-predict-proba-%EC%B0%A8%EC%9D%B4 

 

predict 와 predict_proba 차이 - 인프런 | 질문 & 답변

predict 와 predict_proba 차이 강의자료에 짧게 있지만 잘 이해가 안되서요 자세하게 차이를 알고 싶습니다!그리고 다중분류일때 사용하는법도 알고 싶습니다! 다중분류일때 predict_proba 를 사용해서

www.inflearn.com

 

predict는 

각각의 모델의 최종적인 예측값을 출력하는 결과. 

회귀 모델은, 구체적으로 특정 값 출력.

분류 모델은 확률이 가장 높은 클래스. 

 

그리고 이때 분류 모델이 각 클래스에 대한 확률을 일일이 출력하는 것이 predict_proba 

predict_proba는 각 클래스의 확률을 예측하라는 의미이다. 

그래서 회귀모델에는 predict_proba를 사용할 수 없다. 

 

클래스가 3개인 문제라면 0일 확률, 1일 확률, 2일 확률 이 된다. 

 

그래도 약간 더 헷갈려서 추가로 더 찾아본 내용 

https://subinium.github.io/MLwithPython-2-4/

 

[ML with Python] 2장. 지도 학습 - 분류 예측의 불확실성 추정

2.4 분류 예측의 불확실성 추정

subinium.github.io

 

predict_proba의 결과값에서 각 행의 첫 번째 원소는 클래스의 예측 확률이고 두 번째 원소는 두 번째 클래스의 예측 확률 이다. 

확률이기 때문에 predict_proba의 출력은 항상 0과 1 사이의 값이며, 두 클래스에 대한 확률의 합은 항상 1이다. 

 

그리고 이런저런 gradient boosting algorithms 비교에 대해서 아래의 링크를 읽어보면 재미있

 

https://towardsdatascience.com/boosting-showdown-scikit-learn-vs-xgboost-vs-lightgbm-vs-catboost-in-sentiment-classification-f7c7f46fd956

 

Boosting Showdown: Scikit-Learn vs XGBoost vs LightGBM vs CatBoost in Sentiment Classification

Which boosting algorithm will reign supreme in this head-to-head competition?

towardsdatascience.com

 

그리고 퇴근후딴짓님 강의 마저 이어듣기. 

 

a = pd.read_csv('data/mtcars.csv', index_col=0)
index_col=0: 첫번째 컬럼(0)을 인덱스로 만들겠다는 뜻임. 이걸 안하면 숫자 인덱스 들어감.

pd.set_option('display.max_columns',None)
이거하면 컬럼이 중간에 ... 으로 안 나오고 전부 다 나옴
길면 다음줄에 마저 나옴

 

구름 환경에서 문제 풀어보기.

 

# 출력을 원할 경우 print() 함수 활용
# 예시) print(df.head())

# getcwd(), chdir() 등 작업 폴더 설정 불필요
# 파일 경로 상 내부 드라이브 경로(C: 등) 접근 불가

# 데이터 파일 읽기 예제
import pandas as pd
a = pd.read_csv('data/mtcars.csv', index_col=0)
# pd.set_option('display.max_columns',None)
# 사용자 코딩

# 방법1
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
a[['qsec']] = scaler.fit_transform(a[['qsec']])
print( sum(a['qsec']>0.5)  )

# 방법2
a = pd.read_csv('data/mtcars.csv', index_col=0)
from sklearn.preprocessing import minmax_scale 
print(sum(minmax_scale(a['qsec'])>0.5))

# 답안 제출 예시
# print(평균변수값)

민맥스 스케일링 복습 

 

결측치가 있으면 모델링 시 에러난다.

그래서 결측치 전부 처리 해줘야 한다. 

# 에러코드
import pandas as pd
import numpy as np
from sklearn.datasets import load_wine
wine = load_wine()
df = pd.DataFrame(wine.data, columns=wine.feature_names)
df['target'] = wine.target
# 결측치 생성
df.iloc[:3,0] = np.nan
print(df.head())

# 에러 수정코드 작성(결측치 처리)


from sklearn.model_selection import train_test_split
X_train, X_test, y_train, _ = train_test_split(df.drop('target',axis=1),
                                               df['target'],
                                               test_size=0.2,
                                               random_state=2022)

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_train, y_train)
model.predict(X_test)

# ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

그리고 구름 환경에서 에러 라인 표시는 import 부터 카운트 되어서 알려주니깐 

이거 라인 안 맞으면 에러라인 찾는게 또 어지러움.

그래서 import 로 라인 1을 시작하는게 꿀팁임. 

그리고 만약, train 데이터의 x와 y 가 나누어져서 주어졌는데

x 쪽에 몇개 행을 이상치로 판단하여 삭제하고

y 쪽은 처리 안해버리면 에러난다. 

X_train = X_train[X_train['proline'] < 1500]

그럴때 해결 방법은 y_train 을 x_train 의 target 컬럼으로 넣어버리고 

결측치 행 삭제 및 후속 작업을 계속 진행하면 된다. 

 

또는 해당하는 데이터행의 인덱스를 찾아와서 y 쪽에도 삭제해주면 된다. 

# 삭제할 데이터의 인덱스 값을 구하고 drop함수를 통해 삭제
ind = X_train[X_train['proline'] >= 1500].index
print("삭제할 index:", ind)
X_train = X_train.drop(ind) # 기본값 axis = 0
y_train = y_train.drop(ind)

 

원핫인코딩이나 라벨인코딩할때 주의할점이 

예를 들어 과일 컬럼이 train 데이터에는 사과, 배가 있는데 

test 데이터에는 바나나, 멜론, 딸기, 사과, 배가 있으면 에러가 난다. 

 

해결 방법은 두 데이터를 합쳐서 인코딩 후 다시 그대로 나눠야 한다. 

print("컬럼 추가 전:", X_train.shape, X_test.shape)

# 데이터 합친 후 새 컬럼 추가
all_data = pd.concat([X_train, X_test]) # 기본 axis=0
all_data = pd.get_dummies(all_data, columns=['alcohol'])

# 데이터 전처리 후 다시 분리
X_train = all_data.iloc[:X_train.shape[0],:]
X_test = all_data.iloc[X_train.shape[0]:,:]

print("컬럼 추가 후:",X_train.shape, X_test.shape)

구름 환경에서는 error 가 아니라 warning 도 

실행에 실패했다는 메시지로 뜨기 때문에

최대한 warning도 띄우지 않도록 하자. 

 

df2 = df[cols] ### df2에서 변경이 일어났을때 df에는 변경이 되지 않는다는 warning이 뜬다.

df2 = df[cols].copy() 

 

시험장 꿀팁 


print(dir(pd.DataFrame))
print(help(pd.DataFrame.dropna))

import sklearn
import sklearn.preprocessing

print(sklearn.__all__)
print(sklearn.preprocessing.__all__)

from sklearn.preprocessing import minmax_scale
print(help(minmax_scale))

DATAQ 체험문제 제2유형 코드 작성해보기 

 

https://dataq.goorm.io/exam/116674/%EC%B2%B4%ED%97%98%ED%95%98%EA%B8%B0/quiz/2

 

구름EDU - 모두를 위한 맞춤형 IT교육

구름EDU는 모두를 위한 맞춤형 IT교육 플랫폼입니다. 개인/학교/기업 및 기관 별 최적화된 IT교육 솔루션을 경험해보세요. 기초부터 실무 프로그래밍 교육, 전국 초중고/대학교 온라인 강의, 기업/

edu.goorm.io

 

문제는 저 링크고 내가 작성한 코드는 아래에. 

 

# 출력을 원하실 경우 print() 함수 활용
# 예시) print(df.head())

# getcwd(), chdir() 등 작업 폴더 설정 불필요
# 파일 경로 상 내부 드라이브 경로(C: 등) 접근 불가

# 데이터 파일 읽기 예제
import pandas as pd
X_test = pd.read_csv("data/X_test.csv")
X_train = pd.read_csv("data/X_train.csv")
y_train = pd.read_csv("data/y_train.csv")

# 사용자 코딩

X_train=X_train.drop('cust_id',axis=1)
y_train=y_train.drop('cust_id',axis=1)
test_id=X_test.pop('cust_id')

# 1.결측치
X_test['환불금액']=X_test['환불금액'].fillna(0)
X_train['환불금액']=X_train['환불금액'].fillna(0)



# 스케일링
from sklearn.preprocessing import (RobustScaler,MinMaxScaler)
scaler = MinMaxScaler()
cols = X_train.select_dtypes(exclude=object).columns
# print(X_test.head())
X_train[cols]=scaler.fit_transform(X_train[cols])
X_test[cols]=scaler.transform(X_test[cols])
# print(X_train.head())


# 라벨인코딩
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
# print(X_train.select_dtypes(include=object))
cols = ['주구매상품','주구매지점']
# print('train')
# print(X_train[cols].nunique()) # 주구매상품 42 # 주구매지점 24 로 동일 
# print('test')
# print(X_test[cols].nunique()) # 주구매상품 41
# 합쳐야함
all_data = pd.concat([X_train,X_test])
# print(X_train.shape, X_test.shape, all_data.shape ) # (3500, 10) (2482, 10) (5982, 10) 
# 라벨인코딩 진행함 

# print(all_data[cols].head())
for col in cols:
	all_data[col] = encoder.fit_transform(all_data[col])
# print(all_data[cols].head()) #라벨인코딩 확인완료 
# 다시 나눠야함
X_train = all_data.iloc[:X_train.shape[0],:]
X_test = all_data.iloc[X_train.shape[0]:,:]
# print(X_train.shape, X_test.shape, all_data.shape ) # # (3500, 10) (2482, 10) (5982, 10) # 확인완료 # .iloc 주의할것 

# validation dataset 분리
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(X_train,y_train,random_state=2023,test_size=0.15)
# print(X_tr.shape,X_val.shape,y_tr.shape,y_val.shape) #(2975, 9) (525, 9) (2975, 1) (525, 1)

# 모델링, 평가지표 
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score

model = RandomForestClassifier(random_state=2023,max_depth=7,n_estimators=400)
model.fit(X_tr,y_tr['gender'])
pred=model.predict_proba(X_val)
print(roc_auc_score(y_val ,pred[:,1])) # 남자일 확률 (0:여자,1:남자)


# 답안 제출 참고
# 아래 코드 예측변수와 수험번호를 개인별로 변경하여 활용
pred=model.predict_proba(X_test)
pd.DataFrame({'custid': test_id, 'gender': pred[:,1]}).to_csv('20230615.csv', index=False)

submit = pd.read_csv('20230615.csv')
print(submit.head())

 

근데 궁금한게 있어서 커뮤니티에 질문 남겼음.

 

  • 에러메시지는 이렇게 나오는데요 /goorm/Main.out:68: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples,), for example using ravel().
  • model.fit(X_tr,y_tr)
  • model.fit(X_tr,y_tr['gender']) 이라고 수정해주면 에러메시지가 사라집니다.
  • 그런데 저는 위에서 이미 y_train=y_train.drop('cust_id',axis=1) 이라고 해주었는데도 gender 컬럼을 지정해주어야 에러메시지가 안나오는 이유가 궁금합니다 ㅠㅠ
    제가 작성한 전체 코드는 아래에 첨부드립니다...
    질문이 좀 번거로워서 죄송합니다
  • 그리고 번외로, train 과 test 를 합친 all_data 에 라벨인코딩을 적용할때는 encoder.fit_transform 으로만 적어주면 되는거 같은데 이게 맞는지도 한번 여쭤보고 싶습니다

 

답변 해주시면 돌아와서 업데이트 해야겠음

반응형

댓글