あさの畑

プログラミングが好きな大学生のブログ。統計学や機械学習の勉強記録と、SIGNATE/Kaggle/AtCoderのお話。

「Google Code Jam 2019 Round 2」へ進めることになった!?

f:id:gadada:20190504233755p:plain

Googleが開催している競技プログラミングの大会に参加しました。Qualification Round 2019を通過できたので、今回はRound1に挑みました。

Code Jam - Google’s Coding Competitions

 

 

4月の最初に予選ラウンド(Qualification Round 2019)があり、そこで基準の点数以上取ればRound1に進むことができます。そしてRound1は、A、B、Cの3回行われて、そのうちどれかで上位1500位に入れば次のRound2に進める、ということになっています。

 

各上位1500位、つまり合計でRound2に進めるのは4500人なので、さすがに厳しいかなとは思いつつも良い機会なのでとりあえずRound1に参加しました。Round1Aでは全然わからなくてボロボロ、Round1Bは体調が悪かったので不参加、そして迎えたRound1C。

 

終了直後は1527位と表示されてて、惜しくもギリギリ落ちたわけです。思っていたよりも順位が良かったのは嬉しかったのですが、ここまできたらどうせやったら1500位に入りたかったなーなんて思ってました。

 

 

 まあまた来年がんばろかなと思って忘れていたら、数日前にcode jamから「Congratulations!」ってメールが来ました。なぜか繰り上がっていてRound2に進めるようです。1498位なので、本当にギリギリ滑り込んだ(笑)

 

 ここまでの成績はこんな感じ。

f:id:gadada:20190512074924p:plain

 

ギリギリ通過したのでさすがにRound3に進むのは本当に厳しそうですが、「英語の問題を読んで解く」という普段の競技プログラミング(いつもはAtCoderしてる)とは違った機会で学べることも多いので、とにかく奮闘します。

 

(もちろんAtCoderもがんばる。)

 

AtCoderを始めて二カ月半。緑色になりました。

4月27日に行われた「AtCoder Beginner Contest 125」に参加して、緑色になりました。

 

f:id:gadada:20190428142903p:plain

f:id:gadada:20190428143102p:plain

 

まずは「AtCoder Beginner Contest 125」の振り返り

50分ちょっとで全完できました。全完は初めてなので嬉しいです。いつものC問題やD問題に比べるとそこまで難しくないんじゃないかなと思いました。ただ難易度がちょっと変で、C問題よりD問題の方が正解者数が多いという状況。いつもはD問題は問題も見ずに解いていないのですが(←問題ぐらい読んでみたほうがいいよ)、順位表を見て今回は解いてみたらあっさり解けました。

 

f:id:gadada:20190428143205p:plain

 

過去問は少しづつ解いてます

このまえ茶色になった記事を書いてからも過去問はちょっとずつ解き続けていて、今はこんな感じです。最近は忙しくて、とりあえずA問題とB問題だけでもさらっと解いておこう、ってなってしまってC問題を解かない日もあるのでサボり気味…。

 

f:id:gadada:20190428143426p:plain

 

www.asanohatake.com

 

緑ってどんなもん?

ちなみに緑色とは、以下の記事から引用すると、

印象としては、

  • 学生ならかなり優秀。
  • エンジニアとしてもある程度の安心感がある。論理的に複雑な処理の実装に対応できない、なんてことはなさそう、くらいには思える

くらいの印象です。もちろんアルゴリズム力しか計ってないので個人差があります。

技術的な部分では、

  • if、forはもちろん、それを組み合わせて2次元配列に対して操作をしたり、深さ優先探索や幅優先探索などのキューや再帰を使った実装も出来る。
  • 簡単な動的計画法の問題や、少し数学的に工夫する問題など、計算量の工夫も出来始める。

という感じです。

(引用:http://chokudai.hatenablog.com/entry/2019/02/11/155904

 

「学生ならかなり優秀」なんて言われると嬉しいです。でもあんまり実感がなくて、まだまだ知らないことだらけですし、深さ優先探索、幅優先探索、キュー、再帰、動的計画法については1ミクロンもわからない上に計算量の工夫もできてないです。そして学生なら優秀とか言われても響いてこない一番大きい理由は、「Twitter上に、青い人とか暖色の人とかがいっぱいいること」です。そのため青色や暖色が普通みたいになってて、「まだ緑かー」という印象が強いんですね。

 

とはいっても緑色になれたことは嬉しいですし、次は水色になれるように勉強したり過去問解いたりしていこうと思います。

 

AtCoder Beginner Contest 123を終えて。茶色になりました。

4月6日に「AtCoder Beginner Contest 123」があり、灰色から茶色に昇格しました!「絶対茶色になるぞ!」とかなり気合を入れて挑んだので無事に色が変わって良かったです。

 

今回の結果。ちょっとB問題に時間がかかりすぎた…。でもC問題が解けたので良し。

f:id:gadada:20190406234932p:plain

 

ここまでのRatingの変化はこんな感じです。初めて参加したのが2月16日のABC(AtCoder Beginner Contest 118)でしたので、もうすぐ二カ月というところでなんとか茶色になりました。正直、もっとはやく上がっていくものかと思っていました…。

f:id:gadada:20190406232916p:plain

 

ちなみに、初めて参加したときに記事書いてました。

www.asanohatake.com

 

いっつもABCでは悔しい思いばっかりしていたので、このままではあかんなと思って、最近は過去問がんばって解いています。(ここ10日間ぐらいの話。)

 

f:id:gadada:20190406233608p:plain

f:id:gadada:20190406233710p:plain

 

とりあえず、ABCのA問題、B問題、C問題を過去にさかのぼって解いていっている途中です。A問題とB問題はできるだけ速く解こうという気持ちでやってて、C問題は時間は気にせずまずは解けたらいいかなって感じですけど、解けないことの方が多いです。

 

このまま毎日何問かずつ解いていこうと思います。D問題の過去問に手をつけるのはA問題、B問題、C問題の過去問が終わってからかな。次のABCが終わった後にはRatingのグラフの上の方に緑色が見えてきてくれたらいいなあ。

 

TensorFlow 2.0 によるブースティング木を試してみる

Kaggleでよく使われるLightGBMやXGBoostといった勾配ブースティング木ですが、TensorFlow 2.0にブースティング木のパッケージが実装されて手軽にブースティング木による分類や回帰を実行することができます。今回は「Google Colaboratory」で、TensorFlowのタイタニックのデータセットを使って試してみました。(以下のツイートのページには英語で詳しく書かれてます。)

 

 

まず、インストール。

!pip install tensorflow==2.0.0-alpha0
import numpy as np
import pandas as pd
import tensorflow as tf
tf.random.set_seed(0)
print(tf.__version__)


タイタニックのデータセットを読み込む。

dftrain = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/train.csv')
dfeval = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/eval.csv')
y_train = dftrain.pop('survived')
y_eval = dfeval.pop('survived')


特徴量をカテゴリー変数と数値に分けてる。カテゴリー変数はOne-hot Encodingへ。

fc = tf.feature_column
CATEGORICAL_COLUMNS = ['sex', 'n_siblings_spouses', 'parch', 'class', 'deck', 'embark_town', 'alone']
NUMERIC_COLUMNS = ['age', 'fare']
  
def one_hot_cat_column(feature_name, vocab):
  return fc.indicator_column(
      fc.categorical_column_with_vocabulary_list(feature_name,vocab))

feature_columns = []
for feature_name in CATEGORICAL_COLUMNS:
  # Need to one-hot encode categorical features.
  vocabulary = dftrain[feature_name].unique()
  feature_columns.append(one_hot_cat_column(feature_name, vocabulary))
  
for feature_name in NUMERIC_COLUMNS:
  feature_columns.append(fc.numeric_column(feature_name,dtype=tf.float32))

 

入力するときの関数作るの慣れてない…。ここがscikit-learnとは違うところ。

NUM_EXAMPLES = len(y_train)

def make_input_fn(X, y, n_epochs=None, shuffle=True):
  def input_fn():
    dataset = tf.data.Dataset.from_tensor_slices((dict(X), y))
    if shuffle:
      dataset = dataset.shuffle(NUM_EXAMPLES)
    # For training, cycle thru dataset as many times as need (n_epochs=None).    
    dataset = dataset.repeat(n_epochs)
    # In memory training doesn't use batching.
    dataset = dataset.batch(NUM_EXAMPLES)
    return dataset
  return input_fn

# Training and evaluation input functions.
train_input_fn = make_input_fn(dftrain, y_train)
eval_input_fn = make_input_fn(dfeval, y_eval, shuffle=False, n_epochs=1)


後は、パラメータ設定して動かすだけ!

params = {
    "n_trees": 50,
    "max_depth": 3,
    "n_batches_per_layer": 1,
    "center_bias": True
}

est = tf.estimator.BoostedTreesClassifier(feature_columns, **params)

# The model will stop training once the specified number of trees is built, not 
# based on the number of steps.
est.train(train_input_fn, max_steps=100)

# Eval.
result = est.evaluate(eval_input_fn)
print(pd.Series(result))

結果として以下のものが出力されます。

accuracy                  0.803030
accuracy_baseline         0.625000
auc                       0.862504
auc_precision_recall      0.836979
average_loss              0.424687
global_step             100.000000
label/mean                0.375000
loss                      0.424687
precision                 0.752688
prediction/mean           0.387544
recall                    0.707071

 

特徴量の寄与度を可視化する。

import matplotlib.pyplot as plt
import seaborn as sns
sns_colors = sns.color_palette("colorblind")

importances = est.experimental_feature_importances(normalize=True)
df_imp = pd.Series(importances)

N = 8
ax = (df_imp.iloc[0:N][::-1].plot(kind='barh',color=sns_colors[0],title='feature importances',figsize=(10, 6)))
ax.grid(False, axis='y')

 

よく見かける特徴量の重要度を可視化したものが表示されます。

f:id:gadada:20190315224316p:plain

 

GitHubのチュートリアルページには各サンプル、今回の場合は人ごとに特徴量の寄与度を表示させていて勉強になりました。面白い。これは別にTensorFlowに限った話ではないみたいで、scikit-learnでもできるらしい。知らなかった…。何千、何万ものデータを扱っていたらひとつひとつ見ていくことはできないと思うので、どういう時にこれは使うのかなとは思いました。

 

f:id:gadada:20190315224546p:plain

 

GitHubのチュートリアルページ(プロット図はここから引用)

https://github.com/tensorflow/docs/blob/master/site/en/r2/tutorials/estimators/boosted_trees_model_understanding.ipynb

TensorFlowのドキュメントhttps://www.tensorflow.org/versions/r2.0/api_docs/python/tf/estimator/BoostedTreesClassifier

 

スマホのSDカードに保存されている写真・動画のみをGoogleフォトに同期させないようにする

「SDカードに保存されている写真・動画のみをGoogleフォトに同期させないようにする」というほとんど需要がないかもしれないマニアック(?)な情報をまとめておきます。

 

最近、GoProで動画を撮るのにハマっているのですが、さすがに動画は容量が大きくてGoogleフォトに同期しているとすぐに無料で使える保存容量をオーバーしてしまいそうです。そこで、GoProで撮影した動画を一時的にスマホに保存しておきたいときにはmicroSDカードに保存するようにしています。ですが、microSDカードの写真・動画のみをGoogleフォトと非同期にするのに少し苦労しました。

 

まずはじめに

Googleフォトは、スマホ内の「DCIM」(Digital Camera Imagesの略らしい。)というフォルダに保存されている写真や動画を「カメラ」フォルダだと認識しているようです。たぶん。そして撮った写真や動画はこの「DCIM」に保存されます。これはSDカードの場合も同じで、「DCIM」というフォルダが作られてここに写真や動画が保存されます。

 

つまり何もしないと、スマホ本体(内部ストレージ)の「DCIM」フォルダもSDカードの「DCIM」フォルダも同じ「カメラ」フォルダだと認識されてしまうので、SDカードに保存されている写真や動画だけをGoogleフォトに非同期するというのはできないのです。(「カメラ」フォルダ全体の同期オンオフ設定はできます。)

 

SDカード内に「DCIM」とは別のフォルダを作れば解決

スマホで新しいフォルダを作ったり、別のフォルダに移動したりする機会ってほとんどないですよね。僕も普段することはなかったのですが、Google「Files by Google」というアプリを使うと簡単にできました。


Files by Google: Clean up space on your phone - Apps on Google Play
play.google.com

 

このアプリけっこう便利で、空き容量を確保するために削除するべきいらんファイル(ジャンクファイル)を提案してくれたり、使っていないアプリを削除したらどうですか?と言ってくれたりするんです。Googleが出しているという安心感もあります。

 

アプリを開くと、「見る」「ストレージデバイス」に内部ストレージとSDカードが表示されていると思います。SDカードを選択して中身を見てみると「DCIM」フォルダがあるのでこの中のファイルやフォルダを別のフォルダに移動させたり、「新しいフォルダを追加」して移動されたりすれば、完了です。

f:id:gadada:20190225235543j:plain
f:id:gadada:20190225235540j:plain
どちらも「Files by Google」アプリのスクショ

 

左下の画像は、「Files by Google」アプリでSDカード内に新しいフォルダ「gopro」が作られたスクショです。Googleフォトを起動して「端末のフォルダ」から「バックアップと同期」のオンオフを設定することができます(右下の画像)。

f:id:gadada:20190225235547j:plain
f:id:gadada:20190225235552j:plain
左は「Files by Google」、右は「Googleフォト」

 

最後に

以上です。「SDカードに保存されている写真・動画をGoogleフォトに同期させないようにする」方法をまとめました。Googleフォトに同期させるさせないは別にしても、スマホ内でのフォルダの作成や編集に「Files by Google」アプリは便利なのでおすすめです。

 

ではでは。少しでもこの記事が参考になれば嬉しいです!

 

動画を保存するために外付けハードディスクが欲しいなと思っている今日この頃。

 

AtCoderはじめました。「AtCoder Beginner Contest 118」の結果!

どうも、こんにちは。あさです。ブログを更新するのめちゃくちゃ久しぶりですね。はてな様から「お元気ですか?」とメールをいただくほど(つまり1ヶ月以上)更新をしていなかったわけですが、それなりに元気です。

 

KaggleやSIGNATEに参加したり、論文や技術書を読んだり、大学のテストがあったり、なにかと忙しい日々を送っていました。それにともなって、ブログ更新の意欲があまり湧いてこなくて記事を書けていませんでした…。

 

でも今日は書きます!急に書きたくなったので!何についてかというと、プログラミングコンテストのAtCoderに初参加してみたので、簡単にまとめておこうと思います。

 

AtCoderとは?

先日少し話題になっていたこちらの記事がAtCoderの問題やレベル分けなどについて詳しく書かれています。

chokudai.hatenablog.com

 

「AtCoder Beginner Contest 118」の結果

2月16日に行われた「AtCoder Beginner Contest 118」に参加して2問正解できました!コンテスト開始の2時間ぐらい前に急いでユーザー登録をして、とりあえず一番最初のチュートリアルをして挑みました(この時に、標準入力はinput()で受け取れるということを知った…。明らかに準備不足!)。

 

初心者向けだからもっと簡単なのかと勝手に思ってましたが(←いやいや過去問見ておけよ!)、C問題とD問題はさっぱりわかりませんでした。まだまだ時間は残っていたのですが途中で試合放棄…。

 

参考までに僕が書いたコードを載せておきます。まだまだ全然きれいなコードとは言えないですし無駄も多いです。

(問題はこちらから。https://atcoder.jp/contests/abc118/tasks

 

A問題

a, b = input().split()
a, b = int(a), int(b)
if b % a == 0:
  print(a + b)
else:
  print(b - a)

 

B問題

people, foods = input().split()
people, foods = int(people), int(foods)
 
all_like = []
for i in range(people):
  a = input().split()
  num = int(a[0])
  like_str = a[1:]
  like = [int(j) for j in like_str]
  all_like += like
 
output = 0
for food in range(foods):
  if all_like.count(food+1) == people:
    output += 1

 

これから復習します。ちなみにプロフィールページはこんな感じになりました。

f:id:gadada:20190218204510p:plain

 

最後に

時間を意識して頭を動かしたりプログラムを書いたりすることが普段はほとんど無かったので新鮮でしたし、楽しめました。これからもぼちぼちやっていこうかなと思います。

 

あまり周りと順位などを比べすぎると僕の場合は消耗してしまうことが最近分かったので、KaggleやSIGNATE、AtCoderとは適度な距離感を持ちながら、自分のペースで進めていけたらなと思っています。

 

やっぱりAnaconda便利すぎやろと思ったのでメモ(TensorflowとOpenCVのインストール)

Anacondaがめちゃくちゃ便利だったのでメモ。以前からAnacondaは使っていたのですがどんどん便利になっている模様。環境構築がスムーズに進みすぎて嬉しくなったのでここでまとめておきます。(Anaconda自体はこちらからダウンロードできます:https://www.anaconda.com/download/

 

AnacondaでTensorflow(GPU)をインストール

GPU環境にTensorflowをインストールする場合は、CUDAとcuDNNをインストールしてからTensorflowをインストールする必要がありました。僕も一度これやったことがあるのですが、バージョン確認が面倒であったりいろいろエラーが出たりして、かなり時間がかかったのを覚えています(数時間?というか数日間かかった気がする…)。

 

それがAnacondaを使ってめちゃくちゃ楽にインストールできるようになっていました。以前Twitterで知って、先日実際に試してみる機会があったのですが、conda install tensorflow-gpuとするだけで適切なバージョンのCUDAとcuDNNが自動的にインストールされます!これほんとにめちゃくちゃ便利ですごかった…!

 

ちなみに、condaで仮想環境を作ってインストールしたい場合は、conda create -n tensorflow_gpuenv tensorflow-gpuとしたらいいようです。また、NVIDIA driverは自分でインストールしておく必要があります。

 

詳細:https://www.anaconda.com/blog/developer-blog/tensorflow-in-anaconda/


 

conda-forgeでOpenCVをインストール

conda install opencvとしたらOpenCVがインストールされるのですが、Ubuntu環境ではなぜか動画を扱うことができなくて困っていました(cv2.VideoCaptureが動いていなかった。Windowsではこれで上手くいって動画も読み込めるのですが…)。ffmpegがどうとかlibv4lがどうとか書かれていたのですが、いじってみても解決しないし…。

 

いろいろと調べているうちにconda install -c conda-forge opencvとすれば良いという情報にたどりつき、これでUbuntu環境でも動画を読み込めるようになりました。めでたしめでたし。(うまくいったのはいいのですが、ところでconda-forgeってなんやろう…?)

 

詳細:https://anaconda.org/conda-forge/opencv

 

まとめ

ほんと便利になっているなあと思うこの頃です。AnacondaでのTensorflow(GPU)とOpenCVのインストールについて、忘れないようにブログにまとめておきました!

 

2018年の振り返りと2019年の抱負

2018年の年末には一年を振り返った記事でも書こうかなと思っていたのですが気づけば年が明けて2019年になっており、正月には今年の目標でも書こうかなと思っていたら早くも1月9日になっていました。あけましておめでとうございます。せっかくなので昨年の振り返りや今年したいことを少し書きたいなと思います。ちょうどはてなブログの今週のお題も「2019年の抱負」ですしね。

 

2018年を振り返ってみる

ブログを始めた。

昨年の2月ごろにこのブログを始めました。初めて読者になってくださる方がおられたり、Twitterでシェアしていただいたり、はてなブックマークのエントリーに載ったり、そしてGoogle AdSenseに合格したり、いろんな出来事があっていろんなことが学べました。

 

www.asanohatake.com

 

ブログを始めた当初は職業としてのブロガーへの憧れも少しはありました。好きなことについて記事を書いてお金がもらえるなんてすごいなーと。ですが、最近はそんな気持ちは消えてしまって、情報を発信したり考えをまとめたりするのって大切やなという思いが強いです。まあ、ブログ書いてもほとんどお金は稼げませんしね(笑)。というわけで、今年はもっと「こういうことしましたー」「こういうもの作りましたー」のような日記みたいな記事が増えるかもです。

 

プログラミングの勉強を始めた。

これも同じく2月頃。きっかけはあんまり覚えていないのですが、今輝いている人って子どものころにプログラミングをしていた人たちばっかりやん、と思ったからのような気がします。堀江貴文さんの本を読んだからかもしれません。勝手に期待しすぎていた大学の授業にがっかりして、自分で何か勉強したいなと思っていたからかもしれません。そうこうしてプログラミングの勉強を始めました。ランニングが趣味なので「市民ランナー専用のTwitterのようなSNS」を作ってみたいなと思ってRubyの勉強を始めたのです。

 

ディープラーニングの勉強を始めた。

4月の終わりごろからディープラーニングの勉強を始めました。Rubyの勉強を始めたものの、Ruby on Railsの勉強もしないとアプリが作れないことを知り、もういいっかってなってしまった…。そんな時、「AIやばいな。面白そうやな。」と思ってディープラーニングの勉強を始めることにしました。5月の終わりごろには自分で画像認識をしていたようなので、Pythonで深層学習のことを勉強するのにかなり熱中していたようです。

 

www.asanohatake.com

 

www.asanohatake.com

 

機械学習や統計学を勉強するようになった。

これが10月頃。ディープラーニングで画像認識できるようになったのはいいけど、背景知識は全然ないし、ディープラーニングって解析手法の一つでしかないから基本的なことや理論部分の勉強をしっかりしたいなと思いました。だからディープラーニング以外の機械学習の手法についてや統計学の勉強をし始めました。統計学を学ぶついでにR言語も勉強しました。データサイエンティストってかっこいいなと思い始めたのもこのころかな?全然覚えてない(笑)。

 

データ分析コンペに参加し始めた。

12月。KaggleやSIGNATEといったデータサイエンスのコンペティションが楽しそうだったので、これらに取り組み始めました。といってもまだまだ結果は全然出せてなくて参加しているだけなので、今年は上位に食い込みたいなーと思っちゃったり…。

 

www.asanohatake.com

 

以上、2018年のまとめでした!

え、夏ごろ何してたん?って感じですが、あんまり覚えてないので大したイベントは無かったのだと思います。(あ、そう言えば、大学の実習で北海道に行って山に入ってました。)ほんと2018年はいろんなことできてそれなりに充実してたんじゃないかなと思います。一年前には「Python」を何て読むかもわかっていなかったど素人がそこそこできるようになったのですから、プログラミングってやればできるんやな!って感じですよね。

 

2019年はどんな年にしようかな

2017年の終わりごろから「ITってやばいな!」「プログラミングってやばいな」「じんこうちのうぅぅ~~!?」ってなって(←語彙力無さすぎ…。でも情報科学っていう分野があることも知らなかったぐらい何も知らなかったので…。)、2018年からは自分でプログラミング勉強してブログでちょっと発信したりもして、そして迎える2019年。4月からはついに4回生になるので、大学卒業後のこともちゃんと考えないといけなくなります。 多少の不安はありますが、焦りはなくて、もっと研究したいなーと思ったら大学院に進学するし、会社でデータ分析とかしたいなーと思ったら就職するし、何も思わなかったら「ギャップイヤーです!」って言いながらいろんなこと経験してみるのもありかななんて思っています。(でも家にはお金ないから最悪バイトしないといけないけど、妥協して我慢したら働くとこはあると思ってる。)数年前まで真面目腐っていた人間がこんな楽観的になってどうしたって感じですが、いつの間にかこうなっちゃいました。

 

2019年の目標

12カ月も先のことなんて想像できないので、とりあえず最近興味があることやしたいことを書いておきます。

  • 画像認識の勉強をもっとして衛星画像の解析をする。衛星画像の精度ってどんどん上がっているし、ディープラーニングとか画像解析の技術もどんどん進んでいっているから、こういった分野の研究したい。
  • やっぱりデータサイエンティストかっこいい。会社でデータ分析するってどんな感じなのかわからないので、インターンしてみる。今後の進路を考える上でもデータ分析の仕事を経験しておきたい。
  • 組み込み系のエンジニアかっこいい。最近ハードへの興味がどんどん増えています。なんかよくわからんけど、ロボットとかセンサー(Kinectとか?)すごそうやし、ラズパイも触ってみたいし、「IoTすげー」って思うのでこのへんも勉強したいなと思います。

 

こんな感じですね。統計モデリングの勉強するとか、動画編集できるようになるとか、他にもしたいことはあります。「え、あんたほんまに大学生?」って言われそうですが、気にせずやっていきます。そらもちろん、いろんなとこ旅行行きたいし、おいしいものいっぱい食べたいし、いい出会いがあればいいなーとも思うし、、、でも時間もお金も限られてて優先順位を考えると上に書いたようなことになっちゃうんです。はい。

 

今年もなんやかんや楽しむ

失敗してもいいし、成功したらもちろんいいし、柔軟にいろんなことに取り組んでいきたい。そんな一年にします。自分のために全部の時間を使えるのってそうそう無いやろうし、今年できることは今年します。とかいいつつ疲れたら休むし、休みの日は昼まで寝てるかもしれないけど(笑)。

 

新年あけましておめでとうございます、ということで遅くなりましたが昨年の振り返りと今年の抱負をまとめてみました。言葉にするのって大切なのかな?と思ったので。もうすぐ3000字になっちゃいます。もし読んでくださった方がおられましたらありがとうございました。長いのに内容スカスカなのに本当に感謝です。(そう言えば3000字のレポートの提出期限が迫っていることを思い出しました。はやく書かないと!)

 

Google様からお手紙が届きました。もしやこれはクリスマスプレゼントか…!

12月25日、なんとあのGoogle様からお手紙が送られてきました!

 

f:id:gadada:20181225161646j:plain

 

Googleアドセンスに関するもので、「住所確認のための識別番号」が送られてきたのです。Googleアドセンスでは、収益が基準額である1000円に達すると、「住所確認」と「お支払い方法選択」をするという手順になっています。

 

僕のブログ(当ブログ)では、以下の記事でも書いている通り2018年10月の初めにGoogleアドセンスに承認されました。そして11月の中旬には収益が1000円に達し、11月24日に識別番号を自宅に発送するとの連絡がありました。

 

www.asanohatake.com

 

それがついにクリスマスの12月25日に届いたというわけです。「2~4週間で届く」と書かれているのに、なかなか届かないこともあるようで不安でしたが、なんとか1カ月ぐらいで届いて良かったです。届いてからの作業は簡単で、書かれている識別番号をアドセンスの設定画面に入力するだけでした。

 

お支払い基準額は8000円なので、まだまだ実際に収益を受け取るまでには時間がかかりそうですが、ぼちぼち頑張っていこうかなと思っています。

 

Kaggleの日本版「SIGNATE」に初参戦。国立公園の観光宿泊者数予測コンペで124人中29位でした…。

12月13日まで日本のデータサイエンスコンペティションであるSIGNATEの「国立公園の観光宿泊者数予測」のコンペに参加していました。10月の終わりごろからこのコンペは開催されていたようですが、僕が参加したのは12月7日でかなり遅かったので締め切りまでの1週間は家でも学校でもこのコンペのことばかり考えていました。

 

この記事でKaggleという機械学習コンペを始めた!と書いているのですが、登録したもののどうしたらいいのかさっぱりわからなくて手つかずの状態でした…。

www.asanohatake.com

 

そんなときに見つけたのが「SIGNATE」という日本のデータ分析のコンペ。そしてちょうど「国立公園の観光宿泊者数予測」のコンペが開催されていたので挑戦してみたわけです。

f:id:gadada:20181216180800j:plain

 

結果は124人中29位!

初めてのコンペで、データの前処理の仕方とか時系列データの扱い方とかモデルの選択についてとか全くわからなかったので、めちゃくちゃ調べまくりました。そしてなんとか予測して投稿して124人中29位という結果でした。全然わかっていないにしてはまずまずかな?という感じです。(でもほんとはもっと上位にくいこみたかった…。)

f:id:gadada:20181216180757j:plain

 

感想

データの前処理が8割っていうのは本当だった…

よく、「データ分析の8割はデータの前処理だ。」的なことを耳にしていたのですが、これは本当でした。モデルは、「とりあえずランダムフォレストにしてみるか」、「なんかみんなXGBoost使ってるし使ってみよかな」とあまり考えなくても何とかなったのですが…(いや、なんとかなってないのかな、、、?)。データについては、どれをどのようにして使うのかを全部自分で考えないといけなかったので難しかったです。でも試行錯誤しているうちにデータの可視化の方法やプログラミングのスキルもかなり成長したと思うので良かったです。

 

とりあえず自己流でいくしかなかった(笑)

SNSのデータとか、路線データとか、気象データとか、いろんな種類のデータが提供されていてどれをどのように使ったらいいのか全く分かりませんでした。でも、「宿泊者数なんて土日と連休に一番左右されるんや!」と信じて、とりあえず曜日、祝日、長期休暇など僕が個人的に大事だと思った要因を考えてモデルを作りました。だから提供されたデータはほとんど使えてない、、、(泣)。使い方教えてください。時系列データの扱い方も知りたいです…。

 

Kaggleとは違って、公式サイトでの他の参加者との交流が全くないので、そこは残念でした。上位に入賞されている方々の分析手法を知れたらもっと勉強になるのになと思いました。

 

クロスバリデーションをたぶん間違えていた…

はじめは、train_test_splitでトレインデータとバリデーションデータに分けてから、そのトレインデータに対してcross_val_scoreでクロスバリデーションを行っていました。でもよく考えたら分ける前のデータに対してクロスバリデーションを行わないとちゃんとした汎化性能が測れないんじゃないかと思って…。結局、分ける前のデータに対してクロスバリデーションを行いました。

 

じゃあ学習はどのセットを使えばいいのかっていう疑問がでてきて、さっぱりわからなくなりました。ここらへんは今からちゃんと勉強します。たぶんこのへんの勉強不足によってちょっともったいないことをしてしまったのかなと思います。

f:id:gadada:20181216202327j:plain

 

選択するファイルを別のものしていたら順位が10位ぐらい上がったと考えると本当にもったいない。もちろん最終評価を完璧に予測することは誰にもできないので、こういった悔しさを感じられている方は他にもおられるかもしれませんが…。

 

データ分析は楽しい!

よくわからないことが本当にあって、知識も経験も何もかもが不足しているなと痛感した初コンペでした。でもデータ分析自体はめちゃくちゃ楽しかった!寝食を忘れて、、、というほどではありませんが、大学の課題は忘れて没頭していました。

 

もっと精度良く予測できるようになったり、データを自由自在に操れるようになったりしたら、もっともっと楽しくなると思うので、自由に使える時間が多い大学生のうちにもっともっともっと勉強しようと思いました!Kaggleも頑張ります。

 

他の参加者の方々がどのように分析されているのか知りたいです!!!

 

我が家にドローンがやってきた!【DJIのトイドローンTello購入】

ドローン買いました!

https://twitter.com/asa_gadada/status/1068820136046415872

 

「ドローン買ったわ。」

 

「…。」

「は?」

「どういうつもりなん?」

 

とまあ、家族はこういう反応でして…。これは想定内ですので、だいだい僕はいつも事後報告。今回もAmazonで注文してから「買った。明日届くし。」という感じです。

 

こんな話はどうでもよくて、ついにドローンを買っちゃったのです!ドローンを使った業務の効率化がなされたり、撮影に使われたり、ドローンレースの世界大会が開催されたり、とここ数年かなり普及していますので今さらな感じもしますが、嬉しいのでとりあえずブログに書こうか!ってことで書きます。

 

買ったのは、DJIの「Tello」というトイドローン

 

公式のページはこちらです。

https://www.ryzerobotics.com/jp/tello?utm_source=dji&utm_medium=store&utm_campaign=product_page

 

簡単にスペックをまとめると…

  • 重量:約80g
  • サイズ:98×92.5×41mm
  • 最大飛距離:100m
  • 最大飛行時間:13分
  • 最大飛行高度:10m
  • 写真・動画撮影可

といった感じ。

 

約1万円で買えるドローンとしては性能が良くて、かなりコスパが良いらしいです。スマホアプリで操作ができるので、直感的な操作で飛ばせるのもいいなと思いました。80gなので「航空法」によって規制されないこともいいところです。

 

届いた!開けた!飛ばした!

届いた!

f:id:gadada:20181202201321j:plain

 

さっそく開けてみる!

f:id:gadada:20181202201308j:plain

 

入っているもの!

f:id:gadada:20181202201256j:plain

 

左から、機体、フライトバッテリー、スペアプロペラ、プロペラ取り外しツール、マニュアルです。送信機みたいなのは必要ではなくて、スマホのアプリで操作します。

 

注意する点は、充電ケーブルがついてこないこと!でも、Micro USB充電ポートで充電するので、多くの人は持っていると思います。 ちなみにバッテリーを本体に装着した状態のまま充電します。

 

さあ機体を取り出してみよう!

f:id:gadada:20181202201225j:plain

f:id:gadada:20181202201240j:plain

 

いやいや、待って、かわいすぎるやん!!!

 

めっちゃ気に入った!!!笑

 

さてさて、飛ばしてみました。

 

感想

  • 動きが俊敏でなかなか操作が難しい。
  • プロペラガードがあるので部屋の壁に当たっても大丈夫なのは嬉しい。
  • とはいっても、激しくぶつかると墜落する。そしてバッテリーが飛び出した(笑)。もちろん部屋の中で墜落したぐらいでは壊れないので安心です。
  • 音がうるさいと家族からの文句が飛んでくる。でも家族も興味津々。
  • そして楽しすぎる!!!

 

ついでにYouTubeのチャンネル作ったので、飛び立つ瞬間だけ載せておきます。

 

 

ドローンレーサーになろかな、、、

 

『0才から100才まで学び続けなくてはならない時代を生きる 学ぶ人と育てる人のための教科書』(落合陽一)を読んで考えた

f:id:gadada:20181129091742j:plain

落合陽一さんの最新刊『0才から100才まで学び続けなくてはならない時代を生きる 学ぶ人と育てる人のための教科書』(略して「ゼロヒャク教科書」)をさっそく読みました。落合さんの今までの本とは違ってめちゃくちゃ読み進めやすく、子どもから大人まで幅広い世代におすすめの本でした。

 

 

「ゼロヒャク教科書」の内容紹介

簡単に内容をまとめます。

これまでは、受験戦争に勝ち抜いて、偏差値の高い大学に入学し、一流といわれる大企業に就職することで、高年収のレールに乗ってしまえば安泰という人生のロールモデルがありましたが、現在は法人よりも個人の寿命のほうが長い時代です。これまでのような人生計画は、長さにおいても働き方においても意味をなさない時代になると思います。

と、プロローグにあるように、大きく変わりつつある時代において重要になってくる「学び方」を再定義していく本です。

 

以下の3章から構成されています。

 

第1章 Q&A・幼児教育から生涯教育まで「なぜ学ばなければならないか」

第2章 落合陽一はこう作られた・どんな教育を選び、どう進んで来たか、生成過程

第3章 学び方の実践例・「STEAM教育」時代に身につけておくべき4つの要素

 

第1章では、

・「なぜ学校に行かないといけないの?」と言われたら?

・幼児教育は何から始めればいい?

・これから大学はどう選べばよいですか?

・突出した才能がない人はどう生きていけばいい?

・人生100年時代を生き残るには何をしたらいい?

といった13個の質問に対して答えていくという形式です。その中で、「幼稚園より、仕事場を見せて子供の世界の外側を経験させる」「相手の佇まいを判断する能力を鍛えよう」といった印象的な考えが述べられていました。

 

一方、第2章では、幼少期から今まで落合さんがどのようなことを学んできたか、どのようなことに夢中になってきたかが語られています。そして第3章で、STEAM教育においては、言語・物理・数学・アートの4つの要素を学ぶことが大事だと言われていました。数学をコンピューターサイエンスやデータサイエンスの基礎として学ぶことの必要性も述べられていますが、それは僕自身が最近とても実感していますし、高校の時の数学の学び方も今から思うともっと別の方法があったのでは?なんて考えていたので共感できる部分が多かったです。

 

大学生の僕が読んで思ったこと

プログラミングの早期教育の必要性について

第1章で、「プログラミングの早期教育は必要ですか?」という問いに対すて「プログラミング学習が目的化されてしまっては無意味です」答えられています。これはその通りだと思います。そして、「プログラミングのスタートが早い人より、数学ができる人が有利」とも言われています。

 

これに関しては少し疑問があります。確かに、小学生の時から本気でプログラミングの勉強をする必要はないと思いますが、中学校や高校でプログラミングを学ぶのはかなりのアドバンテージだと思うのです。もちろん数学の勉強も大切なのはわかりますが、プログラミングができる状態で大学に入学すると圧倒的に世界が変わるのではないでしょうか。プログラミングができる状態で大学に入学すると、例えば、ITベンチャー企業でインターンをしたり自分で事業を立ち上げたり、大学の自由な時間を有意義に使える学生になります。僕は、大学2年の終わりからプログラミングの勉強を始めましたが、もっと早くから勉強していたら良かったなーと思うこともあるので…。

 

これからの大学での学び

キャリアを考える上では、学費の安い国立大学に入って基礎を学びながら、オンライン講座で国内外問わず有名なスター教授に学ぶ、というやり方が学部生にはお得かもしれません。

これに関しては、「なるほどなー!!」と思いました。どちらもの良い点を取り入れつつ学んでいくことができるかが大事なんですね。ちなみに、「大学は人材の専門性を保証し認定する機能のほうが現状強い」と書かれていましたが、これは「修士」や「博士」という肩書きを手に入れることが研究をしていく上では必要だということにつながるのでしょうか…。海外では、博士を持っていないと話にならないなんてことを聞きますが、やはり研究の世界ではまだまだこうした「肩書き」があるかないかが重要なんですね。

 

今までしてこなかった鑑賞教育

今までの日本のアート教育は、技術教育ばかりで鑑賞教育をあまりしてこなかった、と述べられていました。本当にそうで、以前落合さんがNewsPicksの番組で「鑑賞教育が大事だ」とおしゃっていたのを聞いても、僕なんかは「具体的にどうやったらいいんやろ!?」とさっぱりわかりませんでした。

 

鑑賞教育について結論を言うと、「作品を見たときに、「こう感じた」「こう思った」と言葉で説明できることが大事」だということです。「鑑賞とは知識を披露することではない」とも言われています。僕は、知識が必ず必要とばかり思っていたので、ハッとさせられました。正解があるんだと思わずに、自分が思ったことに素直になることが大事なんだなと思いました。まあ、これが難しいんですけど…。だから教育が必要というわけですね。

 

まとめ

非常に読みやすい本でしたし、この本を読んだ上でいろいろな議論が起こるのがいいのかなと思いました。落合さんも、特に大学受験のあり方に関しては議論を重ねていくことが大事だとおしゃっていますしね。

 

 

落合さんの著書の中では、『10年後の仕事図鑑』もこれからの時代での働き方や生き方を考える上で勉強になりました。

www.asanohatake.com

 

Python, OpenCVを用いて動画を画像へ変換する(動画から画像の切り出し)

基本的なことではありますが、「PythonとOpenCVを用いた動画から画像への変換」についてまとめておきます。フレームごとの画像への変換と、指定した間隔ごとの画像への変換をまとめます。

 

動画のプロパティを取得する

まずは動画のプロパティを取得しておきます。フレームの幅と高さ、総フレーム数、fpsを調べます。fpsとは、frames per secondの略で、「1秒あたりのフレーム数(静止画像数)」を表します。

 

import cv2

video_path = "動画のパス"
cap = cv2.VideoCapture(video_path)

# 幅
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
# 高さ
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
# 総フレーム数
count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
# fps
fps = cap.get(cv2.CAP_PROP_FPS)

print("width:{}, height:{}, count:{}, fps:{}".format(width,height,count,fps))

 

動画から画像への変換(フレームごと)

ファイルから動画を読み込み、1フレームごとに処理ができるようにして、それぞれを順に画像として保存する、という流れです。

 

import cv2

video_path = "動画のパス"
cap = cv2.VideoCapture(video_path)

num = 0
while(cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        cv2.imwrite("picture{:0=3}".format(num)+".jpg",frame)
        print("save picture{:0=3}".format(num)+".jpg")
        num += 1
    else:
        break

cap.release()

 

動画から画像への変換(フレーム指定、時間指定)

続いて、1フレームごとではなくて、もっと間隔をあけて画像として保存したい場合の方法です。

 

本当は1秒ごとに画像として保存したいなあと思っていたのですが、調べてもよくわからなくて、フレーム数を指定することで「1秒ごとっぽい」間隔で保存してみました。

 

以下のコードで、動画の1フレーム目からfpsごとに画像として保存することができます。fps(=frames per second、1秒当たりのフレーム数)ごとなので、ほぼ1秒ごとと言ってもいいのですが、これが整数でない場合は「ずれ」が生じてしまいます。

 

ちなみに参考までに、1フレーム目からではなくて途中から指定することもできますし、間隔もfpsごとではなくて、例えば3フレームごとなどといった指定も可能です。

 

import cv2

video_path = "動画のパス"
cap = cv2.VideoCapture(video_path)

count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
fps = cap.get(cv2.CAP_PROP_FPS)

print("width:{}, height:{}, count:{}, fps:{}".format(width,height,count,fps))

for num in range(1, int(count), int(fps)):
    cap.set(cv2.CAP_PROP_POS_FRAMES, num)
    cv2.imwrite("picture{:0=3}".format(int((num-1)/int(fps)))+".jpg", cap.read()[1])
    print("save picture{:0=3}".format(int((num-1)/int(fps)))+".jpg")

cap.release()

 

まとめ

ちょっとOpenCVで動画をあつかう機会があったのでまとめておきました。本当はフレーム指定ではなくて、1秒ごとといった時間を指定して画像として保存したかったのですが、わからなかったのでとりあえずフレーム数でなんとかしました。ただ、よく考えてみるとわざわざ1秒ごとといった時間で指定する必要性もないような気もしてきましたが…。

 

参考

動画を扱う — OpenCV-Python Tutorials 1 documentation

OpenCV: Flags for video I/O

 

「Kaggle」始めました。

ついに、Kaggle始めました!

 

まあそんな大したことではないのですが、ずっと「始めよう!」って思っていてようやく登録しました。

 

Kaggle(カグル)は、データサイエンスや機械学習に関する世界規模のコンペティションです。誰でも参加することはできて、何と上位の人には賞金が出ちゃったり…。

 

f:id:gadada:20181105210109j:plain

 

ディープラーニング以外の機械学習についてはただいま勉強中なので、どこまでできるかわからないです。(そう、ディープラーニングネイティブです…。)

 

ディープラーニングを使った画像系の解析についてはそれなりに勉強しているので、当分の間は画像系のコンペティションを中心に参加してみたいなあと考えています。

 

画像系の解析については、実はこのブログでも少し発信しています。例えば、この辺の記事ですね。

www.asanohatake.com

www.asanohatake.com

 

賞金が欲しいとか上位に入りたいとかっていうのは(たぶん無理だけど)、あんまり思っていなくて、単純にデータ分析が好きなのと、経験値を上げたいなあと思って始めてみることにしました。

 

少し出遅れている感はあるかもしれませんが、まあ自分のペースでぼちぼち進めていこうかなという感じです。

 

そして、統計学の勉強にも最近ハマっているので、(いろいろ手を出しすぎて何がしたいのかわからないような気がするかもしれませんが、)そちらも続けていきたいなと思っています。

 

今日のブログ記事はこれでおしまい!

 

たまには内容がなくてもいいかなーなんて(笑)

 

はてなブログの公式アプリで記事を書くときに写真が貼れない事件解決

最近はよく、はてなブログのスマホアプリで記事を書くことが多いです。もちろんパソコンで最終的な細かい調整は行うので、パパーっととりあえずスマホで書いちゃう感じです。

 

スマホで書くのの何がいいかって、どこでもすぐに書けるのと、写真の貼り付けが楽なこと。ですがこの前、スマホで写真を貼り付けることができなかったのです…。

 

はてなブログのアプリで記事に写真を貼れなかった理由

1時間ぐらいいろいろいじってみて格闘しました。そして、ついに、判明しました。写真のサイズが問題だったのです。

 

はてなブログアプリの設定では、画像サイズを「オリジナル」「大」「中」「小」から選ぶことができます。「オリジナル」にしていたら貼れなかったのですが、「中」にしてみたらすんなり貼れました。

 

でも問題が…。

 

写真の画質がめちゃくちゃ悪いんです。

 

www.asanohatake.com

 

この記事の写真はすべてスマホから貼り付けていて、サイズは「中」です。例えば「阪急嵐山駅」という文字が何か変な感じになっていますよね。

f:id:gadada:20181103211657j:plain

 

じゃあサイズを「大」にしたらどうなるのか。

f:id:gadada:20181106205040j:image

 

もう一度「中」も見てみる。

f:id:gadada:20181106205208j:image

 

いちおう「小」も。

f:id:gadada:20181106205145j:image

 

この写真のもともとのサイズは、「4608px×3456px」です。はてなブログのアプリによると、大(1296px)、中(640px)、小(320px)となっています。

 

実際のところどうなっているのでしょうか。大が1296px972px、中が640px×480px、小が320px×240pxでした。つまり、既定の幅(横)に縦横比を保ったまま縮小しているということですね。

 

まとめ

今後は、サイズを「大」にしてスマホから写真を貼ろうと思います。やっぱり写真の貼り付けに関しては、圧倒的にスマホからのほうが楽なんですよね。「大」ならそこまで画質の悪さは気になりませんし…。

 

もしかしたら、スマホカメラの設定で解像度を少し下げればオリジナルサイズのままでも貼り付けることが可能なのかもしれませんね。でも写真はキレイに撮りたいわけで、わざわざブログのために、、解像度を、、、落とすなんて、、、、できない!

 

ということで、スマホからの画像の貼り付けについての記事でした。