【Ruby】形態素解析、ビジュアリゼーション、スクレイピング

この記事は ジーズアカデミー Advent Calendar 2017 の2日目です。

はじめに

ウェブスクレイピングは結構好きで、主にrubyを使ってスクレイピングしているんですが、 blogでは python(記事リンク) しか書いたことがない。

なので、今回は

rubyスクレイピングして形態素解析してビジュアリゼーションしてみます!

対象

せっかくなんで、今回はジーズアカデミーのサイトをスクレイピングしてみます。

画像

f:id:jesushill:20171202175205p:plain

抽出項目

分量が多いほうが良いいので、トップページ下にある

f:id:jesushill:20171202175230p:plain

記事全てを取得します!

f:id:jesushill:20171202175419p:plain

実行準備

利用ライブラリ

主なライブラリは以下の通りです!

を利用します!

手順

手順は以下の通りとなります。

  • open-uri を用いて、トップページを取得し、記事リンク取得
  • 取得したリンクをopen-uriでページ取得、nokogiriを用いて記事ページを取得し、ActiveRecordでDBに保存
  • 形態素解析を用いて英単語(magic_cloud との関係か?日本語の相性がうまくいかなかった汗)をビジュアル化

実行!

スクレイピング

取れた!

f:id:jesushill:20171202180146p:plain

形態素〜ビジュアル化

だらだら、色々とやってたのですが、今回はビジュアルだけにしておきます。

f:id:jesushill:20171202180509p:plain

ソースコード

ココのレポジトリにおきました!

終わりに

スクレイピングpythonが現状優勢ではありますが、慣れているのでrubyは書きやすい! 何より、スクレイピング特有の複雑な条件式やエラーハンドリングに対応しやすいのが良いな〜と改めて感じました!

本日は以上です!

シェルスクリプトその2 制御構文(if文,for文)

はじめに

前回に引き、今回は制御構文をまとめていきます。

if文

他のプログラムと違うところはif文の後ろにつける 条件式 ではなく、コマンド式 ってことです。 最初何行っているのかよくわから買ったのですが、以下の例だとわかりやすいです。

#!/bin/sh
# file名:test1.sh
# []でくくるとbashのコマンドとして評価 スペース注意
if [ true ]; then 
  echo 'true'
end
# test1.sh実行
$ sh test1.sh 
$ true

以下のサンプルコードですと、通常の条件式なら、false では出力されないです。 が、シェルスクリプトだと、あくまでもbash のコマンドとして認識され、出力されます。

#!/bin/sh
# file名:test2.sh
# これでも通る
if [ false ]; then
  echo 'false'
fi
# test2.sh実行
$ sh test2.sh
$ false
#!/bin/sh
# file名:test3.sh
if [ "$1" = "true"  ]; then
  echo 'true'
else
  echo 'false'
fi
# test3.sh実行
$ sh test3.sh 
$ false

$ sh test3.sh true
$ true

for文

for文はあまりハマりどころがなかったので軽くまとめておきます。

for 変数名 in リスト
do 
  # 処理記述
done
#!/bin/sh
# ./test/*.txtを削除するプログラム

for fname in $(find ./test/* -name '*.txt')
do
  rm -rf $fname
done

シェルスクリプト入門 その1 入力、出力、変数

はじめに

動機

シェルスクリプトを最近(ようやく?)、自分で書くようになってきました。 スクリプト言語と違うところ及び自分の頭の整理のために書いていきます。

シェルクスクリプトとは

シェルスクリプトとはunixコマンドを一つのファイルにまとめて実行するプログラムです。

利用シーン

  • ログファイルをリネームして移動したりする
  • VPSMacで作成したプログラム(rubypython)を定期的に実行 (cronと組み合わせる)
  • ...

などなど、使えると色々と便利なのは間違いありません!

入力、出力

とりあえず hello world

#!/bin/sh
echo "hello world" # hello world 

と書いて、実行すると、hello worldと出力されます!

$ sh hello.sh
$ hello world

重要なポイントは以下の点です。

  • 文頭に #!/bin/sh と記述。
  • シェルスクリプトunixコマンドが使える
    • 今回は echo を使用
  • コメントは # と記述した後に記述

標準入力、出力

  • read で値を標準入力
  • echoで値を出力します。
#!/bin/sh
read input 
echo "input=$input"
$ sh read.sh
$ hello
$ input=hello

といった形で標準入力、出力が行えます!

変数

重要なポイントは以下の通りです。

  • 変数に値を与える際、 variable=hoge といったようにスペースをつけない
  • 宣言した変数をアクセスする際は 先頭に$をつける。
  • readonly を用いると変数を上書きされない。
  • readonly を解除するには unsetを用いる。
#!/bin/sh
variable=hoge #スペースを入れない
echo $varible #変数にアクセスする際は$をつける
$ sh variable01.sh
$ hoge

また、readonlyと宣言すると、変数の上書きがされません。

#!/bin/sh
variable="変数"
echo "$variable"
readonly variable
variable="変更"
$ sh variable02.sh
$ 変数
$ variable02.sh: line 5: variable: readonly variable

特別な変数

個人的に使用頻度が高いと思われるものに絞ります。

  • $0 [スクリプト名]
  • $1 ~ $9 [引数をアクセス 数字は引数の順番を示す]
  • $$ [実行したプログラムのプロセスID]
#!/bin/sh
echo $0 #special_varable.sh
echo $1 #1つ目の引数を出力
echo $$ #プロセスIDを出力

Atom ショートカットキー

ココココ が素晴らしかったのでメモ。

暇な時、更新していきたい。

出来ること コマンド
カーソルを上に移動 ctr + p
カーソルを下に移動 ctr + n
カーソルを左に移動 ctr + b
カーソルを右に移動 ctr + f
当該の行まで移動 ctr + g
行の先頭まで移動 ctr + A
次単語の移動 option + F
単語を一つ戻る option + B
プロジェクト追加 cmd + shift + o
単語の選択 cmd + d
末尾までカット ctr + k
当該行を移動 cmd + ctr 上下

2017/11/21: カーソル移動追記

【Go言語】スライス

最近、Go言語を勉強しているので、メモがてら書いておきます。

スライスの特徴

容量を増やせば可変長型配列のように使えるようです。 GoはArrayだと要素数は最初に宣言した以上には増やせません。

使い方コード例

package main

import "fmt"

func main() {
  s := []int{2, 3, 5, 7, 11, 13}
  var s1[]int
  var s2[]int
  var s3[]int
  
  s1 = s[1:4]
  fmt.Println(s1)  // [3 5 7]
  s2 = s[:2] 
  fmt.Println(s2) // [2 3]
  s3 = s[1:]     
  fmt.Println(s3) // [3 5 7 11 13]
  fmt.Println(cap(s)) // 配列の容量
  fmt.Println(len(s)) // 配列の長さ
}

make append

package main

import "fmt"

func main() {
  slices := make([]int, 3)
  fmt.Println(slices)  // [0 0 0]
  var slices_append []int
  slices_append = append(slices, 1) // 追加
  fmt.Println(slices_append) // [0 0 0 1]
  fmt.Println(len(slices_append)) // 要素数 4
  fmt.Println(slices_append[2]) //要素にアクセス 0
}

参考

【ruby】キーワード引数と通常の引数組み合わせ

キーワード引数と通常の引数組み合わせ

エラー例

def test_method1(params = {}, hoge: true)
  return params, hoge
end
# こける
$ irb>  test_method1({test: 'test', test2: 'test2'})
$ ArgumentError: unknown keywords: test, test2

エラーとならない

def test_method2(params, hoge: true)
  return params, hoge
end

すると、

# こけない
$ irb(main)>  test_method2({test: 'test', test2: 'test2'})
$ => [{:test=>"test", :test2=>"test2"}, true]

エラーとならない2

もう一つ

def test_method3(hoge: true, **params) # 引数の順序としてキーワード引数が先となる
  return params, hoge
end

すると、

# これもこけない
$ irb(main)>  test_method3({test: 'test', test2: 'test2'})
$ => [{:test=>"test", :test2=>"test2"}, true]

【サーバーレス Lambda】Apexを使ってデプロイ環境を整備する

Lambdaとは

公式によると 

AWS Lambda はサーバーをプロビジョニングしたり管理しなくてもコードを実行できるコンピューティングサービスです。AWS Lambda は必要に応じてコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケーリングします。使用したコンピューティング時間に対してのみお支払いいただきます- コードが実行中でなければ料金はかかりません。 ...以下、略

と書いてあります。

難しすぎますね。。

個人的に重要な点

個人的にLambdaの重要なところは以下の3点だと思います。

  • 1.サーバー管理、言語環境設定などをせず、コードを実行出来る
  • 2.他のAWSサービスと連携がしやすい
  • 3.使用言語: Node C# JAVA Python

Lambdaの利点

前述したように、サーバー構築を一回でもやったことがある人なら認識あるかもしれないんですが、 新しいインスタンスVPSを立ち上げるのって結構だるいです。

Lambda を使えば環境構築も整備してくれて、すぐに実行出来ます。 そして、AWSのサービス群である CloudWatchAPIGatewayを使えば cron job や 面倒なAPIを作成することが出来ます!

Lambda 面倒な点?

まずはじめにLambda実行方法をあげてから面倒な点を述べます。

Lambdaの実行方法(GUI)形式で乗っ取ると以下のような手順を踏まえます。 注) 以下、python を想定

  • 1 python プログラム作成
  • 2 python プログラム、標準外ライブラリをフォルダに一式入れてZIP化、アップロード
  • 3 実行環境設定 (メモリ、実行時間など)

面倒なのは2と3の実行手順です。標準外のライブラリをダウンロードして ZIP化、さらには実行環境設定などをいちいち設定しなくてはいけません。

Apexとは

Apexは上述した、Lambdaの面倒な点をサポートするデプロイツールです。 Apex公式

利点

利点は以下の通りです。

  • プロジェクトごとに共通の設定を持たせることが出来る
  • プログラムファイルは自動でZIP化し、デプロイ
  • エイリアスを用いることが出来るので、ロールバックやアップデートも楽
  • Go言語が使用可 (デフォルト使用言語: Node C# JAVA Python)

利用方法

想定言語:python(ローカルでパッケージ管理ツール pip がインストール)

apex環境構築

# IAMで access key と secret access keyを取得しておくこと
# コマンドラインでAWSを操作出来るパッケージインストール

$ pip install awscli
$ aws help  # install 確認
$ aws configure
# 以下を入力
# AWS Access Key ID [**********]:
# AWS Secret Access Key [**********]:
# Default region name [ap-northeast-1]:
# Default output format [json]:

apex install

# apex install
curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh
apex version # install確認

apex 実行

$ mkdir apex-test 
$ cd apex-test/
$ apex init #project name descriptionを記入

apex initを実行すると以下のようなプロジェクトフォルダが作成されます。 初期設定はjsになるようです。。

.apex-test
│
├── functions
│   └── hello
│       └── index.js 
└── project.json # プロジェクトの固有設定

ので、python仕様と説明用に以下のようにしておきます。

.apex-test
│
├── functions
│   └── hello
│       │── function.json # function固有の設定(←デプロイされるプログラムの設定)
│       └── main.py # デプロイプログラム
└── project.json # プロジェクトの固有設定

project.json

{
  "name": "blog-test",
  "description": "test",
  "memory": 128, # 使用メモリ、CPUと連動
  "timeout": 5, # 秒
  "role": "[AWS-ROLE]",
  "environment": {} # 環境変数設定 pythonの場合、os.environ["#####"]で取得可
}

ここでは各プロジェクトの共通設定を記述しています。

function.json

用途:各ファンクション固有の環境設定を記載する。 なお、project.jsonの内容は継承されます。

{
  "description": "python functions",
  "runtime": "python3.6", # 実行環境
  "memory": 128,
  "timeout": 20,
  "hooks": {
  "build": "pip install -r requirements.txt -t ./", # デプロイ前の処理
  "clean": "rm -rf */" # デプロイ後の処理
  },
  "environment": {
    "????_API_KEY":"######",
    "URL":"https://hoge.com"
  }
}

このようにLambdaファンクション固有の設定を記述することが出来ます。

なお、hooksの内容は

  • build(deploy前):記述内容はlambdaデプロイ時に標準外パッケージをインストールし、デプロイ
  • clean(deploy後):buildでインストールした標準外パッケージを削除

となります。

上記のようなjsonファイルを作成することで、lambdaの面倒な点

  • 1.プログラム、標準外ライブラリをフォルダに一式入れる処理)
  • 2.実行環境設定 (メモリ、実行時間など)

を自動化することが出来ます。

apex コマンド

少し長くなってしまったので、個人的に有用だと思うコマンドをまとめておきます。

# 新規プロジェクトを作る
apex init
# 当該プロジェクト内のファンクションをデプロイ
apex deploy
# 当該プロジェクト内の特定のファンクションをデプロイ
apex deploy {FunctionName}
# invoke: deploy後の実行結果をローカルで試す。
apex invoke {FunctionName}
# event の受け渡し
apex invoke {FunctionName} < event.json
# エイリアス作成
apex alias {AliasName} {FunctionName}
# エイリアスのデプロイ
apex deploy -a {AliasName}

apex rollback -v n  # n:数字
apex rollback # 一個前に戻す
apex rollback -a {AliasName} # エイリアスロールバック

最後に

最近、Lambdaをはじめたのですが、面白いのでApexを用いて がしがし有用なプログラム作っていきたいです\(^o^)/