個人的神殿

プログラミング

言語処理100本ノック 第1章

www.cl.ecei.tohoku.ac.jp

内定先の研修で少しスクレイピングや言語処理などをやっているので、勉強のために俺もやってみることにした。
とはいえ多くの方々が既に素晴らしい解答を出してくださっているので細かい解説は無しにして、へぇ~と思ったことを書くだけにしようと思う。

00
-1ずつ取得、まぁつまり末尾から1文字ずつ取得って感じか。

"stressed"[::-1]
"desserts"

01.

"パタトクカシーー"[::2]
"パトカー"
"パタトクカシーー"[1::2]
"タクシー"

02.

"".join([x + y for x, y in zip("パトカー", "タクシー")])
"パタトクカシーー"

03.
まずはコンマやピリオドをスペースにしてからsplitで分割する。
ただコンマやピリオドだけじゃなくて色々といらないもんが大量にあったらどうすんだろ。
正規表現とかできるのかな。

text = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
[len(x) for x in text.replace(",", " ").replace(".", " ").split()]
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]

04.
懐かしい(笑)

text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
def get(index, text):
    if index in [0, 4, 5, 6, 7, 8, 14, 15, 18]:
        return text[0]
    else:
        return text[:2]
{get(i, t): i + 1 for i, t in enumerate(text.replace(".", " ").split())}
{'H': 1, 'He': 2, 'Li': 3, 'Be': 4, 'B': 5, 'C': 6, 'N': 7, 'O': 8, 'F': 9, 'Ne': 10, 'Na': 11, 'Mi': 12, 'Al': 13, 'Si': 14, 'P': 15, 'S': 16, 'Cl': 17, 'Ar': 18, 'K': 19, 'Ca': 20}

05.

def n_gram(n, str):
    return [str[x:x + n] for x in range(0, len(str) - n + 1)]
text = "I am an NLPer"
n_gram(2, text)
n_gram(2, text.split(" "))
['I ', ' a', 'am', 'm ', ' a', 'an', 'n ', ' N', 'NL', 'LP', 'Pe', 'er']
[['I', 'am'], ['am', 'an'], ['an', 'NLPer']]

06.

text1, text2 = "paraparaparadise", "paragraph"
x = set(n_gram(2, text1))
y = set(n_gram(2, text2))
x | y               # 和
x & y             # 積(共通部分)
x - y               # 差(xにのみ含まれる)
y - x               # 差(yにのみ含まれる)
"se" in x & y  # xとyの共通部分には含まれてるかどうか
{'ap', 'ph', 'gr', 'ar', 'ad', 'se', 'pa', 'ra', 'ag', 'is', 'di'}
{'ra', 'ap', 'pa', 'ar'}
{'se', 'is', 'di', 'ad'}
{'gr', 'ph', 'ag'}
False

07.

def generate(x, y, z):
    return str(x) + "時の" + y + "は" + str(z)
generate(12, "気温", 22.4)
12時の気温は22.4

08.
意味がわからなかったが、ord(x)でxの文字コードを返してくれるらしい。
で、219-ord(x)という文字コードをまた文字に変換(chr)すればいいわけか。

sentence = "Hello everyone"
def cipher(text):
    return "".join([chr(219 - ord(x)) if x.islower() else x for x in text])
cipher(sentence)
cipher(cipher(sentence))
Hvool veviblmv
Hello everyone

09.
文字列やタプルはイミュータブル(変更不可)なので、元のオブジェクトを変更するrandom.shuffle()を使うとエラーTypeErrorになるらしい。
文字列やタプルをシャッフルしたい場合は新たなオブジェクトを生成するrandom.sample()を使う。

第一引数にリストや文字列、第二引数に取得したい要素の個数を指定する。

第二引数の要素の個数を全要素数にすれば、全要素がランダムに並び替えられた新たな「リスト」が返ってくる。
ここでつまずいてしばらく時間を食った。文字列にまた戻さないといけなかった。

import random
text = "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind."

def typoglycemia(text):
    def shuffle(word):
        if len(word) > 4:
            return word[0] + "".join(random.sample(word[1:len(word)-1], len(word)-2)) + word[-1]
        else:
            return word

    return " ".join([shuffle(x) for x in text.split(" ")])
typoglycemia(text)
I culno'dt bveelie that I cluod aclautly unsatrnded what I was randieg : the panmnheoel peowr of the hmuan mind.