2014年12月14日

Microsoft Office Word 索引作成支援ツール マニュアル


Microsoft Office Word 索引作成支援ツールの利用方法を説明します。


本ツールは、Microsoft Office Wordに実装されている自動索引登録機能で利用するためのファイル作成を支援します。

実際の索引作成には、正規のMicrosoft Office Wordが必要となることにご注意ください。



初回解析


初めて本ツールを利用する場合は、トップ画面の「索引候補ファイル作成」の「ファイルを選択」をクリックし、索引を作成したいWordファイルを選択して「初回解析」をクリックしてください。

※対応している拡張子はdocxのみです。


本マニュアルでは、サンプルファイルとして青空文庫の「羅生門」の本文を利用します。


index1.png


解析が終了すると、索引登録候補一覧画面に遷移します。

大量に列挙された候補の中から、索引として登録すべき用語のみチェックをつけてください。

語句や読みが正確に解析されていない場合は手動で修正してください。



作業状態の保存と再開


「作業状態保存ファイルをダウンロード」をクリックすると、現在の作業状態が記録されたtsvファイルがダウンロードされます。

トップ画面の「索引候補ファイル再編集」から該当のファイルをアップロードすれば、編集作業を再開することができます。



索引登録ファイルをダウンロード


「索引登録ファイルをダウンロード」をクリックすると、Microsoft Office Word用の索引登録ファイルがダウンロードされます。

中身は以下のようなdocxファイルですが、通常このファイルを開く必要はありません。


index2.png



索引登録と索引作成


本作業実施前に、索引作成対象のWordファイルのバックアップを取得するようにして下さい。


索引を作成したいWordファイルをMicrosoft Office Wordで開いてください。

メニューから「参考資料」→「索引の挿入」を選択してください。


index3.png



「自動索引登録」をクリックし、本サイトからダウンロードした索引登録ファイルを選択してください。


index4.png


本文中に索引項目が以下のように自動登録されます。


index5.png


索引項目を非表示にしたい場合は、メニューから「ホーム」→「編集記号の表示/非表示」を選択して表示を切り替えてください。


index6.png


索引を作成します。

索引を作成したい個所にカーソルを合わせた状態で再度メニューから「参考資料」→「索引の挿入」を選択してください。


index3.png


任意のスタイルを設定後、「OK」を選択してください。

以下のように索引が作成されます。


index8.png


説明は以上です。


posted by hahasoha at 21:02| Comment(0) | TrackBack(0) | その他

2014年12月06日

テストデータに対するテストについて

これはPostgreSQL Advent Calendar 2014の12月6日分の記事です。


河原と申します。

僭越ながらPostgreSQL関連本をAmazon PODで出版させて頂いております。







この記事以外に全く記事がないことからもお分かり頂けるように、記事の投稿の為にわざわざブログを解説したわけですが、大した記事は書けませんのであしからず…


早速、本題に入ります。

テストデータはなるべく本番環境のデータに近い内容であるべきなのですが、大量のリアルなデータを作成するには、それなりにテクニックが必要となります。


で、PostgreSQLでのテストデータ作成については既に去年のAdvent Calendarで笠原さんが書かれていますので未読の方はまずはそちらの記事をご覧ください。


リアルなデータを作成するには色々と問題があるわけですが、その一つとしてランダム性が挙げられます。

generate_series関数を使えば大量の連番データは容易に作成できますが、そこにランダム性を加えるとなると一工夫が必要となるわけです。


そして、ただランダムなだけであればrandom関数でも噛ませれば済む話なのですが、「ランダム性もあって整合性も保たれてなければならない」となると更に工夫が必要となります。


例えば先日、「シーケンス列とレコード作成日時列」の2列を持つテーブルのサンプルデータを作成する機会がありました。

簡略化しますが、以下のようなイメージです。



seq | testtime
-----+---------------------
1 | 2014-12-04 00:00:01
2 | 2014-12-04 00:00:02
3 | 2014-12-04 00:00:03
4 | 2014-12-04 00:00:04
5 | 2014-12-04 00:00:05
  :

で、testtimeにランダム性を持たせたいわけですが、現実のデータを模するのであれば、testtimeは、seqが小さいレコードより大きな値でなければなりません。

つまり、ランダムの間隔でレコードが作成されていくのを模したいわけです。


とりあえず、本当にランダム性が高いといえるか疑問はありますが、以下のようにサンプルデータを作成したとします。



=> CREATE TEMP TABLE tempdata AS
SELECT generate_series(1,1000000) seq,
current_timestamp + (generate_series(1,1000000)||'minutes')::interval
- (floor(random() * 60)||'seconds')::interval testtime ;

seq | testtime
-----+-------------------------------
1 | 2014-12-04 00:25:42.593496+09
2 | 2014-12-04 00:26:27.593496+09
3 | 2014-12-04 00:27:22.593496+09
4 | 2014-12-04 00:28:13.593496+09
5 | 2014-12-04 00:29:09.593496+09
  :

レコード単位に1分ずつ加算させつつ、60秒未満のランダムな秒数を減算します。

仮にseqが1のレコードが最小の減算値で、逆にseqが2のレコードが最大の減算値であったとしても、1のtesttimeが2を上回ることはない……筈なのですが、確認したくなるのが人情でしょう。


余談ですが、100点満点のテストの点数のサンプルデータを作成する場合、ceil(random()*100)とやりたくなりますが、これだと0点が出ないことになるので、ceil(random()*101)-1かfloor(random()*101)としないと求めたい結果が出ません。

ですが、公式ドキュメントでは、random関数の範囲は8.3まででは「0.0〜1.0の範囲の乱数値」と、最新のドキュメントでは「0.0 <= x < 1.0の範囲の乱数値」と説明されています。
この説明が正しければ、random関数でジャスト0が出力される可能性があるということになります。
が、とりあえず以下のSQLで10億回ほど施行してみましたが0は出ませんでした。

=> WITH r AS
(SELECT ceil(random()) col1 FROM generate_series(1,1000000000))
SELECT * FROM r WHERE col1 = 0 ;

col1
------
(0 rows)

random関数はdouble precisionを返すようですが、公式ドキュメントの浮動小数点データ型の説明を簡単に読んだ限りでは、相当な桁数まで行くようですね…
本当に0が出るのか確認するためにはソースを読んだ方が早そうです。

本題に戻ります。

testtimeがseqと同様に昇順となっているか確認する方法としてまず思いつくのは、以下のように自己結合を用いる方法でしょうか。


=> SELECT * FROM tempdata t1,tempdata t2
WHERE (t1.seq + 1 = t2.seq) AND (t1.testtime > t2.testtime) ;

seq | testtime | seq | testtime
-----+----------+-----+----------
(0 rows)

ただ、この方法ですと抜け番のない列がないと実施できません。


方法は色々とあると思いますが、個人的にはWindow関数をよく使っています。


row_numberを取得するために使われたことがある人も多いかと思いますが、普通の集約関数も大変便利に使えます。

例えば以下のように使えば、seqでソート後のテーブルに対して、上から順に各行時点での最大値を取得できます。


=> SELECT *,max(testtime) over(ORDER BY seq) FROM tempdata ;

seq | testtime | max
-----+-------------------------------+-------------------------------
1 | 2014-12-04 23:19:49.001853+09 | 2014-12-04 23:19:49.001853+09
2 | 2014-12-04 23:20:48.001853+09 | 2014-12-04 23:20:48.001853+09
3 | 2014-12-04 23:21:49.001853+09 | 2014-12-04 23:21:49.001853+09
4 | 2014-12-04 23:22:32.001853+09 | 2014-12-04 23:22:32.001853+09
5 | 2014-12-04 23:23:55.001853+09 | 2014-12-04 23:23:55.001853+09
  :

後は、testtimeとmaxの値が異なる行が存在しないかを確認するだけです。


=> WITH r AS (SELECT *,max(testtime) over(ORDER BY seq) FROM tempdata)
SELECT * FROM r WHERE testtime <> max ;

seq | testtime | max
-----+----------+-----
(0 rows)

因みに、今回のケースでは自己結合よりWindow関数を利用した方が約1.5倍ほど高速でした。



さて、ここで記事を終えても良いのですが、もう一つありがちな罠を紹介しておきます。


1回のSQLだけで整合性のあるデータを作らなければならないわけでは必ずしもありません。

データを作成後に、後から問題のあるデータを修正するというやり方もあるかと思います。


が、深く考えずにやってしまいますと、その修正により整合性が失われてしまうことがあります。


=> CREATE TEMP TABLE tempdata2 AS
SELECT generate_series(1,1000) seq,
current_timestamp + (generate_series(1,1000)||'days')::interval
- (floor(random() * 24)||'hours')::interval testtime ;

=> WITH r AS (SELECT *,max(testtime) over(ORDER BY seq) FROM tempdata2)
SELECT * FROM r WHERE testtime <> max ;

seq | testtime | max
-----+----------+-----
(0 rows)

この時点では整合性が保たれているのですが、このクエリでは日付が相当未来になってしまいますので、interval型を利用して2年ほど日付を巻き戻しますと……


=> UPDATE tempdata2 SET testtime = testtime - interval '2 years';

=> WITH r AS (SELECT *,max(testtime) over(ORDER BY seq) FROM tempdata2)
SELECT * FROM r WHERE testtime <> max ;

seq | testtime | max
-----+------------------------------+------------------------------
451 | 2014-02-28 07:27:44.77576+09 | 2014-02-28 18:27:44.77576+09
(1 row)

ご覧のように、整合性に問題のあるデータが発生してしまいました。

日付を見れば原因はすぐにお分かり頂けるかと思いますが、うるう年の影響です。


interval型は当然うるう年に対応していますが、対応した結果、

2016年2月29日 00:00:00の2年前は2014年2月28日 00:00:00となり、

2016年2月28日 12:00:00の2年前は2014年2月28日 12:00:00となります。


=> SELECT '2016-2-29 00:00:00'::timestamp - interval '2 years' col1 ,
'2016-2-28 12:00:00'::timestamp - interval '2 years' col2 ;

-[ RECORD 1 ]-------------
col1 | 2014-02-28 00:00:00
col2 | 2014-02-28 12:00:00

このように、前後関係が逆転してしまう可能性があるわけです。


「自分はこんなドジは踏まない」という方も多いかと思いますが、大量のテストデータを作成する場合は、僅かな意識漏れが結果として大きな違いを生む可能性があります。


テストデータを使ってテストをする前に、そのテストデータ自身をテストすることを強くお勧め致します。


12月7日は、nuko_yokohamaさんです。

(カンファレンスお疲れ様でした。私も行きたかったです……)

タグ:PostgreSQL
posted by hahasoha at 00:00| Comment(0) | TrackBack(0) | PostgreSQL