2015年7月30日木曜日

Googleドライブの不要なファイルを自動で削除してみる 【リストアップ編】

こんにちは、井下です。

いよいよ高校野球の甲子園出場校が揃ってきましたね。
野球をやっていたわけではありませんが、一発勝負ならではの真剣みが伝わってきて、毎年時間があれば何となく見てしまいます。


ところで、みなさんはGoogleドライブはご利用でしょうか? "とりあえずのファイル共有"くらいの意識から手軽に使えるストレージサービスです。スプレッドシートを作成したり、保存されているスプレッドを開く場所と言えば、もっと分かりやすいかもしれませんね。

Googleドライブには容量制限がありますが、スプレッドシートやGoogleドキュメントなど、Googleの提供するサービスであれば、容量制限に関係なく、いくらでも作成することができます。

そのため、気が付いたら不要なファイルが大量に作成されている… なんてことも出てきます。(Googleの提供するサービスであれば)容量制限には関係ないとはいえ、不要なファイルがいくつもあるのはあまり良い気持ちにはなりません。


そこで、今回と次回はGoogle Apps Scriptを使って、不要なファイルを削除(※)してみようと思います。
なお、"不要なファイル"かの判断を自動で行うことは難しいので、"最終更新日から一定の日付が経過しているファイル"を"不要かもしれないファイル"とします。"不要かもしれないファイル"から人が見て確認したうえで、本当に"不要なファイル"だけを削除します。

(※)厳密にはゴミ箱への移動を行い、完全に削除はしません。Google Apps Scriptの仕様上、完全に削除することができないためです。また、オーナーが自分でない場合はゴミ箱への移動もできないため、厳密に言えば"オーナーが自分で、不要なファイルをゴミ箱へ移動する"となります。

方法としては、次の手順を踏みます。

  1. "最終更新日から一定の日付が経過しているファイル"をスプレッドシートにリストアップする(不要かもしれないファイルの一覧作成)
  2. リストアップされたファイル名から、不要なファイルのみを削除する

今回は手順の1を実装・説明します。
手順の2は次回実装・説明する予定です。

2015年7月28日火曜日

JavaとRubyの共通点と、相違点について

こんにちは。

これでもか!というくらい、毎週車のホイールを磨いている鷲尾です。
彼女は車内で3DS、私は汗ダラダラでホイールをゴシゴシ。
文句も言わず洗車に付き合ってくれる彼女に感謝です。


さて、前回は機械学習の持つ可能性と、こんなのがあったらどうだろう、という記事を紹介したかと思います。
今回は少し趣向を変え、RubyとJavaの共通点や、書き方の違いなどについて、お話したいと思います。


Ruby(ルビー)とは?
みなさんは、Rubyというプログラミング言語を聞いたことはありますか?
なんとなく聞いたことがあるという方や、バリバリ使っているよという方もいらっしゃると思います。

Rubyとは、まつもとゆきひろ氏(通称:Matz)によって開発された、オブジェクト指向スクリプト言語のことです。インタプリタ言語(※)なので、書いたソースはコンパイルせずに、すぐに実行することが出来ます。

※インタプリタ言語
コンパイル作業が必要なく、ソースファイルをそのまま実行することが出来る言語の種類のこと。速度はコンパイル言語に劣るが、コンパイルする手間が省けるので、コンパイル型言語と比較して開発効率がいいとされている。


■Rubyの特徴
Rubyはオープンソースなので、誰でも無料で利用することが出来ますし、マルチプラットフォームなのでWindows,Linux,Mac OSなど、様々な環境で実行することが出来ます。

以前はあまり知名度が高くなかったRubyですが、現在は様々な企業で自社サイトの開発などに使われる、非常にメジャーな存在になっています。
みなさんも一度は使ったことがあるであろう、レシピサービスを展開するクックパッドのサービスも、Rubyのフレームワーク"Ruby on Rails"を使って開発されています。


■JavaとRuby
オブジェクト指向言語と聞いて初めに思い浮かぶであろうプログラミング言語は、Javaではないでしょうか。Rubyと同じようにオブジェクト指向言語であるJavaは非常に人気があり、様々な場所で使用されています。
また、同じオブジェクト指向言語であるために、言語としての仕様も似ているところがあります。

では、RubyとJavaの共通点、相違点について、見てみましょう。
参考:http://www.atmarkit.co.jp/ait/articles/0803/25/news152.html


2015年7月23日木曜日

Googleカレンダーを元にした作業実績を作成する

こんにちは、井下です。

いよいよ近所の公園でもセミの声が聞こえてきましたが、みなさんの周りはいかがでしょうか?
通勤ルートに小学校があるのですが、彼らは夏休みを満喫中なんですよね。なんとも羨ましい…。

さて、今回は前回予告していた通り、Googleカレンダーを元にして、作業実績を作成します。

イメージ図(前回のものを再掲)



Googleのサービスの関係は下記の図のようになります。



では、実現したコードを見てみましょう。
HOUR_MILLISECOND = 60 * 60 * 1000;
DATE_MILLISECOND = 24 * HOUR_MILLISECOND;

function run() {
  // 出力先スプレッドシートとシートの設定
  var SSHEET_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  var SHEET_NAME = "YYYYY"

  // 出力先スプレッドシートのシートを取得
  var sheet = SpreadsheetApp.openById(SSHEET_ID).getSheetByName(SHEET_NAME);

  // 日付範囲の設定
  var DATE_TERM = 5;
  var startDate = new Date("2015/7/20");
  var endDate = new Date(startDate.getTime() + DATE_TERM * DATE_MILLISECOND);

  // デフォルト(初期表示)されるカレンダーを選択
  var cal = CalendarApp.getDefaultCalendar();

  // カレンダーのイベントを取得
  var events = cal.getEvents(startDate, endDate);

  var row = 0;
  var column = 0;
  var works = [""];
  var result = [[""]];

  for(var index in events) {
    // イベントの名前、作業時間、実施日を取得
    var title = events[index].getTitle();
    var workTime = getWorkTime(events[index]);
    var targetDate = getTargetDate(events[index]);
 
    // イベントの名前がループ中に出てきたかを確認
    row = works.indexOf(title);
 
    // イベントの名前がループ中初めて出てきた場合
    if(row == -1){
      row = works.length;
      result[row] = [];
      result[row][0] = title;
   
      works.push(title);
    }
 
    // イベントの実施日がループ中初めて出てきた場合
    if(index == 0 || targetDate != getTargetDate(events[index - 1])){
      column++;
      result[0][column] = targetDate;
    }

    result[row][column] = result[row][column] == null ? workTime : workTime + result[row][column];
  }

  sheet.clear();

  // 1行目(日付表示の行)の取得・書き込み
  var header =  getDateRow(result[0]);
  sheet.getRange(1, 1, 1, header.length).setValues(new Array(header));

  // 2行目以降の取得・書き込み
  for(var sRow = 1; sRow < result.length; sRow++) {
    var writeRow = getWriteRow(result[sRow]);
    sheet.getRange(sRow + 1, 1, 1, writeRow.length).setValues(new Array(writeRow));
  }
}

function getDateRow(arrray){
  var dateRow = arrray;
  dateRow.splice(1, 0, "合計");

  return dateRow;
}

function getWriteRow(arrray){
  var writeRow = replaceArrayNull(arrray);
  var totalWorkTime = getTotalWorkTime(arrray);
  writeRow.splice(1, 0, totalWorkTime);

  return writeRow;
}

function replaceArrayNull(arrray){
  for(var index = 0; index < arrray.length; index++){
    if(arrray[index] == null){
      arrray[index] = "";
    }
  }
  return arrray;
}

function getTotalWorkTime(arrray){
  var total = 0;

  for(var index = 0; index < arrray.length; index++){
    if(isFinite(arrray[index]) && arrray[index] != ""){
      total += arrray[index];
    }
  }
  return total;
}

function getWorkTime(event){
  return (event.getEndTime() - event.getStartTime()) / HOUR_MILLISECOND;
}

function getTargetDate(event){
  var sourceDate = event.getStartTime();
  return (sourceDate.getMonth() + 1) + "/" + sourceDate.getDate();
}

赤字部分は実行環境に応じて必ず書き換えてください。
なお、"SSHEET_ID"には出力先として指定するスプレッドシートのIDを指定し、そのスプレッドシートのどのシートに出力するかを、"SHEET_NAME"(こちらはシート)に指定します。
青字部分は実行時の都合に応じて書き換えてください。
カレンダーから抜き出す情報の開始日を"startDate"に指定し、開始日から何日分を取得するかを"DATE_TERM"に指定します。

実際に次のようなカレンダーに対して実行すると…

こんな感じに出力されました。


カレンダーの画像が小さくて分かりづらいですが、同じ作業が別の日にあった場合、行は1つに統一するようになっています。(具体的には"打ち合わせ"が7/21と7/24にあるところと、"開発"が7/22と7/24にあるところです)

なお、イベントが1つもない日(上記の図で言えば7/23)は、列が作成されない仕様なので、その点は注意してください。
他に注意するべき仕様として、終日の予定は24時間としてカウントします。

全ての予定と実績をGoogleカレンダーに書き込んでいる方は稀だと思いますが、日常的にGoogleカレンダーを業務で利用している方は、本当の作業実績を作成するための一助としてご利用ください。

2015年7月21日火曜日

人間も犬も猫もインターネットに接続出来る今、機械学習で今後どんなことが出来そうか考えてみる

こんにちは。

ストレートネック鷲尾です。

先日あまりにも体調が悪いので病院へ行ったらすぐにレントゲンを撮られて、「これはこれはキレイにストレートネックになっていますね」と言われました。

「なんだただ姿勢が悪いだけでしょ」と思う事なかれ、これがまた結構キツイんです。
まさか首が原因でそんなことまで起きるの!?なんて症状がたくさんあります。

・頭痛がする
・肩がこる
・首が痛い、首が動かない
・上が向きにくい
・めまい、ふらつき感がある
・手のしびれがある
・寝違いを繰り返す、枕が合わない
・吐き気がする
・自律神経失調症
参考:http://www.straight-neck.com/

などなど・・・。 どうりで・・・。
他にも目が痛い、目が疲れるなんてのもありますね。

現在は薬を飲んで塗って電気治療をしてあれやこれやをしていますが、なんとか苦痛を和らげたいもんです。皆さんも普段からスマホを触ったりパソコンの画面をじーっと見ていることがあると思いますが、割りと重症らしいのでくれぐれも気をつけてくださいね。


さて、前回は人工知能の最新情報や、進化しすぎた人工知能の危険性などについて、お話をしました。
前回はさらっとしか触っていませんでしたが、今回は人工知能の中でも「機械学習」について、お話したいと思います。


■機械学習とは
そもそも機械学習とはなんでしょうか。呼んで字のごとく、機械が学習すること。ですが、
もう少し詳しく書くと、

人間が自然と行っているパターン認識や経験則を導き出したりするような活動を、コンピュータを使って実現するための技術や理論、またはソフトウェアの総称” 


だそうです。
参考:http://www.weblio.jp/content/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92

例えば、機械学習のアルゴリズムの一種に、「ニューラルネットワーク」というものがあります。これは、人間の脳が考える回路を模してコンピュータに処理をさせる技術のことを言います。

2015年7月16日木曜日

Google App ScriptでGoogleカレンダーの情報を抜き出してみる

こんにちは、井下です。

これまでGoogle Apps Scriptからの連携として、主にスプレッドシートやFusion Tables、Google Analyticsについてご紹介してきましたが、今回はGoogleカレンダーとの連携方法についてご紹介しようと思います。

GoogleカレンダーはGoogleから提供されるサービスの中でも比較的利用されていると思います。業務で利用されている方も少なくないのではないでしょうか?


では、早速Google Apps Scriptのプロジェクトを起動し、次のコードを実行してみてください。
function myFunction() {
  var cal = CalendarApp.getDefaultCalendar();
  var startDate = new Date("2015/7/13");
  var endDate = new Date("2015/7/18");
  var events = cal.getEvents(startDate, endDate);

  for(var index in events) {
    Logger.log(events[index].getTitle());
    Logger.log(events[index].getStartTime());
    Logger.log(events[index].getEndTime());
  }
}
※1 Google Apps Scriptのプロジェクト作成方法は過去のブログ("Google Apps Scriptを使う準備"のあたり)をご参照ください。
※2 "startDate"および"endDate"は、取得したい日付の範囲に応じて変更してください。

実行が終わったら、ログを確認してみましょう。

指定した期間内でスケジュールしていた予定の名前、予定の開始日時、予定の終了日時が出てきています。

コードの中身を簡単に説明すると、1行目の"var cal = CalendarApp.getDefaultCalendar()"で連携先のカレンダーを指定しています。"getDefaultCalendar"とあるように、ユーザのデフォルトのカレンダー(Googleカレンダーを開いたとき、最初に開いているカレンダー)を連携先にしています。
ちなみにカレンダーのIDやカレンダーの名前と言った情報を元に、他のカレンダーを連携先に指定することもできます。その場合は"getDefaultCalendar"に代わって、別のメソッドを利用することになりますが、今回は割愛します。気になる方は、Google Apps Scriptのリファレンスをご参照ください。

5行目の"var events = cal.getEvents(startDate, endDate);"で、実際にカレンダーに入っている予定の情報を全て取得しています。(あくまで"startDate"~"endDate"の範囲内のですが)

そして7~11行目で取得した予定の情報から、予定の名前、予定の開始日時、予定の終了日時をログに出力させています。


もちろん、"予定の情報"は予定の名前以外に、様々な情報を持っています。予定の開始時刻や終了時刻、自分以外の予定の参加者(ゲスト)、予定に書いた説明など、"予定"として作成したときに入力したデータなら、取得することが可能です。

逆にGoogle Apps Scriptを使って、予定の情報を書き換えることもできます。取得に比べると用途が限られそうですが、自動で予定を入れたい場合などに使えるでしょうか。


今回は触り程度でしたが、次回はGoogleカレンダーの情報を元に、作業の実績時間を表にして、スプレッドシートへ出力してみようと考えています。

イメージ図

企業に勤めている方は、何の作業にどれだけ時間を使ったか、報告を求められることが多いと思いますが、(Googleカレンダーに予定と実績を入れておくことで)後から時間を計算する手間を省くことを目標にします。

2015年7月14日火曜日

最新の人工知能技術の進化に付随する問題と、これからの人工知能について考えてみる

こんにちは。

夏休みに埼玉から秋田 → フェリー → 北海道と、車で帰郷する予定の鷲尾です。
最近の車は一定の速度のままアクセルを自動で固定したりしてくれまして、長い高速もあまり苦にならないそうですね。



さて、最近研究者の間で盛んな議論がされているトピックスといえば、そう、人工知能(AI)ですよね。
もちろん他の話題もたくさんあるわけですが、グーグルトレンドを見てみると、最近人工知能を検索する人が増えているようです。

たぶんですが、先日放送していたアニメ「サマーウォーズ」も、一役買っているのではないかと思います。あれは、非常に簡単にまとめると(語弊を恐れずにいうのであれば・・・)、暴走した人工知能をみんなの力で倒しましょうというような内容の映画です。これ、非常におもしろいので見てない人は是非見てみてください。

人工知能を扱った映画などは過去にもたくさんありますが、最近の人工知能は、もう映画のようなことが実現できそうなレベルまできています。しかし、人工知能があまりにも進化しすぎてしまって、人間の手に負えなくなるかもしれないと、危惧している研究者もたくさんいます。


そこで今回は、人工知能に関する様々な意見を交えながら、人工知能について書いていきたいと思います。


■人工知能とは
そもそも人工知能ってなんでしょうか。パソコンの中に誰かいるわけではありませんよね?
人工知能の定義は、「コンピュータを使って、学習・推論・判断など人間の知能のはたらきを人工的に実現したもの。」です。人工知能学会では、「知能をもった機械」とも説明されていますね。

人工知能を理解する上でもっともわかりやすいのは、そう、我らがドラえもんだと思いますが、実は人工知能には種類があります。

・本当に知能がある人工知能(システム)
・本当に知能があるように見える人工知能(システム)


本当に知識がある人工知能とは、「推論・探索・知識表現」などを行うことを目的としていますが、まだまだ人間にそれには遠く及ばないと言われています。しかし、これらの技術は、昨今の人工知能研究の基板となっており、その応用された技術は、「本当に知能があるように見えるシステム」として、私たちの身の回りに溢れています。



例えば、以下の様な例があります。

・音声認識
マイクに向かって話した内容をコンピュータに理解させる研究。最も身近なものは、iPhoneに搭載されている「Siri」かと思います。AndroidのOK Googleなども同じですね。

・機械学習
これは音声認識ともかぶりますが、文字通り、機械に学習する機能を持たせたものですね。機械学習は特に最近ホットな話題として、盛り上がりを見せています。
機械学習についてはまた今度、改めて紹介したいと思います。


人工知能は他にも様々な分野で応用されていて、いまや私たちの生活になくてはならないものになっています。


2015年7月9日木曜日

Google AnalyticsのデータをGoogle Apps Scriptを使ってSpreadsheetに出力する(自動化対応・条件追加等)

こんにちは、井下です。

前回はGoogle Apps Scriptを利用して、Google AnalyticsのデータをSpreadsheetに出力してみました。

これで画面上からは見られなかった、3つ以上のディメンションで絞り込んだデータを見られるようになりましたが、前回のサンプルコードのままだと少し不便なところがあります。

例えば…
  • データ取得範囲を決める開始日・終了日が固定値なので、自動で実行しても意味がない
  • 出力先が常に同じシートなので、実行するたびに上書きされてしまう
  • ヘッダーがないので、ぱっと見てどの行が何のデータなのか分かりづらい
  • 検索キーワードが"not set"になっているデータなど、不要なデータは出力させないようにしたい

今回は上記の4点について、修正を行ったサンプルを書いていきます。


ちなみに、前回書いたサンプルコードはこちらです。
function analytics() {
  var PROFILE_ID = "ga:zzzzzzzz";

  var metrics = "ga:sessions, ga:percentNewSessions, ga:newVisits";
  var optArgs = {
    'dimensions': 'ga:keyword, ga:region, ga:networkDomain',
  };
  var startDate = "2015-06-01";
  var endDate = "2015-06-29";

  var ga = Analytics.Data.Ga.get(PROFILE_ID, startDate, endDate, metrics, optArgs).rows;
  var sheet = SpreadsheetApp.getActiveSheet();

  sheet.getRange(1, 1, ga.length, ga[0].length).setValues(ga);
}
※赤字部分は変更必須、青字部分は任意の値に変更する前提です


修正1 開始日・終了日を可変にする

Google AnalyticsとGoogle Apps Scriptの連携させる意義として、定期実行における自動化ができることを前回挙げています。
そのためにはデータの取得範囲の開始日・終了日を実行日に応じて可変にすることと、Google Apps Scriptのトリガー機能の設定が必要になります。

まず、下記のサンプルコードによって、開始日・終了日を実行日に応じて可変にします。
function analytics() {
  var PROFILE_ID = "ga:zzzzzzzz";
  var START_DATE_OFFSET = 8;
  var END_DATE_OFFSET = 1;

  var metrics = "ga:sessions, ga:percentNewSessions, ga:newVisits";
  var optArgs = {
    'dimensions': 'ga:keyword, ga:region, ga:networkDomain',
  };

  var nowDate = new Date();
  var startDate = dateFormat(new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate() - START_DATE_OFFSET));
  var endDate = dateFormat(new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate() - END_DATE_OFFSET));

  var ga = Analytics.Data.Ga.get(PROFILE_ID, startDate, endDate, metrics, optArgs).rows;
  var sheet = SpreadsheetApp.getActiveSheet();

  sheet.getRange(1, 1, ga.length, ga[0].length).setValues(ga);
}

function dateFormat(date) {
  return date.getFullYear() + '-' + ('0' + (date.getMonth() + 1) ).slice(-2) + '-' + ('0' + date.getDate()).slice(-2);
}
サンプルコードでは、「1週間分のデータを抽出」する例としています。

なお、データの日付範囲を変更したい場合は、"START_DATE_OFFSET"および"END_DATE_OFFSET"の値を変更してください。
"START_DATE_OFFSET"は日付範囲の開始日が実行日の何日前か、"END_DATE_OFFSET"は日付範囲の終了日が実行日の何日前かを決めています。

修正2 実行タイミングの自動化

次にトリガー機能の設定です。
Google Apps Scriptには定期実行や、特定の動作がされたときのみ実行するトリガー機能が用意されています。

トリガー機能の設定はGoogle Apps Scriptの[リソース]>[現状のプロジェクトのトリガー]から行います。


最初は何も設定されていないので、ダイアログに表示されているリンクをクリックして設定画面を開きます。

2015年7月7日火曜日

個人情報流出問題にみる、標的型攻撃の脅威と情報セキュリティを考える上で大切なこと

こんにちは。

鷲尾です。

今は梅雨真っ盛りで、どうも天気がパッとしないですね。
天気だけでなく、湿度も高くてジトジトしていますが、実は湿度と気温は大きく関連しています。

なにをいまさらと思うかもしれませんが、湿度が高ければ高いほど暑く感じ、低ければ低いほど寒く感じます。夏は気温が高いうえに湿度も高く、冬は気温が低いのに乾燥していて湿度も低いため、より寒く感じるということなんですね。

ということは、室温をただ下げるのではなくて一緒に除湿機も使うとより涼しくなるということですね。(まぁエアコン自体、除湿もしてくれるんですけどね・・・)


さて、みなさんマイナンバー制度はもうご存知ですよね。
以前このブログでも軽く取り上げていますが、Googleトレンドを見てみると、ここ最近急に気になっている人が多いようです。

マイナンバーに関しては、先日の日本年金機構の個人情報125万件流出の件がありましたね。あれ、メールに記載されていた怪しい誘導URLをポチっと押してしまったことが直接の原因ではあるようですが、他にもまずいことがあったようですね。

とりあえず、今のところ今後のマイナンバー制度の施行スケジュールにあまり変化はないようですが、どうなんでしょう・・・


そこで今回は、日本年金機構の個人情報流出問題と照らし合わせながら、「標的型攻撃の脅威」と、「いかにサイバー攻撃に遭わないようにするか」、そして「情報セキュリティを考える上で大切なこと」について、書いていきたいと思います。


■標的型攻撃の脅威
今回の個人情報流出問題の原因は、"それっぽいメール"に書いてあった"それっぽいURL"を開いてしまったことが原因です。

ネット上では、「そんな怪しいURLすぐにわかるだろ」「業務に関係ないメールだと気が付かないほうがおかしい」といった意見もみられます。確かに、標的型攻撃ではなく、不特定多数に送るような"明らかに怪しい内容のメール"であれば、すぐに気がついたかもしれません。

しかし標的型攻撃の恐ろしいところは、実在する会社、部署名、名前、それに送信先の名前(○○様 など、自分の名前)などが正確に記載してあることです。

普段やりとりしているお客様の名前や、会社の上司を名乗るメールで、内容もおかしくなく、添付されているファイル名もなんら不審に見えないメールが届いたとして、みなさんは本当に簡単にわかるでしょうか。

標的型攻撃で作成されるメールは非常に巧妙で、こちらがファイルを開くことになんら懸念がないよう、うまーく作られているのです。




2015年7月3日金曜日

Google AnalyticsのデータをGoogle Apps Scriptを使ってSpreadsheetに出力する

はじめに

こんにちは、井下です。

本ブログでは過去に数回、Google AnalyticsとGoogle Apps Scriptの連携について触れていますが、顧みてみると実装方法についてあまり説明していませんでした。そこで、今回はGoogle AnalyticsとGoogle Apps Scriptの連携させる際の実装方法について、具体的なコードを交えて説明していきます。

また、初歩的な手順についても説明していきますので、Google Analyticsを使ってるけど、Google Apps Scriptって難しそうで分からない、という方もご参考ください。

ちなみに…。
Google AnalyticsとGoogle Apps Scriptの連携させる意義ですが、大きく2つあると考えています。

  1. 定期的にデータを出力させることで、計測したいデータの推移をすぐ見られるようにする
  2. 3つ以上のディメンションを組み合わせたデータを分析したい

1つ目は計測したいデータが決まっていて、なおかつ分析手法も確立されている状態で、データだけ定期的に欲しいというパターンですね。手動でもデータを取ることはできますが、決まりきったデータの取得はやはり自動化したいものです。

2つ目はGoogle Analyticsの仕様が絡んでくるお話です。
Google Analyticsを利用している方はご存じだと思いますが、Google Analyticsはメインとなっている指標(プライマリディメンション)に、もう一つの指標(セカンダリディメンション)を絡めて、細分化したデータを見ることができるようになっています。

例えば、下図はプライマリディメンションに"キーワード"(オーガニック検索キーワード)、セカンダリディメンションに"地域"を選択しています。つまり、ブラウザからの検索キーワードごとに、どの地域(日本であれば都道府県レベル)からの参照が多いのかが分かるデータが表示されています。

では、さらにどんなユーザが参照しているのかの手がかりとして、"ネットワークドメイン"を指標として細分化したデータが見たくなります。が…。

Google Analyticsの画面からでは、セカンダリディメンション以降のディメンションを設定してデータを細分化することができません。(2015年7月時点)
この仕様は詳細な分析をしたい人にとって、意外と大きい落とし穴になっているのではないでしょうか?

ただし、その仕様はあくまで画面上からの操作に限られるようで、実はGoogle AnalyticsとGoogle Apps Scriptを連携させることで、3つ以上のディメンションを組み合わせたデータを出力させることができます。
セカンダリディメンションまでだと、分析し足りない!と考えている方は、Google Apps Scriptを学ぶ価値が大いにあるということです。


以降は実際にGoogle AnalyticsとGoogle Apps Scriptを連携させる手順について説明します。
以前も書いた内容&前提の準備が含まれていますので、ご存知の方はページ中段までお進みください。

手順は以降の順に説明していきます。

Google Apps Scriptを使う準備
Google Apps ScriptからGoogle Analyticsを使う準備
Google AnalyticsのデータをGoogle Apps Scriptで取得する