ページ

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が思っている以上に色々できるので細々したの作成中です。