• 카테고리

    질문 & 답변
  • 세부 분야

    딥러닝 · 머신러닝

  • 해결 여부

    미해결

feature importance 컬럼명 질문입니다.

22.09.19 18:29 작성 조회수 685

0

안녕하세요 xgboost와 lgbm을 사용하여 학습후 feature importance를 사용하여 중요도를 알아보았는데 몇가지 질문사항이 있습니다.

  1. 그래프 y축이 컬럼명이 아닌 f21. f0 이런식으로 나오게 되었습니다. 혹시 저게 어떤 데이터를 가리키는지 알수있는 방법이 있나요?

2. 컬럼명이 나오게 그래프를 그리려면 pd.Dataframe으로 바꾸면 된다고 했는데 그러면 코드를 처음부터 수정해야하나요?

아니면

from xgboost import plot_importance

fig, ax = plt.subplots(figsize=(10, 12))

plot_importance(clf, ax=ax)

이 부분에서 수정이 가능할까요?

답변 4

·

답변을 작성해보세요.

0

mjwabc님의 프로필

mjwabc

2022.10.04

해보니 잘 안되서 코드 사진 올려봅니다,,

imagedf[[ ~ ]] = df[[ ~ ]].apply(np.log1p) 사진에서 두번째 코드는 이렇게 하여서 로그변화를 시켰습니다,

image이렇게 원핫을 시켜 결과를 얻었는데 이렇게 하면 feature importance가 f1, f2처럼 컬럼명으로 나오지 않아서 dataframe으로 바꿔서 해보고싶습니다. 강사님께서 알려주신 방법으로 했는데 잘 안되네요,,

어떻게 get_dummie를 사용해서 dataframe으로 바꿔야할지 잘 모르겟습니다..

아니면 혹시 f1 f2 가 어떤 변수를 지칭하고 있는지 확인할수 있는 방법이 있을까요??

캡처한 내용만 봐서는 어떻게 데이터를 가공했는지 알수가 없군요.

전체 소스코드와 데이터 파일을 github repository를 하나 만들어서 올려 주십시요. 제가 확인해 보겠습니다.

소스코드를 봐서는 num_cols를 굳이 분리할 이유가 없어 보입니다만,

num_cols 추출한 부분과 OneHotEncoder적용한 부분, hstack 적용한 부분을 모두 없애고

df_ohe = pd.get_dummies(df, columns=cat_cols)

하시면 숫자형 컬럼은 그대로 유지하고 cat_cols로 지정된 컬럼들만 one-hot encoding됩니다.

이후에 피처 DataFrame을 아래와 같이 추출하고

X = df_ohe.drop(target_col, axis=1)

아래와 같이 학습 및 예측 적용해 보십시요.

X_trn, X_tst, y_trn, y_tst = train_test_split(X, df_ohe[target_col], test_size=0.2, random_state=seed)
clf = XGBRegressor(random_state=seed, n_estimators=1000)
clf.fit(X_trn, np.log1p(y_trn))
p = np.expm1(clf.predict(X_tst))

 

 

mjwabc님의 프로필

mjwabc

2022.10.05

정말 감사합니다!!!!!!!!!! 혹시 궁금한게 왜 LGBMRegressor 은 같은 코드를 적용했을때

LightGBMError: Wrong size of feature_names 오류가 나오는데

검색을 해봐도 잘 모르겠는데 혹시 알고 계시는 부분이 있을까요?

아마 문자열에 특수문자가 있어서 원핫 인코딩 변환시 컬럼명이 lightgbm에서 수용이 안되는것 같습니다

아래 참조 부탁드립니다

https://stackoverflow.com/questions/58333893/why-the-lightgbm-training-went-wrong-showing-wrong-size-of-feature-names

 

 

0

mjwabc님의 프로필

mjwabc

2022.10.02

답변 감사합니다! 계속해서 질문 드려 죄송합니다 ㅠㅠ

이렇게 순서대로 코딩을 했습니다

  1. num_cols과 cat_cols을 나누어서

  2. 수치형 변수들은 np.log1p를 주었고

  3. 범주형 데이터는 pd.get_dummies(cat_cols)을 사용하여 아래 사진과같이 0 1로 잘 표현이 된것 같습니다.

image

이전에 OHE를 사용했을 때는 이렇게 X를 지정 했는데 
X = hstack((df[num_cols],
            ohe.fit_transform(df[cat_cols])))

ohe.fit_transform(df[cat_cols]))) 이부분 대신 df[cat_cols]을 했더니 
X = hstack((df[num_cols],
            df[cat_cols]))

ValueError: could not broadcast input array from shape (692,11) into shape (692,) 에러가 나옵니다. 
X에 어떻게 지정해야 할까요?? 

 

뭔가 num_cols관련 변환이 잘못되지 않았나 싶습니다.

shape가 (692,) 이면 1차원 입니다. reshape로 2차원으로 만들어 주십시요. 예를 들어 reshape(-1, 1) .

근데 num_cols는 컬럼이 1개 밖에 없는 건가요? 확인 부탁드립니다.

mjwabc님의 프로필

mjwabc

2022.10.04

아니요 num_cols = [] 이렇게 지정했고 11개 입니다

 

num_cols=[]로 지정하였으면 비어 있기 때문에 1차원이 된것 같은데, num_cols로 만들어지는 DataFrame의 차원을 shape로 조사해 보시지요.

0

mjwabc님의 프로필

mjwabc

2022.10.01

csv파일을 읽고 모델을 만들었는데, DataFrame으로 변경을 어떻게 해야할지 잘 모르겠습니다

 

df = pd.read_csv('membranedt.csv', encoding='cp949')
이렇게 읽고 
df['FS Velocity (cm/s)'].fillna(df['FS Velocity (cm/s)'].mean(), inplace=True)
df['DS Velocity (cm/s)'].fillna(df['DS Velocity (cm/s)'].mean(), inplace=True)
df = df.drop(df.columns[[18,20]], axis=1)

이런식으로 데이터를 채우고 드랍한 후 

np.log1p와 OHE를 사용하여 전처리 후  X 를만들어서 

X_trn, X_tst, y_trn, y_tst = train_test_split(X, df[target_col], test_size=0.2, random_state=seed)
clf = XGBRegressor(random_state=seed, n_estimators=1000)
clf.fit(X_trn, np.log1p(y_trn))

이런식으로 학습을 시켰는데 어디서 dataframe으로 만들어야 할지 잘 모르겠습니다,,

df는 DataFrame 객체 입니다.

다만 X 가 DataFrame 객체인지 코드를 올려주시지 않아서 잘 모르겠습니다.

type(X) 를 하셔서 X가 DataFrame인지 확인해 보십시요.

X가 DataFrame이 아니라 numpy ndarray면 train_test_split()의 결과 반환 데이터 세트도 ndarray입니다.

 

mjwabc님의 프로필

mjwabc

2022.10.01

scipy.sparse.coo.coo_matrix 으로 나오네요,,

df[['Year', 'FS Molarity (M)', 'FS Osmotic pressure\n(atm)', 'DS Molarity (M)', 'DS Osmotic pressure\n(atm)', 'P Difference\n(atm)', 'FS Velocity (cm/s)', 'DS Velocity (cm/s)', 'FS Temperature\n(°C)', 'DS Temperature (°C)', 'Membrane Flux \n(LMH)', 'A\n(LMH/atm)']] = df[['Year', 'FS Molarity (M)', 'FS Osmotic pressure\n(atm)', 'DS Molarity (M)', 'DS Osmotic pressure\n(atm)', 'P Difference\n(atm)', 'FS Velocity (cm/s)', 'DS Velocity (cm/s)', 'FS Temperature\n(°C)', 'DS Temperature (°C)', 'Membrane Flux \n(LMH)', 'A\n(LMH/atm)']].apply(np.log1p)
df[num_cols].describe()

from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder()
X = hstack((df[num_cols],
            ohe.fit_transform(df[cat_cols])))

print(X.shape)
type(X)
이렇게 데이터를 처리했습니다.. X를 dataframe으로 변환할 방법이 있을까요? 

scikit learn의 OneHotEncoder를 이용하면 기본적으로 ndarray로 변환됩니다.

비슷하게 one hot encoding을 수행하는 pandas의 get_dummies()를 이용해 보십시요.

X = pd.get_dummies(df)

다만 one hot encoding을 수행하면 컬럼의 갯수가 많아져서 feature importance에 나오는 컬럼 수가 크게 늘어날 수 있습니다.

mjwabc님의 프로필

mjwabc

2022.10.01

X 에 숫자형과 범주형 데이터가 들어가있어서 숫자형은 로그변환은 해주고 범주형은 원핫을 시켜주고 싶은데

저 상태에서 X = pd.get_dummies(df)를 사용하게 되면 안되는거 아닌가요??

해봤더니 score가 너무 높게 나와버렸습니다.

get_dummies 인자로 colums=카테고리 컬럼 리스트를 입력하면 원하는 카테고리 컬럼들만 원핫 인코딩 할 수 있습니다

0

안녕하십니까,

학습을 시킨 데이터 세트가 numpy면 xgboost와 lightgbm에서 feature importance 구할 시 feature 명이 나오지 않습니다. 왜냐하면 numpy는 feature 명을 알수가 없기 때문입니다.

때문에 feature 명을 알 수 있도록 DataFrame으로 학습 데이터 세트를 변경 해주셔야 합니다. 그렇지 않으면 f1, f2와 같은 값을 feature 명으로 변경할 수 없습니다.

코드를 다시 확인해 보시고, 학습시 사용된 데이터 세트를 DataFrame으로 변경해 주시면 됩니다.

감사합니다.