ほろ酔い開発日誌

有意義な技術的Tipsを共有出来たら嬉しいです。Ruby、Railsが好きです。Web開発全般(Rails多め、フロント、サーバー、インフラ)、データ分析、機械学習あたりの記事が中心になる予定です。

Kaggle 「Allstate Claims Severity」を終えての振り返りと整理

約1ヶ月程の期間ちょこちょこ時間を使って、データ分析・データモデリングのコンペのプラットフォームであるKaggleで Allstate Claims Severityというコンペに挑戦しました。

www.kaggle.com

このようなコンペははじめてで学びだらけでした。今回の復習をして今後に活かしていきたいと思うところです。

目次

  1. コンペ期間に行ったこと
  2. 他の方の手法をきいて
  3. 次回以降のアプローチ
  4. おわりに

1. コンペ期間に行ったこと

はじめに順位は、676位 / 3055位 (Public LeaderBoard: 上位22.1%程度) でした。はじめてなのでそんなものですね。(ニューラルネット使えばもっと点数上がったのに時間的にやめておいたのが悔やまれる。。PCスペック低かったし仕方ないと言い訳しときます笑)

データセット

このコンペでは保険会社のデータが使われていて、データとしてはtrain dataが20万弱、test dataが10万強のサンプル数で、カラムはカテゴリカラムが116、数値カラムが14で目的変数であるlossが1つあるといった感じのデータセットです。 手頃な感じでやりやすいもののようです。(普通はもっとデータ量が多くてラップトップPCではきついものが多いようです。。)

Forum

コンペを進めていく上で重要だったのは Forumという意見交換の場を利用していくことでした。初心者からするとものすごい貴重な情報がたくさん載っています。戦略を立てる上でForumに載っている手法を真似して試していきました。

さて、Forumを眺めて点数が取れている手法はXgboostというGradient Boostingのライブラリを用いた手法とNeural Networkの手法(Kerasを用いたもの)でした。 そこで、ひとまずXgboostingの手法を試してみることにしました。

XGBoost のスクリプト

最初に試したのは以下のスクリプトでした。

https://www.kaggle.com/iglovikov/allstate-claims-severity/xgb-1114/code

こちらはxgboostのスクリプトでこれだけである程度の点数がとれます。 xgboost自体も使うのがはじめてだったので参考になりました。

ポイントとしては

  • カテゴリ変数がファクトライズされている(A->0、B->1、、のように数値化)
  • 目的変数を調整している (logを使ってるところ)
  • パラメータが調整されている
  • 評価関数をMAEに変更している(今回の評価関数がMAE)

といったところだと思います。すっきりしたスクリプトでしたが参考になるところは多かったです。これが今回のベースになりました。

パラメータの調整

次にパラメータを調整しようと思いました。

  • グリッドサーチ
  • ランダムサーチ
  • 手動で狙いうち

sklearn とかにも用意されていたり、hyperoptなるものも人気らしいです。 しかし、今回は使わなかったです。なぜかというと時間がかかりすぎると思ったからです。先程のサンプルのコードを1回まわすのに100分強の時間がかかっていたので例えばグリッドサーチなどをやるにしてもある程度どれくらいの値がいいかの感覚もないのできついです。(まだ新しいPC届く前でスペックが低く、実行中は他の作業も出来ない) ただ少しはやってみようと数個値を変えてやってみたところ、max_depthというパラメータをちょっと大きくすると精度があがりました。他は逆に下がるばかりでだめだめでした。 max_depthは木を深くすれば精度が上がるのはまあ当たり前だなーって感じで、むしろ実行時間が長くなってしまって今思うと微妙でした。このあたり、精度と時間のトレードオフも学びです。また、あとから聞いたのですが、このスクリプトはパラメータはある程度調整は出来ていてこれ以上のパラメータ調整はそんなに意味をなさなかったらしいです。

データの処理・加工

順番が前後したのですが、ここでデータがどうなってるかを考えました。(本来なら一番最初にやらなきゃいけないですが) まず、今回のデータセットは欠損値がないというミラクルが起きていたようです。欠損値があれば、そのサンプルは消すが他のサンプルの平均で穴埋めするかとかしないといけなかったです。

あと、カテゴリ変数はファクトライズ(A->0, B->1、、)してあったのですが、XGBoostの場合はこれで問題ないようです。モデルによってはonehot-encodingとかしないといけないのでちょっと困惑ポイントでした。直感的には木で分岐していくのでonehot-encodingじゃなくてもよいようです。

データ分析については以下の投稿が参考になりました。

https://www.kaggle.com/achalshah/allstate-claims-severity/allstate-feature-analysis-python

次元削除・特徴量作成

これ以上同一モデルで点数を上げるには特徴量をいじるしかないということで取り組むことにしました。

PCA

まず、やったのはPCA (主成分分析)という次元削除の手法を試してみました。PCAはざっくりいうと出来るだけ情報量を失わないように特徴量を減らす手法です。

今回は数値のデータが14つあるので、14->7に次元を削除してみました。それで予測を行うと点数が下がってしまいました。ただ、これは当たり前でそもそも情報量を落としているので基本的には点数は下がります。特徴を適当にいじれば点数上がるような感じでやってみてもダメですね。次元削除と特徴量を作ることは別ですね。次元を下げると計算量が少なくなるので今後効果的に使えるといいなと思います。

相関

それで次にloss(目的変数)と相関の高い特徴量を生み出すことに挑戦しました。今回のコンペのデータはカラムの名前に意味がなく全く手がかりがないので相関で考えることにしました。数値データのうちランダムに組み合わせて(足し合わせたり、logをとったり)相関が既存のカラムより高くなったものを新たな特徴量として追加しました。(大体20個くらい新しい特徴量が出来ました) しかし、逆に点数が下がってしまい失敗でした。

カテゴリデータの組み合わせ

Forumで上がっているもので点数が上がっている特徴量作成のやり方として、カテゴリデータを使ったものがありました。 任意の2つのカテゴリデータから1つの新たな特徴量を作成します。 例えば一方がAでもう片方がBならABというカラムが出来上がります。 その後に、数字にするのですがA、B、...、Z、AA、AB、...、AZ、BB、のような順に数をつけます。例えば、A->0、B->1、AA->27のような数です。

カテゴリデータは116個あるので全部使うと数が多すぎるので35個の特徴量を使いました。Forumに載ってるものをそのまま使いましたが、おそらくXGBoostのfeature importanceの上位35個を使ったものと思われます。feature importanceは分岐の使われた回数を示すらしいです。xgboostのライブラリ中のメソッドから簡単に順位を出すことが出来ます。

これは点数アップにつながりました。

アンサンブル

違うモデルを組み合わせると点数が上がるということでやってみようと思いました。本当はNearal Networkを使いたいところだったのですがまわす時間がなくて諦め、他のモデルも試さずにコンペが終わりそうだったので、とりあえず、XGBoostのいくつか試したものを加重平均してみました。これだけでも点数が上がったのでアンサンブルすごいなーと思いました。

2. 他の方の手法をきいて

コンペが終わってから、同じコンペに挑戦していた研究室の先輩のお話を聞いてとても参考になったのでまとめます。(今回のコンペの上位4%以内の方)

XGBoostのチューニング

今回はForumのスクリプトがパラメータのチューニングを行っていたのでもともといい感じにチューニングしてありました。実際のところはどのようにやればいいのかききました。

大体の感覚として以下のような感じらしいです。

eta: 0.3~0.01 (0.3はチューニング用で、0.01でトレーニングをやる)
Max depth: 6~12
Subsample: 0.5~1.0
Colsample: 0.25~0.7,0.8
Round: 100000 (Early stopping を利用)

randomサーチかマニュアルでパラメータを探すようです。Kaggleの上位者程、勘でパラメータを調整するらしいです。 今回調整したのは上記のパラメータの範囲で適当に試して決めたとのことです。 学習率はパラメータ調整のときは高めに設定して学習して100epochくらいまわして比較したみたいです。 僕はパラメータ調整のときも時間をかけてしまっていたので参考になりました。

ちなみに、Nearal NetworkのほうはForumに出てるスクリプトのunit数、epoch数を増やしたものを使ったとのこと。

目的変数変換や目的関数の重要性

今回の目的変数のlossは歪度が正で、右に裾が広がる形をしていました。これにlogを取ると正規分布に近いかたちになります。このあたりの調整はForumでは先人がやってくれていたので、今回は大丈夫でKaggleでは基本的に誰かが見つけてくれるようなのですが、もしこれに気づかないと勝負にならないので注意が必要だということです。また、今回の評価関数のMAEは2回微分までを用意出来ない形なので近似した関数を目的関数におきました。これも適切に設定することが大事のようです。テーラー展開とかを使って近似させることもあるようです。

このあたりは、Kaggleでは誰かが先にやってしまうので単純にこれによって点数差がつくことはほとんどないらしいのですが、上位を狙うためにはForumで共有される前段階で気づいて他の施策を行わないと時間的に勝てないみたいです。

特徴量作成 (XGBoost)

特徴量の作成方法としては、上記のカテゴリの組み合わせと同様のことをやっていたみたいです。

feature importanceの上位50個くらいをとってやったみたいです。さらに2つの組み合わせだけではなく、3つ、4つまで行ったとのことです。

それでどのカテゴリを組み合わせればよいかは以下のxgbfiというものを利用するとよいみたいです。

github.com

また、数値カラムも適当な組み合わせで+-×÷の四則演算を試したようですが点数には寄与しなかったみたいです。

カテゴリと数値のカラムも両方をカテゴリデータとして扱うか、療法を数値データとして扱うことで特徴量を作ることも出来るとのことでした。

アンサンブル

今回は加重平均を使ってXGBoostとNeural Networkをアンサンブルさせたとのことですが、もっと点数をあげるにはスタッキングというやり方を行うとよかったとのことです。

加重平均したモデルとしては、Neural Network 1つとXGBoost3つでした。その3つは違う特徴量によって作られたものです。

スタッキングは複数の分類器でtrainデータを用いて予測を出し、その結果をまとめて新たな特徴量にし、それを新たなモデルにかける手法です。

ちょっと面倒ですが精度は出るみたいです。

他の分類器

色々な分類器を試した(もしくは試したかった)ようです。例えば、

  • SVR
  • KNN
  • Xtra Trees
  • Random Forest
  • Liner Regression
  • Regularized Regression
  • Light GBM
  • Vowpal Wabbit

その他諸々、聞きたいことをことごとく聞けたので良かったです笑 今回のわからない部分を聞けたの一般論的な部分もちょっとわかった気がします。 それと上位に食い込むにはどうすれば良いかのイメージが出来ました。

3. 次回以降のアプローチ

ここはすごくざっくり。

まず、データを分析する。特に

  • データの基本情報を見る。(データ数、特徴量、相関、分布、など)
  • 欠損値がないか

とか。

XGBoostとNeural Networkのアンサンブルをやってみる。この2つである程度の精度は基本的に出るらしい。 目的変数、目的関数、評価関数はちゃんと考える。 epoch数少なめにパラメータ調整。

特徴量を考える。feature importanceとかxgbfiとか。特徴量の意味がわかる場合はそこから考える。

過去に終わったコンペですが、下記のコンペを復習も兼ねてやります。

www.kaggle.com

ちなみに、今回僕がやったコンペも期間は終わりましたが、サブミットして点数も返ってくるので挑戦出来ます。

Neural Networkのスクリプトは3日かかったよ、とも聞いたので根気強く待つのも大切ですね。(今回僕は1日まわしても終わらなくて諦めました)

あと、Forumに上位者がどういうことをやったかを共有してくれているので見ようと思います。

#1st Place Solution - Allstate Claims Severity | Kaggle

#2nd Place Solution - Allstate Claims Severity | Kaggle

Faron's 3rd Place Solution - Allstate Claims Severity | Kaggle

GIBA - #7 Place Solution - Allstate Claims Severity | Kaggle

#8 solution - Allstate Claims Severity | Kaggle

12th place solution - Allstate Claims Severity | Kaggle

#16 place solution and some questions about it. - Allstate Claims Severity | Kaggle

コンペが終わっても学びが多いです。

4. 終わりに

細かいことの説明はしていませんが、大まかにやったことをログとして書きました。学びが多かったので次に活かしたいです。 Forumなどを読んで理解を深めたいと思います。

また、学習したことは共有したいと思っています。

XGBoostをPythonで動かす on Mac

XGBoostは、Gradient Boostingのframeworkを提供してくれるライブラリです。Gradient Boostingは決定木のような弱学習機をアンサンブルする形態のモデルを生み出します。

高い精度が期待出来るためコンペでもよく登場するライブラリです。Deep Leaningより気軽に使えるところも嬉しいです。

Kaggleより: xgb 1114

今回はMacへのインストール方法をメモしておきます。

この内容はXGBoost Installation Guideに書いてあります。

Build

$ git clone --recursive https://github.com/dmlc/xgboost
$ cd xgboost; cp make/minimum.mk ./config.mk; make -j4

Package Installation

$ cd python-package; sudo python setup.py install

終わりに

ひとまずメモ程度にインストール方法を書いたので、今度もっと詳しいことを書くかもしれないです。

MacBookを購入後に最初に行う環境構築 (エンジニア向け)

f:id:seishin55:20161210145007j:plain

新しくMacBookを購入しました。初期設定を色々としないといけなかったので備忘録も兼ねて設定手順を書きます。

こういう設定は正解もないですし、あまり教わる機会もないので参考になればと思います。

初心者エンジニアの方でこれを真似してご自身のスタイルを模索してはいかがでしょうか。先輩エンジニアの皆さんには是非おすすめ設定等ありましたら教えて頂きたいです。また、少しでも参考になる部分があれば幸いです。

環境

  • MacBook Pro late 2016
  • OS: Sierra 10.12.1
  • USキーボード
  • Vimつかい

大きく上記環境に依存することはないと思いますが、部分的に差異が出る可能性があります。

目次

  • システム環境設定
  • Finder設定
  • homebrewの準備
  • zshの設定
  • アプリケーションのインストール
  • vimの設定
  • iTerm2の設定
  • gitの設定
  • PHPの環境構築
  • Rubyの環境構築
  • Pythonの環境構築

システム環境設定

デスクトップとスクリーンセーバ

  • デスクトップ: 無地の色 → ソリッドアクア・ブルー
  • スクリーンセーバ: Arabesque
  • ホットコーナー (ウィンドウの右下辺りにある)
    • 左上、右上: Mission Control
    • 右下: Launchpad

Dock

  • サイズ: 「小」よりに調節
  • 画面上の位置: 左
  • 「Dockを自動的に隠す/表示」にチェックを入れる
  • 「起動済みのアプリケーションにインジゲータを表示」のチェックを外す

トラックパッド

  • 「ポイントとクリック」
    • 「調べる&データ検出」: チェックを外す
    • 軌跡の速さ: 「速い」側に完全によせる(最速)
  • 「その他のジェスチャ」
    • 全てのチェックを外す

アクセシビリティ

  • 「一般」タブ
    • 「マウスキー」のチェックを外す
  • 「マウスとトラックパッド」タブ
    • タブルクリック間隔: 「速い」側に完全によせる(最速)
    • トラックパッドオプション
      • スクロールの速さ:「速い」側に完全によせる(最速)
      • ドラッグを有効にする: 「ドラックロックあり」を選択

キーボード

  • 「キーボード」タブ
    • キーのリピート: 「速い」側に完全によせる(最速)
    • リピート入力認識までの時間: 「短い」側に完全によせる(最短)
    • 修飾キー(ウィンドウ右下): 「Caps Lock」→「Control」
  • 「ショートカット」タブ
    • 「Spotlight」→「Spotlight検索を表示」: 「Option + Space」に変更
  • 「入力ソース」タブ
    • defaultのものは使わずに「Google 日本語入力」を使用(以下の手順でセッティング)
    • Google 日本語入力からインストール
    • インストール出来たら「英数(Google)」と「ひらがな(Google)」の2つだけにする
    • 一旦、再起動すると反映される

省エネルギー

  • 「バッテリー」タブ
    • 「ディスプレイをオフにするまでの時間」: 1時間
    • 「バッテリー電源使用時はディスプレイを少し暗くする」チェックを外す
  • 「電源アダプタ」タブ
    • 「ディスプレイをオフにするまでの時間」: 1時間

サウンド

  • 「サウンドエフェクト」タブ
    • 主音量: 消音
    • メニューバーに音量を表示: チェックを入れる

Finder設定

環境設定

( 左上タブ 「Finder」→ 「環境設定」)

  • 「一般」タブ
    • 「デスクトップに表示する項目」: すべてのチェックを外す
    • 「新規FInderウィンドウで次を表示」: 「ホームディレクトリ」(家アイコン)
  • 「サイドバー」タブ
    • ホームディレクトリ(家のアイコンとユーザー名)のチェックを入れる
    • 「ハードディスク」にチェックを入れる
  • 「詳細」タブ
    • 「すべてのファイル名拡張子を表示」にチェックを入れる

隠しフォルダを表示

ついてでにLibraryの表示も。以下のコマンドをターミナルに打ち込む

$ defaults write com.apple.finder AppleShowAllFiles -bool YES
$ chflags nohidden ~/Library/
$ killall Finder

homebrewの準備

Command Line Toolsのインストール

$ xcode-select --install

homebrewのインストール

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

バージョンを確認出来たらインストール完了。

$ brew -v

zshの設定

defaultシェルの変更

$ chsh -s /bin/zsh

ターミナルを立ち上げ直すとzshに変わる

補足

defaultシェルはbash

$ echo $SHELL
/bin/bash

上記のシェルの変更を行うとzshになったことが確かめられる

% echo $SHELL
/bin/zsh

zshrcの設定

.zshrc_kuboshizuma.zshrcとしてホームディレクトリに置く。

.zshrc_mac_kuboshizuma.zshrc_macとしてホームディレクトリに置く。

$ source ~/.zshrc

として設定を読み込む。

アプリケーションのインストール

homebrew-bundleを用いて初期に必要なアプリケーションを一括でインストール。

以下のコマンドでインストールが始まる。

$ brew tap Homebrew/bundle

ホームディレクトリにBrewfileというファイル名で以下のファイルを作成する。 (emacs使いの皆さんはvimのような感じでemacsも追加してみてください)

cask_args appdir: '/Applications'
tap 'caskroom/cask'

brew 'tmux'
brew 'wget'
brew 'mysql'
brew 'node'
brew 'vim'
brew 'git'

cask 'google-chrome'
cask 'firefox'
cask 'java'
cask 'iterm2'
cask 'dropbox'
$ brew bundle

vimの設定

vimrcの準備

vimrc_kuboshizumavimrcとしてホームディレクトリに置く。

プラグイン管理

$ mkdir -p ~/.vim/bundle
$ git clone git://github.com/Shougo/neobundle.vim ~/.vim/bundle/neobundle.vim

vim を開いて

:NeoBundleInstall

補足

プラグイン自体の説明はあまりここではしませんが、vimを開いて「ctr + o」とか「ctr + e」とかしてファイルを変えるのはよくやるのでコメントしておきます。 あと以下のようにすればes6シンタックスにも対応出来ます。

:set filetype=javascript

ついでに、プラグインではなく.vimrcの設定ですが、「; + v」、「; + s」で画面分割も出来るので便利だと思います。

vimの設定に関しては慣れた人は自身の好きな設定があると思いますのでそれを適用させてください。これから使い始めるかたはここで紹介したものをベースにいらないものは捨て、よさそうなものを試して追加していくことをおすすめします。

iTem2の設定

「iTerm2」 →「Preferences」から設定ウィンドウを開く。

  • 「Profiles」タブ
    • 「Window」タブ
      • Transparency: ちょっと「transparent」側にする
      • 「Settings for new window」: columns 90, Rows: 30
    • 「Terminal」タブ
      • Scrollback Buffer
        • Scrollback Lines: 10,000
      • Notifications
        • Silent bell: チェックを入れる

僕はターミナルの代わりに「iTerm2」を使っています。

gitの設定

gitの諸設定

.gitconfig_kuboshizuma.gitconfigとしてホームディレクトリに置く。

ファイル内の[user][core]user_nameuser_emailはご自身のものを入れてください。

githubとの連携

以前書きました以下記事を参照ください。

gitHubでssh接続する手順~公開鍵・秘密鍵の生成から~

PHPの環境構築

MAMPのインストール

MAMPを利用。(「Macintosh」、「Apache」、「MySQL」、「PHP」の頭文字。)

MAMPのサイトよりダウンロード。 インストールまで完了したら「MAMP」を起動して「サーバを起動」をクリックする。(PCを再起動するときは再度「サーバを起動」することになります)

MySQLは基本MAMPMySQLを今後使っていく。 .zshrc_macでaliasをはっているので以下のようにMySQLを使える。 (初期はユーザー名 root、パスワード root)

$ mysql -uroot -p
root

ポートの変更

これでlocalhostにアクセスすれば/Applications/MAMP/htdocsのファイルにアクセス出来るようになる。

Rubyの環境構築

rbenvとruby-build のインストール

brew install rbenv ruby-build

rbenvとreadlineのパスを通す

$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ brew link readline --force

readlineを利用してRubyをインストール

$ RUBY_CONFIGURE_OPTS="--with-readline-dir=$(brew --prefix readline)"
$ rbenv install 2.3.1

補足

$ rbenv install --list

でインストール出来るRubyのバージョンを表示させることが出来ます。

Rubyのバージョン選択

$ rbenv rehash
$ rbenv global 2.3.1
$ ruby -v
2.3.1

必要なバージョンを適宜追加する。

Railsのインストール

ついでにRailsもインストールしておく。

$ gem install bundler
$ gem install rails
$ rbenv rehash
$ rails -v

Pythonの環境構築

以前書きました以下記事を参照ください。

Pythonの環境構築 on Mac ( pyenv, virtualenv, anaconda, ipython notebook )

その他 (必要に応じて)

ここまでで一通り出来ましたが、補足的なものを書きます。

Chromeの設定

などなど設定してみるとよいと思います。

おすすめのアプリケーション

終わりに

これだけの設定ができればとりあえず作業出来るのではないでしょうか。

僕個人の環境構築ですが、皆さんのお役に立てれば幸いです。

大学生がプログラミングをはじめる方法

最近更新がなかったので久々の投稿です。。 Qiita(shizuma) に書いちゃうんですよね。こちらもちゃんと更新したいところです。

さて、今回はいつも書くような技術のお話とはちょっと違うことを書いてみたいと思います。テーマは「大学生がプログラミングをはじめる方法」です。

プログラミングに興味があるけど、はじめの一歩が踏み出せない。そんな方に少しでも役立つと幸いです。

ちなみに、ここでいうプログラミングとはWEB系のプログラミング、nativeアプリ、あとは機械学習等など、僕がやった範囲を想定しながら書いていることを予めお伝えしておきます。

僕自身大学生になってからはじめてプログラミングを勉強し始めました。興味があれば是非これからはじめましょう!

どうやってはじめるか

  1. 独学 (書籍)
  2. 独学 (WEBサービス)
  3. プログラミング教室
  4. 勉強会
  5. インターン・アルバイ

1. 独学 (書籍)

最初に思いついつくのは独学です。

僕は結構、本を使って勉強するのは好きです。ただし、いきなり初学者が本を取り出すと上手くいかない可能性は高いと思います。それは、自分に合う本がどれか分からないからです。もし、身近に詳しい方がいて教えてもらえる環境であれば良いのですが独学の場合は難しいですよね。 プログラミングに慣れてきたらいろんな本を手にとって見て下さい。

2. 独学 (WEBサービス)

最近?では様々なプログラミングを学ぶためのサービスがあります。しかも基本的には無料のものも多いです。一旦ここからはじめて感覚を掴むのは良いと思います。

ドットインストール

http://dotinstall.com/

まずは、3分動画のドットインストールです。僕も一番最初にこの動画を見た覚えがあります。様々な言語がありますし、初心者でも分かりやすい説明で定番ともいえるサイトです。(基本無料)

Progate

prog-8.com

ブラウザ上で実際にコードを書いて学んでいくスタイルの学習サイトです。カリキュラムもどんどん増えてきて勢いがあります。ドットインストールより実践的なイメージです。こちらもおすすめです。(基本無料)

Udemy

www.udemy.com

オンラインの動画学習サイトです。基本お金がかかりますが、カリキュラム立っていて学習しやすかったり、サポートがしっかりしているなどおすすめです。質問したら作者の方から翌日には回答されました。日本ではドットインストールやProgate程使われてない気がしますが(個人の感覚)、自分にあった講座に出会えると思います。

Coursera

www.coursera.org

海外の有名大学の講師が提供してくれる授業です。英語ですが日本語字幕もあります。(全てではないかもしれませんが)理論的なところが多い気がするので一番最初は他のサービスのほうがいいかもしれません。

他にも色々なものがありますが、有名で個人的におすすめな4つのサービスでした。

公式のTutorial

公式のTutorialは各種あります。例えば、Railsチュートリアル等、役立つものがたくさんあります。

railstutorial.jp

ただし、一番最初はやめておいておいたほうがいいかなと思います。ひとつはプログラミング言語を知った上で新しく違う言語をはじめるときはいいかと思います。

プログラミング教室

TECH::CAMP

tech-camp.in

世の中には現在たくさんのプログラミング教室があります。従来の塾のような授業形式のものよりも実践型のものが勢いがあると思います。その中でおすすめはTECH::CAMPです。なぜ、おすすめできるかというと、自分が通った&メンターをしていたから良さを知っているからです。他社のプラグラミング教室には通っていないので比較は出来ないですが、少なくともTECH::CAMPで失敗はないです。カリキュラムの質や質問のしやすさもいいですし、仲間が出来ることも大切です。

お金はかかりますが、独学よりも手っ取り早く学ぶことが出来ると思います。

勉強会

僕自身は、勉強会の情報は今はSNSから入ってきたり、人からの紹介が多いですがはじめのうちは以下のようなサイトを頼るといいでしょう。

dots

eventdots.jp

勉強会の紹介サイトです。dots自体も渋谷にコミュニティスペースがあり、勉強会が開催されています。学生部といったコミュニティもあるので興味があれば是非参加すると良いと思います。学生部に入ると1日いても500円で最高の環境でプログラミング出来ますよ。

conpass、doorkeeper

connpass.com

www.doorkeeper.jp

dotsと同じような勉強会のサイトです。僕は能動的にこの2つのサイトで勉強会は探すことは少ないですが、前はまあまあ見てた気がします。

TECH SALON

tech-salon.com

最近勢いがある学生向けの勉強会コミュニティです。イベントが月に20本以上やっているので気になるものがきっとあると思います。仲間も出来ると思うのでかなりおすすめです。僕も機械学習関係は行っています。

インターン・アルバイ

Wantedly

www.wantedly.com

おすすめ度が高いです。ここに載っているものは面白そうなものが多いです。また、今勢いがある会社も多いので、モダンな開発が出来る可能性も高いです。募集自体もどんな技術が使われているか等わかりやすいです。まずはプロフィールを書いて、興味がある会社に話を聞きに行ってみてはいかがでしょうか?スカウトされることもあります。

ニクリーチ

29reach.com

肉を食べたい。そんな軽い気持ちで登録しておくと会社から連絡が来るというなんともお得なサービスです。意外と?連絡がきてアルバイト等に結びついたのでおすすめです。とりあえず登録だけでもどうぞ。

サポーターズ

supporterz.jp

企業から支援金をもらって就活しよう的な就活風味のきいたサービスです。学部3年生とかであればここで会社の人と仲良くなってインターン・アルバイトしてみるといいかもしれません。

goodfind

www.goodfind.jp

こちらも就活風味が強いですが、インターンを探せます。勉強会も探せます。前は使っていたこともありますが、最近はほとんど使っていません。

紹介・その他

知り合いから紹介されると良いですが、はじめはなかなか難しいかもしれません。 ちなみに、僕がはじめてインターンに行った会社はセミナー終わりに直接スピーカーの方に話にいってそこでインターンが決まりました。積極的に社会人の方に話してこういうことがしたいっていうことを伝えるとスキルがなくても「うちでおしえてあげるよ」ってことになる可能性はあります。

継続させるためには

さて、勉強をはじめても続けないと意味がありません。以下のようなことを意識的・積極的にやってみてはいかがでしょうか。

  • 勉強会に定期的に出る
  • 有名人をfollow
  • QiitaやBlogに成果を書く
  • コミュニティに入る
  • サービスを作る
  • インターン・アルバイトに行く

プログラミングをはじめる目的は色々あると思います(作りたいサービスがある、他の人に差をつけるスキルが欲しい、就職に役立つ、一儲けしたい、なんとなく、etc...)。いずれにせよ、今回紹介したことを参考にしてはじめてみることがまず大切かと思います。(勿論、その後の継続も)

Rails サイト内検索機能を作った (AND検索にも対応)

サイトの記事数が増えてきてサイト内検索が欲しくなりました。というわけで検索機能を実装するためのgemのransackで検索機能を実装することにしました。

github.com

今回やろうと思っているのは記事のタイトル検索が出来ればいいなーと思っています。あと検索のときに空白で区切ってAND検索になるようにしたいと思います。

ひとまず、gemを入れます。

gem 'ransack'

それで、今回やりたいことを整理します。

  1. 全ページのヘッダーに検索窓をつける。
  2. /search?q=hoge みたいな感じでqueryを渡す。
  3. 検索ページに検索結果を表示する。

1. 全ページのヘッダーに検索窓をつける。

好きなように検索窓を作ってしまいます。「q」でvalueをgetメソッドで渡すのでその部分は注意してください。(qはqueryとか何でもいんですが)

= form_tag search_index_path, method: 'get' do
  = text_field_tag :q, '', placeholder: "気になるワードを入力"
  = button_tag type: 'submit' do
    %i.fa.fa-search

あと、classとかつけてstyle付ければいいですね。僕はfont-awesomeとか入れるの好きですが何でもいいですね。お好きに。

2. /search?q=hoge みたいな感じでqueryを渡す。

それで、ひとつ注意があって単純にgetメソッドをつける以下みたいな余計なqueryがくっついてきてしまうことです。カッコ悪いですね。。

/search?q=hoge&utf8=✓&commit=submit

というわけで解消します。以下のサイトを参考にします。

www.mk-mode.com

まず、commitなんちゃらのほうを取り除きます。button_tagに name: nil のオプションを渡すだけです。うん、簡単。

= form_tag search_index_path, method: 'get' do
  = text_field_tag :q, '', placeholder: "気になるワードを入力"
  = button_tag type: 'submit', name: nil do
    %i.fa.fa-search

で次にconfig/initializer に以下のファイルを作ればuft8なんちゃらが消えます。

module ActionView
  module Helpers
    module FormTagHelper
      def utf8_enforcer_tag
        "".html_safe
      end
    end
  end
end

これでオーケー!

3. 検索ページに検索結果を表示する。

  def index(q, page=1)
    @q = q
    query_arr = q.split(/[[:blank:]]+/)
    @search = Article.ransack(title_cont_all: query_arr)
    @articles = @search.result.published.newest.page(page)
  end

以下で詳しく解説します。

query_arr = q.split(/[[:blank:]]+/)

qは受け取ったqueryですが、空白で切り分けて配列にします。splitの引数に入れたやつで区切ってくれます。はじめ普通に /\s/ のようにすれば空白区切り出来るかと思ったのですが全角に対応出来ないみたいだったので探してみたらこんな感じでいけました。

 Article.ransack(title_cont_all: query_arr)

Articleというテーブルに ransack というメソッドをgemの力をかりて実行します。 title_cont_all というオプションで値にqueryの配列を与えるとそれら全てを含む記事を引っ張ってくれます。 title_cont_allの部分なのですが(検索するcolumn名)_cont_allの意味で、今回はtitleカラムを使いましたが適宜変更可能です。

それで後は好きに加工して表示させちゃってください! ( 上記サンプルコードは、action_argsとかkaminariといったgemを使ったことがコードに反映されてます。)

これで完成です!

正直まあこの程度の検索ならgem使わなくても...とか思ったりもしたのですが、and検索とかあとひらがなでもカタカナでも取得してくれたりとか簡単に出来るので入れてみると便利だなとか思いました!

Rails使うときほとんど正規化考えないよね

正規化とはRDBにおいてデータを適切に管理するための手順です。

正規化

まずはさらっと正規化を考えます。 正規化は以下の手順で行っていきます。

  • 第一正規化
  • 第二正規化
  • 第三正規化
  • ボイスコッド正規化
  • 第四正規化
  • 第五正規化

第一正規化

  • 同一の内容の行が複数存在することはない
  • 候補キーが存在する

候補キー

特定の行を識別することの出来る項目を候補キーといいます。「候補」というのは主キーとなる候補という意味合い。主キーは候補キーの条件+「null値を持たない」という条件がつきます。

第一正規化は普通にすれば普通に出来るはずです笑 表で考えた時にひとつのセルに3つ項目入っているとか変なことをしなければ大体できてると思います。

第二正規化

  • キーに対する部分関数従属がない

キーの一部が決まることで一意に決まる非キー属性がないというと分かりやすいかと思います。 キーは複数あることがあります。以下の様な項目を持つテーブルを考えるときitem_idとorder_idがキーであるとします。

  • item_id
  • order_id
  • name
  • price

このときitem_idが決まれば name、priceは一意に決まっていまいます。これはもうひとつのキーであるorder_idとは関係なく決まります。item_idとorder_idの2つが決まってはじめて他の項目が決まることを完全関数従属といい、例のようにキーの一部で他の項目が決まってしまうことを部分関数従属であるといいます。

第二正規化ではこの部分関数従属を別テーブルに分解して部分関数従属をなくします。

第三正規化

  • 非キー属性の関数従属をなくす

Booksテーブルがあったとしてtitleをキーとします。

  • title
  • writer_name
  • writer_birth_day

writer_nameが決まればwriter_birth_dayが一意に決まります。これが非キー属性での関数従属です。 なのでこの部分を別テーブルに分けることが第三正規化となります。

ボイスコッド正規化

ボイスコッド正規化以下は簡潔に。 ボイスコッド正規化までくると、主キー同士の関数従属も排除します。

第四正規化

第四正規化と第五正規化は非キー属性をもたないキー属性のみのテーブルにのみ適用します。

多値従属性を考える必要があります。 対称性のある多値従属性を分解します。

第五正規化

対称性のない場合の多値従属性も考えます。

第四正規化と第五正規化は以下がわかりやすいので参照下さい。 http://www.atmarkit.co.jp/ait/articles/0605/11/news124_4.html

Railsの正規化

Railsはテーブルを設計するときに、「id」というキーが単独のprimary keyとなります。第一正規化はまあ普通にやれば出来ているとして、キーが単独なので第二正規化、ボイスコッド正規化、第四正規化、第五正規化は考える必要がなくなり、第三正規化だけ考えればよさそうです。 「id」を使うようになった背景や詳しい理由は気になるところなので参照記事や書籍を是非ご紹介頂きたいです。

Imagemagickをupdateしたらrmagickに怒られたから直した

imagemagick脆弱性が見つかってわちゃわちゃしてますね。

ImageMagick の脆弱性 (CVE-2016-3714) に関する注意喚起

rubyでいうとrmagickとか普通に使うので古いimagemagickに依存してたらよくないですね。というわけでimagemagickをupdateしてみた。 そしたらなんかエラー >< (rails s でサーバー立ち上げるとき)

This installation of RMagick was configured with ImageMagick 6.9.0 but ImageMagick 6.9.4-1 is in use. (RuntimeError)

あれ、rmagick対応出来てないのかな?とか一瞬思ったのですが、なんか 6.9.0 にconfiguredされちゃってるらしいのでインストールし直してみた。

$ gem uninstall rmagick
$ gem install rmagick

そしたら直った!!(reinstallとか出来たっけ?) imagemagickのバージョン変わったらrmagickはインストールし直す必要があるんですね。