05. n-gram
自分の力では文字列のみにしか対応できなかった。 間違った出力をしていたため、できていなかった...
できるだけ、自分の力でできるようにしたい
ほかの人の回答を見る前に書いたソース
#!/bin/usr/env python ''' 与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ. この関数を用い,"I am an NLPer"という文から単語bi-gram,文字bi-gramを得よ. ''' def ws_bigram_str(sequence): ''' 与えられたシーケンスをもとに文字bi-gramと単語bi-gramを作成する 今はstrのみ対応 :return: word-bi-gram, str-bi-gram ''' # 単語bi-gram seqList = sequence.split(' ') wbigram = bigram(seqList) # 文字bi-gram sbigram = bigram(sequence) return wbigram, sbigram def bigram(sequence): rtnbigram = [] for i in range(len(sequence)): # もし、最後の要素だったら抜ける if i == len(sequence) - 1: break rtnbigram.append([sequence[i:i+1], sequence[i+1:i+2]]) return rtnbigram def main(): s = 'I am an NLPer' wordBiGram, strBiGram = ws_bigram_str(s) print(wordBiGram) print(strBiGram) if __name__ == '__main__': main()
ほかの人の回答を見てみると、文字列を渡した時には文字bi-gram、リストを渡した時には単語bi-gramとなっていた。
たしかに、同時に文字bi-gramと単語bi-gramを作成し返す関数 とは書いてなかった...
あと、n-gramを作る関数って書いてあるため、引数でどの形式化を指定できるようにするべき。
ほかの人の回答を見たあとのソース
#!/bin/usr/env python ''' 05. n-gram 与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ. この関数を用い,"I am an NLPer"という文から単語bi-gram,文字bi-gramを得よ. ''' def ngram(sequence, n=2): rtnngram = [] for i in range(len(sequence)-n+1): rtnngram.append(sequence[i:i+n]) return rtnngram def main(): s = 'I am an NLPer' char_bi_gram = ngram(s, 2) splited = s.split(' ') word_bi_gram = ngram(splited, 2) print(char_bi_gram) # ['I ', ' a', 'am', 'm ', ' a', 'an', 'n ', ' N', 'NL', 'LP', 'Pe', 'er'] print(word_bi_gram) # [['I', 'am'], ['am', 'an'], ['an', 'NLPer']] if __name__ == '__main__': main()
len(sequence)-n+1
で後ろから n 文字前までという感じにできる- strもlistもスライスが使えるため、
sequence[i:i+n]
というように書くことができる!!!
他の人の回答を見てお勉強させて頂く。
#!/usr/bin/python def n_gram(sent, n): n_gram_list = [] for i in range(len(sent)-n+1): n_gram_list.append(sent[i:i+n]) return n_gram_list if __name__ == "__main__": sent = "I am an NLPer" word_bi_gram = n_gram(sent.split(), 2) char_bi_gram = n_gram(sent, 2) print word_bi_gram print char_bi_gram
自分なりに理解してみる
n_gramへの引数で、n が 2 で、sent が list型 の場合
len(sent)-n+1
は
配列の要素数-1 となる
これは、最後の要素より後ろは取得する必要が無いため、このようになっている。
sent[i:i+n]
は今の位置からn個分取り出す処理
strの場合も流れは同じ!