言語処理100本ノックやってみる　05~09

今日もがんばっていこー

#05. n-gram
与えられたシーケンス（文字列やリストなど）からn-gramを作る関数を作成せよ．この関数を用い，"I am an NLPer"という文から単語bi-gram，文字bi-gramを得よ．
###n-gramのメリットは自然言語処理において、隣接したｎ個の文字の出現頻度を集計できる！（詳しくは下のリンクへ）
https://mieruca-ai.com/ai/bi-gram_markov_model/

##自分の解答
```py
def n_gram(n,sentence):
    list_1=[]
    for i in range(len(sentence)-n+1):
        list_1.append(sentence[i:i+n])
    return list_1

word="I am an NLPer"
word_new=word.split()
#print(word_new) >> ['I', 'am', 'an', 'NLPer']

#単語bi-gram
ans1=n_gram(2,word_new)
print(ans1)

#文字bi-gram
ans2=n_gram(2,word)
print(ans2)
```


```py
#出力結果
[['I', 'am'], ['am', 'an'], ['an', 'NLPer']]
['I ', ' a', 'am', 'm ', ' a', 'an', 'n ', ' N', 'NL', 'LP', 'Pe', 'er']
```
##新たに知ったこと
###①単語bi-gramと文字bi-gramの出力手順
最初に**n_gram関数を作る**　これはただn数によってリストに入れるだけで良い！
その後、空白を考慮するかは、**関数外で操作する！**
それにより、**単語n-gram,文字n-gram**を自由に作れる!
#06. 集合
"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を，それぞれ, XとYとして求め，XとYの和集合，積集合，差集合を求めよ．さらに，'se'というbi-gramがXおよびYに含まれるかどうかを調べよ．
##自分の解答

```py
def n_gram(n,sentence):
    list_1=[]
    for i in range(len(sentence)-n+1):
        list_1.append(sentence[i:i+n])
    return list_1

X=n_gram(2,"paraparaparadise")
Y=n_gram(2,"paragraph")
#print(X) >> ['pa', 'ar', 'ra', 'ap', 'pa', 'ar', 'ra', 'ap', 'pa', 'ar', 'ra', 'ad', 'di', 'is', 'se']
#print(Y) >> ['pa', 'ar', 'ra', 'ag', 'gr', 'ra', 'ap', 'ph']

X=set(X)#リスト型[]→集合型{}に変換
Y=set(Y)#リスト型[]→集合型{}に変換
#print(X) >> {'se', 'ad', 'di', 'ar', 'pa', 'ra', 'is', 'ap'}
#print(Y) >> {'pa', 'ph', 'ra', 'ar', 'ag', 'gr', 'ap'}

ans1=X|Y
print("和集合: "+str(ans1))
ans2=X&Y
print("積集合: "+str(ans2))
ans3=X-Y
print("差集合: "+str(ans3))

if "se" in X:
    print("True")
else :
    print("False")

if "se" in Y:
    print("True")
else :
    print("False")
```
```py
#出力結果
和集合: {'ph', 'se', 'ag', 'gr', 'pa', 'ap', 'ad', 'ar', 'di', 'ra', 'is'}
積集合: {'ra', 'ap', 'pa', 'ar'}
差集合: {'ad', 'se', 'is', 'di'}
True
False
```

##新たに知ったこと
###①集合の演算**(和集合(a|b),差集合(a-b),積集合(a&b))**をする際には必ず**集合型**にしなければならない
その方法とは
**X=set(X)**と**set( )**と書けばよい！

#07. テンプレートによる文生成
引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ．さらに，x=12, y="気温", z=22.4として，実行結果を確認せよ．

##自分の解答
```py
def A(x,y,z):
    return (str(x)+"時の"+y+"は"+str(z))
    
ans=A(12,"気温",22.4)
print(ans)
```
```py
#出力結果
12時の気温は22.4
```

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

```py
def cipher(sentence):
    ans=""
    for i in sentence:#この書き方で、1文字ずつ処理している
        if i.islower():
            ans+=chr(219-ord(i))
        else:
            ans+=i
    return ans

#暗号化
A=input()
ans1=cipher(A)
print("暗号化 : "+ans1)

#複合化
ans2=cipher(ans1)
print("複合化 : "+ans2)
```
```py
#出力結果
#暗号化 : I xlfowm'g yvorvev gszg I xlfow zxgfzoob fmwvihgzmw dszg I dzh ivzwrmt : gsv ksvmlnvmzo kldvi lu gsv sfnzm nrmw .
#複合化 : I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .
```

##新たに知ったこと
###①文字からアスキーコードに変換する方法
**ord("a") >> 97** といったように、**ord型**にする！
###②アスキーコードから文字へ変換する方法
**chr(97) >> a**　といったように、**chr型**にする！

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

##自分の解答
```py
import random #モジュール名"random"を読み込む 

def Typoglycemia(sentence):
    A_list=[]
    sentence=sentence.split(" ")
    for i in sentence:
        if len(i)<=4:
            A_list.append(i)
        else :
            B_list=list(i[1:-1])
            random.shuffle(B_list) #"random"に書かれている関数を利用
            A_list.append(i[0] + "".join(B_list) + i[-1])
            
    return " ".join(A_list)
        
target=input() #I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .を入力
ans=Typoglycemia(target)
print(ans)
```
```
#出力結果
I cod'lnut beievle that I could aaclluty uetdsnnrad what I was radnieg : the pehonenaml poewr of the hmaun mind .
```

##新たに分かったこと
###①モジュールからある関数(shuffle)を利用する方法
**モジュール**とは、**一連の関数を備えたPythonのプログラム**のこと（**~.py**）

**import モジュール名**
**モジュール名.関数名()**
これでOK!

###②リストから文字列に変換する方法
**文字列 = ‘区切り文字’.join(リスト)**
**区切り文字**とは、リスト内の[0],[1]の間をどうするかということ
例えば、空白、カンマなどなど

```py
str_list = ['python', 'list', 'exchange']
mojiretu = ' '.join(str_list)
    
print(mojiretu)
```
```py
#出力結果
python list exchange #空白にしてみた
```