ラフ集合
オリジナル
Qiitaからの移行記事です。
はじめに
私自身、学生時代(2005-2007くらい)の専門としてラフ集合理論を勉強していたので、アドカレネタとして今回書いてみようと思う。 ただ、こういう文章を書くのは久々なので、見苦しい点も多々あるかと思いますが、 ツッコミがあれば遠慮なくいただければ幸いです。 (と、今のうちに逃げを打っておく。)
ラフ集合とは
ラフ集合とは識別不能関係(対象説明の粗さなどにより識別ができない関係のこと)による不確実性を扱う集合概念であり,感性工学やデザイン工学などで使われているらしい。
ラフ集合では、非数値データや矛盾があるようなデータ表(決定表)から,If-Thenルール(決定ルール)を導くことにより、知識獲得が可能であるとして、1982年にZ.Pawlak (ポーランド)が提唱して以来,様々な理論的な研究が行われていた。
最近は何かあるのかな?と思い、少し調べてみたが、あまり引っかからないので廃れてしまったのかな?
ラフ集合を拡張した理論
- 可変精度ラフ集合
- ファジィ-ラフ集合
可変精度ラフ集合は学生当時にはあった理論だったが、 ファジィ-ラフ集合についてはどんなものかは知らないので、今度調べてみようかと思う。
こっから先は普通のラフ集合について簡単に
1. 決定表
だいぶ説明は端折って書いていると思います。ツッコミがありましたら遠慮なく。 以下のような表を情報表と呼ぶ。
サンプル | 種類 | 色 | おサイフケータイ | キャリア | 印象 |
---|---|---|---|---|---|
s1 | ガラケー | カラフル系 | あり | D社 | 好き |
s2 | スマホ | モノクロ系 | なし | S社 | 嫌い |
s3 | スマホ | カラフル系 | あり | A社 | 嫌い |
s4 | ガラケー | モノクロ系 | あり | A社 | 好き |
s5 | スマホ | モノクロ系 | あり | S社 | 嫌い |
s6 | スマホ | カラフル系 | なし | D社 | 好き |
情報表の中で、一部の属性を目的変数とし、残りの属性を説明変数とした時、この情報表は決定表と呼ばれる。目的変数に該当する属性の集合のことを決定属性と呼び、説明変数となる属性の集合を条件集合と呼ぶ。
例えば、条件属性$C=${種類,色,おサイフケータイ,キャリア}、決定属性$D=${印象}のようになる。 これでIf-Thenルールを作っても面白くないので、
2. 上近似と下近似
サンプル | 種類 | 色 | 印象 |
---|---|---|---|
s1 | ガラケー | カラフル系 | 好き |
s2 | スマホ | モノクロ系 | 嫌い |
s3 | スマホ | カラフル系 | 嫌い |
s4 | ガラケー | モノクロ系 | 好き |
s5 | スマホ | モノクロ系 | 嫌い |
s6 | スマホ | カラフル系 | 好き |
説明しやすいように、決定表を小さくした。 決定属性でそれぞれ「好き」の集合$D_1=${$s1,s4,s6$}、「嫌い」の集合$D_2=${$s2,s3,s5$}に分割することができる。この$D_1$と$D_2$のことを決定クラスと呼ぶ。
条件属性集合{種類,色}の基本集合は{{$s1$}$,${$s2,s5$}$,${$s3,s6$}$,${$s4$}}である。$D_1$の中のサンプル$s1$と$s4$の種類と色の組み合わせは、この表の中では必ず「好き」であると識別できるといえる。これをラフ集合では、
$A_*(D_1)=${$s1,s4$}
と書き、決定クラス$D_1$の下近似という。
一方、サンプル$s3$と$s6$は種類と色の組み合わせからは決定クラスの判別ができない。言い換えると、サンプル$s3$と$s6$は必ず$D_1$に属するとは断言はできないが、その可能性があるといえる。 これをラフ集合では、
$A^*(D_1)=${$s1,s3,s4,s6$}
と書き、決定クラス$D_1$の上近似という。
3. 縮約
縮約とは、全ての条件属性と同等に決定属性を識別するための「最小」の属性の部分集合のこという。縮約は複数存在しうる。 決定表における縮約を求める場合は、識別行列を作成して論理演算を行うが、具体的な計算方法については割愛する。
ざっくり何をするかというと、
$(A∨B)∧(C∨D)∧・・・∧(Y∨Z)$ を $(a∧b)∨(c∧d)∨・・・∨(y∧z)$
の形に変換して求める。(英字部分については、テキトーなのでご了承ください。)
4. 決定行列と決定ルール
で、決定ルール(If-Thenルール)を求めるわけだが、条件部がダラダラと長いのはイマイチということで、縮約を条件部として、決定ルールを求められれば、決定表から簡潔なルールが導けると嬉しいね、ということのようだ。
決定ルールを求めるのに、決定行列を作って、論理演算をして求めるのだが・・・・ 限界なので現時点では割愛させていただく・・・・
Rでラフ集合
昔はC/C++で実装して計算を行っていたが、最近RとかPythonを勉強し始めたので、ラフ集合のパッケージでもないかと探してみたら、あった。
現時点では、動かすまではやらないが、近日中に動かしてみて結果をここに載せたいと思っている。
似たような何か
統計学の勉強も少しやってみている中で、アソシエーション分析に似ているな、という印象を持った。 アソシエーション分析の方が有名なんだろうが、こちらの知識がないため具体的な違いなんかは理解していないので、今後比較でもしてみようかと思う。 ラフ集合がマイナーだからどこまで突っ込むかは考えちゃうんだけど。
ラフ集合の情報
ラフ集合と感性 データからの知識獲得と推論 当時の教科書といえば、これ1択だった。後は論文くらいしか当時はなかった記憶が。
人の考え方に最も近いデータ解析法―ラフ集合が意思決定を支援する おそらく一番新しい、ラフ集合の本。
ラフ集合の感性工学への応用 私の先生の名前がチラッと見かけたので、うっかり買ってしまった本。中身はまだ読んでないw
Variable precision rough set model 可変精度ラフ集合モデルの論文。これは読んだ記憶がある。
おわりに
こんな時間になってしまった(2016/12/22 3:45)ので一旦ここで終りだが、プログラムでの実行結果などは適宜編集していく予定。
Handsontableを入力フォームとして使って、JSONファイルを検索して結果を表示する
オリジナル
Handsontableを入力フォームとして使って、JSONファイルを検索して結果を表示する - Qiita
はじめに
前回は、JSONファイルを読み込んだ結果をHandsontableで表示させた。今回は、Handsontableを入力フォームとして使って、JSONファイル内を検索して、結果を表示させてみた。 HTMLだけでやっているので、モックアップを作るときには便利そうなのでメモ。
やってること
(1) JSONファイルを読み込む (2) JSONファイル内のテーブル一覧をコンボボックスに表示 (3) コンボボックスを変更した場合、そのテーブルに該当するカラム名を入力フォームに展開 (4) searchボタンを押すと、コンボボックスで選択されたテーブルを検索 (5) clearボタンを押すと、画面の初期状態に戻す (6) csvボタンを押すと、csvをダウンロードする(前回と同じ機能)
環境
Windows 8.1(64bit) Internet Explorer 11
用意したもの
Handsontable * handsontable.full.js * handsontable.full.css
juantascon * jquery.handsontable.csv.js
JSONファイル(自前)
{ "tableA":[ {"Year": "2009", "Maserati": "0", "Mazda": "2941", "Mercedes": "4303", "Mini": "354", "Mitsubishi": "5814" }, {"Year": "2010", "Maserati": "3", "Mazda": "2905", "Mercedes": "2867", "Mini": "412", "Mitsubishi": "5284" }, {"Year": "2011", "Maserati": "4", "Mazda": "2517", "Mercedes": "4822", "Mini": "552", "Mitsubishi": "6127" }, {"Year": "2012", "Maserati": "2", "Mazda": "2422", "Mercedes": "5399", "Mini": "776", "Mitsubishi": "4151" } ], "tableB":[ {"Name": "Maserati", "Since": "1914"}, {"Name": "Mazda", "Since": "1920"}, {"Name": "Mercedes", "Since": "1926"}, {"Name": "Mini", "Since": "1952"}, {"Name": "Mitsubishi", "Since": "1970"} ] }
内容
(1) JSONファイルを読み込む
(2) JSONファイル内のテーブル一覧をコンボボックスに表示
$.getJSON("json/table.json", function(table) { jsondata = table; // コンボボックスに表示するテーブル名を取得 tableName = new Array(); var count = 0; for(key in jsondata){ tableName[count] = key; count++; } // コンボボックスにOPTIONを追加 for(var i = 0 ; i < tableName.length ; i++){ $('#selectTable').append($('<option>').html(tableName[i]).val(tableName[i])); } // csvボタンを非活性にする $('#csvDownLoad').attr("disabled", "disabled"); });
(3) コンボボックスを変更した場合、そのテーブルに該当するカラム名を入力フォームに展開
// コンボボックスの値を変更した場合に動く $('#selectTable').change(function(){ // コンボボックスの値が、"NA"でなければ、テーブルを展開 // コンボボックスの値が、"NA"の場合は、テーブルを削除 if( $('#selectTable').val() != "NA") { // コンボボックスの値をキーにして、テーブルを取得 var obj = jsondata[$('#selectTable').val()]; // テーブルが持っている、カラム名を取得 // データ持っている、ありき。 var searchHeader = new Array(); var count = 0; for(key in obj[0]){ searchHeader[count] = key; count++; } // Handsontableに展開する配列を作成 // 中身は空文字にする。 var inputCell = new Array(); for(var i = 0; i < searchHeader.length; i++){ inputCell[i] = ""; } var data = [inputCell]; // 表の定義 hot = $('#searchGrid').handsontable({ //以下はデータ指定と表示オプション data: data, //さっき作ったdataを指定 minSpareRows: 0, //表の一番下にいくつ空行を表示するか colHeaders: searchHeader, //カラムの名前を表示するかどうか colheader: true/false //カラムの名前を任意の名前にする colheader: 配列 contextMenu: true }); } else { $('#searchGrid').handsontable("destroy"); } });
(4) searchボタンを押すと、コンボボックスで選択されたテーブルを検索
// searchボタンが押されたら、検索して結果を表示 $('#search').click( function() { // コンボボックスでテーブルを選択していること。 if( $('#selectTable').val() != "NA") { // 現在のコンボボックスの選択内容から、テーブルを取得する // コンボボックスの値をキーにして、テーブルを取得 var obj = jsondata[$('#selectTable').val()]; // searchGridから入力されているデータを取得する(配列) var row = $('#searchGrid').handsontable('getDataAtRow',0); // カラムを取得する var searchData = new Array(); var count = 0; for(key in obj[0]){ searchData[count] = key; count++; } // 取得したデータを元に、テーブルを検索 var resultData = obj.filter(function(record) { var flag = false; for( var j = 0; j < row.length; j++ ){ if( row[j] != "" ) { flag = true; break; } } // 検索条件が入力されていたら、JSONを検索 // 検索条件が未入力であれば、全てを表示する if( flag ){ for( var colCn = 0; colCn < searchData.length; colCn++){ if( record[searchData[colCn]] === row[colCn] ){ return true; } } } else { return true; } }); // resultに展開する if( resultData.length > 0 ){ if(hot2 != undefined){ try{ hot2.destroy(); } catch(e) { } } resultData = resultData, container2 = document.getElementById('result'), //後ほど表を展開する要素を指定 hot2; hot2 = new Handsontable(container2, { //以下はデータ指定と表示オプション data: resultData, //さっき作ったdataを指定 minSpareRows: 0, //表の一番下にいくつ空行を表示するか colHeaders: searchData, //カラムの名前を表示するかどうか colheader: true/false //カラムの名前を任意の名前にする colheader: 配列 rowHeaders: true, contextMenu: true, //セルを右クリックしたときのメニューをすべて表示 columnSorting: true //カラムのヘッダーをクリックした際に昇順、再クリックで降順にソート }); // csvボタンを活性にする $('#csvDownLoad').removeAttr("disabled"); } else { if(hot2 != undefined){ hot2.destroy(); hot2 = undefined; } // csvボタンを非活性にする $('#csvDownLoad').attr("disabled", "disabled"); alert("検索結果がありません"); } } else { alert("テーブルを選択してください"); } });
(5) clearボタンを押すと、画面の初期状態に戻す
// clearボタンが初期状態に戻す $('#clear').click(function(){ if(hot2 != undefined){ hot2.destroy(); hot2 = undefined; } $('#selectTable').val("NA"); $('#searchGrid').handsontable("destroy"); // csvボタンを非活性にする $('#csvDownLoad').attr("disabled", "disabled"); });
全文
<!DOCTYPE html> <html> <head> <meta charset="Shift_JIS"> <title>handsontable_test</title> <link rel="stylesheet" type="text/css" href='css/handsontable.full.css'> <script src='js/jquery-1.11.3.min.js'></script> <script src='js/handsontable.full.js'></script> <script src='js/jquery.handsontable.csv.js'></script> <script> $(document).ready(function () { var jsondata; //JSON var tableName; //テーブル一覧 var hot2; //resultの表定義 // 画面読み込み時、table.jsonの内容を取得する $.getJSON("json/table.json", function(table) { jsondata = table; // コンボボックスに表示するテーブル名を取得 tableName = new Array(); var count = 0; for(key in jsondata){ tableName[count] = key; count++; } // コンボボックスにOPTIONを追加 for(var i = 0 ; i < tableName.length ; i++){ $('#selectTable').append($('<option>').html(tableName[i]).val(tableName[i])); } // csvボタンを非活性にする $('#csvDownLoad').attr("disabled", "disabled"); }); // コンボボックスの値を変更した場合に動く $('#selectTable').change(function(){ // コンボボックスの値が、"NA"でなければ、テーブルを展開 // コンボボックスの値が、"NA"の場合は、テーブルを削除 if( $('#selectTable').val() != "NA") { // コンボボックスの値をキーにして、テーブルを取得 var obj = jsondata[$('#selectTable').val()]; // テーブルが持っている、カラム名を取得 // データ持っている、ありき。 var searchHeader = new Array(); var count = 0; for(key in obj[0]){ searchHeader[count] = key; count++; } // Handsontableに展開する配列を作成 // 中身は空文字にする。 var inputCell = new Array(); for(var i = 0; i < searchHeader.length; i++){ inputCell[i] = ""; } var data = [inputCell]; // 表の定義 hot = $('#searchGrid').handsontable({ //以下はデータ指定と表示オプション data: data, //さっき作ったdataを指定 minSpareRows: 0, //表の一番下にいくつ空行を表示するか colHeaders: searchHeader, //カラムの名前を表示するかどうか colheader: true/false //カラムの名前を任意の名前にする colheader: 配列 contextMenu: true }); } else { $('#searchGrid').handsontable("destroy"); } }); // searchボタンが押されたら、検索して結果を表示 $('#search').click( function() { // コンボボックスでテーブルを選択していること。 if( $('#selectTable').val() != "NA") { // 現在のコンボボックスの選択内容から、テーブルを取得する // コンボボックスの値をキーにして、テーブルを取得 var obj = jsondata[$('#selectTable').val()]; // searchGridから入力されているデータを取得する(配列) var row = $('#searchGrid').handsontable('getDataAtRow',0); // カラムを取得する var searchData = new Array(); var count = 0; for(key in obj[0]){ searchData[count] = key; count++; } // 取得したデータを元に、テーブルを検索 var resultData = obj.filter(function(record) { var flag = false; for( var j = 0; j < row.length; j++ ){ if( row[j] != "" ) { flag = true; break; } } // 検索条件が入力されていたら、JSONを検索 // 検索条件が未入力であれば、全てを表示する if( flag ){ for( var colCn = 0; colCn < searchData.length; colCn++){ if( record[searchData[colCn]] === row[colCn] ){ return true; } } } else { return true; } }); // resultに展開する if( resultData.length > 0 ){ if(hot2 != undefined){ try{ hot2.destroy(); } catch(e) { } } resultData = resultData, container2 = document.getElementById('result'), //後ほど表を展開する要素を指定 hot2; hot2 = new Handsontable(container2, { //以下はデータ指定と表示オプション data: resultData, //さっき作ったdataを指定 minSpareRows: 0, //表の一番下にいくつ空行を表示するか colHeaders: searchData, //カラムの名前を表示するかどうか colheader: true/false //カラムの名前を任意の名前にする colheader: 配列 rowHeaders: true, contextMenu: true, //セルを右クリックしたときのメニューをすべて表示 columnSorting: true //カラムのヘッダーをクリックした際に昇順、再クリックで降順にソート }); // csvボタンを活性にする $('#csvDownLoad').removeAttr("disabled"); } else { if(hot2 != undefined){ hot2.destroy(); hot2 = undefined; } // csvボタンを非活性にする $('#csvDownLoad').attr("disabled", "disabled"); alert("検索結果がありません"); } } else { alert("テーブルを選択してください"); } }); // csvボタンがクリックされたら表の内容をCSV出力する $('#csvDownLoad').click(function(){ var csv_string = handsontable2csv.string(hot2); var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); var blob = new Blob([bom, csv_string], { type: 'text/csv'}); // IE独自関数 window.navigator.msSaveBlob(blob, "test.csv"); }); // clearボタンが初期状態に戻す $('#clear').click(function(){ if(hot2 != undefined){ hot2.destroy(); hot2 = undefined; } $('#selectTable').val("NA"); $('#searchGrid').handsontable("destroy"); // csvボタンを非活性にする $('#csvDownLoad').attr("disabled", "disabled"); }); // Handsontableのおまじない //以下は基本的にいじらない function bindDumpButton() { Handsontable.Dom.addEvent(document.body, 'click', function (e) { var element = e.target || e.srcElement; if (element.nodeName == "BUTTON" && element.name == 'dump') { var name = element.getAttribute('data-dump'); var instance = element.getAttribute('data-instance'); var hot = window[instance]; console.log('data of ' + name, hot.getData()); } }); } //関数実行 bindDumpButton(); }); </script> </head> <body> <p>テーブル選択</p> <select style="width:200px;" id="selectTable"> <option value="NA"></option> </select> <div id="searchGrid" class="handsontable"></div><br> <input id="search" type="button" value="search"/> <input id="clear" type="button" value="clear"/> <hr> <div id="result" class="handsontable"></div><br> <input id="csvDownLoad" type="button" value="csv"/> </body> </html>
最後に
わかりにくい点、間違っている点、効率的に書ける箇所などあれば教えていただければ幸いです。
JSONファイルを読み込んだ結果を、Handsontableを使って表示してみた。(ついでにCSVもダウンロード)
オリジナル
JSONファイルを読み込んだ結果を、Handsontableを使って表示してみた。(ついでにCSVもダウンロード) - Qiita
Qiitaからの移行記事です。
はじめに
jQueryの勉強をしようと思い立ち、面白そうなライブラリを探していたらHandsontableを見つけたので、さわってみた。 (基本的に通信なしで、HTMLで全て行う。)
(1) JSONファイルを読み込む (2) JSONをHandsontableに渡して表示 (3) 表の内容をCSVにしてダウンロード
環境
Windows 8.1(64bit) Internet Explorer 11
用意したもの
Handsontable * handsontable.full.js * handsontable.full.css
juantascon * jquery.handsontable.csv.js
JSONファイル(自前)
{ "cars":[ {"Year": 2009, "Maserati": 0, "Mazda": 2941, "Mercedes": 4303, "Mini": 354, "Mitsubishi": 5814}, {"Year": 2010, "Maserati": 3, "Mazda": 2905, "Mercedes": 2867, "Mini": 412, "Mitsubishi": 5284}, {"Year": 2011, "Maserati": 4, "Mazda": 2517, "Mercedes": 4822, "Mini": 552, "Mitsubishi": 6127}, {"Year": 2012, "Maserati": 2, "Mazda": 2422, "Mercedes": 5399, "Mini": 776, "Mitsubishi": 4151} ] }
内容
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Handsontable Test</title> <link rel="stylesheet" type="text/css" href='css/handsontable.full.css'> <script src='js/jquery-1.11.3.min.js'></script> <script src='js/handsontable.full.js'></script> <script src='js/jquery.handsontable.csv.js'></script> <script> $(document).ready(function () { // 知らない人は「jquery.Deferred」で調べよう var d = new $.Deferred(); var header; var jsondata; // (1) JSONファイルを読み込む $.getJSON("json/data.json", function(sample) { jsondata = sample.cars; // Handsontableで表示するヘッダーをjsonから取得して配列に格納 // この辺ダサイんだけど、JSONデータ内の属性を一括で取得する方法とかないかな? header = new Array(); var count = 0; for(key in jsondata[0]){ header[count] = key; count++; } d.resolve(); }); d.promise().then(function() { // (2) JSONをHandsontableに渡して表示 var data = jsondata, container = document.getElementById('example'), //後ほど表を展開する要素を指定 hot; // 表の定義 hot = new Handsontable(container, { //以下はデータ指定と表示オプション data: data, //さっき作ったdataを指定 minSpareRows: 1, //表の一番下にいくつ空行を表示するか。今回は1行を空行にして表示する。 colHeaders: header, //カラムの名前を表示するかどうか colheader: true 表示/false 非表示 //カラムの名前を任意の名前にする colheader: 配列(カラム名) rowHeaders: true, //ロウの名前を表示するか contextMenu: true, //セルを右クリックしたときのメニューをすべて表示 columnSorting: true //カラムのヘッダーをクリックした際に昇順、再クリックで降順にソート }); // 表上で以下のキーが押されても編集モードにならない // 変換(28)、無変換(29)、カタカナ(241)、ひらがな(242)、漢字キー(243, 244) hot.updateSettings({ beforeKeyDown: function(e){ if([28, 29, 241, 242, 243, 244].indexOf(e.keyCode) >= 0) { e.isImmediatePropagationEnabled = false; e.isImmediatePropagationStopped = function(){ return true; } } } }); // (3) 表の内容をCSVにしてダウンロード $("input:button").click(function(){ // 表の状態を文字列にする。 var csv_string = handsontable2csv.string(hot); var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); var blob = new Blob([bom, csv_string], { type: 'text/csv'}); // IE独自関数でダウンロード window.navigator.msSaveBlob(blob, "test.csv"); }); }); // Handsontableのおまじない // 以下は基本的にいじらない function bindDumpButton() { Handsontable.Dom.addEvent(document.body, 'click', function (e) { var element = e.target || e.srcElement; if (element.nodeName == "BUTTON" && element.name == 'dump') { var name = element.getAttribute('data-dump'); var instance = element.getAttribute('data-instance'); var hot = window[instance]; console.log('data of ' + name, hot.getData()); } }); } bindDumpButton(); //関数実行 }); </script> </head> <body> <div id="example" class="handsontable"></div> <br> <input type="button" value="csv"/> </body> </html>
参考
1.Qiita - Handsontableで日本語入力関連キーを無視する 2.Qiita - 【JavaScript】連想配列のkeyとvalueの取得 3.Qiita - 100万行扱えるグリッドw2ui GridとHandsontableの紹介 4.新人Webエンジニアの記録。- JavaScriptだけでファイルの保存機能を実装する 5.MSDN - Blob と msSaveBlob を使ってファイルをローカルに保存する.aspx)