線形計画法

勉強の参考にしたURL。

シンプレックス法(単体法:Simplex method)

http://www.th.cs.meiji.ac.jp/researches/2007/nakata/integer.html

Rで解く最適化問題 線型計画問題編


線形計画法は、最適化問題の一つ。
他にも、非線形計画法や動的計画法などがある。

遺伝的アルゴリズム最適化問題の解き方の代表例。
遺伝的アルゴリズムは、ナップザック問題や、巡回セールスマン問題などにも使える。

共起ネットワーク

テキストマイニングでよく使われる語の共起ネットワークを
トランザクションデータで使用してみた。

今回もアソシエーション分析に使用したものと同じデータを使用。

行:ID
列:メディア名
値:メディアへの接触フラグ

このトランザクションデータから、メディアの類似度を計算し、
その類似行列を用いて、ネットワーク図を描画する。
スクリプトは、KH Coderを参考にして作成。
KH Coder: 計量テキスト分析・テキストマイニングのためのフリーソフトウェア

# データの用意
dat <- read.csv("共起ネットワーク作成用データ.csv", header=TRUE)
dat2 <- as.matrix(dat)
dat3 <- t(dat2)


# 負の値を0に変換する関数
neg_to_zero <- function(nums){
temp <- NULL
for (i in 1:length(nums) ){
if (nums[i] < 0){
temp[i] <- 0
} else {
temp[i] <- nums[i]
}
}
return(temp)
}

# 類似度計算
d <- dist(dat3 ,method="binary")
d <- as.matrix(d)
d <- 1 - d;

# 標準化
std <- d
std <- t(std)
std <- scale(std, center=T, scale=F)
std <- t(std)

if ( min(std) < 0 ){
std <- std - min(std);
}
std <- std / max(std)

d2 <- std


# グラフ作成
new_igraph <- 0
if (as.numeric( substr(sessionInfo()$otherPkgs$igraph$Version, 3,3) ) > 5){
new_igraph <- 1
}

n <- graph.adjacency(d, mode="lower", weighted=T, diag=F)
n <- set.vertex.attribute(
n,
"name",
(0+new_igraph):(length(d[1,])-1+new_igraph),
as.character( 1:length(d[1,]) )
)


# edgeリストの作成
el <- data.frame(
edge1 = get.edgelist(n,name=T)[,1],
edge2 = get.edgelist(n,name=T)[,2],
weight = get.edge.attribute(n, "weight"),
stringsAsFactors = FALSE
)


# edge.widthを計算
edg_width <- el[,3]
if ( sd( edg_width ) == 0 ){
edg_width <- 1
} else {
edg_width <- edg_width / sd( edg_width )
edg_width <- edg_width - mean( edg_width )
edg_width <- edg_width * 0.6 + 2 # 分散 = 0.5, 平均 = 2
edg_width <- neg_to_zero(edg_width)
}


# 出力する円の大きさ
v_size <- 25


# エッジの色
# これはエッジの幅が太ければ太いほど色を濃くしている
edg_color <- rep("gray85", length(edg_width))
edg_color <- replace(edg_color, edg_width>2.0, "gray70")
edg_color <- replace(edg_color, edg_width>2.5, "gray40")


# ノードの形
# コメントアウトしてあるところを変えれば、特定のノードを好きな形に変えられる
v_shape <- rep("circle", length(colnames(d)))
# v_shape[9:10] <- "square"   

# ノードの色
# これもコメントアウトしてあるところを編集すれば、好きな色に変えられる
v_col <- rep("green", length(colnames(d)))
# v_col[6:8] <- "blue"
# v_col[9] <- "orange"
# v_col[10] <- "red"


# 描画
plot.igraph(n,
vertex.label = colnames(d),
edge.width = edg_width,
layout = layout.circle,
vertex.size = v_size,
vertex.color =v_col,
edge.color = edg_color,
vertex.shape =v_shape,
vertex.label.font=2,
vertex.label.color="black")

参考
igraphパッケージの使い方 1. グラフオブジェクトの作成と取り扱い - もうカツ丼はいいよな
統計的テキスト解析(6)~語のネットワーク分析~
ネットワーク分析 - ベイジアン・ネットワーク - yokkunsの日記

アソシエーション分析(バスケット分析)

基本的にアソシエーション分析をするときは、データはlist型で定義したものを
トランザクション型に変換(as(リスト名, "transactions"))して使用するが、
外部データ(csvなど)から読み込むときは、自動的にdata.frame型になってしまう。

外部データからデータを読み込みたいときは、以下のように実行する。

今回使用しているデータは、

行:ID
列:メディア名
値:メディアへの接触フラグ

ただし、この形式でなくともアソシエーション分析はできる。
(※読み込み方は以下とは異なる)
が、実際この形式でデータ持ってることの方が多い気がする…


以下、実行用スクリプト

# トランザクションクラスのデータを作成する
dat <- read.csv("アソシエーション分析用データ.csv", header=TRUE)
dat1 <- as.matrix(dat)
dat2 <- as(dat1, "transactions")

# 各アイテムの頻度をプロットする
itemFrequencyPlot(dat2)

# 相関関係を分析する
res <- apriori(dat2)

# アソシエーションルールの数を出力する
print(res)


# アソシエーションルールのトップ20を表示する
inspect(head(SORT(res, by = "support"), n = 20))


参考
http://mjin.doshisha.ac.jp/R/40/40.html
Rによるアソシエーション分析 - Qiita
kkaneko.com
R言語による アソシエーション分析-組合せ・事象の規則を解明する-(第5回R勉強会@東京)

GASでの日時データ

GASでの日時データの使用方法は
JavaScriptと全く同じらしい。

  • 今の日時を取得

var date = new Date();

  • dateから一日後の日時を取得

date.setDate(date.getDate()+1);

  • 時間を設定する

// dateの時間部分を21時に設定する
date.setHours(21,0,0);


とか。


参考
http://www.artemis.ac/contents/javascript/jsdate.htm

Google カレンダーとの連携

Googleカレンダーは、CalendarAppsオブジェクトを使うといろいろ操作が可能。

  • カレンダーオブジェクトを取得する
  • イベントを取得する
  • カレンダーを作る
  • イベントを作る

とか。

基本的にGoogleカレンダーGUIでできること
ほぼ全部できる。



ただ、イベントを作るときに、
「メールアドレスからゲストを招待し、同時に招待メールを送信する」
っていう指定ができるはずなんだけど、
それがどうも実行されない...

以下、スクリプト

// start_tは開始時間
// end_tは終了時間
// guests_listにはカンマ区切りのメールアドレス

cal.createEvent("test3", start_t, end_t,
{guests: guests_list_t,
sendInvites:true}
);

イベントを指定された条件で作成して、
ゲストを招待するところまでは実行されるんだけど、
招待メールはいつになってもやってこない。

なんででしょう。。







参考
[GAS][カレンダー]予定を作成するには : 逆引きGoogle Apps Script
Googleカレンダーにアクセスする(4/5):初心者のためのGoogle Apps Scriptプログラミング入門 - libro
[GAS][カレンダー]予定を作成するには : 逆引きGoogle Apps Scripthttp://www.artemis.ac/contents/javascript/jsdate.htm
Google Apps Scriptを使ってみよう! - サテライト原口社長のスクリプト指南(6) 今日の予定をカレンダーからメールで自動送信 | マイナビニュース

異なるスプレッドシートからセルをコピーする

-異なるシートを参照する
現在アクティブになっているスプレッドシートではなく、
ドライブ上にある別のスプレッドシートを参照したいとき
スプレッドシートのIDを指定することで参照できる。

SpreadsheetApp.openById(id)
スプレッドシートIdからスプレッドシートオブジェクトを取得する。

このidの取得方法は、2つあるっぽい。
1)URLから取得
 「https://docs.google.com/a/yourdomain/spreadsheet/ccc?key=[この部分]#gid=0」
  の[この部分]の英数字。

2)参照したいスプレッドシートのIdを表示させて取得

var sid = SpreadsheetApp.getActiveSpreadsheet().getId();
Browser.msgBox(sid);

上記を実行して、ウィンドウに表示された英数字。


1)でもうまくいくらしいんだけど、私はなぜかできず。
2)のほうで成功したので、私は2)を推奨。




-セルの情報をコピーする
copyToメソッドをつかう

var sheet = SpreadsheetApp.getActiveSheet();
var rangeToCopy = sheet.getRange(1, 1, sheet.getMaxRows(), 1);

//値と書式(シングルセル)A1をD1へコピー
rangeToCopy.copyTo(sheet.getRange(1, 4));

//値と書式(複数セル)A1:B4をD2:E5へコピー
var rangeToCopy = sheet.getRange(1, 1, sheet.getMaxRows(), 2);
rangeToCopy.copyTo(sheet.getRange(2, 4));

こんな風に使える。
ただし、copyToメソッドは同じシート内でしか使用できないため、今回は不使用。


setValue()でコピーする

var ss_copyFrom = SpreadsheetApp.getActiveSpreadsheet();
var ss_copyTo = SpreadsheetApp.openById('xxxxxxxxxx');
var sheet_copyFrom = ss_copyFrom.getSheetByName('部署一覧');
var sheet_copyTo = ss_copyTo.getSheetByName('部署一覧');

var copyValue = sheet_copyFrom.getRange('A2:B6').getValues();
sheet_copyTo.getRange('A2:B6').setValues(copyValue);


-その他注意

別のシートを参照するとき、getRangeを行列で指定することはできない。
今回は、最終行にデータをコピーしたかったため、以下のように実行。

var lastRow2 = list_sheet.getLastRow();
var lastRow21 = lastRow2 + 1;

var copyValue = sheet.getRange('A'+lastRow+':N'+lastRow).getValues();
list_sheet.getRange('B'+lastRow21+':O'+lastRow21).setValues(copyValue);

シングルクオーテーションとプラスで文字列が結合できるらしい。
今回は列を指定しなくていいからよかったけど、列の場所も変数で取得したい場合、
面倒くさそうだ。



参考
[GAS][スプレッドシート]別のスプレッドシートにデータをコピーするには : 逆引きGoogle Apps Script
[GAS][スプレッドシート]セルをコピーするには : 逆引きGoogle Apps Script
[GAS][スプレッドシート]Idからスプレッドシートオブジェクトを取得するには : 逆引きGoogle Apps Script
http://googlestyle.client.jp/sheet/class_range.html
長文日記

イベントハンドラとトリガー

Google Apps Scriptの勉強

イベントハンドラとトリガーについて。
「初心者のためのGoogle Apps Scriptプログラミング入門」より
スクリプトの実行とイベントハンドラ(2/5):初心者のためのGoogle Apps Scriptプログラミング入門 - libro

イベントに応じて何らかの処理を実行するためのもの
特に覚えておくべきは以下の2つの「シンプルイベントハンドラ」。

onOpen(event)スプレッドシートを開いたときに実行されます。開いたWebページをリロードした場合なども実行されます。

onEdit(event)スプレッドシートを編集したときに実行されます。編集中、あちこちのセルを書き換えるたびにイベントが発生し、このイベントハンドラが呼び出されることになります。

  • 使い方

/* シートを開いた時のイベントを指定 */
function onOpen(event){
var sheet = event.source.getActiveSheet();
sheet.getRange("A1").setComment("OPEN:" + event.user);
}

sheetには、イベント発生時にアクティブになっているシートが格納される。
setComment()はコメント挿入用関数。
event.userはシートを開いた人のアカウント名。

  • トリガーとは

特定のイベントが発生したら、指定の関数を実行するための仕組み。
インストーラブル・イベントハンドラ」と呼ばれる。
作成した関数をどのタイミングに実行するかをダイアログ上で選択できる。
選択は「リソースタブ」⇒「すべてのトリガー」または「現在のプロジェクトのトリガー」

「起動時」「フォーム入力時」だけでなく、
「イベント」をプルダウンすると「時間手動型」というものもあり、
定期的に更新を行うことができる。