はじめに
現在、とある件でGUIを使った機械学習ツールの開発をしています。
その過程で初めてStreamlitのcolumn_configを触ったので、その中のselectboxを実際のコードを交えつつここに書こうかと思います。
そもそもcolumn_configとは?
(※ Streamlitのドキュメントから引用)
データフレームの中にインプット系のウィジットを入れたり、画像やグラフなども挿入できる便利な機能です。
公式のドキュメントにも使用例が豊富なので実際に見に行くと想像しやすいと思います。
今回の使用例
今回は、ユーザが自由に入力したデータを機械学習モデルに挿入しPredictするという機能で使いました。
[ユーザが入力したデータ] → [学習済みモデル] → [予測結果]
これの[ユーザが入力したデータ]という部分で入力を受け付けたということです。
実際のUIがこちら↓
こんな感じで直接データフレームに対して入力できます。
実装
初見だと結構複雑でどこに何を入力すべきかわからなくなりますが、data_editorのウィジットの書き方を基本に考えました。
# data_editorの実装
df = pd.DataFrame("ポルトガルの数学成績データ") # 今回使っていたデータ
edited_df = st.data_editor(df)
# column_configの実装
df = pd.DataFrame("ポルトガルの数学成績データ") # 今回使っていたデータ
edited_data = st.data_editor(
df,
column_config={
"学校": st.column_config.SelectboxColumn(
"学校",
help="The category of school",
width="medium",
options=["GP", "MS"],
required=True,
),
# .... 略
"恋愛関係": st.column_config.SelectboxColumn(
"恋愛関係",
help="Romantic relationship",
width="medium",
options=["no", "yes"],
required=True,
),
},
hide_index=True,
)
ほんとは辞書型などで一通り定義してからforで回すなどすればスマートな実装ができそうですね。
少し工夫した点
アプリでは入力時だとカテゴリ名で、そうじゃないときは数字で入力する必要がありました。
そこで以下の辞書と関数を定義してeditする前後で変換を挟みました。
mat_data_label_name = {
"学校": {
"0": "GP",
"1": "MS"
},
"性別": {
"0": "F",
"1": "M"
},
# ... 略
}
def categori_to_name_by_matdata(df):
for col in df.columns:
if col in mat_data_label_name:
df[col] = df[col].astype(str)
df[col] = df[col].replace(mat_data_label_name[col])
return df
def name_to_categori_by_matdata(df):
for col in df.columns:
if col in mat_data_label_name:
df[col] = df[col].astype(str)
df[col] = df[col].replace({v: k for k, v in mat_data_label_name[col].items()})
return df.astype(np.int64)
こうすることで、学習済みモデルには数字が入力され、ユーザはカテゴリ名で編集できるので便利という感じにできます。
おわりに
column_configはいろいろと種類も多く、便利そうなので今後とも使っていきたいですね。