ページ

2015年12月14日月曜日

Tensorflowで学ぶ最急降下法

Tensorflowで学ぶ最急降下法

ありきたりですが、Tensorflowの初期サンプルに掲載されている
最急降下法(train.GradientDescentOptimizer)の解説です。

最急降下法とは、ある式を作りその式に基づき
微分を行いもっとも傾きから最小の値を算出する手法です。


TensorFlowのget startedにあるIntroductionが
この最急降下法のサンプルとなります。

大まかなフローとしては
Step1.初期データ作成
Step2.予測モデルする方程式を作成
Step3.ロス関数と目標設定を作成
Step4.最適化の実行
すごくざっくりですがこの4ステップで最急降下法を実現しています。


# おまじない
import tensorflow as tf
import numpy as np

### Step1.初期データ作成 ###
# ランダムなxの値を作成
x_data = np.random.rand(100).astype("float32")
# y = 0.1x + 0.3の式に基づいた値を算出
y_data = x_data * 0.1 + 0.3

### Step2.予測モデルする方程式を作成 ###
# W 上でいう aに値する係数を初期値として-1.0~1.0の範囲でランダム生成
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
# bの値を初期値0で作成
b = tf.Variable(tf.zeros([1]))
# y = W * x + bを再現
y = W * x_data + b

### Step3.ロス関数と目標設定を作成 ###
# 予想した結果y - 実際のyのデータ二乗した結果の平均をlossと位置付ける
loss = tf.reduce_mean(tf.square(y - y_data))
# Learning Rateの指定
optimizer = tf.train.GradientDescentOptimizer(0.5)
# lossが最小化する値を目的に置く
train = optimizer.minimize(loss)

### Step4.最適化の実行 ###
# TensorFlowの実行準備
init = tf.initialize_all_variables()

# graphの準備
sess = tf.Session()
sess.run(init)

# 201回の最適化を実行
for step in xrange(201):
sess.run(train)
# 20回毎に途中の値を出力
if step % 20 == 0:
print step, sess.run(W), sess.run(b)


この流れになります。
何の脈略もないのですが自己理解のための簡易解説となります。

2015年12月1日火曜日

Apps ScriptとQiita APIを利用してGoogleスプレットシートにデータを書き込む

Qiitaの情報を自分なりに見やすくしたいと思い
APIを利用しExcelのような形で見れるようにできないかと奮闘の備忘録

まずは準備
Qiita APIを利用すために個人用認証トークンを取得設定=>アプリケーション
から設定可能で今回は読み込みだけなので「read_qiita」で発行以後のソースにこちらの認証トークンを利用します。






続いてGoogle Drive上にファイルを作成2つのファイルを作成します。

まずは、Google Drive上でスプレットシートを作成
作成自体は簡単です。
続いて名前を付けて保存します。


ここでは、ファイル名「Qiita」シート名「lists」とします。
またA列にid,B列にtitle,C列にcreate date,D列にurl,E列にtagsを入れます。 


名称はなんでも良いですが見出しとして入れてください。
シート名はApps sciprtで利用しますので注意してください。



もう一つ必要なのがスプレットシートのIDです
IDはURLから取得できます。

パターンとしては
https://docs.google.com/spreadsheets/d/{ID}/edit#gid=0&vpid=A1
上記の{ID}部分がIDとなります。


例として以下となります。



青く塗られている部分がこのシートのIDになります。
※URLにアクセスしてもすでに削除済みなので開くことができません。





ようやく本題
apps scriptを利用していきます。

apps scriptが有効でない場合は以下の処理が必要です。


新規=>その他=>アプリを追加に行きます。
検索で「apps script」と検索すると以下がでます。

こちらを追加してください。
追加ができれば前の図様ように「Google Apps Script」が表示されます。
こちらを選択しApps Scriptを新規作成します。




コードは以下です。
コード実行時にアクセス許可をもめられうので許可して実行.
ファイル名:qiita

function myFunction() {
  // スプレッドシートのID.
  var spreadsheetId = '{ID}';
 // スプレッドシートのシート名.
  var spreadsheetName = 'list';
  // Qiita APIのURL.
  var url = 'https://qiita.com/api/v2/items?page=1&per_page=100';

  // スプレッドシートにアクセス.
  var spreadsheetData = SpreadsheetApp.openById(spreadsheetId);
  // スプレッドシートのシートにアクセス.
  var sheet = spreadsheetData.getSheetByName(spreadsheetName)
  // シートのデータを取得.
  var sheetdata = sheet.getSheetValues(1, 1, sheet.getLastRow(), sheet.getLastColumn());
  // Qiita APIからデータを取得.
  var qiitas = getHttpQiitaApiRequest(url);
  
  // Qiita APIから取得したデータを列へ挿入.
  for (var n in qiitas) {
    var qitta = qiitas[n];
    var isCheck = findById(sheetdata, qitta.id);
    // 既に存在しているか確認.
    if (!isCheck) write(sheet, qitta);
    else break;
  }
  // ソートをcreate dateで降順にソート
  var sortRange = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn());
  sortRange.sort([{column: 3, ascending: false}, {column: 1, ascending: true}]);
}

/**
 * Qiita APIにアクセスしデータを取得します.
 */
function getHttpQiitaApiRequest(url) {
  // 認証トークンをセット
  var options =
      {
        'method' : 'get',
        'headers' : {
          'Authorization' : 'Bearer {認証トークン}'
        }
      };
  // HTTPリクエストを送信.
  var response = UrlFetchApp.fetch(url, options);
  // レスポンス結果を取得.
  var text = response.getContentText("UTF-8");
  // JSONパース.
  return JSON.parse(text);
}

/**
 * シートから重複するIDを検索します.
 * true: 既にIDが存在する場合. false: IDが存在しない場合.
 */
function findById(sheetdata, id) {
  for (var i in sheetdata) {
    // IDの重複チェック
    if (sheetdata[i][0] == id) return true;
  }
  return false;
}

/**
 * シートにデータを書き込みます. 
 */
function write(sheet, qitta) {
  // 最終行を取得.
  var n = sheet.getLastRow() + 1;
  // 日付の書式を変更
  var date = qitta.created_at.replace(/T/g, ' ').replace(/\+09:00/g, ' ');
  // データの書き込み
  sheet.getRange(n, 1).setValue(qitta.id);
  sheet.getRange(n, 2).setValue(qitta.title);
  sheet.getRange(n, 3).setValue(date);
  sheet.getRange(n, 4).setValue(qitta.url);
  var tag = "";
  for (var i in qitta.tags) {
    tag += qitta.tags[i].name + ",";
  }
  sheet.getRange(n, 5).setValue(tag);  
}

これを動かせば下図のような結果となります。



以上となります。
スケジューラーに組み込むと毎時更新とかが可能です。
Apps Scriptが思っている以上に色々できるので細々したの作成中です。

2015年11月25日水曜日

node.js配列データを同期処理する方法

Node.jsを利用し配列データを同期処理する方法を記載

どのように表現して良いかわからないのですが
以下のようなデータの処理です。


var datas = [{"id" : "1"}, {"id" : "2"}];

これを
id = 1
id = 2
と表示してくれるのを同期処理で書く方法です。
単純にfor文を利用すれば良いのではという話ではなく
datasはDBに保存したいデータとらえてください。

つまり実際には
INSERT INTO test(id) VALUES(1);
INSERT INTO test(id) VALUES(2);
と上記の処理をしたい比同期処理ではどちらが先にくるか不明のため
順番に配列からSQLを実行したい場合に考えた方法です。

結論的には再起処理を行います。
実際のサンプルは以下です。

function insert(datas, n, callBack) {
    if (datas.length == n) {
        if (callBack != null) callBack();
        return;
    }
    var sql = "INSERT INTO test(id) VALUES(" + datas[n].id + ")";
    console.log(sql);
    // 実際にここでSQLを実行.
    insert(datas, n + 1, callBack);
}

var datas = [{"id" : "1"}, {"id" : "2"}];
insert(datas, 0, function() {
    console.log("complite");
});
上記のようなソースになります。


INSERT INTO test(id) VALUES(1);
INSERT INTO test(id) VALUES(2);
complite
これで同期処理のようにできます。
ライブラリを使えばほかの方法もあると思うのですが
利用しない場合の考え方になります。

callback地獄感もありますが、これはこれで個人的には使い勝手が良いと思っています。

TensorFlowについて事前知識編【乱数生成】

Googleから出た話題の機械学習用のライブラリTensorFlow
こちらを触ろうと思い奮闘の備忘録

機械学習なんてやったことない+Pythonも初なのでサンプルを理解しようとするだけで必死とりあえず
ちょっとずつまとめ
※インストール手順等は公式ドキュメントとかを見て対応していただきますようにお願いいたします。
そのあたりはQiitaとかの方がすごく良いドキュメントがあります。

チュートリアルを見たらデータの生成があるのですが
まずはここからつまづいたのでまとめる

ランダムデータを作成する段階でわからなかった・・・・
じつはこの「np.float32」、「np.random.rand(2, 100)」はimport文を見たらわかるのですが
TensorFlowとは違いnumpyと言う数学用のライブラリです。
Python発なのでわからなかった(汗汗

と事前にnumpyについて少し備忘録をまとめます。

x_data = np.float32(np.random.rand(2, 100)) # Random input
これの意味ですが、0.0〜1.0までの乱数を2次元配列で100個作るという意味になります。

もっと値を小さくして2次元配列を5個つくるを実行
import numpy as np
x_data = np.float32(np.random.rand(2, 5))
print x_data
実行結果が以下

[[ 0.22113453 0.77961475 0.08531918 0.12012649 0.43397358]
[ 0.72542971 0.40160421 0.13799493 0.22445418 0.3758058 ]]


x_data = np.float32(np.random.rand(2, 5))
この中の2が次元を5が個数を表しているので変更すれば
相当な次元のデータが出来ると思います。


2次元配列で5個のランダム数が出来上がりました。
では、次に1〜10の少数にしたいであればどうするかは10をかけるだけです

import numpy as np
x_data = np.float32(np.random.rand(2, 5)) * 10
print x_data

[[ 5.39343119 5.11242962 2.86795855 7.04219055 6.99380398]
[ 1.75642431 2.2877152 8.44399357 4.74935007 5.61556864]]


高校数学の行列のイメージで0.0〜1.0の間の数字に10をかけてくれます。
ではさらに、1〜10の整数はどうするのか?
答えは以下です。

import numpy as np
x_data = np.int32(np.random.rand(2, 5) * 10)
print x_data

[[4 8 3 5 8]
[1 2 0 8 0]]


なんとなくfloat32をint32に変更すればうまいこといくと思ったのですが
先に10をかける必要がありました。 ということは0.0〜10.0までの少数も先に10をかけることも可能ということでした。
まだまだ難しい・・・

こちらを応用すれば整数は無限と出来ると思います。
64bit型がないか確認しところ以下できるみたいです。

x_data = np.int64(np.random.rand(2, 5) * 10)
x_data = np.float64(np.random.rand(2, 5) * 10)


なんかこれ以外とテストデータ作成もこれでできそうな気がしてたw
まずは基礎の基礎かと思いますが以上乱数生成に関する内容でした。

2015年9月28日月曜日

Node.jsを利用してYoutube APIにアクセスする。

Node.jsを利用したYootube APIのアクセスを行います。

まずはpackage.jsonを作りましょう。
npm利用のためです。

package.json
{
  "name": "youtube-sample",
  "version": "0.0.0",
  "description": "",
  "devDependencies": {
    "googleapis": "*"
  }
}

次にライブラリをインストールしましょう
先ほどのpackage.json同一フォルダで以下のコマンドを実行
npm install

本題の部分ですが先に認証ファイルを用意する必要があります。
ローカルで利用するためなのでoAuthの認証キーを取得する必要があります。

Google Developer Consoleへ移動し






認証情報へ移動します。

続いて「認証情報を追加」=>「サービスアカウント」を選択します。















最後に「JSON」を選択してダウンロードできるファイルを保存してpackage.jsonと同じフォルダーに置いてください












あとはただ使うだけだと10行前後で終わります。
youtube.js
var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var key = require('./{ファイル名をDLしたファイルに変更}.json');
var jwtClient = new google.auth.JWT(key.client_email, null, key.private_key, ["https://www.googleapis.com/auth/youtube"], null);
jwtClient.authorize(function(err, tokens) {
    if (err) {
      console.log(err);
      return;
    }
    var youtube = google.youtube({ version: 'v3', auth: jwtClient });
    youtube.search.list({"part" : "id,snippet", q: "node.js"}, function(err2, datas) {
        if (err2) {
            console.log(err2);
            return;
        }
        for (var i = 0; i < datas.items.length; i++) console.log(datas.items[i]);
    });
});

これであとは実行だけ
node youtube.js
とすれば結果が帰ります。
Google側が用意しているライブラリを利用すれば簡単に出来るので
あとは検索の種類とかをドキュメントから探すだけで良いです。

2015年3月29日日曜日

Rを使って株価の株価チャート出す

ちょっとRを触りだし株価のチャートが出せないか検討してのでまとめました。

株価のチャート?
ぱっと思いつくのがヒゲ? ロウソク?などです。
今回の内容でこのようなイメージができます。



とある株価の3ヶ月の推移です。
出ているのは株価、25日移動平均線、75日移動平均線
出来高などが出ています。

いろいろカスタマイズできるみたいですがまだ不明な点もあるので
現在鋭意ドキュメントを解読中

では実際に必要なデータはどのようなものかというと以下のCSVになります。
"Date","Open","High","Low","Close","Volume"
2015-01-01,220,224,219,222,68000
2015-01-02,217,218,211,211,100000
2015-01-03,212,213,208,212,44000
・
・
・
2015-03-25,212,213,208,212,44000
それぞれ、ヘッダーが
日付,初値,高値,安値,終値,出来高
を示しています。

データ自体は転がっているものをまとめて持ってきたとして
使い方をご説明します。

今回は以下の要件とします。
・ヒゲグラフを出す
・過去3ヶ月の内容を出す
・25日移動平均線を出す
・75日移動平均線を出す
・出来高をだす

上記を満たす実装を作ります。
早速ソースコード
install.packages("quantmod")
library("quantmod")
loadCsv <- "~/data.csv"

data <- read.zoo(loadCsv, header=T, sep=",")

candleChart(data, theme="white",subset="last 3 months")
addSMA(25, on = 1, with.col = Close, overlay = TRUE, col = "blue")
addSMA(75, on = 1, with.col = Close, overlay = TRUE, col = "red")

このようなコードで作成ができます。
Rの中でquantmodが実際に利用するライブラリです。

5行目のデータのロードまでは、おまじないとして割愛します。

data <- read.zoo(loadCsv, header=T, sep=",")
7行目の部分で、データを入れます。
header=T
こちらでヘッダーコードを無視(だと思う)

sep=","
セパレータの指定です。
データをロードすると後は、描画だけです。


candleChart(data, theme="white",subset="last 3 months")
こちらで、ベースとなるチャートを出します。

theme="white"
初期の色が黒背景なので、白背景に変えるのをお勧めします。(黒だと個人的には見えにく)

subset="last 3 months"
3ヶ月前を出す指示を与えます。
その他の場合は「2014::2015-01」のように記述します。
2014年から2015-01までを示しているのだと思うが正直まだ自信がない
日付の指定もできるのかなど検証中

addSMA(25, on = 1, with.col = Cl, overlay = TRUE, col = "blue")
addSMA(75, on = 1, with.col = Cl, overlay = TRUE, col = "red")
最後に2つの内容ですが移動平均を出します。
移動平均といっても正確には、単純移動平均になります。
最初の数値が何日分を指定

on = 1
いまのところ用途が不明だが表示系に関するものらしい

with.col = Close
カラムの指定になります。(おそらくこれであっている)

overlay = TRUE
描画を上書きするかの指定になります。
基本TRUEになると思います。

col = "red"
移動平均線の色を指定します。

このような感じで実行すれば株のグラフがつくれます
後は、保存するなりをするだけです。

まだ不明な点はあるのですがとりあえず。
動くものはできます。

思っている以上にドキュメンがなく苦労しました。

2015年2月6日金曜日

MacにMongoDB3.0をインストール

NoSQLを本格的に勉強しようと思いとりあえずMongoDB3.0をインストール

brewで行えば簡単そうですが、まだ(2015/02/06日現在)3.0できなさそうなので
手動にてインストール

インストール先
/Users/{ユーザ名}/mongoldb
※以後のユーザ名は自分の名前に書き換えて下さい.
$ cd ~/Downloads/
# DLと解凍しインストール
$ curl -O http://downloads.mongodb.org/osx/mongodb-osx-x86_64-3.0.0-rc6.tgz
$ tar -zxvf mongodb-osx-x86_64-3.0.0-rc6.tgz
$ mkdir -p ~/mongodb
$ cp -R -n mongodb-osx-x86_64-3.0.0-rc6/ ~/mongodb

# DLしたファイルを削除
$ rm -rf mongodb-osx-x86_64-3.0.0-rc6/
$ rm mongodb-osx-x86_64-3.0.0-rc6.tgz


# パスを通します.
$ echo "export PATH=/Users/{ユーザ名}/mongodb/bin:\$PATH" >> ~/.bash_profile
$ source ~/.bash_profile
$ mkdir -p ./data/db
$ mongod --dbpath ./data/db

# ちなみに以下のようにするとログが書き込みできます。
$ sudo mongod --dbpath ./data/db --logpath /var/log/mongodb.log



以下でアクセスするととりあえず動きました。
$ mongo
==================================
MongoDB shell version: 3.0.0-rc6
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings: 
2015-02-06T01:07:50.323+0900 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2015-02-06T01:07:50.323+0900 I CONTROL  [initandlisten] 
>
==================================


launchd/launchctlを利用し、起動時に実行できるようにします。
sudo vi /Library/LaunchDaemons/org.mongodb.mongod.plist
====以下を貼り付け=============================




        Label
        org.mongodb.mongod
        RunAtLoad
        
        ProgramArguments
        
                /Users/{ユーザ名}/mongodb/bin/mongod
                --dbpath
                /Users/{ユーザ名}/mongodb/data/db
                --logpath
                /var/log/mongodb.log
        


==========================

# 権限を付与
$ sudo chown root:wheel /Library/LaunchDaemons/org.mongodb.mongod.plist
$ sudo chmod 644 /Library/LaunchDaemons/org.mongodb.mongod.plist

# サービスの実行
$ sudo launchctl load /Library/LaunchDaemons/org.mongodb.mongod.plist

# サービスの停止
# sudo launchctl unload /Library/LaunchDaemons/org.mongodb.mongod.plist

次回に触ってみようと思います。
とりあえず今日はここまで