関数を理解しよう(前編)- なぜ関数が必要なのか

【連載】

対話システムをつくろう! Python超入門

【第14回】関数を理解しよう(前編)- なぜ関数が必要なのか

[2019/09/24 08:00]阿部憲幸 ブックマーク ブックマーク

開発ソフトウェア

前回まででモジュールや変数、条件分岐、繰り返し処理といったPythonの機能を一通り紹介しました。これらの機能を使うことで高度なプログラムが書けるようになりましたが、プログラムの中身も徐々に複雑になってきました。

そこで今度は「関数」という、プログラムの処理をまとめる仕組みを紹介します。関数でプログラムを処理ごとにまとめることで、読みやすいプログラムを作成できるようになるのです。

今回と次回は、第11~13回で作成したQA対話システムの主要な処理部分を関数を使って書き直すことで、関数の使い方を説明していきたいと思います。

作業ディレクトリは「C:\Users\user\Documents\pychat\function」としますので、事前に作成しておいてください。

※ 今回の内容は、第13回で紹介した質問回答リストを知らなくても問題ありません。ただし、第12回で紹介した関数re.searchの使い方に自信がない方は、先に復習しておきましょう!

似た処理を含むプログラム

第12回第13回では、文字列が正規表現にマッチするかどうかを確認する関数re.searchを使ってQA対話システムを作成しました。QA対話システムの主要な処理は、ユーザー発話の質問(文字列)が質問回答リスト中の質問パターン(正規表現)のいずれかにマッチするかどうかを確認することです。

そこでまず初めに、文字列が正規表現のリストのいずれかにマッチするかどうかを確認するプログラム「match.py」を書いてみましょう。

# match.py - 文字列がパターンにマッチするか確認するプログラム
import re

patterns = ["富士山.*高さ", "東京.*区.*いくつ"]

text_fuji = "ねぇ、富士山の高さは?"
matched_fuji = False
for pattern in patterns:
    if re.search(pattern, text_fuji):
        matched_fuji = True
        break
print(matched_fuji)

このプログラムでは、4行目の正規表現のリストpatternsのいずれかの要素に6行目の「text_fuji」に束縛された文字列「ねぇ、富士山の高さは?」がマッチするかどうかを判定します。

7行目の「matched_fuji」はマッチしたかどうかを記録するブール値(True/False)を値に持つ変数です。「True」の場合マッチしたことを、「False」の場合マッチしなかったことを表します。

そして8行目のfor文でリストpatterns中の要素(パターン)を1つずつ変数patternに束縛します。9行目では関数re.searchを使って変数patternが「text_fuji」にマッチするかを確認し、マッチした場合は10行目で変数matched_fujiに「True」を入れて、breakによりfor文を抜けます。

連載が進むに連れて、こうした処理を書く機会も増えてきたので、だんだんと慣れてきたのではないでしょうか。

さて、プログラムの概略を把握したので実際に実行してみましょう。「text_fuji」の文字列「ねぇ、富士山の高さは?」は正規表現リスト中のパターン「”富士山.*高さ”」にマッチするので「True」と表示されるはずです。試してみましょう。

$ python match.py
True

続いて、「東京の区っていくつあるの?」という文字列もマッチするかどうかを確認してみましょう。先ほどのプログラムにコードを追加し、「match_multi.py」というファイルを作成します。

# match_multi.py - 文字列がパターンにマッチするか確認するプログラム
import re

patterns = ["富士山.*高さ", "東京.*区.*いくつ"]

text_fuji = "ねぇ、富士山の高さは?"
matched_fuji = False
for pattern in patterns:
    if re.search(pattern, text_fuji):
        matched_fuji = True
        break
print(matched_fuji)

# New: 「東京の区っていくつあるの?」をチェックするプログラムを追加
text_tokyo = "東京の区っていくつあるの?"
matched_tokyo = False
for pattern in patterns:
    if re.search(pattern, text_tokyo):
        matched_tokyo = True
        break
print(matched_tokyo)

「東京の区っていくつあるの?」という文がマッチするかどうかを確認するために「New:」で始まるコメント以下のコードを新しく追加しました。text_fujiとmatched_fujiの代わりに、text_tokyoとmatched_tokyoという変数を導入した以外は、前のプログラムとほぼ同じ処理を追加しただけであることがわかるかと思います。

文字列「東京の区っていくつあるの?」は正規表現のパターン「”東京.区.いくつ”」にマッチするので、実行すると2つ目の「True」も表示されます。

$ python match_multi.py
True
True

期待通りに動作はしているのですが、ここで改めてmatch_multi.pyをご覧になってみてください。皆さんはどう感じるでしょうか?

「似たような処理を何度も書かないといけなくて面倒だなあ……」
「変数名が違うだけの似た処理が増えて、ミスが発生しやすそうだなあ……」
「片方の処理を変更したら、もう片方も同じように変更しないと! 忘れそうだなあ……」

どれも、当然の感想です。ミスが起きないか心配になるのもわかります。

プログラム内で何度も登場する「似たような処理」は、本質的には同じ処理であるはずです。そうした処理を関数でまとめて再利用することで、プログラミングの手間が軽減され、プログラム自体もわかりやすくなります。

今回は、あえて似た処理を含むプログラムを書いてみることで関数が必要となる状況について説明しました。次回は、このプログラムに関数を導入し、わかりやすく書き直してみたいと思います。

著者紹介


株式会社NTTドコモ
R&Dイノベーション本部 サービスイノベーション部
阿部憲幸

2015年京都大学大学院理学研究科数学・数理解析専攻修了。 同年、NECに入社。 2016年から国立研究開発法人情報通信研究機構出向。 2018年より現職。 自然言語処理、特に対話システムの研究開発に従事。 毎日話したくなるAIを夢見て日夜コーディングに励む。
GitHub:https://github.com/noriyukipy

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

【連載】教えてカナコさん! これならわかるAI入門 [11] ディープラーニングの基礎「パーセプトロン」を理解しよう

【連載】教えてカナコさん! これならわかるAI入門 [11] ディープラーニングの基礎「パーセプトロン」を理解しよう

最近よく耳にする「ディープラーニング」。これは機械学習の一種で、「深層学習」と呼ばれることもある技術です。「深層学習=ディープラーニング」は正しいのですが、「機械学習=ディープラーニング」は誤りですので注意してください。ディープラーニングは、たくさんある機械学習の手法の1つに過ぎません。今回からは、いよいよこのディープラーニングについて解説していきます。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で IT Search+ の人気記事をお届けします

会員登録(無料)

注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
[解説動画] 個人の業務効率化術 - 短時間集中はこうして作る
ミッションステートメント
教えてカナコさん! これならわかるAI入門
知りたい! カナコさん 皆で話そうAIのコト
対話システムをつくろう! Python超入門
Kubernetes入門
AWSで作るクラウドネイティブアプリケーションの基本
PowerShell Core入門
徹底研究! ハイブリッドクラウド
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

ページの先頭に戻る