裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

言語処理100本ノック 第1章 : 準備運動

2015年10月28日 | ブログラミング

東北大学の乾・岡崎研究室で公開されている言語処理100本ノック(2015年版)http://www.cl.ecei.tohoku.ac.jp/nlp100/ を、R言語で解く。

同趣旨のページ https://rpubs.com/yamano357/84965 では,

library(dplyr)
library(stringr)
library(stringi)

なんかを使っているんだけど,かえって面倒くさくなっているように見受けられる(ご本人はキレイだと思っているんだろうなぁ)。

そこで,特別なパッケージなど使わずに,基本関数だけで書く(関数のネストって,キレイだと思うんだけどなぁ)。

00. 文字列の逆順

文字列 “stressed” の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ。

paste(rev(unlist(strsplit("stressed", ""))), collapse="")

01. 「パタトクカシーー」

「パタトクカシーー」という文字列の 1,3,5,7 文字目を取り出して連結した文字列を得よ。

paste(unlist(strsplit("パタトクカシーー", ""))[1:4*2-1], collapse="")

02. 「パトカー」+「タクシー」=「パタトクカシーー」

「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ。

paste(t(matrix(unlist(strsplit("パトカータクシー", "")), 4)), collapse="")

03. 円周率

“Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.” という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ。

s = gsub("[,.]", "", "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.")
nchar(unlist(strsplit(s, " ")))

04. 元素記号

“Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.” という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19 番目の単語は先頭の 1 文字,それ以外の単語は先頭の 2 文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ。

s = gsub("[.]", "", "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.")
s = sapply(unlist(strsplit(s, " ")), substring, 1, 2)
i = c(1, 5, 6, 7, 8, 9, 15, 16, 19)
s[i] = substr(s[i], 1, 1)
names(s) = 1:length(s)
s

05. n-gram

与えられたシーケンス(文字列やリストなど)から n-gram を作る関数を作成せよ。この関数を用い,“I am an NLPer” という文から単語 bi-gram,文字 bi-gramを得よ。

func = function(s) {
  if (is.list(s)) s = paste(unlist(s), sep=" ")
  s = unlist(strsplit(s, " "))
  t = unlist(strsplit(s, ""))
  list(word.bi.gram = cbind(s[-length(s)], s[-1]),
       char.bi.gram = cbind(t[-length(t)], t[-1]))
}
func("I am an NLPer") # 引数が文字列
func(list("I am", "an", "NLPer")) # 引数がリスト

06. 集合

“paraparaparadise” と “paragraph” に含まれる文字 bi-gram の集合を,それぞれ, X と Y として求め,X と Y の和集合,積集合,差集合を求めよ。さらに,`se' という bi-gram が X および Y に含まれるかどうかを調べよ。

func = function(s) {
  s = unlist(strsplit(s, ""))
  unname(mapply(function(x, y) paste(x, y, sep=""), s[-length(s)], s[-1]))
}
(X = func("paraparaparadise"))
(Y = func("paragraph"))
union(X, Y)
intersect(X, Y)
setdiff(X, Y)
is.element("se", X)
is.element("se", Y)

07. テンプレートによる文生成

引数 x, y, z を受け取り「x 時の y は z」という文字列を返す関数を実装せよ。さらに,x=12, y=“気温”, z=22.4 として,実行結果を確認せよ。

func1 = function(x, y, z) sprintf("%s時の%sは%s", x, y, z)
func1(12, "気温", 22.4)

func2 = function(x, y, z) paste(x, "時の", y, "は", z, sep="", collapse="")
func2(12, "気温", 22.4)

08. 暗号文

与えられた文字列の各文字を,以下の仕様で変換する関数 cipher を実装せよ。
- 英小文字ならば (219 - 文字コード) の文字に置換
- その他の文字はそのまま出力
この関数を用い,英語のメッセージを暗号化・復号化せよ。

s = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
cipher = function(s) paste(sapply(unlist(strsplit(s, "")), function(c) ifelse(is.element(c, letters), intToUtf8(219-utf8ToInt(c)), c)), collapse="")
(t = cipher(s))
cipher(t) # a to z を z to a にする関数だから,暗号化された文を同じ関数に渡せば元に戻る

09. Typoglycemia

スペースで区切られた単語列に対して,各単語の先頭と末尾の文字は残し,それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ。ただし,長さが 4 以下の単語は並び替えないこととする。適当な英語の文(例えば “I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .”)を与え,その実行結果を確認せよ。

s = "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind."
paste(sapply(unlist(strsplit(s, " ")), function(t) {
  if ((n = nchar(t)) > 4) {
    t = unlist(strsplit(t, ""))
    t = paste(t[1], paste(sample(t[2:(n-1)]), collapse=""), t[n], sep="")
  }
  t}), collapse=" ")

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« BASP の「P 値禁止,CI も禁... | トップ | 言語処理100本ノック 第2章 :... »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事