\documentclass[japanese,tombow,other]{jnlp_3.2}
\usepackage{jnlpbbl_1.4}
\usepackage[dvipdfmx]{graphicx}
\usepackage{amsmath}
\usepackage{gentombow}
\settombowbleed{5mm}
%%%%\usepackage{hangcaption_jnlp}
%%%%\usepackage{udline}
%%%%\setulminsep{1.2ex}{0.2ex}
%%%%\let\underline=\ul

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% author's definition
%%%%\usepackage{amsmath,amssymb,mathtools}
%%%%% add
%%%%\usepackage{algorithm}
%%%%\usepackage{algorithmic}
%%%%\usepackage{amsfonts}
%%%%\usepackage{amssymb}
%%%%\usepackage{ascmac}
%%%%\usepackage{booktabs}
%%%%\usepackage{color}
%%%%\usepackage{comment}
%%%%\usepackage{float}
%%%%\usepackage[ipaex]{pxchfon}
%%%%\usepackage{lingmacros}
%%%%\usepackage{multirow}
%%%%\usepackage{subfigure}
%%%%\usepackage{textcomp}
\usepackage{url}
%%%%\usepackage{lingmacros}
%%%%\newcommand{\argmax}{\mathop{\rm arg~max}\limits}
%%%%\newcommand{\argmin}{\mathop{\rm arg~min}\limits}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\renewcommand\UrlFont{\rmfamily}


\Volume{27}
\Number{3}
\Month{September}
\Year{2020}
%%%%\Issuetitle{「　　　　」特集号}

\setcounter{page}{703}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\jsubject{学会記事}
\jtitle{言語処理100本ノック}
\jauthor{岡崎　直観\affiref{titech} \and 清野　　舜\affiref{aip}\affiref{tohoku} \and 高橋　　諒\affiref{tohoku}\affiref{aip} \and 横井　　祥\affiref{tohoku}\affiref{aip}}
%%%% 英語タイトル・英語著者名は出力せず
\jkeywords{自然言語処理，プログラミング，研修}
\etitle{NLP 100 Exercise}
\eauthor{Naoaki Okazaki\affiref{titech} \and Shun Kiyono\affiref{aip}\affiref{tohoku} \and Ryo Takahashi\affiref{tohoku}\affiref{aip} \and Sho Yokoi\affiref{tohoku}\affiref{aip}}
\ekeywords{Natural Language Processing, Programming, Training Program}

\headauthor{岡崎，清野，高橋，横井}
\headtitle{言語処理100本ノック}

%%%% 英語所属は出力せず
\affilabel{titech}{東京工業大学情報理工学院}{School of Computing, Tokyo Institute of Technology}
\affilabel{aip}{理化学研究所革新知能統合研究センター}{RIKEN Center for Advanced Intelligence Project}
\affilabel{tohoku}{東北大学情報科学研究科}{Graduate School of Information Sciences, Tohoku University}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\maketitle


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{背景}
\label{sec:intro}

言語処理100本ノックは，実用的でワクワクするような課題に取り組みながら，プログラミング，データ分析，研究のスキルを楽しく習得することを目指した問題集である．東北大学の乾・岡崎研究室での新人研修を想定し，岡崎が2011年の冬頃に制作を開始し，初版\footnote{http://www.cl.ecei.tohoku.ac.jp/index.php?NLP\%20100\%20Drill\%20Exercises}を2012年4月3日に公開した．その後，大幅な改訂を2回実施した．2015年版\footnote{\url{http://www.cl.ecei.tohoku.ac.jp/nlp100/}}（2015年3月12日公開）では，データが再配布可能となるように全面的な改訂を行うとともに，単語の分散表現などの新たなテーマを導入した． 2020年版\footnote{\url{https://nlp100.github.io/}}（2020年4月6日公開，2020年6月8日改訂）では，深層ニューラルネットワークに関する問題を強化するとともに，英語版や韓国語版など多言語への翻訳を推進した（図\ref{fig:nlp100}）．

言語処理100本ノックの問題作成にあたり，次のようなことを意識した．

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% fig. 1
\begin{figure}[t]
\begin{center}
\includegraphics{27-3ia15f1.eps}
\end{center}
\caption{言語処理100本ノック 2020年版 (Rev 1)}
\label{fig:nlp100}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{実践的な題材を選ぶ}
自然言語処理の研究・開発を行うために習得して欲しい技術（例えばUNIXコマンドや正規表現など）やトピック（例えば形態素解析や係り受け解析，単語ベクトル，深層学習など）を洗い出したうえで，その技術の典型的な応用をゴールとして設定し，問題を構成した．例えば，第 3 章「正規表現」では，全ての問題を解くことでWikipediaデータからの知識獲得を体験できる．また，第4章「形態素解析」のゴールはコーパスの統計的な分析であるが，その過程でデータの可視化技術が習得できる．実践的な応用を実現するために，自分で調べながらプログラムを書くことで，必要な技術が自然と身につくことを狙っている．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{楽しさを重視する}
プログラミングの醍醐味のひとつは，短い手続きを記述するだけでも，意外性のある面白い実行結果を生み出しうることにある．例えば，第 1 章「準備運動」では文字列，リスト型，辞書型，集合型，イテレータ，スライスなど，プログラミング言語の基礎を習得することに狙いがあるが，単にこれらの実装例を問うのではなく，面白い実行結果が得られる題材を探した．過去に見たネットニュースから着想を得たり，英語の語呂合わせを調べたり，子供向けの教育番組を見ながら着想を得たり，題材選びに多くの時間を費やした．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{実験の進め方を示す}
自然言語処理の実験では，データの前処理（データのダウンロードや特徴量抽出など）や提案手法の実装，ハイパー・パラメータの調整，正解率やF1スコアの測定，失敗事例分析など，多くの研究に共通する流れがある．例えば，第 6 章「機械学習」は，ニュースのカテゴリ分類器を構築しながら，この一連の流れを体験できるように構成されている．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{ゴールを分割する}
自然言語処理の研究において，プログラミングによる実験は，研究のアイディアが計算機上で期待通りに動作することを実証することが主目的である．研究の成果物は知見（論文）であって，ソフトウェアそのものではない．したがって，研究のアイディアを正確かつ効率よく実現し，実験を進めることが望ましい．言語処理100本ノックでは，各章をサブゴールに分解し，各サブゴールを実現するプログラムを積み重ねることで，全体のゴールを達成する構成とした．これには以下の理由がある．
\begin{itemize}
    \item ゴールをサブゴールに分解する実践例を示す．
    \item 各プログラムの実装や検証の難易度を下げる．
    \item プログラムを実行結果を確認する習慣をつける．
    \item 実験の途中結果を記録・保管する習慣をつける．
\end{itemize}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{指示を与えすぎない}
言語処理100本ノックの問題文は，わざと細かい指示を与えないようにしている．これは，教員やメンターからのアドバイスは，「テキスト分類にBERTを使ったらどうだろうか？」みたいな指示が多く，具体的な解決法は自分で見つけることが推奨されるからである．また，問題に対する解き方は一通りではなく，複数の解き方を仲間と議論することが言語処理100本ノックの楽しみ方のひとつである．このため，指示を細かく与えすぎないように配慮した．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{理論やアルゴリズムの演習ではない}
自然言語処理の問題集と銘打っているが，理論やアルゴリズム，データ構造の実装することはゴールとせず，実践的な応用を実現することを優先した．例えば，確率的勾配降下法やViterbiアルゴリズムなどを自分で実装してみることは，大変勉強になることではあるが，対象外とした．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{特定のプログラミング言語に依存しない}
言語処理100本ノックの初版は，Pythonでプログラムを記述することを想定した．これは，2011年当時の乾・岡崎研究室の標準のプログラミング言語がPythonであったことによる．しかし，自然言語処理の研究で使われるプログラミング言語として，Java, Ruby, Scala等も有力な選択肢であった．このため，Pythonを標準的なプログラミング言語と想定しつつも，言語仕様に依存した問題にならないように配慮した．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{特定のツールに依存しない}
自然言語処理の研究・開発では，既存のツールやライブラリを活用することが欠かせない．一方で，どのツールやライブラリを選択するかは，個人の自由である．そこで，言語処理100本ノックの問題文では，特定のツール・ライブラリへの言及は原則として回避することとした．ただし，形態素解析や係り受け解析など，ツールを明示した方が問題の説明が分かりやすくなる場合や，メージャーなツール・ライブラリを紹介した方が初学者にとって有益である場合は，ツール・ライブラリの具体名を挙げた．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{ツールを活用する}
ツールやライブラリは研究や実験を加速する．例えば，コーパス中に出現する単語とその出現頻度のリストを作成したとき，出現頻度順に並び替えることは，プログラムの正しさやコーパスの特徴を短時間で把握するのに役立つ．しかし，並び替えのプログラムを書くのは面倒なので，心理的な障壁を下げるためにも既存のツールを活用すべきである．そこで，第2章「UNIXコマンド」では，タブ区切り形式のデータを分析するプログラムを書きつつ，同様の実行結果をUNIXコマンドだけですぐに得られることを確認する構成とした．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{データを公開する}
言語処理100本ノックの初版では，問題を解くために必要なデータの入手性に難があった．そこで，2015年版では，問題で用いるデータは一般に入手可能なものとして，誰でもすぐに始められるようにした．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{一般的な計算資源を利用する}
言語処理100本ノックのプログラムの計算環境として，個人のノートパソコンもしくはGoogle Colaboratory\footnote{\url{https://colab.research.google.com/}}を想定している．例えば，第10章「機械翻訳」では，さらに大きなデータを用いて翻訳の性能を向上させたいが，特殊なGPU環境が必要だったり，学習に数日かかる等の理由で，比較的規模の小さいデータを用いた．

なお，言語処理100本ノックの問題は公開とした．これは，研究室の学生が身につけるスキルセットを公開することで，研究室や所属する学生の価値を高める狙いがあった．一方で，問題を公開すると解答がウェブ等で流通し，学習効果が減る懸念もあった．しかしながら，これまでに多くの研究室や企業に採用して頂いた結果，ウェブ上で様々な解説が公開された．自然言語処理や機械学習の解説を一切行わないなど，不親切な問題を公開しただけであるが，みんなで助け合いながら学ぶ状況が自然に生まれたことは，我々にとって予想外の展開であった．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{実践例}

言語処理100本ノックの活用例として，東北大学乾・鈴木研究室にて毎年実施されている「プログラミング基礎勉強会（以下勉強会）」\footnote{\url{https://www.nlp.ecei.tohoku.ac.jp/study-groups/learning-programming/}}の様子とそこで行われている工夫を紹介する．
勉強会は，自然言語処理の基礎，とりわけ実装技術の習得の目指す会で，2010年から新人研修の一環として実施されている．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{学びを最大化するための勉強会運営}

週に1度の勉強会で主に行われるのはコードレビューである．メンターとなる先輩学生やスタッフからの模範解答の提供ではない．
具体的には，問題ごとに数名の受講生が自分の書いてきたコードを解説し，その後メンターを中心に参加者全員でコードについて議論を行う．
あわせてメンターからの補足説明（考えられる改善点，より良いコードの例，便利なライブラリやイディオム，etc.）が与えられる．
ここで触れられる話題は，個々の具体的な解答に関する内容にとどまらず，アルゴリズムやデータ構造の基礎知識，困ったときの調べ方や質問の仕方，デバッグのコツなど多岐に渡る．したがって1.5時間の勉強会で扱う問題は1～5問程度と少なく，100問を解くまでにはおよそ1年を要する．
また，研究室には歴代の参加者やメンターによって書かれたコードが8年分蓄積されており，見本となる解答例の品質は年々洗練されてきている．
なお，以前は新人の人全員が一度に参加する形式であったが，各受講生のコードレビューの頻度をあげるために2020年度から小グループ化を行った．

運営上の工夫として，予習の際は「他人の回答を見ずに自分自身の力で解く」ことを強く推奨している．
理由の一点目は，それが実際の問題解決の予行演習になるからである．
研究や開発で直面する問題には答えがついていない．ついていないからこそ研究や開発が必要となる．
問題に直面したとき，一体何を解けば良いのか，どう解けば良いか，エラーや実装ミスが生じた場合どう対処すれば良いかについて，自力で試行錯誤と問題解決を行う訓練は重要である．
言語処理100本ノックの問題文が一部well-definedでないことが気になるかたもおられるかもしれないが，これも「解くべき問題を考える」スキルを身につけてもらうことを意図したものである．
自力で問題を解いてもらう理由の二点目は，参加者の回答のパターンが大きくばらけることで，コードレビューにおける学び，とくに計算コストに関する学びが増えるからである．
お互いが事前に回答を見ないことで，必然的に各参加者の回答（実装戦略）にばらつきが生じる．
そのため，各勉強会では，問題一つを取ってみてもデータ構造，アルゴリズムや使われたライブラリなどその中身は多種多様である．
それぞれの回答を比較することで，実装戦略による計算量やメモリ効率の差を参加者全員が学ぶことができる．真剣に書いたコードに対してより良い代替案が提示されることほど良い学びの機会はない．

最後に，研究室として中長期的に勉強会を持続していくためのメンターに関する工夫を紹介する．
まず，一部の学生・スタッフに負荷がかかりすぎないよう，メンターは各章ごとの持ち回り制としている．
また各メンターの得意分野が割り当たるように調整を行っている．これによってメンター自身が楽しめ，また勉強会で提供される説明の品質も高くなることを期待している．
なお余談ではあるが，最近は競技プログラミングの経験者が研究室に配属されること増えており，メンターよりも参加者のほうがプログラミングに精通していることも多い．これにより勉強会における学びの機会が増え，メンターにとっても刺激的な時間となっている．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{プログラミング基礎勉強会を支える技術}

本節では，プログラミング基礎勉強会
で利用しているツールやそれらの活用法を紹介する．
言語処理100本ノックはその名の通り自然言語処理の知識・技術を習得するための目的志向の問題集であり，解く際に用いる道具（プログラミング言語，エディタ，バージョン管理システムなど）は学習者が自由に選べる設計になっている．
したがってここに挙げるツール群もあくまで一例に過ぎないが，2020年現在自然言語処理の学習および研究・開発のプロトタイピング時に用いるツールとして最も学習効果と運用効率の高い組み合わせのひとつであろう．
また，読者が複数名での勉強会を検討している場合は，どんなツールを使うにせよ参加者全員の利用ツールを統一しておくことをおすすめしたい．とくに参加メンバーに自然言語処理ないしプログラミングの初心者が含まれる場合，利用技術の統一は相互の教えあいや学びの効率に大きく影響する．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Python 3}

勉強会ではプログラミング言語としてPython 3.xを採用している．
そのもっとも大きな理由は，Pythonが潤沢な外部ライブラリを備えた自然言語処理および機械学習の今日のデファクト言語であり，既存の有用なアルゴリズムがほぼすべて再実装抜きに利用できるからである\footnote{MeCab, spaCy, AllenNLP, numpy/scipy, scikit-learn, fairseq, Hugging Face の提供する各種ツールなど，枚挙に暇がない．}．研究開発の主目的である新しい価値の創造に時間を割けるようになり，またプログラムにもバグが入りづらくなる．
また，Pythonがいわゆる軽量プログラミング言語であることも大きな利点である．初心者にとっては習得が容易となり，熟練者にとってもプログラム完成までの時間が比較的短く済むため試行錯誤サイクルの短縮が期待できる．

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% fig. 2
\begin{figure}[b]
\begin{center}
\includegraphics{27-3ia15f2.eps}
\end{center}
\caption{JupyterLab}
\label{fig:jupyterlab}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{JupyterLab}

コード編集環境（エディタ）としては，JupyterLabを採用している．
JupyterLabはJupyter Notebookを中心としたWebベースの統合開発環境である（図\ref{fig:jupyterlab}）．
Vim/Emacs等のエディタやPyCharm等の統合開発環境に比べ，とくに勉強会での利用にあたっては以下に述べるようなすぐれた利点がある．
\begin{itemize}
\item
    第一に，テキストをMarkdownで挿入できる．リッチなメモをコードの隣に記載できることで，予習時には考察や勉強の助けとなり，勉強会時には複数のコードの指針やそこに至る考察の比較が容易となり，復習時には勉強会での解説などを書き加えて自分だけのノートを作ることができる．
    また，コード内に単にコメントでメモをとるよりも，リッチな構造化テキストを利用した方が視覚的にも分かりやすく参加者の理解を助けやすい．
    さらに，軽量マークアップ言語のデファクトであるMarkdown記法に慣れてもらうという副次的なメリットも得られる．
\item 
    第二に，コードとその実行結果を対にして共有できる．参加者が問題文を読み間違えていた場合など，コードだけではすぐに確認できない誤りも出力結果を見れば（コードの問題点とあわせて）すぐに捕捉できる．また，参加者が工夫してプリントした「見やすい出力」も一目でわかる．さらに，参加者間の出力自体が異なる複数のコードの比較も容易となる．
\item
    第三に，探索的なデータ分析を助ける．
    実際JupyterLabは，自然言語処理の研究・開発で必須であるテーブルデータの処理（Pandasなど）や可視化（Matplotlib，Plotlyなど）をインタラクティブかつシームレスに実行できるため，データ分析と可視化における最も強力なツールのひとつとして盤石な地位を得ている．
    大規模なコードを書き始めたあとでも，データの観察や可視化の際はJupyterLabが作業を効率化してくれる．
    また，実データ（言語データ）を扱う自然言語処理を志す若者に，データをよく観察することにできるだけ早く慣れて欲しいという思いもある．
\end{itemize}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Git/GitHub}

バージョン管理システムおよびホスティングサービスとしてはGit/GitHubを採用している．
いまや広く情報系の研究開発においてGit/GitHubの活用は必要不可欠である．
勉強会での利用を通してGit/GitHubに慣れ，自身の研究開発がはじまったあと抵抗なくこれらを使い始められることが目標である．

具体的な運用方法を述べる．
参加者は個人ごとにブランチとそれに紐づくディレクトリを持ち，主にその下で作業する．
また，各個人ディレクトリでは章ごとにサブディレクトリを作成し，その下にipynbファイルを配置する（図\ref{fig:directory}）．
さらに，各ipynbファイルの先頭にその人だと分かる文字列を入れると，参加者全員のipynbファイルをJupyterLabで開いたときに，誰のコードを見ているかの判別に役立つ．

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% fig. 3
\begin{figure}[t]
\begin{center}
\includegraphics{27-3ia15f3.eps}
\end{center}
\caption{プログラミング基礎勉強会における典型的なディレクトリ構造}
\label{fig:directory}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

勉強会の開始前に，参加者は個人ブランチでの作業の差分を勉強会用のGitHubレポジトリに\texttt{push}する．
メンターは各ブランチの差分を\texttt{master}に\texttt{merge}後\texttt{push}し，参加者全員の解答が集約された状態にする．
万が一コンフリクトが発生した場合でも，その解消はメンターの責任になるため，誤って他人のファイルを削除する等のトラブルを回避することができる．

Git/GitHubへの心理的な抵抗を少なくするために初期段階では細かい原理を教えず，上に挙げた一連のコマンドをマニュアル通りに操作してもらう．
そうすることで，参加者はGit自身の複雑さに直面することなく，変更履歴をトラッキングできる利便性のみを享受することができる．
実際，乾・鈴木研究室では共通のコードベースを複数人で扱うような数多くの研究プロジェクトが走っているが，Git/GitHubを追加のチュートリアルなしにスムーズに活用できていることが観察されている．


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{謝辞}

言語処理100本ノックは，名古屋大学の佐藤理史先生が自然言語処理のプログラミングの演習のために作成された100問の問題に着想を得た．また，「100本ノック」という名称は，東北大学の乾・岡崎研究室に在籍していた杉浦純氏のアイディアである．最後に，問題へのフィードバックを送っていただいた皆様，ウェブ上で解説を公開していただいた皆様に，この場を借りて感謝申し上げる．





\end{document}

