takeshi kiura のすべての投稿

Spotfireと飲酒。ヨガと仏教と宇宙論を嗜んで生きています。

複数ファイルの一括取り込み

ファイル一括取り込みツール

Spotfireで日ごとに生成されるような複数ファイルをマージして使う場合、行の追加機能を使います。

便利な機能ではあるのですが、一度に一つのファイルしか取り込むことができないため
10ファイルある場合は10回同じ操作を繰り返す必要があります。
2
↑100個のファイルは気合で100回マージだ!

あまり楽しい作業ではないので、一括取り込みのカスタムツールをご紹介します。

こちらからダウンロードしてください。

マニュアルダウンロード

解凍後のSPKファイルをSpotfireサーバー上からデプロイする必要があります。
※デスクトップ版では使用不可能です。ご容赦ください。

対応バージョンは6.5、7.0、7.5,7.6に対応しています。
対応ファイル形式はテキストファイルのみです。Excelファイルなどには対応しておりません。

使用方法

使い方は簡単です。
デプロイしてAnalystに反映されると「ツール」に
「複数テキスト一括取り込み」というメニューが追加されます。
1

選択するとメニューが表示されますので「ファイル追加」ボタンからマージしたいファイルを選択します。
6

「OK」を押すと選択ファイルをマージしたデータが取り込まれます。
4

内部的には「ローの追加」作業を繰り返しているだけなので作成したDXPファイルはWebPlayer上でも動作します。
5

有償版との違い

今回ご紹介したのはフリー版になります。
有償版との違いは

  • 日英中3か国語対応(フリー版は日本語のみ)
  • ファイル検索可能(拡張子、ファイル名、日付での条件指定が可能)
  • Web Player Serverで動作 (オープン時再検索可能)
  • ドキュメント付

などになります。

2017/9/6 最新版に差し替えました。
旧バージョンとの違いは下記となります。
1.一度のUndoで一括追加分戻れるように変更
2.データ取込み後の自動立上げビジュアライゼーションをテーブルに変更
3.発行元署名ファイルを最新版に差し替え(署名なし、の警告表示防止)
4.その他軽微なバグ修正

ご興味のある方は日本TIBCOまで

データの横変換

データの横変換

データの横変換にはピボット処理を使用します。
集計結果として確認したい場合はクロス集計表で十分ですが、
データテーブルとして同じ形式のデータを持ちたい場合に使用します。

主に他のデータと結合する際にキーカラムが一対一になるように集計したり、
相関を取る為にはデータを横持ちにする必要があります。

今回は縦長のデータをピボットで集計したデータテーブルを作成します。

3

データ変換

「データテーブルの追加」
データ変換の中のピボット処理を使用します。
「ファイル」→「データテーブルの追加」を選択します。
1

取り込む元データはこのような縦長のデータです。
2

データソースを選択したら変換メニューを開きます。
「変換」から「ピボット」を選択してください。
4

ピボット処理

データのピボット画面になるので、
ローの識別子に縦項目、カラムタイトルに横項目を設定します。
「値および集計方法」が実際に集計される値になります。

今回は一つずつですが、それぞれ複数項目も設定可能です。
5

カラムの命名パターンですが’%M(%V) (%C用)’だと非常に長いので
‘%C’にしてしまう事がほとんどです。

こちらが変換後のデータです。
6

せっかくなのでData Relationshipsで相関を見てみましたが、
それほど優位なペアはなさそうですね。
7

データの縦変換

データの縦変換はアンピボット処理

アンピボット処理によりデータを縦変換します。

以下の例は、単純なアンピボット変換を示しています。元のデータテーブルには、3つのカラムと 4つのローがあります。それぞれのローには、都市と朝の気温、および夕方の気温が含まれています。
データをアンピボットすると、朝夕の気温ごとに 1 つのローが作成され、倍の8ロー分のデータに変換されます。

2

データ変換

アンピボットはデータ変換メニューの中にあります。
まずは「ファイル」→「データテーブルの追加」を開きます。

1

今回取り込むのはこのようなデータです。
日付けなどがカラムとして横に長いデータになっている場合は、時系列として扱う事が出来ないので、アンピボット処理が必要になります。

3

データテーブルの追加メニュー

4

データを指定後、「変換」メニューから「ピボットの解除」を選択し「追加」ボタンを押します。
※「変換」メニュー表示されてない場合は「変換(追加された変換ステップはありません)を表示する」をクリックしてください。

ピボットの解除処理

5

左にカラムの一覧が表示されます。右には「移動するカラム」と「変換するカラム」という欄があります。
「移動するカラム」はキーカラムとして変換後も保持するカラムを選択し、
「変換するカラム」は縦変換したいカラムを選択します。

画面下のサンプルで変換後のイメージを確認できますので、間違いがないか確認できます。

6

実行するとデータが変換されます。
縦長のデータになっています。

7

棒グラフを作成してみました。
横軸で日付を指定しましたが、日付として階層で表示されています。

マークデータをDBへ書き込み

Spotfireはデータ分析には非常に便利なのですが、
解析した結果をデータベースに残すことはできません。

結果をエクスポートしてデータベースにInsertする作業は非効率ですし、
複数のツールを行ったり来たりする手間が非常に面倒くさいです。

そんな時にはやはりPython!
一つのインターフェースで様々な機能を実装できるのはすごく便利です。

Spotfireからデータベースに書き込みをする。

Pythonスクリプトを使用して、Spotfireのマーク済みのデータをSQL Serverに書き込んでみました。

使うデータはBaseBallです。
マークした範囲の選手名をSQL Serverのテーブルに書き込みましょう。

1

実行イメージ

このようにサラリーが高いのにホームランをあまり打っていなさそうな人を選択してDBに記録します。

2

ボタンを押すとPythonがSQL ServerにInsertして、処理内容をメッセージボックスで通知します。

3

実行後のテーブルデータ
ちゃんと4人分入っています。

テーブル定義

書き込み先のテーブルはBaseballRecordという名前で
一カラムしかないのですが一応ソースはこちらです。

CREATE TABLE [dbo].[BaseballRecord](
	[Name] [varchar](50) NULL
) ON [PRIMARY]

GO
Pythonコード

データベースの接続情報は環境に合わせて変更してください。

#SQL Server Setting
import clr
clr.AddReference('System.Data')
from System.Data import *
TheConnection = SqlClient.SqlConnection("server=servername;database=database;uid=sa;password=password")
TheConnection.Open()

#MsgBox用
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox

#マークからデータ取得用
from Spotfire.Dxp.Data import DataValueCursor

#マークされた行からデータを抽出
myCursor = DataValueCursor.CreateFormatted(Document.Data.Tables["Baseball"].Columns["Player Name"])
markedRows = Document.Data.Markings["マーク"].GetSelection(Document.Data.Tables["Baseball"]).AsIndexSet()

totalCount = 0 

#SQL Serverへアクセス
for row in Document.Data.Tables["Baseball"].GetRows(markedRows, myCursor):
 print  myCursor.CurrentValue
# 処理SQLの作成と実行
 sqlcmd = "insert into BaseballRecord values ( '" + myCursor.CurrentValue +"')"
 MyAction = SqlClient.SqlCommand( sqlcmd , TheConnection)
 totalCount += MyAction.ExecuteNonQuery()

TheConnection.Close()
MessageBox.Show( str(totalCount) + "人分追加しました。")

挿入処理後にデータテーブルをリフレッシュ

スクリプトを少し改良しました。
Insert対象のBaseballRecordテーブルをデータテーブルとして追加して、
処理後にリロードをするようにしました。
これでボタンを押した後に追加データを確認できます。
スクリプトとしては最初と最後に数行追加したのみです。

4

#テーブルリフレッシュ用に追加
from Spotfire.Dxp.Data import *
from Spotfire.Dxp.Data.Import import *

#SQL Server Setting
import clr
clr.AddReference('System.Data')
from System.Data import *
TheConnection = SqlClient.SqlConnection("server=servername;database=database;uid=sa;password=password")
TheConnection.Open()

#MsgBox用
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox

#マークからデータ取得用
from Spotfire.Dxp.Data import DataValueCursor

#マークされた行からデータを抽出
myCursor = DataValueCursor.CreateFormatted(Document.Data.Tables["Baseball"].Columns["Player Name"])
markedRows = Document.Data.Markings["マーク"].GetSelection(Document.Data.Tables["Baseball"]).AsIndexSet()

totalCount = 0 

#SQL Serverへアクセス
for row in Document.Data.Tables["Baseball"].GetRows(markedRows, myCursor):
 print  myCursor.CurrentValue
# 処理SQLの作成と実行
 sqlcmd = "insert into BaseballRecord values ( '" + myCursor.CurrentValue +"')"
 MyAction = SqlClient.SqlCommand( sqlcmd , TheConnection)
 totalCount += MyAction.ExecuteNonQuery()

TheConnection.Close()
MessageBox.Show( str(totalCount) + "人分追加しました。")

# Refresh table
Document.Data.Tables["BaseballRecord"].Refresh()

正規性確率プロット

Spotfireで正規性確率プロット(Q-Qプロット)を作成

正規確率プロットは、データの分布が正規分布を示しているかどうかを視覚的に判断するための散布図です。

3

正規性に関してはヒストグラムやガウス分布などの方が直観的に理解しやすいかもしれませんね。
何はともあれ分布が正規かどうかを知ることは、いくつかの状況で重要です。
正規分布に従うデータの利点は、平均値と標準偏差が信頼できるということです。

多くの統計ツール (たとえば ANOVA) ではデータが正規分布していることを前提としているので、正規分布からの偏差が非常に大きい場合には、正確な結果が得られない事が多いです。
そのような場合は、事前にどれだけ正規性が取れているのか確認するのは重要です。

データのイメージ

測定値とカテゴリとIDのシンプルなデータです。
描画は2万行くらいです使用しています。

1

正規性確率プロットの作成

丁寧な方法

実際のValueからrankとpを計算カラムで追加し、それを元にNorminvで期待値を計算
それを元にY軸ValueでX軸期待値の散布図を作成する事ができます。
2

#rankの計算式
Rank([Value],"desc")

#pの計算式
([rank] - 0.5) / Count([Value])

#期待値の計算式
NormInv([p],Avg([Value]),StdDev([Value]))

カスタム演算式で作成

Spotfireに慣れてくると計算カラムよりカスタム演算式の方が便利ですよね。
Y軸はValue、X軸をカスタム演算式で下記の式を入力して作成しました。
先ほどは3つのカラムを作成しましたが、これだと1つのカスタム演算式でOKです。

NormInv((rank([Value],"desc") - 0.5) / count([Value]),
 Avg([Value]),StdDev([Value]))

3

ヒストグラムとの比較

ヒストグラムでの表現です。ガウス曲線を追加しています。

4

カテゴリ別の比較

今回はデータの中にCategoryが含まれているので、個別に描画しましょう。

カスタム演算式を

NormInv((rank([Value],"Desc",[Category]) - 0.5) / count([Value]) OVER ([Category]),
Avg([Value]) over ([Category]),
StdDev([Value]) over ([Category]))

に修正しました。
over式でカテゴリ別に集計しています。

7

見やすいようにトレリスをかけてみます。
5

ヒストグラムも同様に表現しています。
6

起動時にPython起動

起動時にPython起動

何回かにわたり記事を書いてきましたが、今回で一区切りです。
今回は起動時にPythonを起動する方法をご紹介します。

Python連携
Pythonスクリプトの入出力
閾値を超えた場合にメール送信
基準値の変更時にスクリプトを実行

SpotfireのPythonは「ボタンを押す」「プロパティ変更時」などのタイミングで起動しますが、ファイルを開いたときに起動するオプションはありません。

しかし、いくつかの機能を組み合わせることで実現可能です。

前回プロパティからPythonを起動させました。なので、起動時にプロパティを変更する事ができれば良いですね。

起動時に実行可能なスクリプトとしてはTERRがあります。
TERRからプロパティを変更する事ができるので、連携でPythonを実行します。

<全体のイメージ図>
9

TERRによるプロパティの更新

まずはプロパティを設定します。
curTimeというDatatime型のプロパティを作成し、メール送信スクリプトを設定しました。

2

このプロパティが変更される度にPythonスクリプトが実行されます。
TERRスクリプトは起動時に実行されるので、データロード時にチェック操作を行うことが可能です。

データ関数の登録

TERRスクリプトはデータ関数として登録します。
「ツール」→「データ関数の登録」で

名前はGetCurTimeとし

スクリプトは

print ( sysdate ) 
OutCurTime <- Sys.time()

sysdateを受け取って、OutCurTimeを返すスクリプトです。

3

パラメータの入力でDatatime型のsysdateを設定
4

出力パラメータでOutCurTimeを設定します。
5

右上のアイコンから実行します。
6

実行パラメータ

TERRの引数と戻り値を設定します。
入力のsysdateは引数として「式」でDateTimeNow()を指定します。

これでシステム日付けを渡しています。
7

出力は
OutCurTimeを文章のプロパティでcurTimeとして受け取るよう設定します。
「関数を自動的に更新」チェックボックスもONにしておいてくださいね。
8

これでDXPファイルを開く時にスクリプトが実行されます。

基準値の変更時にスクリプトを実行

前回の記事では基準値を設定して測定がそれをオーバーした際に
Pythonからメールを送信する例を紹介しました。

それはそれで便利なのですが、
条件判別のために都度ボタンを押す必要があり、いまいち利便性に欠けます。

Spotfireではプロパティの変更をトリガーとしてPythonスクリプトを起動する事ができるのでこちらの設定をしてみましょう。

この閾値を変更した際にPythonを実行したい。
1

プロパティにPythonを登録

「編集」から「ドキュメントのプロパティ」を選択し
「プロパティ」タブを開きます。

2
ファイル内のプロパティ一覧が表示されています。
3列目に「スクリプト」とあり、Pythonが設定されている場合は
ここに表示されます。

今回はPTPara1MaxLimitというプロパティが変更された時にPythonを起動します。
「スクリプト」ボタンを押して起動時の条件を設定します。

3

この設定はボタンから実行する場合と同じです。

4
設定完了です。
これで閾値を変更した際にPythonが実行されるようになります。

閾値を超えた場合にメール送信

Pythonでメール送信

前回の続きです。

データ分析の結果、異常条件や閾値を判別できるようになります。

その結果をリアルタイムのデータに当てはめ、
同様の条件が発生した場合にアラートとしてメールで通知できると便利です。
Pythonを使用したサンプルを作成してみました。

外部ライブラリの取り込み

Pythonのsmtplibライブラリを使ってメール送信します。
このライブラリを使用すると簡単にメール送信ロジックを実装できるのですが、
残念なことにSpotfireのironPythonには含まれていませんので
pythonを別途インストールしそちらのライブラリを読み込みます。

手順は普通のPythonと同じです。

import clr
import sys
paths = 'C:\Python25\Lib'
sys.path.append ( paths ) 

pythonのバージョンですが、
SpotfireのPythonと合わせるために2.5を使用しました。

Gailを使用してメール送信

今回のサンプルではsmtpサーバーとしてgmailを使用しています。
あらかじめgoogleのアカウント情報から
ログインとセキュリティの「安全性の低いアプリの許可」を有効化する必要があります。

1

ソースはこちら

※ログイン情報はご自分の物に書き換えてください。

# coding: UTF-8 #文字コード設定
# -*- coding: utf-8 -*-

import clr
import sys
paths = 'C:\Python25\Lib'
sys.path.append ( paths ) 

import smtplib
from email.MIMEText import MIMEText
from email.header import Header
from email import charset
from email.Utils import formatdate

#メールを作成
def create_message(from_addr, to_addr, subject, body):
    cset = 'iso-2022-jp'
    msg  = MIMEText(body.encode(cset), 'plain' , cset )
    msg['Subject'] =  Header ( subject.encode(cset) ,cset ) 
    msg['From']    = from_addr
    msg['To']      = to_addr
    msg['Date']    = formatdate()
    return msg

#メールを送信
def send_gmail(from_addr, to_addr, msg):
    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login('xxxxxxxxxxxxx@gmail.com', 'xxxxxxxxxx')
    s.sendmail(from_addr, [to_addr], msg.as_string())
    s.close()

#----------------
#  specValue(閾値)がtheValue(測定値)を超えている場合はメール送信
#    from_addr : メール送信元( gmailの場合は認証アドレスが指定される )
#    to_addr   : メール送信先
#    Title     : 件名
#    Body      : 本文
#    specValue : 設定値
#    theValue  : 測定値
#----------------

if ( specValue < theValue ) :
    msg = create_message(from_addr, to_addr, Title, Body )
    send_gmail(from_addr, to_addr, msg)

送信先アドレスやメールタイトルと本文
閾値と測定値はそれぞれパラメータとして入力できるようにしてありますので
from_addr , to_addr , Title , Body , specValue , theValueの値をプロパティなり
計算式で設定してください。

Pythonスクリプトの入出力

Pythonスクリプトの入出力に関して

前回、Pythonを使用してメッセージボックスを表示しましたが、
実際に使用する場合はSpotfireからデータを渡したり、Pythonの結果をSpotfireに戻したりする処理が必要になってくることが多いと思います。

今回は入出力のサンプルとして、プロパティの値やカスタム演算式の値をPythonに渡して、
結果をプロパティで受け取りましょう。

やりたい事

まずこのようなグラフがあるとします。
1

途中に大きな外れ値が発生しているようです。
このようなイレギュラーなデータが発生した場合に何かの処理を追加します。

プロパティの作成

プロパティの作成は必須ではないですが、
インタラクティブな操作と非常に相性がいいので使用頻度が多いです。

2

ドキュメントプロパティを新規に作成して上限値を入力し、
それを元に閾値のラインを引くようにしました。
プロパティ名はULで
5.2だとこの辺で、

3

6.0だとここまでです。

1.5

プロパティの作成は、テキストエリアの編集画面で「プロパティコントロールの挿入」で「入力フィールド」を選択します。

1.7

新規作成で今回はULという名前のReal型プロパティを作成します。
初期値は5にしておきます。
これでテキストエリアで入力する事ができるようになります。

18

ちなみに作成したULに連動したラインをチャートに引く場合は
プロパティの「線およびカーブ」から「追加」→「水平線」→「直線」
でカスタム演算式を選択して${UL}のプロパティを指定します。

1.8

Pythonへのインプット

閾値を超えている場合をPythonで判別して、テキストエリアの表示を変更しましょう。
前回作成したPythonを流用します。
ボタンとして埋め込まれているPythonをダブルクリックして編集します。

4

パラメータ設定
プロパティの渡し方

まずはプロパティ変数として上限の閾値を設定します。
スクリプトのパラメータで「追加」を選択
名前は「upperLimit」値は「プロパティ」でULを指定します。
これでSpotfireのULプロパティをPython側ではupperLimitとして扱えます。

6

次は平均値を集計して渡します。
名前はmaxValで、式は「式の編集」から入力する事ができます。
こちらはカスタム演算式で設定します。

8

メッセージボックスで表示する内容を変更してみました。
パラメータとして渡されているulvalとmaxValを使用しています。

9

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox
MessageBox.Show( "上限閾値は" + str(ulval) + " 最大値は " + str(maxVal) ) 

Pythonへの入力はパラメータを使用しますが、出力はこちらではできません。
今回は新規プロパティを作成し、それをPythonで書き換えましょう。
プロパティを変更する事ができれば、計算カラムやカスタム演算式の内容や、テキストエリアの中身など様々な変更が可能になります。

結果プロパティの作成

テキストエリアの編集から「プロパティの作成」でラベルを選択します。

10

pythonOutputという名前のString型のプロパティを作成しました。
初期値は”デフォルト”にしてみました。

11

作成すると”デフォルト”というラベルがテキストエリアに表示されています。

12

ドキュメントプロパティの変更

再度Pythonを編集します
プロパティをPythonから変更するには
Document.Properties[‘property name’] = ‘変更したい内容’
というAPIを使用します。

今回は分岐で上限値を超えている場合は’閾値オーバー’を表示します。

15

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox
outputStr = ""

if ulval > maxVal :
	outputStr = ( "閾値オーバー:上限閾値は" + str(ulval) + " 最大値は " + str(maxVal) ) 
else:
	outputStr = ( "上限閾値は" + str(ulval) + " 最大値は " + str(maxVal) ) 

Document.Properties['pythonOutput'] = outputStr

結果です。今回は閾値に引っかかったので、閾値オーバーになっています。

16

閾値をオーバーしない場合の実行結果です。

17

次回は閾値を超えた時にメール送信するようにしてみます。

Python連携

Python連携初歩の初歩

Python連携に関して

Pyrhonとは汎用のインタプリタ言語で、Spotfireだけで無く、多くのプラットフォームで動作します。
日本ではそれほどメジャーではないかもしれませんが、多くのライブラリを持っており、データ分析をお手軽に実装するのにはかなり便利な言語です。

Spotfireに搭載されているPythonはironPythonというWindowsと親和性の高いディストリビューションになっております。
Pythonを使用することにより、ライブラリを使用した解析や、外部ツールとの連携など、Spotfireの分析をより有効活用できます。

Pythonの実装

それではテキストエリアのボタンにPythonを実装して見ましょう。
クリックで”Hello Python”というメッセージボックスを表示するのが今回のゴールです。

テキストエリアの作成と実行

1

新規のテキストエリアを作成します。

2

右クリックし、テキストエリアを編集。

3

Pythonスクリプトは「アクションコントロール」というカテゴリになりますので、
アクションコントロールの挿入アイコンをクリックします。

4

表示テキストにはボタンに表示したい文言を記載します。
左の選択項目から「スクリプト」を選択し「新規」をクリックしてください。

ちなみにアクションコントロールはPython以外にもR言語を埋め込んだり、
他のページへ移動するボタンなども作成する事ができます。
左から「データ関数」を選択した場合はR言語
「アクション」を選択した場合はページ移動や、ブックマークの実行を指定できます。

5

スクリプトを記載していきます。
「スクリプト名」に”helloPython”
「スクリプト」には下記のスクリプトを記載してください。

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import MessageBox
MessageBox.Show("hello Python")

最初の3行はWindowsのメッセージボックスを表示するのに必要な設定です。
逆に言うとこれらの設定を色々することでWindowsの機能や他のライブラリの機能が簡単に実装できるようになっています。

5.5

ちなみに超見ずらいですが「出力」の右の隠れたボタンをクリックすると
この場で動作させることが可能です。
日本語に翻訳した際にレイアウト崩れたのでしょうか?

6

これでスクリプトは完成したので、保存して編集画面を閉じます。

7

ボタンを押すと”hello Python”とメッセージウインドウが表示されました。

お疲れさまでした。
今回はさわりですが、次回からPythonとの入出力や、他のライブラリを使用した例を紹介していきたいと思います。

その他

Spotfireで登録したPythonはDXPファイル内に保存されています。
「文書のプロパティ」から「スクリプト」で一覧を確認できますので、
こちらから編集することも可能です。
7.5

テキストエリア以外にもPythonを設定する事が可能です。
グラフィカルテーブルの軸や、文書のプロパティに設定する事ができますので、
プロパティの値が変更されたときに自動的にスクリプトを実行することもできます。

8

9