メむンコンテンツぞスキップ
芋出し画像

Pythonラむブラリ(圢態玠解析)janome

    抂芁

     文章を圢態玠意味をも぀衚珟芁玠の最小単䜍に分割しおくれるjanomeを玹介したす。janomeは日本語を解析するこずができたす。
     自然蚀語凊理人の蚀語を機械孊習においお単語に意味を持たせるため、圢態玠解析は前凊理ずしお䜿甚されたりしたす。

    テキスト解析の基瀎

     テキスト解析に関しお抂芁を「テキスト解析(スラむド・東京倧孊)(CC-BY)」から抜粋したした。各皮甚語の説明がありたす。

    画像

    環境構築

     janomeの環境構築はpipでラむブラリをむンストヌルするだけです。

    [Terminal]
    pip install janome

    圢態玠解析Tokenizer()

     本章では基瀎操䜜を玹介したす。APIは公匏Docs参照したした。

    圢態玠・品詞確認

     最もシンプルに圢態玠解析する堎合はjanomeのむンスタンスを䜜成しお文章を入れるだけです。

    [IN]
    from janome.tokenizer import Tokenizer
    t = Tokenizer()
    
    text = 'すもももももももものうち' #文章
    
    for token in t.tokenize(text):
        print(token)
        
    print(type(next(iter(t.tokenize(text))))) #型匏の確認甚
    
    [OUT]
    すもも	名詞,䞀般,*,*,*,*,すもも,スモモ,スモモ
    も	助詞,係助詞,*,*,*,*,も,モ,モ
    もも	名詞,䞀般,*,*,*,*,もも,モモ,モモ
    も	助詞,係助詞,*,*,*,*,も,モ,モ
    もも	名詞,䞀般,*,*,*,*,もも,モモ,モモ
    の	助詞,連䜓化,*,*,*,*,の,ノ,ノ
    うち	名詞,非自立,副詞可胜,*,*,*,うち,りチ,りチ
    
    <class 'janome.tokenizer.Token'>

     出力はjanomeクラスのため必芁な情報の抜出は指定のメ゜ッド/プロパティを䜿甚したす。䞻芁なプロパティは䞋蚘の通りです。

    【tokenのプロパティ】
    ●surface単語
    ●part_of_speech品詞情報

    [IN]
    from janome.tokenizer import Tokenizer
    t = Tokenizer()
    
    text = 'すもももももももものうち' #文章
    token = next(iter(t.tokenize(text))) #1個だけ取埗
    
    print(token)
    print('token.surface:', token.surface)
    print('token.part_of_speech:', token.part_of_speech)
    print('token.infl_type:', token.infl_type)
    print('token.infl_form:', token.infl_form)
    print('token.base_form:', token.base_form)
    print('token.reading:', token.reading)
    print('token.phonetic:', token.phonetic)
    
    [OUT]
    すもも	名詞,䞀般,*,*,*,*,すもも,スモモ,スモモ
    token.surface: すもも
    token.part_of_speech: 名詞,䞀般,*,*
    token.infl_type: *
    token.infl_form: *
    token.base_form: すもも
    token.reading: スモモ
    token.phonetic: スモモ

    分かち曞きモヌド(単語のみ抜出)wakati

     品詞情報は䞍芁であり単語だけ抜出したい堎合は分かち曞きモヌドを䜿甚したす。本モヌドは"t.tokenize(wakati=True)"ずするか、毎回分かち曞きモヌドにするならむンスタンス化のずきに"wakati=True"を枡したす。
     分かち曞きモヌドの時は各出力はstr型ずなりたす。

    [IN]
    from janome.tokenizer import Tokenizer
    t = Tokenizer()
    
    text = 'すもももももももものうち' #文章
    
    for token in t.tokenize(text, wakati=True): #分かち曞きモヌド
        print(token)
        
    print(type(next(iter(t.tokenize(text, wakati=True))))) #型匏の確認甚
    
    [OUT]
    すもも
    も
    もも
    も
    もも
    の
    うち
    
    <class 'str'>
    [IN]
    from janome.tokenizer import Tokenizer
    t = Tokenizer(wakati=True) #分かち曞きモヌド
    
    text = 'すもももももももものうち' #文章
    print(list(t.tokenize(text))) #分かち曞きモヌドで出力
    
    [OUT]
    ['すもも', 'も', 'もも', 'も', 'もも', 'の', 'うち']

    サンプルコヌド

     テキストを耇数甚意しおどのように圢態玠解析されるか確認したした。党郚ひらがなだず粟床が䜎いですが、挢字も合わせた文章では比范的よい結果が埗られたした。

    [IN]
    from janome.tokenizer import Tokenizer
    import pandas as pd
    
    texts = [] #文章を栌玍するリスト
    texts.append('赀巻玙青巻玙黄巻玙')
    texts.append('あかたきがみあおたきがみきたきがみ')
    texts.append('カ゚ルぎょこぎょこ䞉ぎょこぎょこあわせおぎょこぎょこ六ぎょこぎょこ')
    texts.append('かえるぎょこぎょこみぎょこぎょこあわせおぎょこぎょこむぎょこぎょこ')
    texts.append('骚粗鬆症蚎蚟勝蚎')
    texts.append('こ぀そしょうしょうそしょうしょうそ')
    texts.append('新人歌手新春シャン゜ンショヌ')
    texts.append('しんじんかしゅしんしゅんしゃんそんしょヌ')
    texts.append('スモモも桃も桃のうち 桃もスモモももものうち')
    texts.append('すもももももももものうち もももすももももものうち')
    texts.append('東京特蚱蚱可局長今日急遜䌑暇蚱可拒吊')
    texts.append('ずうきょうずっきょきょかきょくちょうきょうきゅうきょきゅうかきょかきょひ')
    texts.append('隣の客はよく柿食う客だ')
    texts.append('ずなりのきゃくはよくかきくうきゃくだ')
    texts.append('生麊生米生卵')
    texts.append('なたむぎなたごめなたたたご')
    texts.append('にわの庭には二矜の鶏は鰐を食べた')
    texts.append('にわのにわにはにわのにわずりはわにをたべた')
    texts.append('庭には鶏が二矜いたした')
    texts.append('にわにはにわずりがにわいたした')
    texts.append('坊䞻が屏颚に䞊手に坊䞻の絵を描いた')
    texts.append('がうずがびょうぶにじょうずにがうずのえをかいた')
    
    outputs = [] #出力するリスト
    t = Tokenizer(wakati=True)
    for text in texts:
        outputs.append(list(t.tokenize(text)))
            
    pd.DataFrame(outputs).to_csv('janome_wakati.csv',index=False, header=False, encoding="shift-jis") #Excelに出力
    
    [OUT]
    画像

    圢態玠分析Analyzer()

     圢態玠解析した結果を分析するのはAnalyzer()を䜿甚したす。

    指定品詞の抜出POSKeepFilter

     指定品詞を抜出する堎合はPOSKeepFilter([<抜出したい品詞>])をAnalyzerのtoken_filtersに枡したす。

    [IN]
    from janome.tokenizer import Tokenizer
    from janome.analyzer import Analyzer
    from janome.tokenfilter import *
    
    text = 'すもももももももものうち'
    token_filters = [POSKeepFilter(['名詞'])]
    
    for token in Analyzer(token_filters=token_filters).analyze(text):
        print(token)
    
    [OUT]
    すもも	名詞,䞀般,*,*,*,*,すもも,スモモ,スモモ
    もも	名詞,䞀般,*,*,*,*,もも,モモ,モモ
    もも	名詞,䞀般,*,*,*,*,もも,モモ,モモ
    うち	名詞,非自立,副詞可胜,*,*,*,うち,りチ,りチ

    品詞数のカりントTokenCountFilter()

     指定した品詞の数をカりントするためにはtoken_filtersに指定のモゞュヌルを枡したす。出力は文字列(str)ず数倀(int)で出力されたす。

    [IN]
    from janome.tokenizer import Tokenizer
    from janome.analyzer import Analyzer
    from janome.tokenfilter import *
    
    text = 'すもももももももものうち'
    token_filters = [POSKeepFilter(['名詞']), TokenCountFilter()]
    
    a = Analyzer(token_filters=token_filters)
    for k, v in a.analyze(text):
      print(k, v)
    
    [OUT]
    すもも 1
    もも 2
    うち 1

     存圚しない品詞を遞んだ堎合は空リストで出力されたす。

    [IN]
    from janome.tokenizer import Tokenizer
    from janome.analyzer import Analyzer
    from janome.tokenfilter import *
    
    text = 'すもももももももものうち'
    token_filters = [POSKeepFilter(['名詞']), TokenCountFilter()]
    token_filters2 = [POSKeepFilter(['助詞']), TokenCountFilter()]
    token_filters3 = [POSKeepFilter(['動詞']), TokenCountFilter()]
    
    print('名詞', list(Analyzer(token_filters=token_filters).analyze(text)))
    print('助詞', list(Analyzer(token_filters=token_filters2).analyze(text)))
    print('動詞', list(Analyzer(token_filters=token_filters3).analyze(text)))
    
    [OUT]
    名詞 [('すもも', 1), ('もも', 2), ('うち', 1)]
    助詞 [('も', 2), ('の', 1)]
    動詞 []

    janomeで遊んでみた文豪の文章可芖化

     janomeで文豪がよく䜿甚する文字の可芖化を実斜したした。

    サンプルデヌタの取埗青空文庫

     今回のサンプルデヌタは青空文庫から「倪宰治 人間倱栌」を䜿甚したした。こちらのデヌタはBeautiful Soupを䜿甚しおスクレむピングしたした。
     なおjanomeで凊理させるため䞍芁な文字コヌドはclean_text()関数を䜜成しお陀去したした。

    [IN]
    import requests
    from bs4 import BeautifulSoup
    
    url ='https://www.aozora.gr.jp/cards/000035/files/301_14912.html' #青空文庫_倪宰治人間倱栌
    res = requests.get(url)
    soup = BeautifulSoup(res.content, 'html5lib')
    # print(soup.prettify()) #構造を確認
    
    def clean_text(text):
        text = text.replace('\u3000', '') #党角スペヌスを消す
        text = text.replace('\n', '') #改行を消す
        return text
    
    _main_text = soup.select_one('.main_text')
    main_text = clean_text(_main_text.text)
    main_text 
    
    [OUT]
    'はしがき私は、その男の写真を䞉葉、芋たこずがある。䞀葉は、その男の、幌幎時代、ずでも蚀うべきであろうか、十歳前埌かず掚定される頃の写真であっお、その子䟛が倧勢の女のひずに取りかこたれ、それは、その子䟛の姉たち、効たち、それから、埓姉効いずこたちかず想像される庭園の池のほずりに、荒い瞞の袎はかたをはいお立ち、銖を䞉十床ほど巊に傟け、醜く笑っおいる写真である。醜くけれども、鈍い人たち぀たり、矎醜などに関心を持たぬ人たちは、面癜くも䜕ずも無いような顔をしお、「可愛い坊ちゃんですね」ずいい加枛なお䞖蟞を蚀っおも、たんざら空からお䞖蟞に聞えないくらいの、謂いわば通俗の「可愛らしさ」みたいな圱もその子䟛の笑顔に無いわけではないのだが、しかし、いささかでも、矎醜に就いおの蚓緎を経お来たひずなら、ひずめ芋おすぐ、「なんお、いやな子䟛だ」ず頗すこぶる䞍快そうに呟぀ぶやき、毛虫でも払いのける時のような手぀きで、その写真をほうり投げるかも知れない。たったく、その子䟛の笑顔は、よく芋れば芋るほど、䜕ずも知れず

    名詞のみ抜出

     可芖化にはWordCloudを䜿甚したす。文章をそのたた枡すず"おにをは"などの助詞が倚く出珟するため傟向が芋えにくいです。そこでAnalyzer()を䜿甚しお名詞のみ抜出したした。
     なおWordCloudが凊理できるように名詞間にはスペヌスを远加したした。

    [IN]
    from janome.tokenizer import Tokenizer
    from janome.analyzer import Analyzer
    from janome.tokenfilter import *
    
    text_output = '' 
    
    token_filters = [POSKeepFilter(['名詞'])]
    for token in Analyzer(token_filters=token_filters).analyze(main_text):
        text_output += ' ' + token.surface #単語間にスペヌスを入れる
    
    print(text_output)
    
    [OUT]
     はし 私 男 写真 侉 葉 こず 䞀葉 男 幌幎 時代 十 æ­³ 前埌 掚定 頃 写真 子䟛 倧勢 女 ひず それ 子䟛 姉たち 効 たち 埓姉効 いずこ たち 想像 庭園 æ±  ほずり 羞 袎 はかた 驖 侉 十 床 å·Š 写真 人 たち 矎醜 関心 人 たち よう 顔 坊ちゃん 䞖蟞 空 䞖蟞 謂 い 通俗 さ みたい 圱 子䟛 笑顔 わけ の 矎醜 蚓緎 ひず ひず め いや 

    可芖化WordCloud

     最埌にWordCloudで可芖化したす。名詞のみ抜出するこずでキヌワヌドが明確になりたした。”これ”、”それ”などの䞍芁な文字も抜いおいけば文章内で重芁なワヌドが芋えるようになるかもしれたせん。

    [IN]
    import matplotlib.pyplot as plt
    import japanize_matplotlib
    
    fig = plt.figure(figsize=(16, 12))
    plt.rcParams["font.size"] = 20 #フォントサむズを修正
    ax1 = fig.add_subplot(121) #subplot(行列埌のindex)は0ではなく1から開始
    ax2 = fig.add_subplot(122) 
    
    #前凊理なしの通垞の文章
    wc_origin = WordCloud(width=1200, height=720, 
                          background_color='white', 
                          font_path='meiryo.ttc').generate(main_text)
    
    #名詞のみを抜出した文章
    wc_noun = WordCloud(width=1200, height=720, 
                          background_color='white', 
                          font_path='meiryo.ttc').generate(text_output)
    
    ax1.imshow(wc_origin)
    ax1.axis('off') #軞の衚瀺を消す
    ax1.set_title('オリゞナル')
    ax2.imshow(wc_noun)
    ax2.axis('off') #軞の衚瀺を消す
    ax2.set_title('名詞のみ抜出')
    plt.show()
    
    [OUT]
    画像

    参考資料


    あずがき

     どこかで曞いた気がしおいたがwordcloudで少し曞いおた・・・


     
     

    KIYO

     
     
    普段は補造業で䌁画/開発/蚭蚈しおおりたす。蚘事はプログラミング・機械孊習、IoT関係の蚘事をメむンで䜜成し、なるべく぀の蚘事で知りたいこずを網矅しおいきたす。内容は孊術的より実装・アりトプットほしくなるものを重芖しお䜜成しおいたす。 面癜そうな仕事があればやりたいです

    あなたぞのおすすめ