情報学部大学生のダラダラ日記

β日記

機械学習や日記っぽいものを書きます

桜尾蒸留所見学体験記

はじめに

去年の夏(2023年8月)に桜尾蒸留所の見学ツアーに参加して決ました。もう1年近く経ってしまいましたが、その体験紀を書こうと思います。

体験記

桜尾+お酒と言えばジンを想像する方が多いのではないでしょうか。桜尾ジンと同じ蒸留所でウイスキーも作られており、私は今回ウイスキーの方を目当てに蒸留所を訪れました。

今回参加した見学ツアーは、ウイスキーもジンもどちらも紹介してくれました。1人2000円で、1回当たりの参加者は10人ほどでした。

DISTILLERY TOUR | SAKURAO DISTILLERY

ツアーの流れは

  1. モルトウイスキーとジンの製造工程紹介
  2. グレーンウイスキーの糖化・発酵見学
  3. 蒸留器での蒸留と樽詰め
  4. 貯蔵庫見学
  5. テイスティング

です。1~4ではガイドの方がビデオや実際の現場を見せながら説明してくれます。当時私はウイスキーの作り方を知らず、当然貯蔵庫は初めて見たので感動しました。そりゃウイスキーはそれなりの値段するなあと思いました笑

5のテイスティングでは、桜尾シングルモルトや蒸留所限定の宮ノ鹿、ニューポット(樽入れ前のもの)、桜尾ジン3種のうち、3杯選ぶことができました。ニューポットをいただきましたが、アルコール度数が高すぎてよくわかりませんでした笑 あとは宮ノ鹿と桜尾ジンLimitedをいただきました。

f:id:Parco1021:20240703210345j:image
f:id:Parco1021:20240703210347j:image

蒸留所見学が一通り終わった後、ショップで買い物ができました。こちらはツアー参加者でなくても購入可能でした。テイスティングで飲むことができなかった桜尾シングルモルトを購入しようと思ったのですが、売り切れていました泣 見学ツアー前に3,4本あったのを確認していたのでツアー後に買おうと思っていたのですが。。。買えないものは仕方がないので、蒸留所限定の宮ノ鹿とテイスティングで美味しかった桜尾ジンLimitedを購入しました。ショップには他にもだるま焼酎やジン3種、戸河内ウイスキー(シングルモルト除く)があり、見ているだけで楽しかったです。

さいごに

人生初のウイスキー蒸留所見学に行きました。当時もウイスキーは好きでしたが、この見学をきっかけにさらにドハマりしたのでその体験記として残しました。ちなみに東京に帰ってきて酒屋さんに行ったら普通に桜尾シングルモルトが売っていて即購入しました笑

 

 

 

 

 

日本百名城巡りその3 甲府城

概要

甲府城はおよそ450年前に浅野長政によって築かれた城です。山梨県甲府市にあり、日本百名城に選出されています。

歴史

西暦 城主 出来事
1582 徳川家 本能寺の変徳川家康が甲斐に入国し、平岩親吉が城主、着工する
1590 羽柴家 家康が関東へ転封
羽柴秀勝が入国
1591 加藤家 秀勝が美濃へ転封
加藤光泰が城主となる。ここで築城が本格的に開始
1593 浅野家 光泰が朝鮮出兵中に病没
浅野長政・幸長が城主となる
1600 関ヶ原の戦い。浅野家は東軍として戦う
1601 徳川家 浅野家が和歌山へ転封
平岩親吉が再度城代となる
1603 徳川義直(家康九男)が城主となる
1607 義直が清州へ転封(親吉は犬山へ)
城番制となる
1618 徳川忠長(秀忠次男)が城主となる
1632 忠長が蟄居となり、再び城番制へ
1661 徳川綱重(家光三男)が城主となる
1664 大修理が行われる
1678 綱重の嫡男である綱豊が城主となる
1704 綱豊が将軍綱吉の養子となり江戸城
1705 柳沢家 柳沢吉保が甲斐の国の大名になる
1706 場内の曲輪が修復
1724 吉保嫡男が大和郡山へ転封
1724 徳川家 甲斐の国が天領となり、甲府勤番が設置される
1727 甲府城大火(本丸御殿、銅門などを焼失)
1734 城内に盗賊が侵入
1867 大政奉還により江戸幕府滅亡
1868 ---- 明治維新、新政府軍が無血入城
1874 廃城
1968 県指定史跡となる
2019 国指定史跡となる

入城

天守台のみが残っており天守閣は残っていません。しかし、2004年に再建された稲荷櫓があります。

f:id:Parco1021:20240624231325j:image
f:id:Parco1021:20240624231319j:image
f:id:Parco1021:20240624231322j:image

駅や県庁から近く、甲府を広く見渡すことができました。

f:id:Parco1021:20240624231359j:image
f:id:Parco1021:20240624231356j:image

100名城スタンプは舞鶴城公園管理事務所や稲荷櫓のところに設置されていました。

f:id:Parco1021:20240624231403j:image

さいごに

人はあまり多くなく、駅から近いためふらっとよることができます。県庁も一般公開されているところがあり、甲府市の歴史を学ぶことができました。

 

 

統計検定2級 CBT合格体験記

はじめに

2024年6月に統計検定2級CBT試験を受け、無事合格したのでその体験記を残します。

f:id:Parco1021:20240611002218j:image

統計検定2級の合格点は60%であり、合格率は50%前後と低くもなく高くもないです。試験時間は90分、テストセンターに自分で申し込み受検します。

勉強方法

私は情報系の大学に通っており、統計学の講義も取っていました。しかしそこまでちゃんとやっておらず最低限単位を取る程度の知識であったため、学習開始時にはこの単語聞いたことあるけど意味は全く分からないといった状態でした。

学習は最初Udemyの講座が会社のアカウントで無料で見られたのでボーっと見ていました。が、ボーっと見ていたので講座修了時にはほとんど頭に残っていませんでした笑。Udemyの講座を受け始めたのが2023年の8月ぐらいで12月ぐらいに見終わりました。ここからわかるようにモチベーションが低かったです。。。その後は何もせず、4月に資格を何も取得していないことに気が付いて勉強を再開しました。とはいってもUdemyは頭に入らなさそうなので、統計検定2級CBT公式問題集を一周解きました。

これは過去問を各単元ごとに出されている問題集なので良い勉強法だと思います。当然いきなり解いてもほとんどわからないので、わからないところは統計学の時間というサイトで復習するという手法を取りました。これでだいたいの問題は見たことある程度にはなりましたが、とても合格はできそうにないぐらいです(おそらく5~6割ぐらい)。

その後GWを挟んでしまいまたモチベーションが消えました。このままじゃまずいと思い、1週間後に受検申し込みをし、背水の陣で勉強せざるを得ない状況にしました。そこからの1週間で1日1年分の過去問を解く→間違えたところを復習→自分の弱いところのカンペを作成としました。この学習方法は非常に良く、2,3日目には合格点を取れるようになっていました。調べていると過去問は2013年など昔の方が良いという記事も見られましたが、受けてみて特別そのようなことは感じずとにかくたくさんの過去問を解いてみてパターンに慣れる方が大事です。自分は1週間しか過去問を解かなかったのでたまたまF分布の過去問を解いたことがなく、本番でそこが5問ぐらい出て全く分からないという事態になってしまいました。なのでたくさん解きましょう!自分は2011~13,14~16,17~19を購入し、全て解く時間はなかったため気分で適当に年度を選んで解いていました。

 

 

 

時間配分に関しては自分は元々問題を解くのが早いタイプなので特に意識しなかったですが、めちゃくちゃ余裕があるわけではないです。見直しもできるようにできるだけ早く解けるようにした方が良いです。

個人的合格のコツ

数学が苦手な方や統計学に触れたことがない人はまずはUdemyや参考書を購入し、一通り学習した方が良いです。

そうではなく、私のように少し数学や統計学を学んだことがある人はCBT公式問題集を解きながら統計学の時間を見つつ、ここで怪しいところはカンペを作ってください。1週間で詰め込んだときにわかったのが、覚えてさえいれば解ける問題が非常に多く(統計分布の期待値や分散、統計量など)、さらに自分でまとめてそれを見直すことで定着も早いです。そのあとに過去問をできるだけ解きましょう。CBT公式問題集だけでも内容としては十分なのですが、数学はとにかく多くのパターンで解くことが重要なので高いですが再受験するよりマシだと考えて買いましょう笑。

次に合格するための勉強のウェイトについてです。1変数2変数の記述統計と確率はできるだけ落とさないことです。統計検定2級は合格点が60%です。35問ならば21問解ければ良いです。つまり半分ぐらい出題される高校数学のデータ分野や確率をしっかり取れば推定・検定・線形モデルを少し取るだけで合格することが可能です。さらに検定などの分野も覚えているだけで解ける問題もあるのでそれを合わせれば十二分に合格が可能です。

さいごに

学習開始から合格まで10カ月ぐらいかかってしまい、効率の悪い学習をしてしまいました。私のような非効率な学習をしないように、これから受ける方は頑張ってください。

日本百名城巡りその2 箕輪城

概要

箕輪城はおよそ500年前に長野業尚によって築かれた城です。群馬県高崎市にあり、昭和62年に国指定史跡に指定され、日本百名城にも選出されています。

歴史

西暦 城主 出来事
1512 長野家 長野業正によって築城される
1561 業正が死去。業盛が後を継ぐ
1566 武田信玄によって攻められ、業盛は自刃
1570 武田家 内藤昌豊が城代となる
1575 昌豊が長篠設楽原の戦いで戦死。子の昌月が城代となる
1582 武田家が滅亡
織田家 滝川一益が城主となる。本能寺の変後北条家の城となる
北条家 北条氏邦が城主となる
1590 小田原征伐で北条家が滅亡
徳川家 徳川家の関東移封により井伊直政が城主となる
1598 井伊直政が高崎城を築城し、移る。それに伴い箕輪城は廃城となる
1987 ------- 国の史跡に指定される

入城

f:id:Parco1021:20240205231535j:image
f:id:Parco1021:20240205231539j:image

見どころのようなものはあまりなく、立派な門があるぐらいでした。散歩コースになっており、お散歩している人がちらほらいましたが、観光地のような場所にはなっていません。

スタンプも城の敷地内にあるわけではなく、少し離れた役所のような場所にありました。上下逆さまに押してしまったがすごく悔しいです。。。笑

f:id:Parco1021:20240205232603j:imagef:id:Parco1021:20240205232605j:image

さいごに

散歩コースになっているので歩き甲斐のあるルートになっていました。駅からのアクセスはあまりよくなく、中々行くことができないので旅行のついでに行くことができてよかったです。

 

 

日本百名城巡りその1 鶴ヶ城(会津若松城)

概要

鶴ヶ城福島県会津若松市にある城です。鶴ヶ城会津城だとか会津若松城と呼ばれています。以後会津若松城と呼びます。会津若松城会津若松駅から3kmほどのところにあります。

歴史

会津若松城は蘆名氏から始まり、幕府血縁の松平氏に終わりました。伊達や上杉氏など名家が城主となっていた時期がありますがどちらもかなり短いです。城での案内もやはり命名し長く治めていた蒲生氏郷のものが多かったです。

西暦 城主 出来事
1384 蘆名家 7代当主蘆名直盛によって築城、当時は黒川城と呼ばれる
1553 16代当主蘆名盛氏が城主となる
蘆名家全盛期
1589 伊達家 伊達政宗が蘆名家を攻め滅ぼし、黒川城を入手
1590 伊達政宗豊臣秀吉に臣従し、黒川城を没収される
蒲生氏郷入城
1593 蒲生家 7層の天守閣が完成
地の名前を黒川から若松に変え、城の名前を鶴ヶ城へと変更
1598 氏郷の子である秀行は家中騒動の影響で会津を没収される
上杉家 上杉景勝が入城
1600 関ヶ原の戦いにて上杉家が西軍に加担したため会津を没収される
蒲生家 蒲生秀行が再度入城
1627 跡取りがいない問題のため四国へ移封
加藤家 代わりに同地から加藤家が入城
1643 家中騒動のため改易
松平家 徳川家光の弟である保科正之(後に松平へ改名)が入城
1868 戊辰戦争の1つである会津戦争にて会津城は新政府軍に攻められ、開城
1873 --- 廃城令によって鶴ヶ城は廃城となる

 

入城

まず敷地に入ると全体マップがあります。

f:id:Parco1021:20230506184529j:image

お堀を抜け、進んでいくと天守閣が見えてきます、ネットで見た通りの壮大さでした。天守閣が最近リニューアルされたらしいのですがかなり混んでおり、予定も詰まっていたので入ることができませんでした。次行くときはリベンジします。

f:id:Parco1021:20230506184540j:image

f:id:Parco1021:20230506184547j:image

天守閣の麓には自由市が開かれており、そこでは会津若松名物の味噌を使った食べ物や地酒、漆器などが売られていました。

f:id:Parco1021:20230506184611j:image

f:id:Parco1021:20230506184626j:image

さいごに

観光地として売り出されているだけに自由市や喫茶店など観光客向けのものが多くありました。100名城として初めて訪れるお城として楽しかったです。

f:id:Parco1021:20230506184635j:image

論文メモ⑥:Spatially-Adaptive Pixelwise Networks for Fast Image Translation

論文の情報

まとめ

 CycleGANなどのある画像を別のドメインへ変換する技術はGANに関する研究の中でも活発に行われている分野の一つである。生成画像の品質や制度の向上と引き換えにモデルのサイズが大きくなり、計算量が膨大となる。本論文で提案されたASAP-Net(A Spartially-Adaptive Pixcelwise Network)はFigure 1のように既存手法と比較して性能をそのままに大幅に実行時間を減らすことに成功した。

f:id:Parco1021:20211115155936p:plain

 手法の詳細は記事に示す通りであるが簡単に述べると高解像度の画像マップをダウンサンプリングすることによって低解像度で解釈を行う。その後各ピクセルごとのMLPを導入することで計算量を削減している。

f:id:Parco1021:20211115174503p:plain

 

感想

 ピクセル単位でMLPを用いることは画像生成等において良い性能を出せていなかったのは有名な話だが、計算量を減らすためにピクセル単位で小さなMLPを導入するという発想が意外だった。論文を読み解説記事を書いたがこのような手法になった経緯等が筆者には難しく、なぜこのようなアーキテクチャになったかがあまりわからなかった。興味深い内容なのでまた時間があるときに読みたい。

 

 

論文メモ⑤:Reducing Transformer Depth on Demand with Structured Dropout

論文の情報

一言まとめ

Dropoutは深層学習を用いる際にほぼ必ずと言っていいほど使われる技術である。Dropoutとは一般的にノード間の重みを無視することを指すが、本論文ではノード間の重みではなく層全体をDropout、すなわち無視する。今回対象のモデルとして非常にDeepなモデルであるTransformerを正規化させ、学習を安定化させた。

本論文は実験を多く行っている。結果を以下に示したが他にも多くの実験でTransformerにLayerDropを施すことでスコアが上昇した。

感想

層全体をDropoutするという発想は非常に面白かった。層をDropoutするのならば初めからなければ良いのでは?と思ったがそうではない。学習の過程でいらない層を識別し、Dropoutしてから再学習のような手法を取っているからだ。多くの実験で良いスコアを出しており、2019年に出された論文であるにも関わらず2021年最近の論文でLayerDropの文字を見ないのであまり使われていないのだろうか。見逃しているだけかもしれない。被引用数も多いので反響は大きかったと思う。

 

 

pandasのdatatime型でのAssertionError: <class 'numpy.ndarray'>

はじめに

pandasのdatetime型を扱ったときにエラーを吐かれ、検索してもほぼ出てこなかったので残しておきます。

問題設定

以下のようなcsvファイルをpandasで読み込み、dateをindexにした後にdateが2020年のものをスライスすることを目的とする。下の表は一例だがデータ収集の際、日付に関して降順にソートされている。

title date
aa 2021/4/3
bb 2021/2/1
cc 2020/6/11
dd 2020/2/20

今回動かしたコードは以下:

import pandas as pd

df = pd.read_csv('./data.csv')
df['date'] = pd.to_datetime(df['date'])
df.index = df['date']
print(df['2020'])

まずdateが年/月/日となっているのでpandasのdatatime型に変換する。変換すると年-月-日の形となる。このdatatime型をindexに設定するといろいろと楽なのでindexを変更する。日付で範囲指定できたりスライシングができる。 https://qiita.com/sakabe/items/ae1fa47a58c796006627 とりあえず2020年のものを抜き出そうとすると、、、

AssertionError: <class 'numpy.ndarray'>

解決方法

初めに解決方法だけ書く。どうやらdatetime型は昇順にソートされていないとスライスができないようなのでdateに対してソートを行う。すなわちdf = df.sort_index()を追加することで期待する出力(=2020年のtitle)が得られる。

原因

AssertionErrorはプログラムが設定されたアサーションがFalseとなったときに出るエラー。今回はpandas側でエラーが出ている。エラーログを見るとassert isinstance(slobj, slice), type(slobj)となっているため本来受け取ってはいけないnumpy配列型がきてしまっている。pandasの中身を見てみるとslice型?スライスオブジェクトを受け取るらしい。それが何故昇順にソートすることでnumpy配列からスライスオブジェクトになるのかはわからない。numpy配列で何を受け取っているのか確認すると元のインデックスを受け取っているようだった。また、(ないとは思ったが)sort_index()で特別な処理がされているのでは?と思い敢えて降順でソートsort_index(ascending=False)として実行してみたが同様のエラーが出た。よって昇順にソートされていることが重要であると考えられる。もし何か知っている方がいたら教えてください…。

論文メモ④TransGaGa: Geometry-Aware Unsupervised Image-to-Image Translation

論文の情報

簡単なメモ

CycleGANなどの従来の手法は、猫⇔人間などの大きな幾何学的変化を伴うドメイン変換のimage2imageタスクは達成できていなかった。提案手法では入力画像をgeometry(向き)とappearance(形状)に分け、それぞれ潜在変数に落とし、さらにそれぞれに変換器を用意することでタスクを達成している。アーキテクチャは以下の図(論文より)。

f:id:Parco1021:20210315134227p:plain

geometryはヒートマップを用いて表現されている。このヒートマップをきちんと実現するための損失関数が導入されている。

さいごに

アーキテクチャや損失関数の自分なりの詳細な解説はこちらに書かせていただいたので興味のある方は是非。

ai-scholar.tech

2020年第3回G検定合格体験記

はじめに

資格とかには特に興味がなかったのですが、コロナの影響で大学へあまり行くことができず、春休み~夏休みを何もせずに過ごしさらに年も越してしまいそうな勢いだったので何かやることのきっかけが欲しくて受験を決意しました。研究室で深層学習について学んでいるので1週間あれば大丈夫だろ~wと思い1週間前にやっと申し込みしました。しかし受験日が卒業研究中間発表の数日前で資料の作成等をしなければならず、あまり勉強時間が確保できませんでした。

G検定とは

G検定は日本ディープラーニング協会が開催している資格であり、深層学習などの人工知能全般に関する知識問題が出題されます。計算問題はほぼ無く、法律に関する問題や用語に関する問題が多く出題されます。シラバスは以下の通りです。

f:id:Parco1021:20201119194158p:plain

引用元:日本ディープラーニング協会

 

G検定はネット受験なので好きなだけインターネットで調査することが可能です。しかし当然運営さんもそれは承知であるため時間は厳しく設定されています。試験時間は120分で問題数は220問ほどです。全ての問題を逐一調べていたら間に合いません。

 

合格率は6~7割とかなり高いです。合格率が高いため余計にプレッシャーを感じました。今回受けた試験は従来よりも合格率が低く、やはり受けてみても思ったより難しかったです。

f:id:Parco1021:20201119201353p:plain

f:id:Parco1021:20201119202334p:plain

f:id:Parco1021:20201119203518p:plain

引用元:日本ディープラーニング協会

難易度は低い試験なので人工知能初学者の大学生が受けてそうだな~と思っていたんですが意外と開発職の2,30代の方が受けていて驚きました。それだけ会社で人工知能を導入しているということでしょうか、知らんけど。

勉強方法

何からやればいいのかようわからんかったのでとりあえず公式テキストなるものを読もうと思い、1週間前に買い、全9章あるため1日2章で4日目は3章読むことで4日で読み終わらせました。

残り2日は問題集を半分ずつ解きました。当日はなんかやる気が起きなくて何もやっていません。テストあるあるじゃないですか??直前にやる気なくなるの。

 

勉強方法の振り返りなのですが、まず公式テキストはかなり浅く広くといった印象を受けました。元から知っている単語は「あーはいはいそれね」となるのですが初見の単語だと説明が浅すぎて全く頭に入ってきません。特にRNNやCNN周りの応用の範囲は少し難しいで別で検索して理解をしておく必要があります。ただ範囲がある程度広いためこのようになることはしょうがないと思います。カバーしきれていない分を問題集で演習を積みつつ補填するイメージです。また、試験中に逐一参考書を開いて~とやるのは効率が悪いので事前に自分の言葉でどこかのファイルにまとめておきましょう。検索すると他の方がまとめた記事が大量に見つかるのですが網羅できているかわかりませんし、自分でまとめたほうが当日見つけるのも読み解くのも時間が圧倒的にかかりません。勉強時間は1日3時間程度行いました。

 

 

試験

試験は先ほども書きましたが法律周りの問題が圧倒的に多く、知識問題は事前の知識で事足りる程度のものが多かったです。法律は試験中に調べるつもりだったので試験中はひたすらに法律についてググっていました。他の受験者も同様だったようでG(oogle)検定などと言われていました。公式テキストからはほぼ出題されていない印象でした。

 

総評

今回の目的は資格をとることよりも人工知能を体系的に学ぶことでした。結果的に試験前の参考書での勉強や当日の試験での検索で知見を深めることはできたと思います。ただ資格自体に価値があるかと問われるとプログラムや理論的なことは全く問われないので機械学習エンジニアになりたいような人には難易度等考慮してあまり感じられませんでした。しかし初学者であったり私のように勉強するきっかけとして受験することには意味があると思います。

SGDを使うにあたってのハイパーパラメータの設定(論文紹介③ Control Batch Size and Learning Rate to Generalize Well: Theoretical and Empirical Evidence)

概要

深層学習において、確率的勾配降下法(SGD)はOptimizerとして良い結果を出しており、SGDをより良く動かすためにハイパーパラメータの調整が必要。複数あるハイパーパラメータのうち、特にバッチサイズ(Batch Size)と学習率(Learning Rate)に着目し、どのように設定すべきかを解析的に考えた論文。数値解析の結果、バッチサイズの大きさSと学習率ηの比S/ηが小さいほどより良い結果となる。

 

papers.nips.cc

 

予測損失と経験損失

本来最小化したい損失は予測損失である。

f:id:Parco1021:20200930015555p:plain

しかし、データの分布Dがわからないため予測損失と近似することのできる経験損失を用意する。

f:id:Parco1021:20200930015658p:plain

できるだけ経験損失が予測損失と近くなるようにアルゴリズムを設定したい。以後、経験損失を最小化することを目的とする。

 

解析的証明(略)

※具体的な証明は別で記事にする…かもしれません※

経験損失と予測損失の差(≒アルゴリズムの良さ)の変数部分をIと置く。また、バッチサイズと学習率の比をk(=|S|/η)と置き、Iをkで微分すると以下になる。

f:id:Parco1021:20200930014428p:plain

パラメータ数dが十分に大きい、具体的に以下の条件を満たすと仮定すると∂I/∂kは常に正となる。

f:id:Parco1021:20200930015120p:plain

この時、変数kはS,η>0より予測損失と経験損失の差はk>0で単調増加である。よってバッチサイズと学習率の比が予測損失と経験損失の差と正の相関がある。つまりaccuracyとは負の相関があるということでありkが小さいほどより良い結果が得られると期待できる。この時、むやみにkを小さくすれば良いというわけではなく、あくまで上記のdの範囲内であることに注意。

 

実験

  • モデル…ResNet-110,VGG-19
  • データセット…CIFAR-10,CIFAR-100
  • バッチサイズ…16,32,48,64,80,96,112,128,144,160,176,192,208
  • 学習率…0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.10,0.11,0.12,0.13,0.14,0.15,0.16,0.17,0.18,0.19,0.20
  • エポック数…200

以上の実験設定でテスト誤差(accuracy)を比較。スピアマンの順位相関係数(SCC)を求める。

 

実験結果

Ⅰバッチサイズとaccuracy

表左部の学習率で固定し、バッチサイズとaccuracyでSCCを取る。SCCが全てのケースで-1.0付近なのでバッチサイズとaccuracyは負の相関がある。

f:id:Parco1021:20200930010858p:plain

 

Ⅱ 学習率とaccuracy

表左部のバッチサイズで固定し、学習率とaccuracyでSCCを取る。SCCが全てのケースで1.0付近なのでバッチサイズとaccuracyは正の相関がある。

f:id:Parco1021:20200930011151p:plain

 

Ⅲ バッチサイズと学習率の比とaccuracy

横軸にBSとLRの比(=k)、縦軸にaccuracyをとると負の相関があることがわかる。

f:id:Parco1021:20200930011353p:plain

f:id:Parco1021:20200930011406p:plain

 

まとめ

数値解析と実験結果から、バッチサイズと学習率の比が予測損失と経験損失の差と正の相関(=accuracyと負の相関)があることがわかった。よってSGDで学習率を行う時はバッチサイズを小さく、学習率を大きくすると結果が良くなると期待できる。しかし、パラメータの制約等があるためむやみに大きくor小さくすれば良いというわけではない。

便利なPythonのリスト内包表記

最近、競プロみたいな問題をPythonで解いたりしているのですが、その時にデータの入出力周りでリストをよく扱います。いたずらにfor文とappend()メソッドを用いるとコードが冗長になってしまうのでリスト内包表記を用いるのですがちゃんと調べたことがなかったので調べて備忘録としてまとめます。

 

リスト内包表記のメリット・デメリット

  • コードが短くなる
  • 実行速度が上がる
  • Pythonわかってる風になれる
  • あまりディープな表記にすると可読性が著しく下がる

シンプルなリスト内包表記

元データ

for文
data = 
for i in range(10):
    data.append(i)
print(data)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
リスト内包表記

[式 for 変数 in イテラブルオブジェクト]といった形です。上記のfor文記法と比較するとわかりやすいと思います。

data = [i for i in range(10)]
print(data)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
補足

上記の例ではrange()から1つずつ要素を抽出しましたが、そのままlist()関数でリスト化できます。

data = list(range(10))
print(data)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

リストの型を変える

先ほどのリストの各要素はint型です。それをstr型に変更します。

for文
data_str = 
for i in data:
    data_str.append(str(i))
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
リスト内包表記
data_str = [str(i) for i in data]
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
補足

map関数を使うことで同様の処理をすることができます。

data_str = list(map(str,data))
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

 

if文のあるリスト内包表記

if文のみ

for文
data_if = 
for i in data:
    if i == 2 or i == 8:
        data_if.append(i)
print(data_if)
#[2, 8]
リスト内包表記

[式 for 変数 in イテラブルオブジェクト if文]といった形です。

data_if = [i for i in data if i == 2 or i == 8]
print(data_if)
#[2, 8]

if-else

まず、先ほど作成したdata_strに要素を追加します。

data_str.append('G')
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'G']
for文

int型への変更が可能であるならばint型にし、不可能ならばそのままにするプログラムです。

data_ifelse = 
for i in data_str:
    if i.isdigit():
        data_ifelse.append(int(i))
    else:
        data_ifelse.append(i)
print(data_ifelse)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'G']
リスト内包表記

先ほどのif文と位置が異なります。

[Trueの式 if 式 else Falseの式 for 変数 in イテラブルオブジェクト]と書きます。

elif文はif-elseを組み合わせて記述することができますが、可読性が落ちてしまうので辞めた方がいいかもしれません。

data_ifelse = [int(i) if i.isdigit() else i for i in data_str]
print(data_ifelse)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'G']

 

まとめ

今回はPythonのリスト内包表記についてまとめました。内包表記はリストだけでなく、dict型やset型にも同様に使えるので試してみてください。繰り返しになりますが、ここで挙げた以上の複雑な処理を内包表記で書くととても読みにくくなってしまうので注意が必要です。実行速度が上がるとメリットで書きましたが、そこまで大きな差はなく、これぐらいを気にするのならばリストではなくnumpy配列等を使った方がよほど早くなります。

 

 

言語処理100本ノック2020 第4章 Pythonでの解答例

前章↓↓

parco1021.hatenablog.com

 

第4章 形態素解析

まず、与えられたneko.txtをMeCabを使って形態素解析します。MeCabの導入等は別途調べてみてください。形態素解析するコマンドは以下の通りです。

mecab neko.txt --output neko.txt.macab

 

30.形態素解析結果の読み込み(31日目|9月4日)

形態素解析結果(neko.txt.mecab)を読み込むプログラムを実装せよ.ただし,各形態素は表層形(surface),基本形(base),品詞(pos),品詞細分類1(pos1)をキーとするマッピング型に格納し,1文を形態素マッピング型)のリストとして表現せよ.第4章の残りの問題では,ここで作ったプログラムを活用せよ.

まず、各行をタブ(\t)区切りで分割します。文末文字(EOS)のみである行があるため、それを除くために分割した長さが2である場合にのみ適用します。分割した後の方を次は','区切りで分割し、それぞれ求められたキーとマッピングします。

 

31.動詞(32日目|9月5日)

動詞の表層形をすべて抽出せよ.

30で作成した辞書型のデータを使います。まず、動詞の重複等が考えられるのでset()を用いて重複する要素を除きます。

 

32.動詞の原形(33日目|9月6日)

動詞の原形を全て抽出せよ.

31と同様です。

 

33.「AのB」(34日目|9月7日)

2つの名詞が「の」で連結されている名詞句を抽出せよ.

"名詞"+”の”+"名詞"となっている場所を探します。

 

34.名詞の連接(35日目|9月8日)

名詞の連接(連続して出現する名詞)を最長一致で抽出せよ.

現在参照している品詞が名詞ならばtempに追加し、次の文字を参照する。次の文字も名詞ならば再度tempに追加する。tempの長さが2以上つまり名詞が2連続以上続いているならばそれを出力します。

 

35.単語の出現頻度(36日目|9月9日)

文章中に出現する単語とその出現頻度を求め,出現頻度の高い順に並べよ.

単語と出現回数を対応させたdictを作成します。そのままカウントを開始すると','や'。'をカウントしてしまうため、posが記号のものはdictへ格納しないようにします。未登録の単語が来た場合、新たにdictへ登録し、その後登録未登録に関わらずインクリメントします。

 

36.頻度上位10語(37日目|9月10日)

出現頻度が高い10語とその出現頻度をグラフ(例えば棒グラフなど)で表示せよ.

35で出現頻度順にしたデータが用意されたのでそれを使います。棒グラフにする際、横軸のラベルを単語にします。それが当然日本語であり、そのままグラフにすると日本語は豆腐になってしまうため専用のライブラリ?をインストールします。pip install japanize_matplotlibを実行してから動かしましょう。

f:id:Parco1021:20200910221438p:plain

 

37.「猫」と共起頻度の高い上位10語(38日目|9月11日)

「猫」とよく共起する(共起頻度が高い)10語とその出現頻度をグラフ(例えば棒グラフなど)で表示せよ.

今回、何をどうするかが具体的に問題文で示されていません。自分で何を"よく共起する"か定義する必要があります。僕は"猫"の前後5単語の記号と助詞、及び助動詞を除いた品詞をそれとし、カウントしました。

 

f:id:Parco1021:20200911194504p:plain


 

38.ヒストグラム(39日目|9月12日)

単語の出現頻度のヒストグラムを描け.ただし,横軸は出現頻度を表し,1から単語の出現頻度の最大値までの線形目盛とする.縦軸はx軸で示される出現頻度となった単語の異なり数(種類数)である.

35のデータをヒストグラムにするだけで特に難しいことはないです。

f:id:Parco1021:20200912203730p:plain

 

39.Zipfの法則(40日目|9月13日)

単語の出現頻度順位を横軸,その出現頻度を縦軸として,両対数グラフをプロットせよ.

対数グラフはそれぞれのスケールをlogにすればよいのでplt.x(y)scale('log')とします。余談ですが、Zipf(ジップ)の法則は、ある膨大なテキストの要素を出現頻度順にしたとき、その順位と頻度を乗算すると定数になる法則です。つまり今回は縦軸に出現頻度、横軸に順位としているためプロットしたグラフは1次関数のような形になることが期待されます。

f:id:Parco1021:20200913214349p:plain

 以上で4章は終わりです。お疲れ様でした。

言語処理100本ノック2020 第3章 Pythonでの解答例

第2章↓↓

parco1021.hatenablog.com

 

 

第3章:正規表現

20.JSONデータの読み込み(21日目|8月25日)

Wikipedia記事のJSONファイルを読み込み,「イギリス」に関する記事本文を表示せよ.問題21-29では,ここで抽出した記事本文に対して実行せよ.

今回与えられたデータはよく見るJSONと少し形式が異なります。一行ずつ読み込む必要があるのでfor文で1行ずつ読み込みます。そのタイトルがイギリスであるテキストを出力します。

 

21.カテゴリ名を含む行を抽出(22日目|8月26日)

記事中でカテゴリ名を宣言している行を抽出せよ.

カテゴリを宣言している行は"Catedory:〇〇"という形になっています。[]は正規表現で用いられる記号なので\でエスケープします。そしてCategory:の後は任意の文字がくるので.*とします。python正規表現を用いる時はreモジュールをインポートします。findall()に正規表現と対象データと複数行にマッチさせるためにre.MULTILINEを引数として渡します。

 

22.カテゴリ名の抽出(23日目|8月27日)

記事のカテゴリ名を(行単位ではなく名前で)抽出せよ.

21で抽出したもののうち、":"以降であり、"|*"より前まで抽出したいです。前者は簡単なのですが、後者をどのようにすれば良いのかわかりませんでした。調べた結果、(?:pattern)とすることでそのpatternをマッチした場合、抽出しないことができるそうです。正規表現だけ用いる必要がないならば"|"をreplace()したりすることで実装可能です。

 

 

23.セクション構造(24日目|8月28日)

記事中に含まれるセクション名とそのレベル(例えば”== セクション名 ==”なら1)を表示せよ.

セクションのレベル?はよくわからないのですが、おそらく"=="の長さ-1がレベルなんでしょう。["=の部分","セクション名","=の部分"]のような形でリストに格納します。[^pattern]はpattern以外のものにマッチします。

 

24.ファイル参照の抽出(25日目|8月29日)

記事から参照されているメディアファイルをすべて抜き出せ.

参照されているファイルは"ファイルorFile"の後にファイル名が指定されます。そこを指定して抽出します。

 

25. テンプレートの抽出(26日目|8月30日)

記事中に含まれる「基礎情報」テンプレートのフィールド名と値を抽出し,辞書オブジェクトとして格納せよ.

基礎情報のフィールド名と値は、「|"フィールド名""任意の空白文字"="任意の空白文字""値"」となっています。なのでそれを抽出する正規表現をpatternマッチさせます。\sは任意の空白文字です。それを辞書型に保存します。

 

26.強調マークアップの除去(27日目|8月31日)

25の処理時に,テンプレートの値からMediaWikiの強調マークアップ(弱い強調,強調,強い強調のすべて)を除去してテキストに変換せよ(参考: マークアップ早見表).

指定されたマークアップ早見表を見てみると、強調には「'」が使われています。この数によって強調の度合いが変わりますが、2~5個であるため25のresultに正規表現で指定して削除します。\で'をエスケープし、{n,m}でその数を指定します。それをsub()関数で削除します。

 

27.内部リンクの削除(28日目|9月1日)

26の処理に加えて,テンプレートの値からMediaWikiの内部リンクマークアップを除去し,テキストに変換せよ(参考: マークアップ早見表).

(内部リンクは内部リンク|表示名となっているのでそれを削除すればいいのだがよくわからなかった)

 

28.MediaWikiマークアップの削除(29日目|9月2日)

27の処理に加えて,テンプレートの値からMediaWikiマークアップを可能な限り除去し,国の基本情報を整形せよ.

27で内部リンクは削除できた(?)ので残りの部分の気になるところを削除します。<br>等のhtmlタグを削除しました。

 

29.国旗画像のURLを取得する(30日目|9月3日)

テンプレートの内容を利用し,国旗画像のURLを取得せよ.(ヒント: MediaWiki APIのimageinfoを呼び出して,ファイル参照をURLに変換すればよい)

WikiAPIを使って画像urlを取得します。APIの説明は以下のページから

API:Imageinfo - MediaWiki

Pythonでのサンプルコードもあるので利用します。サンプルでpropはimageinfoが指定されているためそこからさらに画像urlを指定するにはiipopでurlを指定するだけです。結果をjsonで受け取り構造を確認してurlを出力します。

 

これで第3章は終わりです。お疲れ様でした。 

 

 

言語処理100本ノック2020 第2章 Pythonでの解答例

第1章↓↓

parco1021.hatenablog.com

第2章:UNIXコマンド

UNIXコマンドとありますが、筆者は現在WindowsにしかPythonの実行環境をそろえておらず、Linuxもさっぱり使っていないのでコマンドは省略します。他の方がやった解答を見て自分のプログラムの出力が正しいことは確認します。※

 

10.行数のカウント(11日目|8月15日)

行数をカウントせよ.確認にはwcコマンドを用いよ.

テキストファイルをpythonで読み込む方法は何通りかありますが、今回は最も(?)ポピュラーなpandasを使います。pandasで読み込み表示するだけで行数*列数も表示されるのですが、shapeを使ってそれぞれ表示してみます。行数だけでなく、ついでに列数を表示させてみました。

 

11.タブをスペースに変換(12日目|8月16日)

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

区切り文字をタブにして読み込んだtxtファイルを区切り文字を半角スペースにして保存します。この時、headerとindexをFalseにしておかないとインデックス番号等がついたまま保存されてしまうので注意が必要です。

元のファイルと出力されたファイルの一部

Get-Content data.txt -last 5
Benjamin M 13381 2018
Elijah M 12886 2018
Lucas M 12585 2018
Mason M 12435 2018
Logan M 12352 2018 Get-Content newdata.txt -last 5
Benjamin M 13381 2018
Elijah M 12886 2018
Lucas M 12585 2018
Mason M 12435 2018
Logan M 12352 2018

全体↓↓

github.com

12.1列目をcol1.txtに、2列目をcol2.txtに保存(13日目|8月17日)

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.

 df[0]に1列目がdf[1]に2列目が格納されているのでそれを保存します。

 

結果

github.com

 

13.col1.txtとcol2.txtをマージ(14日目|8月18日)

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.

pandasのconcat()関数を使います。デフォルトだと縦方向にマージしてしまうので、axis=1とすることで横方向にマージするよう指定します。

出力ファイルは上記のgithubにあります。

 

14.先頭からN行を出力(15日目|8月19日)

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ. 

コマンドライン引数はsys.argvで受け取ります。ここで注意すべきは第一引数がargv[0]ではなくargv[1]に格納されていることです。受け取ったnはstr型なのでint型に変換し、pandasの関数head()に渡します。


15.末尾のN行を出力(16日目|8月20日)

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.

 14と同様です。異なる点はhead()ではなく、tail()を使います。

 

16.ファイルをN分割する(17日目|8月21日)

自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.

演算子'//'は除算の結果を切り捨てます。例えば10//3ならば3となります。

 

17.1列目の文字列の異なり(18日目|8月22日)

1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはcut, sort, uniqコマンドを用いよ.

duplicated().value_counts()は重複する場合にTrueとします。なのでFalseの数が重複しない要素の数です。例えばAnna,Bnna,Cnna,Annaだった場合、False,False,False,Trueとなります。重複しない要素を取り出すにはunique()メソッドを使います。その要素数を数えるにはlen(df.unique())でもいいのですが、nunique()によっても得られます。

 

 

18.各行を3コラム目の数値の降順にソート(19日目|8月23日)

各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).

sort_values()を用います。引数にソートしたい対象のコラムを指定します。今回は3カラム目なので2を指定しました。出力は先頭の5行のみとしています。

 

19.各行の1コラム目の文字列の出現頻度を求め、出現頻度の高い順に並べる(20日目|8月24日)

各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.

 value_counts()メソッドを用います。value_counts()は出現回数のカウントだけでなく、デフォルトで降順にソートしてくれるため題意の出力をすることができます。ソートをしたくない場合はvalue_counts(sort=False)とし、昇順にしたい場合はvalue_counts(ascending=True)とします。

これで第2章は終わりです。

 

第3章↓↓

parco1021.hatenablog.com

スポンサーリンク