Daconは年齢予測コンテストを覆す
ダイコン大会に出場するのは初めてです.3月21日から4月1日まで行われたアワビの年齢予測試合は、比較的簡単な基本試合だったが、EDAからモデリングまで、多くのことを学んだ.特に学習者たちは良い内容をたくさん共有しています😭 (私ももっと頑張ります…)
与えられたアワビのデータを通じてアワビの年齢の試合を予測する.
1. train.csv:学習データid:サンプルID Gender:アワビの性別 Lenght:反転長さ Diameter:あわび囲い Height:反転キー Whole Weight:アワビ総重量 Shecked Weight:シェルを持たない重量 Viscr Weight:内部重量 Shell Weight:シェル重量 Target:アワビ年齢
2. test.csv:テストデータ
学習データと同じ
3. sample_submissoin.csvid:サンプルID Target:アワビ年齢
Dtypeが
欠測値は存在しないため、欠測値の前処理過程は不要である.
上記異常値判別も行った.最初はz-methodを用いたが,すべての行が異常値と判定されたため,IQR法を用いた.しかし、要するに、モデリング中に異常値が除去されるとパフォーマンスが低下することがわかり、元のデータに従ってモデリングが行われました.
Shell Weightは最も高い正の相関を示した.
これは、年を取るほど皮の重さが重くなることを意味する.
また,ピルソン相関係数は0.3以上であり,アワビの重量,身長,直径,周長は年齢とともに増加することを示した.
Feature間の相関は高い.正規化後vif値も高く,特徴間の高い相関は多重共線形問題を生じる.
したがって,回帰モデルを使用するには,他の方法で正規化するか,特定の特徴のみを用いてモデリングする必要がある場合がある.
変数の線形結合を使用して新しい変数を追加
多重共線形性は増加したが,深さ学習モデルの使用は考慮されなかった.
(回帰モデルを使用する場合は考慮する必要があります)
モデリング中に変数を含めたり除外したりしました.最後にval mae値は最低のモデル結果を提出したが,当時使用していた変数を覚えていない.ほほほ、6~7個くらいの新しい変数を使いました.ration=シェルなし重量/総重量 w origin=シェルを持たない重量 異物=総重量-(皮付き重量+内蔵重量+皮付き重量)
アワビ不必要物質の価値(異物、血水など) water=総重量-(シェル重量+シェル重量なし) area=直径/2キー/2 pi volume=(キーx長x周長/pi)/重量 n ratio=異物/周長 new=weightration*アスペクト比
アクティブ化関数として使用される
真ん中にもう1つ積み重ねてみましたが、train setでエラー値が低下し、validation setでエラー値が上昇します.データが小さい場合は、DNモデルを構築する場合、レイヤが多ければ多いほど、マッチングが容易になることに注意してください.
当初,
結論:Public 64位、Private 53位の結果が得られた.
これも私の力ではないコードと小さな投稿者の他の参加者たちが作った結果だと思います.いつかコード共有やチャットページを見ずに、自分の実力でランキングに入りたい.
試合中に限って専門試験がある...ふふ、試合が終わる前日からモデリングが始まっていて、1日に3回の制限を提出するのが思ったより大事でした😭
したがって,今週からのニュースグループ分類コンテストでは,非常に単純なモデルであっても,必ず1日に3回提出しなければならない.今回の大会のテーマは教育会議の後初めて触れたNLPであり、困難に直面する可能性があるが、1週間の勉強に励み、様々な試みを試みる.
アワビ年齢予測慶津大会をテーマに学習を行い、学習者から
最後にprivate scoreが上位にランクインした人は主にニューラルネットワークモデルを組み合わせたようだ.ケゲルプロジェクトをしていたときも感じましたが、組み合わせは確かに性能の向上に役立ちます.逆に、性別を
確かに,他の性別と比較して,すべての特徴における数値が低い
モデル自体は簡単ですが、異なる分布を持つfeatureを分類モデリングし、パフォーマンスを向上させることができます.これにより,データ探索と前処理プロセスの重要性を再認識した.
🦪 アワビの年齢予測試合
与えられたアワビのデータを通じてアワビの年齢の試合を予測する.
データ#データ#
1. train.csv:学習データ
2. test.csv:テストデータ
学習データと同じ
3. sample_submissoin.csv
コード#コード#
EDA
train.info()
Dtypeが
object
のGender
変数は非常に注目されている.その後の前処理では、符号化が必要になる場合がある.print(f'train: {train.shape}')
print(f'test: {test.shape}')
# output
# train: (1253, 10)
# test: (2924, 9)
train.isnull().sum().to_frame('nan_count')
欠測値は存在しないため、欠測値の前処理過程は不要である.
train = train.drop(['id'], axis = 1) # id 열 제거
id
は一意番号(シリアル番号)と同じなので削除します.上記異常値判別も行った.最初はz-methodを用いたが,すべての行が異常値と判定されたため,IQR法を用いた.しかし、要するに、モデリング中に異常値が除去されるとパフォーマンスが低下することがわかり、元のデータに従ってモデリングが行われました.
目標(年齢)
temp = train['Target'].unique()
print(np.sort(temp))
plt.figure(figsize=(20,10))
sns.countplot('Target', data=train)
plt.title("Abalone age by count", fontsize = 30)
plt.xlabel("target(age)")
plt.ylabel("count")
plt.show()
Gender
plt.figure(figsize=(10,5))
sns.countplot('Gender', data=train)
plt.title("Abalone gender by count", fontsize = 20)
plt.show()
# kdeplot은 확률밀도가 추정되어 범주형 변수를 연속적으로 만들어줌
plt.figure(figsize=(10,5))
sns.kdeplot('Target', hue='Gender', data=train)
plt.title("Abalone age by gender", fontsize=30)
plt.show()
Target and Features
train_corr = train.drop(['Gender'], axis=1)
scaler = MinMaxScaler()
train_corr[train_corr.columns] = scaler.fit_transform(train_corr[train_corr.columns])
corr28 = train_corr.corr('pearson')
s28 = corr28.unstack()
df_temp28 = pd.DataFrame(s28['Target'].sort_values(ascending=False), columns=['Target'])
df_temp28.style.background_gradient()
Shell Weightは最も高い正の相関を示した.
これは、年を取るほど皮の重さが重くなることを意味する.
また,ピルソン相関係数は0.3以上であり,アワビの重量,身長,直径,周長は年齢とともに増加することを示した.
Features
plt.figure(figsize=(10,10))
features = train.drop(['Gender','Target'], axis=1)
heat_table = features.corr()
mask = np.zeros_like(heat_table)
mask[np.triu_indices_from(mask)] = True
heatmap_ax = sns.heatmap(heat_table, annot=True, mask = mask, cmap='coolwarm')
heatmap_ax.set_xticklabels(heatmap_ax.get_xticklabels(), fontsize=20, rotation=45)
heatmap_ax.set_yticklabels(heatmap_ax.get_yticklabels(), fontsize=20, rotation=45)
plt.title('correlation between features', fontsize=20)
plt.show()
%%time
f1 = features
scaler = MinMaxScaler()
f1[f1.columns] = scaler.fit_transform(f1[f1.columns])
vif_data = pd.DataFrame()
vif_data["features"] = f1.columns
vif_data["VIF"] = [variance_inflation_factor(f1.values.astype("float32"), i) for i in range(f1.shape[1])]
vif_data.sort_values("VIF")
Feature間の相関は高い.正規化後vif値も高く,特徴間の高い相関は多重共線形問題を生じる.
したがって,回帰モデルを使用するには,他の方法で正規化するか,特定の特徴のみを用いてモデリングする必要がある場合がある.
前処理
カテゴリ変数の処理
train = pd.get_dummies(data = train, columns = ['Gender'], prefix = 'Gender')
test = pd.get_dummies(data = test, columns = ['Gender'], prefix = 'Gender')
Gender
はカテゴリ変数であり、get_dummies
を使用して符号化される.データ分割
train_X = train.drop(['id', 'Target'], axis=1)
train_y = train.Target
test.drop(['id'], axis=1, inplace=True)
新しい変数の追加
変数の線形結合を使用して新しい変数を追加
多重共線形性は増加したが,深さ学習モデルの使用は考慮されなかった.
(回帰モデルを使用する場合は考慮する必要があります)
モデリング中に変数を含めたり除外したりしました.最後にval mae値は最低のモデル結果を提出したが,当時使用していた変数を覚えていない.ほほほ、6~7個くらいの新しい変数を使いました.
train_X['ratio'] = train_X['Shucked Weight']/train_X['Whole Weight']
test['ratio'] = test['Shucked Weight']/test['Whole Weight']
train_X['w_origin'] = train_X['Viscra Weight'] + train_X['Shucked Weight']
test['w_origin'] = test['Viscra Weight'] + test['Shucked Weight']
アワビ不必要物質の価値(異物、血水など)
train_X['foreign body'] = train_X['Whole Weight'] - (train_X['Shucked Weight'] + train_X['Viscra Weight'] + train_X['Shell Weight'])
test['foreign body'] = test['Whole Weight'] - (test['Shucked Weight'] + test['Viscra Weight'] + test['Shell Weight'])
# 음수 값은 0으로 처리했을 때보다, min 값으로 처리했을 때 높은 성능을 보임
train_X.loc[train_X['foreign body'] < 0 , 'foreign body'] = np.min(train_X[train_X['foreign body'] > 0])['foreign body']
test.loc[test['foreign body'] < 0 , 'foreign body'] = np.min(test[test['foreign body'] > 0])['foreign body']
train_X['water'] = train_X['Whole Weight'] - (train_X['Shell Weight'] + train_X['Shucked Weight'])
test['water'] = test['Whole Weight'] - (test['Shell Weight'] + test['Shucked Weight'])
# 음수 값은 0으로 처리했을 때보다, min 값으로 처리했을 때 높은 성능을 보임
train_X.loc[train_X['water'] < 0 , 'water'] = np.min(train_X[train_X['water'] > 0])['water']
test.loc[test['water'] < 0 , 'water'] = np.min(test[test['water'] > 0])['water']
train_X['area'] = train_X['Diameter']/2 * train_X['Height']/2 * np.pi
test['area'] = test['Diameter']/2 * test['Height']/2 * np.pi
train_X['volume'] = (train_X['Lenght']/2) * (train_X['Height']/2) * (train_X['Diameter']/(2*np.pi)) * 3/4 * np.pi
test['volume'] = (test['Lenght']/2) * (test['Height']/2) * (test['Diameter']/(2*np.pi)) * 3/4 * np.pi
train_X['n_ratio'] = train_X['foreign body'] / (train_X['Shucked Weight']/train_X['Whole Weight'])
test['n_ratio'] = test['foreign body'] / (test['Shucked Weight']/test['Whole Weight'])
train_X['new'] = train_X['Viscra Weight'] / train_X['Shucked Weight'] * train_X['Height'] / train_X['Lenght']
test['new'] = test['Viscra Weight'] / test['Shucked Weight'] * test['Height'] / test['Lenght']
モデリング
# 딥러닝 모델 선언
model.add(Dense(16, input_dim=15, activation='LeakyReLU'))
model.add(Dense(32, activation='elu'))
model.add(Dense(64, activation='LeakyReLU'))
model.add(Dropout(0.3))
model.add(Dense(64, activation='LeakyReLU'))
model.add(Dense(32, activation='elu'))
model.add(Dense(16, activation='LeakyReLU'))
model.add(Dense(1))
model.compile(loss='mean_absolute_error',
optimizer='Nadam',
metrics=['mae'])
# 모델 저장 폴더 만들기
MODEL_DIR = './model/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
modelpath = "./model/{epoch:02d}-{val_loss:.4f}.hdf5"
# 모델 업데이트 및 저장
cp = ModelCheckpoint(filepath=modelpath, monitor='val_mae', verbose=0, save_best_only=True, mode = 'min')
# 학습 자동 중단 설정
es = EarlyStopping(monitor='val_mae', patience=100, mode='min')
# 모델의 개선이 없을 경우 learning rate를 조절해 모델의 개선 유도
rlrp = ReduceLROnPlateau(monitor='val_mae', factor=0.8, patience=100, mode='min')
model.fit(train_X, train_y, validation_split=0.3, epochs=1000, batch_size=32, verbose=1, callbacks=[es, cp, rlrp])
複数のモデルを試みたところ,データ量が少なすぎるため性能が悪いと考えられる深さ学習モデルが意外に先進的であることが分かった.合計コードは、じゃあアップロードしたコードを参照しています.アクティブ化関数として使用される
elu
およびLeakyReLU
は、既存のReLU
におけるDying RELUの問題の補完である.elu
およびLeakyReLU
のいずれかの関数を使用する場合と比較して、2つのスタックを混合する場合のパフォーマンスが高く、データ量が少ないため、損失率を0.5に設定した場合のパフォーマンスは0.3に設定した場合よりも向上します.真ん中にもう1つ積み重ねてみましたが、train setでエラー値が低下し、validation setでエラー値が上昇します.データが小さい場合は、DNモデルを構築する場合、レイヤが多ければ多いほど、マッチングが容易になることに注意してください.
dropout
のほか、earlystopping
、ReduceLROnPlateau
などによりモデルのオーバーフィット(オーバーフィット)を防止した.またvalidation splitのパーセンテージも複数回調整されているため、30%に設定した場合の性能が最も高い.当初,
val_mae
値は0.157程度にとどまり,新しい特性を定義し,活性化関数を調整すると,val_mae
値は0.152に低下した.モデルを複数回レビューし,検証セットエラー値が最も低いモデル予測値を提案した.予測
Y_prediction = model.predict(test)
結果
結論:Public 64位、Private 53位の結果が得られた.
これも私の力ではないコードと小さな投稿者の他の参加者たちが作った結果だと思います.いつかコード共有やチャットページを見ずに、自分の実力でランキングに入りたい.
試合中に限って専門試験がある...ふふ、試合が終わる前日からモデリングが始まっていて、1日に3回の制限を提出するのが思ったより大事でした😭
したがって,今週からのニュースグループ分類コンテストでは,非常に単純なモデルであっても,必ず1日に3回提出しなければならない.今回の大会のテーマは教育会議の後初めて触れたNLPであり、困難に直面する可能性があるが、1週間の勉強に励み、様々な試みを試みる.
アワビ年齢予測慶津大会をテーマに学習を行い、学習者から
AutoML
、pandas-profiling
など多くの機械学習ツールやデータの多角度を学ぶことができる.勉强を通じていろいろなことを得たので、私ももっと努力して役に立つ勉强者になりたいです.がんばって…!最後にprivate scoreが上位にランクインした人は主にニューラルネットワークモデルを組み合わせたようだ.ケゲルプロジェクトをしていたときも感じましたが、組み合わせは確かに性能の向上に役立ちます.逆に、性別を
M
F
とI
の2種類に分けて、性別によって2種類のDNNモデルを作成した人もいます.確かに,他の性別と比較して,すべての特徴における数値が低い
I
性別は,単独モデリングがより効果的であるようである.(I
=Infrant:まだ成長中の幼児アワビを示す)モデル自体は簡単ですが、異なる分布を持つfeatureを分類モデリングし、パフォーマンスを向上させることができます.これにより,データ探索と前処理プロセスの重要性を再認識した.
Reference
この問題について(Daconは年齢予測コンテストを覆す), 我々は、より多くの情報をここで見つけました https://velog.io/@ssokeem/Dacon-abalone-age-predictionテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol