문장 분류 어노테이션을 ipywidgets로 UI를 작성하여 효율화

했던 일



문서 분류 어노테이션을 조금이라도 편하게 하기 위해, 노트북상에서 움직이는 어노테이션용 UI를 ipywidgets로 구현했습니다.
아래는 실제 화면입니다 (livedoor 뉴스를 어노테이션하는 형태를 가정). 버튼을 누르면 문장 표시, 카테고리 라벨 선택, csv에 저장이 가능합니다.


코드



환경은 Google 공동체입니다.
text 열과 category 열이 있는 DataFrame이 이미 준비되어 있는 전제로의 코드가 됩니다. 지금부터 주석을 달기 때문에 카테고리 열은 None입니다.

import datetime
import pandas as pd
from IPython.display import HTML, display
from ipywidgets import HBox, VBox, interactive, widgets

# 文章を折り返し表示する設定
# 設定が適用されるのは次回以降に実行されるセルのため、先に実行しておく
def set_css():
  display(HTML('''
  <style>
    pre {
        white-space: pre-wrap;
    }
  </style>
  '''))
get_ipython().events.register('pre_run_cell', set_css)
########################################################################
# ボタン押下時の挙動を設定
########################################################################
def show_text():
    print(df.loc[output_row_box.value, ["text"]].values[0])
    print("-"*50)
    print("現在のカテゴリ", df.loc[output_row_box.value, ["category"]].values[0])
    print("-"*50)

def change_category():
    cat_before = df.loc[output_row_box.value, ["category"]].values[0]
    df.loc[output_row_box.value, "category"] = category_btn.value
    print(f"カテゴリ変更: {cat_before}{category_btn.value}")

def make_csv():
    df.to_csv(output_text_box.value)

    current_japan_time = datetime.datetime.now(
        datetime.timezone(datetime.timedelta(hours=9)))
    save_time = current_japan_time.strftime('%Y/%m/%d %H:%M:%S')
    print(f"保存完了:{save_time}")

########################################################################
# widgets(テキストボックス、各種ボタン)の作成
########################################################################
# 表示する行を入力するボックス
output_row_box = widgets.BoundedIntText(min=0, max=len(df))

# テキスト表示の実行ボタン
show_text_btn = interactive(show_text, {'manual': True, 'manual_name': 'テキストを表示'})
show_text_btn.manual_button.style.button_color = 'lightblue'

# カテゴリの選択肢ボタン
categories = ["トピックニュース", "Sports Watch", "ITライフハック","家電チャンネル", 
    "MOVIE ENTER", "独女通信","エスマックス", "livedoor HOMME", "Peachy"]
category_btn = widgets.ToggleButtons(options=categories, disabled=False)

# カテゴリ変更の実行ボタン
change_category_btn = interactive(change_category, {'manual': True, 'manual_name': 'カテゴリを変更'})
change_category_btn.manual_button.style.button_color = 'lightblue'

# csvのファイル名を設定するテキストボックス
output_text_box = widgets.Text("annotation.csv")

# csv出力の実行ボタン
make_csv_btn = interactive(make_csv, {'manual': True, 'manual_name': 'csvに保存'})
make_csv_btn.manual_button.style.button_color = 'lightblue'

########################################################################
# notebook上にwidgetsを表示
########################################################################
# テキスト選択
print("【テキストを選択】")
display(HBox(children=[output_row_box, show_text_btn]))

# カテゴリ変更
print("\r\n【カテゴリを選択】")
category_btn.layout.flex = '1'
change_category_btn.layout.flex = '1'
display(HBox(children=[category_btn, change_category_btn]))

# csv出力
print("\r\n【csvへ保存】")
display(HBox(children=[output_text_box, make_csv_btn]))

감상



카테고리 일람이 항상 보이기 때문에, Excel등을 사용하는 것보다 쾌적하게 어노테이션을 할 수 있게 되었을까라고 생각합니다.
ipywidgets는 직관적으로 조작할 수 있는 UI를 쉽게 만들 수 있는 점이 훌륭하네요. 아이디어 나름으로 여러가지 사용도가 있을 것 같다고 느꼈기 때문에, 다른에서의 활용 방법을 생각해 가고 싶습니다.

좋은 웹페이지 즐겨찾기