ラベル アプリケーション の投稿を表示しています。 すべての投稿を表示
ラベル アプリケーション の投稿を表示しています。 すべての投稿を表示

2025年12月13日土曜日

MacのOCR(3)

MacのOCR(2)・石原純からの続き

石原純の「現代物理の基礎理論」という古いpdfファイルを見かけた。中央公論社が1943年の3月に発行した,國民學術協會編の國民學術選書の一冊である。講演録の「現代物理學の基礎理論」と書き下ろしの「自然科学の方法論について」からなる160ページ(63MB)ほどの本だ。

画像イメージのpdfなので,そのままではテキストが取り出せない。さっそく前回のショートカットによるmacOSのOCR機能を使ったコマンドに2-3ページを投入する。すぐにテキストは抽出出来たものの,解像度の悪い旧字ファイルなので,精度が悪い。

Geminiに相談したところ,
第1推奨:高性能な市販PDFソフト/OCRサービス(Adobe Acrobat Proなど)
第2推奨:Google ドライブのOCR機能(フリー)
第3推奨:macOS標準の「プレビュー」アプリ(低精度・非推奨)
とのことだった。

市販のものはコストがかかるので,GoogleドライブのOCR機能を試すことに。
(1) Googleドライブにpdfファイルをアップロード
(2) Googleドライブ中のpdfファイルを選び右クリック,Googleドキュメントを選んで開く。
(3) これでtextファイルができあがり。

・63MBの元ファイルは扱えなかったので,qpdf --split-pages=15 ishihara.pdf ishihara.pdf で分割した。20ページ分割ではエラーだったので,15ページ分割でOKとなる。
・でき上がったファイルは1文字1ページで1万ページに達したが,普通のテキストエディタにそのままコピペすれば問題なし。
・やはり旧字の誤認識が混じるがさきほどよりはましである。

肝腎の本書の内容はそこまでおもしろくはないかもしれない。


写真:石原純(理科ハウスから引用)

2025年12月12日金曜日

MacのOCR(2)

MacのOCR(1)からの続き

以前(2023年1月),MacのOCRプログラム(tesseract)を試したことなどすっかり忘れていた。全く別の方向からの話題をみかけたので,しばらく熟成させた後に試してみた。

一つは,165行のシェルスクリプト(ocr.sh)である。
「純bash → 一時的にAppleScriptAppleScriptObjC)を起動 → macOSのVision/QuartzフレームワークでOCR」という三層構成。入出力は「画像(jpg/png)またはPDF → 標準出力に認識テキスト。引数で言語(ja/en)とPDFをラスタライズするDPIを切り替え。制御のキモは、PDFはページごとに指定DPIで画像化→白背景で正規化→VisionでOCR、画像も同様に白背景で正規化してからOCR、という“前処理の徹底”と、“Visionへの最小限・最適な設定”にある。
しかしこれでは縦書き日本語がうまくいかないことがあるらしい。そこで示されたのが,macOSのビルトインOCR機能をmacOSの「ショートカット」アプリで呼び出すというものだ。ショートカットは,他のジョブでもこれまで何度もトライしてきたのだが,すべて途中で挫折してしまった。ちゃんと勉強せずに行き当たりばったりでやるとそうなる。

今度もだめかなと半分あきらめつつ,ChatGPTにやり方を繰り返し教えてもらうことで,なんとかうまくいった。Scratchみたいなビジュアルプログラミング言語はどうも苦手だ。年寄りにはよけい難しく感じる。普通のエディタでテキスト入力したいよ。こうしてつくったスクリプトが,Extract_text_from_files(下図参照)だ。

これをコマンドラインから次のように起動する。

shortcuts run "Extract_text_from_files" -i ~/sample.pdf -o ~/sample.txt  


入力ファイルは,pdf,jpg,png である。出力ファイルを省略すると標準出力に流れる。実際に試したところ,縦書きのpdfファイルもjpgファイルもpngファイルもうまくいっている。認識精度はtesseractよりもずっとよかった。





図:はじめてのショートカット


2025年11月18日火曜日

こっき(3)

こっき(2)からの続き

Q(koshix):
(旧ファイル kokki.html を添付)
外部サイト("https://restcountries.com/v3.1/all")の国旗データにアクセスできなくなりました。そこで,このサイトはつかわないことにします。flagpedia.netから国連加盟国の国旗のsvgデータを持ってきました。 250カ国ほどの国旗データはjp.svgのように,二文字の国旗コード名のsvgファイルとして flagsディレクトリ以下に格納されています。 このローカルデータを用いてもとのkokki.htmlと同等の機能を実現するhtmlファイルを作成してください

A(ChatGPT-5):
もとの kokki.html は restcountries.com に依存して国名や地域情報を取得していましたが、今回は 外部APIを使わず、flags/xx.svg(ISO α2コード)だけで動く版に作り替えます。(以下回答略)

Q(koshix):
表示部で国記号(国記号)となっているのを,国記号(日本語の国名)になるようにしてください。

A(ChatGPT-5):
了解しました。いまのHTMLでは表示部分を「JP(日本)」のように 国記号(日本語の国名) に変更したい、ということですね。(以下回答略)

Q(koshix):
改善されていませんが。

A(ChatGPT-5):
ごめんなさい。原因は「日本語名の辞書が無いと、itNameJa() が国コードをそのまま返す」仕様のままだったことです。(以下回答略)

Q(koshix):
修正した全コードを下さい。
A(ChatGPT-5):
了解です。ご指定の「国記号(日本語の国名)」表示に修正済みの全体コードをお渡しします。外部API不要・flags/xx.svgのみで動作し、日本語名は Intl.DisplayNames で自動生成(辞書があれば優先)します。(以下回答略)

Q(koshix):
表示領域が全世界だけイキの状態です。現行の5つの地域ごとに選択することはできないのですか?
A(ChatGPT-5):
ありがとうございます。原因は、地域フィルタが「flags/regions.json が無いと無効化」される設計のままだったことです。(以下回答略=ほぼ希望どおりのものに)



図:kokki.htmlの例


P. S. なお,その後かざはチャンは国旗への関心を失ってしまい,どの国旗ももう憶えていないらしい。チーン。

2025年9月19日金曜日

Welcome to BUNRAKU!

国立文楽劇場の爽秋文楽特別公演は,9月6日から10月14日までと,例年(去年は11月2日〜24日)より早期に始まり長期間にわたって開催される。これは10月13日まで開催される2025大阪・関西万博対応の特別仕立てである。

プログラムは次のようになっている。
Aプロ
・Welcome to BUNRAKU!
・恋女房染分手綱(道中双六の段,重の井子別れの段)
・日高川入相花王(渡し場の段)
Bプロ
・心中天網島(北新地河庄の段,天満紙屋内の段,大和屋の段,道行名残の橋づくし)
Cプロ
・Welcome to BUNRAKU!
・曾根崎心中(生玉社前の段,天満屋の段,天神森の段)
前半の9月25日までが,A-B-C,後半の9月26日からが,C-B-A という順に上演される。

今回は,外国人向けの英語での文楽の概要説明(約10分)Welcom to BUNRAKU! が含まれるAプロを観賞した。恋女房染分手綱も日高川入相花王もこれまで何度か見ている演目だ。

いつもより上演期間が倍近くに延びているためか,731席の国立文楽劇場は3-4割の入りだった。外国人は10人程度なので,3-4%というところか。万博の外国人観光客をターゲットとしているため,新たな試みとして従来の日本語字幕投影のかわりに,スマホアプリによる日本語・英語字幕表示システムが取り入れられた。

EG-Gというアプリで,手元に字幕が表示される。ところが,これはネットワークを使わないので,端末は機内モードにしておく。アプリで端末のマイク利用をONにしておくと,劇場内に流れる非可聴音で信号を流し,これを聞き取って端末に字幕を表示するというものらしい。

問題は,舞台を見るときは眼鏡をかけているので,手元だと眼鏡を外さないといけないということ。やはり視線移動が多くなるとちょっとしんどい。これが耳からの情報ならばOKなのだけれど。端末側でイアホンを利用しているかどうかが判別できて,なおかつスピーカーから音が出ないという設定ができればいいけど。AirPods とか指定すればできそうではあるが。

肝腎の文楽の中身だけれど,日高川を泳ぐ清姫のウロコ模様の帯着物がいまいちきれいに伸びてはいなかったのが残念。



図:EG-Gの画面(2025.9.17 撮影)


2025年7月18日金曜日

Japan DashBoard

7月10日,内閣府とデジタル庁が「Japan Dashboard(経済・財政・人口と暮らしに関するダッシュボード)とデータカタログ」を公開した。
普通だと,ダッシュボードのトップページへのリンクがあって,そこにアクセスして話が進んでいくようなものだけれど,デジタル庁の該当ページは何だか面倒なことになっていた。
1.指標の分類
2.Japan Dashboard
 ・指標のデータをみる
 ・1つの指標を都道府県ごとにみる
 ・2つの指標の関係性をみる
 ・4つの指標の推移を並べてみる
3.データカタログ
 (1) 1つの指標のデータをコピーして利用する
 (2) 複数の指標を一括ダウンロードする
4.関連資料
 (1) Japan Dashboardの見方と操作方法
 (2)「見える化」ポータルサイトのリニューアル方針
5.留意事項
この目次がいきなり登場するということは,ここがダッシュボードなのか?ここは単なるお知らせのページではなかったのか?わからない。あわててリンク先の内閣府のページに行くと内閣府側のまったく同じものに誘導された。わかりにくすぎる。とにかく,
691の指標を7つの大分類と62の中分類に分けて整理しています。
人口:人口、婚姻・出生、高齢者割合等
経済:県内総生産、就業・労働、所得・課税等
教育:学校数・教員数、学校のICT環境等
社会保障:医療体制、医療費、検診受診率等
暮らし:安全、居住等
社会基盤:社会基盤
地方財政:基金、歳出・歳入等
について,都道府県別のデータ,2つの指標の相関と年次推移,4つの指標の比較などが上記の事例から選んで試せることだけがわかった。遊んでいるうちに思わぬ発見をするかもしれない。それにしても面倒だ。AI チャットボットに対話的に依頼するシステムにしてほしい。



図:Japan Dashboard で扱われるデータ項目一覧

2025年7月14日月曜日

jReadability

量子コンピュータからの続き

放送大学の数理・データサイエンス・AI講座をみていたら,自然言語処理の話の中で,jReadability というウェブアプリが紹介されていた。ICT・AI・言語教育の科研グループが開発しているもののようだ。

日本語学習者向けのもので,日本語文章難易度判定システム(jReadability,難易度6段階判定),日本語学習者作文評価システム(jWriter,到達レベル5段階判定),日本語教育語彙集(JEV,18000語),機能後用例文データベース(はごろも)の4つのシステムから成り立っていて自由に使える。

早速,自分のブログテキストを日本語文章難易度判定システムに入れてみた。400字から1000字のテキストを受け付けるようになっている。「可視化機能を使用する」にチェックをいれると,ワードクラウド,語彙ネットワーク,意味階層図を出力してくれる。標準だと,テキスト情報,テキスト詳細,語彙リストが出てくる。

さて,「量子コンピュータ(13文,962字,229異形態素)」のリーダビリティは2.75であり,中級後半(ややむずかしい)となった。いいのか悪いのか。ひらがなが半分,和語が2/3で漢語が1/3,普通名詞が1/3で助詞助動詞が1/3。



図:ワードクラウドの結果

2025年6月12日木曜日

HyperCard

アップルと私からの続き

6月5日,HyperCard(1987-1998)を産みだしたビル・アトキンソン(1951-2025)が亡くなった。ビル・アトキンソンは,先日テレビでみた映画スティーブ・ジョブス(2013)にも本人とよく似た役者さんが登場していた。

1988年に大阪教育大学にMacintosh IIを40台導入して使い始めようとしていたとき,HyperCardがインストール済みかどうかは我々には大きな問題だった。というのも,そのハイパーテキストスタックの例をみて,これは教育に使えると直感したからだ。HyperCardは1987年に発表されたばかりだったが,無事にインストールされていた。

その後,自分の研究室に入った代々のMacintoshにもしばらくHyperCardがのっていた。やったー。しかし,残念ながらそれだけで満足してしまい自分でHyperCardスタックを開発することは全くなかった。ハイパーテキストを実際に自分で操って教育用コンテンツを作るようになるには,WorldWideWebの登場によるHTMLファイルの作成まで待たなければならなかった。


京大の情報科学演習の非常勤を担当していたころ,WWWブラウザ普及の嚆矢となるNSCAMosaicが登場した。筒井多圭志さんに,ハイパーテキストの重要性を初めて認識したのはHyperCardを見たからだというと,ハイパーテキストはTexinfoで実装されているよと教えてもらった。

なお,ビル・アトキンソンは,MacPaintでも知られるQuickDraw を開発し,MacintoshのGUIを成功に導いた人だ。以下,小龍茶館から引用。
1987年8月11日から1992年まで、Appleは販売した全てのMac(Macintosh)にHyperCardをプレインストールしていました。またそれ以外の時期に発売されたMacにも、49ドルという価格でHyperCardを購入できてインストールすることが可能でした。そして2004年3月、HyperCardは正式にAppleのプラットフォームから”引退”し、Appleとコンピュータの歴史にその名が刻まれることになります。


図:HyperCardのホーム画面(ITmediaから引用)

[1]HyperCard on the Archive(Internet Archive)
[2]HyperCard Stacks(Internet Archive)
[5]HyperCard AI(平野友康)
[6]青空のリスタート(富田倫生)

2025年2月21日金曜日

こっき(2)

こっき(1)からの続き

国旗アプリを改良しようと考えた。1ステップ前の国旗に戻れるようにするものだ。最初は,左下の1/4×1/4領域に,前回表示した国旗の小さなイメージを表示させてそこをクリックすると前の表示に戻るようにするものだ。国名は通し番号をつけて右下に移動した。

ChatGPT o3-mini-highにお願いしたところ,何度かのやりとりの後に目的のものはできたにはできたが,国旗が2つも表示されているのは子どもにはわかりにくそうだ。やり直し。

Q(koshix):
国旗表示アプリ
以下のウェブアプリに修正を加えてください。
(1) 各国旗には次の3つの番号を持ちます。(a) アルファベット順の通し番号,(b) アイウエオ順の通し番号,(c) アプリ起動後にその国旗が最初に表示されたときの通し番号
(2) カタカナの国名表示部分を,通し番号:カタカナ国名 の形に修正してください。このときの通し番号は,表示モードに対応したものとします。
(3) 右下に半透明グレーのボタン領域を設定してください。その機能は後で説明します。まずは,(1) (2) を実装した全体コードをお願いします。
なお,修正前のコードは以下のとおりです。

Q(koshix):
ボタン領域を「もどる」というなまえにして,ここをクリックすると選択された領域で表示されている国旗より通し番号がワンステップ小さいものに戻って表示するようにしてください。

これで目的のものはできた。361行のウェブアプリである。やはりどういうロジックにするかを想定しながらプロンプトを考えるのが重要だ。前回は単なる仕様だけで依頼したので,うまく機能しなかったので結構モチャついた371行



図:kokki.htmlのiPhoneでの実行画面

以下が,修正版のkokki.htmlのソースコードだ。108行目あたりのkazaha.jpgを自分のイメージファイルに変えて,kokki.htmlと同じフォルダに設置して,ブラウザで閲覧すればOKだ。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>かざは の こっき</title>
  <style>
    html, body {
      margin: 0;
      padding: 0;
      background-color: #f0f0f0;
      height: 100%;
      font-family: sans-serif;
    }
    /* トップページ(スタート前) */
    #top-page {
      text-align: center;
      padding: 20px;
    }
    #top-page h1 {
      font-size: 2em;
      margin-bottom: 20px;
    }
    #top-page img {
      width: 437px;
      height: 377px;
      margin-bottom: 20px;
    }
    /* スタートボタン */
    #start-button {
      padding: 12px 24px;
      font-size: 1.5em;
      border: none;
      border-radius: 8px;
      background-color: #007aff;
      color: #fff;
      cursor: pointer;
    }
    /* 国旗表示ボックス */
    #flag-container {
      width: 90vw;
      height: 70vh;
      margin: 5vh auto;
      position: relative;
      background-color: #000;
      border: 5px solid #fff;
      box-shadow: 0 4px 8px rgba(0,0,0,0.5);
      cursor: pointer;
      display: none; /* スタート前は非表示 */
      touch-action: manipulation;
    }
    #flag-container img {
      width: 100%;
      height: 100%;
      object-fit: contain;
      opacity: 0;
      transition: opacity 0.8s ease-in-out;
      position: absolute;
      top: 0;
      left: 0;
    }
    #country-name {
      position: absolute;
      bottom: 10px;
      left: 10px;
      background: rgba(255, 255, 255, 0.7);
      padding: 4px 8px;
      border-radius: 8px;
      font-size: 1.2em;
      z-index: 10;
    }
    /* 設定パネル */
    #control-panel {
      position: absolute;
      top: 10px;
      left: 50%;
      transform: translateX(-50%);
      background: rgba(255,255,255,0.9);
      padding: 8px;
      border-radius: 8px;
      z-index: 10;
      display: flex;
      gap: 10px;
      align-items: center;
    }
    #control-panel select {
      font-size: 1em;
      padding: 4px;
    }
    /* 右下の半透明グレーのボタン領域(もどるボタン) */
    #button-area {
      position: absolute;
      bottom: 10px;
      right: 10px;
      background: rgba(128, 128, 128, 0.5);
      padding: 10px;
      border-radius: 8px;
      z-index: 10;
      cursor: pointer;
      user-select: none;
    }
  </style>
</head>
<body>
  <!-- トップページ(初回表示) -->
  <div id="top-page">
    <h1>かざは の こっき</h1>
    <img src="kazaha.jpg" alt="かざはの顔">
    <br>
    <button id="start-button">スタート</button>
  </div>
  
  <!-- 国旗表示エリア -->
  <div id="flag-container">
    <img id="flag-image" src="" alt="国旗">
    <div id="country-name"></div>
    <div id="control-panel">
      <div>
        <label for="order-select">表示順序:</label>
        <select id="order-select">
          <option value="alphabetical">アルファベット順</option>
          <option value="japanese">アイウエオ順</option>
          <option value="random">ランダム</option>
        </select>
      </div>
      <div>
        <label for="region-select">表示領域:</label>
        <select id="region-select">
          <option value="all">全世界</option>
          <option value="eastAsiaOceania">東アジア〜オセアニア</option>
          <option value="southWestAsia">南〜西アジア</option>
          <option value="europe">ヨーロッパ</option>
          <option value="africa">アフリカ大陸</option>
          <option value="americas">アメリカ大陸</option>
        </select>
      </div>
    </div>
    <!-- 右下の「もどる」ボタン領域 -->
    <div id="button-area">もどる</div>
  </div>

  <!-- Kuroshiro と Kuromoji の読み込み -->
  <script src="https://unpkg.com/kuroshiro@1.1.3/dist/kuroshiro.min.js"></script>
  <script src="https://unpkg.com/kuroshiro-analyzer-kuromoji@1.1.0/dist/kuroshiro-analyzer-kuromoji.min.js"></script>
  
  <script>
    // グローバル変数
    let allCountries = [];
    let countries = [];
    let currentIndex = 0;
    let kuroshiro;
    let randomDisplayCounter = 1; // ランダムモードで初回表示されたときの番号用
    
    // 初期化処理全体をまとめる
    async function initializeApp() {
      // トップページを非表示、国旗エリアを表示
      document.getElementById("top-page").style.display = "none";
      document.getElementById("flag-container").style.display = "block";
      
      // Kuroshiro の初期化
      try {
        kuroshiro = new Kuroshiro();
        await kuroshiro.init(new KuroshiroAnalyzerKuromoji({
          dictPath: 'https://unpkg.com/kuromoji@0.1.2/dict/'
        }));
        console.log("Kuroshiro initialized");
      } catch (error) {
        console.error("Kuroshiro initialization failed:", error);
      }
      
      // 国データの取得
      await fetchCountries();
      // イベントリスナーの設定
      setupEventListeners();
    }
    
    // 国データ取得
    async function fetchCountries() {
      try {
        const response = await fetch("https://restcountries.com/v3.1/all");
        const data = await response.json();
        allCountries = await Promise.all(data.map(async country => {
          const flagUrl = country.flags && country.flags.png ? country.flags.png : "";
          const nameEn = country.name && country.name.common ? country.name.common : "";
          const jpName = (country.translations &&
                          country.translations.jpn &&
                          country.translations.jpn.common) ? country.translations.jpn.common : nameEn;
          let nameKatakana = "";
          try {
            nameKatakana = await kuroshiro.convert(jpName, { to: "katakana", mode: "normal" });
          } catch (err) {
            console.error("Conversion error:", err);
            nameKatakana = jpName;
          }
          return {
            flag: flagUrl,
            name_en: nameEn,
            name_katakana: nameKatakana,
            region: country.region || "",
            subregion: country.subregion || ""
          };
        }));
        // 不要なデータの除外
        allCountries = allCountries.filter(c => c.flag && c.name_en && c.name_katakana);
        
        // 各国旗に対してグローバルな番号を付与
        // (a) アルファベット順の通し番号
        let sortedAlpha = [...allCountries].sort((a, b) => a.name_en.localeCompare(b.name_en));
        sortedAlpha.forEach((country, index) => {
          country.numAlpha = index + 1;
        });
        // (b) アイウエオ順(カタカナ順)の通し番号
        let sortedKatakana = [...allCountries].sort((a, b) => a.name_katakana.localeCompare(b.name_katakana, "ja"));
        sortedKatakana.forEach((country, index) => {
          country.numKatakana = index + 1;
        });
        // (c) ランダムモード用(初回表示時に設定)の番号は未設定状態に
        allCountries.forEach(country => {
          country.numDisplay = null;
        });
        
        // 初期のフィルタ・ソート処理
        filterCountries();
        sortCountries();
        displayCountry();
      } catch (error) {
        console.error("Error fetching countries:", error);
      }
    }
    
    // 表示領域でフィルタ
    function filterCountries() {
      const regionValue = document.getElementById("region-select").value;
      if (regionValue === "all") {
        countries = allCountries.slice();
      } else if (regionValue === "eastAsiaOceania") {
        countries = allCountries.filter(c => 
          (c.region === "Oceania") ||
          (c.region === "Asia" && (c.subregion === "Eastern Asia" || c.subregion === "South-Eastern Asia"))
        );
      } else if (regionValue === "southWestAsia") {
        countries = allCountries.filter(c => 
          c.region === "Asia" && !(c.subregion === "Eastern Asia" || c.subregion === "South-Eastern Asia")
        );
      } else if (regionValue === "europe") {
        countries = allCountries.filter(c => c.region === "Europe");
      } else if (regionValue === "africa") {
        countries = allCountries.filter(c => c.region === "Africa");
      } else if (regionValue === "americas") {
        countries = allCountries.filter(c => c.region === "Americas");
      }
      currentIndex = 0;
    }
    
    // 表示順序でソート
    function sortCountries() {
      const order = document.getElementById("order-select").value;
      if (order === "alphabetical") {
        countries.sort((a, b) => a.name_en.localeCompare(b.name_en));
      } else if (order === "japanese") {
        countries.sort((a, b) => a.name_katakana.localeCompare(b.name_katakana, "ja"));
      } else if (order === "random") {
        // ランダムモードでは Fisher-Yates シャッフルを実施
        for (let i = countries.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1));
          [countries[i], countries[j]] = [countries[j], countries[i]];
        }
      }
      currentIndex = 0;
    }
    
    // 現在の国を表示
    function displayCountry() {
      if (countries.length === 0) {
        console.error("No countries available for the selected region.");
        document.getElementById("country-name").textContent = "データなし";
        document.getElementById("flag-image").src = "";
        return;
      }
      const currentCountry = countries[currentIndex];
      
      // 表示モードに応じた番号を取得
      const orderMode = document.getElementById("order-select").value;
      let displayNumber;
      if (orderMode === "alphabetical") {
        displayNumber = currentCountry.numAlpha;
      } else if (orderMode === "japanese") {
        displayNumber = currentCountry.numKatakana;
      } else if (orderMode === "random") {
        if (!currentCountry.numDisplay) {  // 初回表示時のみ番号を付与
          currentCountry.numDisplay = randomDisplayCounter++;
        }
        displayNumber = currentCountry.numDisplay;
      }
      
      // 国旗画像の切替演出
      const flagImage = document.getElementById("flag-image");
      flagImage.style.opacity = 0;
      setTimeout(() => {
        flagImage.src = currentCountry.flag;
        // 「通し番号:カタカナ国名」の形式で表示
        document.getElementById("country-name").textContent = displayNumber + ":" + currentCountry.name_katakana;
        flagImage.onload = () => {
          flagImage.style.opacity = 1;
        };
      }, 800);
    }
    
    // イベントリスナーの設定(タッチ対応の場合は touchend を優先)
    function setupEventListeners() {
      const flagContainer = document.getElementById("flag-container");
      
      function nextCountry() {
        currentIndex = (currentIndex + 1) % countries.length;
        displayCountry();
      }
      
      // タッチまたはクリックで次の国を表示
      if ('ontouchstart' in window || navigator.maxTouchPoints) {
        flagContainer.addEventListener("touchend", function(e) {
          nextCountry();
        }, false);
      } else {
        flagContainer.addEventListener("click", function(e) {
          nextCountry();
        }, false);
      }
      
      // 表示順序・表示領域の変更時の再ソート/再表示
      document.getElementById("order-select").addEventListener("change", () => {
        sortCountries();
        displayCountry();
      });
      document.getElementById("region-select").addEventListener("change", () => {
        filterCountries();
        sortCountries();
        displayCountry();
      });
      
      // 「もどる」ボタンのイベント設定
      const buttonArea = document.getElementById("button-area");
      
      // タッチイベントに対応
      buttonArea.addEventListener("touchend", function(e) {
        e.stopPropagation();
        e.preventDefault();  // タッチ操作時のデフォルト動作を防止
        if (countries.length > 0) {
          currentIndex = (currentIndex - 1 + countries.length) % countries.length;
          displayCountry();
        }
      }, false);
      
      // PCなど、タッチ以外のデバイス用のクリックイベントも残す
      buttonArea.addEventListener("click", function(e) {
        e.stopPropagation();
        if (countries.length > 0) {
          currentIndex = (currentIndex - 1 + countries.length) % countries.length;
          displayCountry();
        }
      }, false);
    }
    
    // スタートボタンのイベント設定(pointerup イベントを使用)
    document.getElementById("start-button").addEventListener("pointerup", () => {
      initializeApp();
    });
  </script>
</body>
</html>


2025年2月20日木曜日

こっき(1)

まだ1歳10ヶ月の風葉ちゃんは国旗を覚えるのが得意だ。GGが知らない国の国旗を沢山知っている。ママからのリクエストで国旗アプリを考えることになった。市販のスマホアプリは1-2歳向けではないのだ。要求仕様は次のようなものになる。

(1) 世界の国旗が地域別(または全世界)に表示される。
(2) その下にはカタカナの国名が表示されている。ママだけが読める。 
(3) タップすると順に次の国旗が表示される。国名がわからなければママが解説する。
(4) 表示は,アルファベット順,アイウエオ順,ランダムとする。
(5) 地域は,東アジア・オセアニア,西・南アジア,ヨーロッパ,アフリカ大陸,アメリカ大陸とする。

本物のiPhoneアプリはハードルが高すぎるので,とりあえずWebアプリにしよう。もちろん,高齢者の脳力に頼っていては死ぬまでにできあがらないので,ChatGPT o3-mini-high にお願いするわけだ。自分が入れた一連のプロンプトは以下のとおりである。

Q(koshix):
幼児向けの国旗のウェブアプリを作ってください。
お母さんと子どもが一緒に遊べるものです。
・国旗の画面が大写しになります。
・その画面に国名が小さく表示されます。
・スライドするとつぎの国旗にうつります。
・表示順序をアルファベット順,五十音順,ランダムに設定変更できます。
国連に加盟しているすべての国や地域のフリーのイメージデータに
アクセスして表示できるようにします。

Q(koshix):
国名はカタカナにしてください。
クリックしたら次の国旗に進むようにしてください。それまでは静止です。

Q(koshix):
画面が真っ暗で表示されず,クリックしても進まないのですが。

Q(koshix):
(1) 国旗の表示が画面いっぱいになっているので,もう少し小さめにして余白領域を作ってください。
(2) 表示範囲を,東アジア〜オセアニア・南〜西アジア・ヨーロッパ・アフリカ大陸・アメリカ大陸の5領域および全世界の6つから選択できるようにしてください。
(3) iPhoneにこのhtmlファイルを転送して実行しようとすると,スタート時点でつまづいて進みません。iPhoneでも使えるように対処可能でしょうか。

Q(koshix):
ありがとうございます。機能はほぼ希望通りになりました。しかし,iPhoneでは画面が真っ暗のままで進まずに停まっています。どこかへのアクセスが拒否されているような感じです。どうすればよいでしょうか。

Q(koshix):
iPhoneだけでなんとかしたいので,外部にhttps対応サーバを準備することができないのですが。マウスクリック操作の機能部分ははタッチ操作に対応するようになっていますかね。

Q(koshix):
1.ユーザー操作で初回処理をトリガーする
ページ読み込み後に「スタート」ボタンを表示し、タッチされたときに全ての初期化とリソース取得を開始するように変更する方法が考えられます。これなら、iOS側での自動起動制限を回避できる場合があります。
2.ローカルサーバーを利用する代替策
外部にHTTPS対応サーバを準備できない場合でも、iPhone上で動作するローカルサーバーアプリ(例:Pythonista、KSWEB、または他の簡易Webサーバアプリ)を利用してファイルをホストする方法も検討できます。

これらの場合の具体的な手順を詳細に説明してください。

Q(koshix):
localでウェブサーバを立ち上げ,iphoneでアクセスすることに成功しました。

Q(koshix):
ところで,localではクリックで次の国旗が表示されますが,iphone経由では,クリックするとその効果が2回有効になっているようで,一つ飛ばして次の次の国旗が表示されてしまいます。どうすればいいでしょうか。

Q(koshix):
1の方法をとりたいのですが,元のコードで言うとどの部分の修正になりますか。修正後の全コードを教えてもらったほうが助かります。

Q(koshix):
最初のスタートで次に進むことができなくなりました。

Q(koshix):
ありがとうございます,うまくいきました。
トップ頁に「かざは の こっき」というタイトルをいれて,かざはの顔写真 kazaha.jpg  437x377 ピクセルを表示するように修正できますか。 kazaha.jpg はkokki.html と同じフォルダにあります。


図:世界の国旗(外務省から編集して引用)

pythonでローカルのウェブサーバを立ち上げ,ngrokでトンネルを設定すると,外部からローカルウェブサーバのコンテンツにアクセスすることができる。そこで,kokki.html(296行)とkazaha.jpgを置いたディレクトリでローカルウェブサーバを立ち上げておけば,ngrokが指定するURLでiPhoneからこの国旗Webアプリが使えるようになった。
python3 -m http.server 8000
ngrok http 8000
https://zzzzzzzzzz.ngrok.io/kokki.html 
問題は,ngrokを無料で使っている限りこのURLが永続的ではないことだ。sakuraインターネットに眠らせてあるWebサイトを起すべきだろうか。ChatGPTを使えば一日一ウェブアプリを公開することができる。

(付)http.server ファイルの中身
import http.server
import socketserver
PORT = 8000
class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
    def end_headers(self):
        # iOS Safari のキャッシュ対策のため
        self.send_header("Cache-Control", "no-store, no-cache, must-revalidate")        http.server.SimpleHTTPRequestHandler.end_headers(self)
Handler = MyHttpRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("Serving at port", PORT)
    httpd.serve_forever()

2025年2月9日日曜日

立ちタイム

家人から「高齢者が1日20分程度立つ時間や機会を作ることは,立つ能力を維持し寝たきりになることを防ぐのに役立つ」と聞いた。調べてみるとGoogleもそう言っている。

老人が立っている時間を計測するアプリを作ると儲かるのではないかと考えた。考えるだけはタダなので。こんな場合,推論モデルの生成AI(DeepSeek R1とChatGPT o1)に聞いてみるといいかもしれない。なお「立ちタイム」というアプリ名はDeepSeekの提案だ。

Q(koshix):
老人の健康を維持するためには1日に20分以上立っていることが必要だということを聞きました。そこで,(1) スマートフォンだけ,あるいは,(2) スマートフォンと他のウェアラブルデバイスとの組み合わせ,によって,人が立っている時間を記録するアプリを作りたいと考えました。どのような原理とセンサーを用いれば,人間が立っている時間を測定することができるか,そのアイディアと具体的な実現方法を考えてみてください。

A(DeepSeek R1):
人間が立っている時間を測定するためのアプリ開発には、以下のような原理とセンサーの組み合わせが考えられます。スマートフォン単体と複数デバイス併用の両ケースについて具体的に説明します。

【基本原理】
立位状態の判定には「姿勢」「動き」「重力方向」の3要素を組み合わせます。特に重要なのは:
(1) 重力ベクトルの方向(スマホの傾き)
(2) 身体の垂直軸方向の加速度
(3) 高さ変化の検出(オプション)

【ケース1:スマートフォン単体での実現方法】
使用センサー
(1) 加速度センサー
・重力方向の検出:Z軸方向の重力値がほぼ1G(9.8m/s²)かつ安定している場合、直立状態と推定。
・動きの検出:3軸加速度の変動が少ないとき「静止立位」、周期的な変動があれば「歩行中」と区別。
(2) ジャイロセンサー
・姿勢の持続時間:デバイスの傾き角度が一定範囲(±15度以内)を維持した時間を計測。
 例:スマホがポケット内で縦方向に安定 → 立位と判断。
(3) 気圧センサー(搭載機種限定)
・相対高度変化:座る/立つの0.5m程度の高さ差を検出(例:±5hPaの変化をトリガーに)。

【アルゴリズム例】 python # 疑似コード (略)

【課題と対策】
・誤検知対策:椅子に座ったままスマホを机に置くケース → 照度センサーで「ポケット内/手持ち」を判別。
・省電力化:サンプリング間隔を調整(例:静止時は1Hz、動き検出時は10Hz)。

【ケース2:スマートフォン+ウェアラブルデバイスの組み合わせ】
追加センサー
(1) スマートウォッチの心拍数センサー
・静脈パターン変化:手首が心臓より下(垂れ下がった状態)で静脈圧が上昇 → 立位の補助指標。
(2) 骨伝導センサー(イヤホン)
・関節音の検出:膝の伸展時の「ポキッ」という微小な音を検出(実験段階の技術)。
(3) 足首バンドの圧力センサー
・足底荷重検出:直立時に均等な圧力分布が持続する特性を利用。

データ融合の例
複数デバイスのデータを組み合わせて信頼性向上:

【ユーザビリティ向上策】
(1) キャリブレーション機能
・初回設定時に「立つ」「座る」を指示し、個人のデバイス保持癖を学習。
(2) 誤検知フィードバック
・ユーザーが手動で誤りを修正すると、AIモデルが継続学習(Active Learning)。
(3) 省電力設計
・エッジAIで処理(クラウド依存せず)、TensorFlow Liteモデルを使用。

【検証方法】
(1) ベンチマークテスト
・カメラ映像とセンサーデータを同期記録し、教師データとして使用。
(2) シニア向け調整
・ゆっくりした動作に対応するため、状態遷移の判定閾値を緩和(例:立ち上がりに5秒以上かかるケース)。

【発展的な応用】
転倒予防:ふらつき検出(加速度の急激な揺れ)と連動。
血圧管理:立位時間と健康データ(Apple Health/Google Fit連携)を相関分析。

このように、スマートフォンの基本センサーを活用しつつ、ウェアラブルデバイスを組み合わせることで、より正確な立位時間の測定が可能になります。特に高齢者向けには「誤検知の少なさ」と「操作の簡便さ」のバランスが重要です。


A(ChatGPT o1):
以下では、まず「人が立っている状態をどのような原理で判定できるか」について、考え方をステップバイステップで整理し、そのうえで(1)スマートフォンのみを用いるケースと(2)スマートフォン+ウェアラブルデバイスを用いるケースの具体例を示します。

1.コンテキストと前提条件
「人が立っている状態の検知」は、腰や胸の位置にあるデバイスがどのような姿勢にあるか、あるいは体重のかかり方・重心の変化などをベースに判断できます。
スマートフォンだけで測定する方法と、ウェアラブルデバイスを追加で使う方法では、利用可能なセンサーや精度、実装の容易さが異なります。
特に高齢者が使う場合、「装着位置をどれだけ徹底できるか」「デバイスの充電や操作が煩雑にならないか」など、実際の利用シーンを考慮する必要があります。

2.人が立っている状態を推定するための主な原理
(1) 加速度計(加速度センサー)
・本体が垂直方向にどの程度加速度を受けているか、また姿勢がどう変化しているかを推定する。
・スマートフォンや多くのウェアラブルに標準搭載されているセンサー。
(2) ジャイロセンサー(角速度センサー)
・デバイスの回転や傾きの変化を検知する。
・姿勢の変化(座っている・立ち上がる・歩いている)などを判定するときに有用。
(3) 気圧センサー(バロメーター)
・スマートフォンやスマートウォッチに搭載されている場合、上下方向の移動(高さの変化)を推定できる。
・立ち上がった・しゃがんだなど、高さの小さな変化を捉えられる可能性がある(ただし微妙な変化をしっかり捉えられるほど精度が高いかは機種依存)。
(4) 近接センサー / 人感センサー / カメラ
・外部環境との距離や動きを把握して、立っている状態を推測する方法もあるが、スマホの近接センサーだけでは精度が不十分なことが多い。
・カメラを使う場合、人の姿勢推定アルゴリズム(Pose Estimation)などを適用する方法はあるが、バッテリー消費やプライバシー面で課題がある。
(5) 歩数センサー(ペドメーターAPI) と静止判定
・スマートフォンやスマートウォッチは、OS側で歩行や静止をある程度分類してくれるAPIがある(例:iOSのCore Motion、AndroidのActivity Recognition API など)。
・立って「静止」している場合と「座っている」場合を区別できるかは精度やアルゴリズム次第。ただしモーションAPIで「Standing」を直接判定できるとは限らないため、追加ロジックが必要。

3.スマートフォンのみを用いる場合のアイディアと実装方法
3-1. 装着場所の想定
・スマートフォンを腰の位置(ベルトクリップやポケット)に入れておく。
・「なるべく毎日同じ場所に装着する」ことを利用者に徹底してもらう。
3-2. センサー活用の流れ
(1) 加速度センサーによる傾き・姿勢検知
・加速度センサーの値から、スマホがほぼ垂直にあるか(重力方向と端末の姿勢方向が一致しているか)を確認する。
・人間が立っているときは、腰ベルト付近でスマホが縦方向に近い姿勢になりやすい。一方で、座るときはスマホの角度が変わる(背もたれとの関係や腿との角度など)。
(2) ジャイロセンサーによる動きの検知
・立ち上がる、座るといった動作時の角速度変化を検知し、姿勢遷移を検出する。
(3) Activity Recognition APIの利用(Android/iOS)
・端末のモーション処理APIを用いて、「歩行中」「静止中」などのステータスを取得。
・「静止中」かつ「端末が垂直に近い姿勢」という条件を満たす場合を「立っている」とみなすなどのロジックを組む。
3-3. 実装の例
(1) 単純ルールベース
・一定時間ごと(1秒単位など)に加速度ベクトル(x, y, z)を取得して、そのベクトルが重力方向(9.8m/s^2)とどの程度ズレているかを計算する。
・そのズレが小さい(つまり端末が垂直に近い)&歩数変化がない(=歩いていない)状態が連続した場合を「立位状態」とカウントする。
(2) API活用 + フィルタリング
・OS標準のActivity Recognition(例: Androidなら「STILL」「WALKING」「ON_FOOT」等)を取得。
・STILLの状態が一定秒数続き、スマホの傾きが一定範囲内なら「立位」とカウント。傾きが大きければ「座位」と推定。
・データを5秒ごとにログ化し、合計時間を算出。
3-4. 課題と工夫
・スマートフォンをテーブルやカバンの中に置きっぱなしにすると、加速度が検知されず誤検出が増える。
・スマートフォンの装着位置に依存するため、利用者の協力が必要になる。
・デバイスが古い場合はセンサー精度が低いことがある。

4.スマートフォン+ウェアラブルデバイスを用いる場合のアイディアと実装方法
4-1. 使えるウェアラブルの例
(1) スマートウォッチ
・加速度・ジャイロ・気圧センサーが入っていることが多い。
・歩数計測、立ち上がり、座っている時間のログ機能などが標準アプリに付いていることもある。
(2) スマートシューズ
・足裏の圧力センサーで、足に体重がかかっているかを検知できる。
・立っている・座っているの判定精度が比較的高い。
(3) 腰ベルト型の専用装置
・リハビリや介護分野で市販されている、姿勢判定に特化したデバイスも存在する。
4-2. スマートフォンとの連携によるメリット
(1) 装着の自由度
・スマートフォンはポケットなどに入れたままでも、ウェアラブル側のセンサーから姿勢推定が可能になる。
(2) データの統合
・スマートウォッチから取得した歩数や心拍データ、加速度データをスマホアプリと同期して、細かい姿勢判定に活用できる。
(3) 精度向上
・ウェアラブルは腕や足など人体により近い位置で計測し続けるため、加速度や姿勢変化をより正確に測定可能。
4-3. 実装の例
(1) 腕時計型デバイス + スマホ
・スマートウォッチの加速度データから「立位」と判定される動きを検知したら、Bluetooth等でスマホに通知。
・スマホ側アプリが受け取った時刻と連動して、「いつから立っているか」を計測し、座ったタイミング(=姿勢の変化を検知)で終了時刻を記録。
(2) 体重移動センサー(スマートシューズ) + スマホ
・足裏圧力が安定している場合を「立位」、不安定(分散が大きい)なら歩行や走行中、といった分類を行う。
・座位の場合は足への荷重が極端に減るため、閾値判定によって立位/座位を見分けやすい。
・スマホとはアプリやクラウド経由でデータを共有し、立っている合計時間を管理する。
4-4. 開発上の注意点
・ウェアラブルのバッテリー消費量を意識する:常にセンサーを高頻度でスキャンすると電池が早く切れる。
・高齢者が利用する場合、デバイスの装着が苦にならない設計が必要:腕時計タイプであれば普段から装着してもらえるが、足に何かつける場合は履き替えなどの煩雑さがないか考慮する。

5.まとめ
アイディアのポイント
(1) 基本は加速度センサーとジャイロセンサーが要
・スマホのみの場合はActivity Recognitionの利用や、スマホの傾き+静止判定を組み合わせて立位時間を推計。
(2) ウェアラブルを使うと精度・利便性が上がる
・腕時計型・足裏センサーなど、身体に近い場所で計測すると姿勢推定が簡単になり、アプリ側でのロジックも複雑になりすぎない。
(3) 利用者側の負担を減らす工夫
・特に高齢者向けでは、設定や充電、装着場所の固定など、ユーザーがミスしにくい仕組みづくりが重要。

以上のように、スマートフォン単体の場合でも加速度・ジャイロセンサーやOSのActivity Recognitionを活用すれば実現は可能です。しかし、利用者が毎回スマホをポケットや腰付近に装着してくれる前提がないと精度が低下することが多いです。その点、腕時計型ウェアラブルや足裏センサー等と連携することで、より精度の高い立位時間の計測や動作推定がしやすくなるでしょう。

 


図:立ちタイムのイメージポスター(DALL-E3による)


P. S. 灯台下暗し。隣のApple Watch ユーザによれば,Apple Watch はときどき「立ってね」とスタンドアップを促すそうだ。スタンドリマインダーというらしい。
「スタンドリマインダー」は、Apple Watchを装着している状態で1時間のうち最初の50分間座り続けている場合に「スタンドの時間です!」とメッセージ通知され、座り続けていることを予防する機能となっています。
Apple Watchでは1日の1時間当たり1分以上立っていた回数を測定しており、「アクティビティ」アプリの画面でその結果を確認することができます。(iPhone Wave から引用

2024年11月30日土曜日

古典籍OCR-Lite

NDLデジタルコレクションからの続き

NHK大河ドラマの「光る君へ」では毎回,出演者の努力の結晶である美しい筆運びが披露されている。古典籍のくずし字を読めたらいいなと思うことはしばしばで,教科書を買って積ん読状態にして挫折したことも何度もある。最近は,OCR技術が進んだのでその恩恵を被ることができるようになった。

NDL古典籍OCR-Liteは,GPUを持たないノートパソコンの環境で,江戸期以前の和古書,清代以前の漢籍といった古典籍資料のデジタル化画像からテキストデータが作成できる軽量なOCRだ。先日,NDLラボ公式GitHub公開されたところだ

Mac版のアプリケーションも公開されているので,怪しくないよとmacOSに宣言してあげれば使うことができる。早速試してみた。「古」を象ったアイコンのアプリケーションだ。

国立国会図書館デジタルコレクション枕草紙の最初の1ページを試しに与えてみたところ,
結果は次のようなテキストファイルで出力された。
枕草紙「阿波国81 
春はあけほのそらはいたくかろみにたるにやう〳〵
しろくなりゆく山きはのすこしつゝあかみて
むらさきたちたる雲のほそくたな引たる
なといとおかし
夏はよる月のころはさらなりやみもなをほたる
おほ〳〵とひちかひた又たゝ一二なとほのかに
うちひかりてゆくもいとおかし
雨のとやかにふりたるさへこそおかしけれ
秋は夕暮夕日のきはやかにさして山の葉ちかみ
あれ?普通の枕草子とは違うのかな?


写真:枕草紙のイメージ(NDLデジタルライブラリから引用)


2024年6月27日木曜日

東京都知事選挙(2)

東京都知事選挙(1)人民の敵からの続き 

たしかに,外山恒一いうように,この選挙地獄絵図を招いたのは2007年の東京都知事選挙における外山恒一の政見放送演説だったのかもしれない。それを反省してか?彼は2016年に,九州ファシスト党〈我々団〉の選挙制度改革案を提案している。現在のサニタイズされた生成AIにはこれを出力することができない。

このpdfファイルをClaude 3.5 Sonnetに読ませようとしたところ,日本語pdfが読めないようだった(ほんとか)。そこで,テキストをコピペして与えたところ次のようにまとめてくれた。
Q(koshix):
これなら読めますか。
A(Claude 3.5 Sonnet): 
はい、ありがとうございます。この文書は日本語で書かれており、内容を読み取ることができます。これは「九州ファシスト党〈我々団〉」という組織の選挙制度改革案についての詳細な文書です。主なポイントを要約いたします:
  1. 最終的要求:「学力試験による制限選挙制」の導入
    • 高校入試レベルまたはセンター試験の現代文レベルの試験を実施
    • 合格者のみに投票権を付与、または試験の成績に応じて投票の重みを変える
  2. その他の個別的な選挙制度改革の要求: a) 期日前投票の廃止、または選挙期間制の廃止 b) 供託金制度の廃止と「立候補同意署名」制度の導入 c) 小選挙区制の廃止、全国区制または中選挙区制の導入 d) 政令市議選における選挙区制の廃止 e) 戸別訪問や公開討論会などの自由化 f) 選挙権年齢と刑事罰が科される年齢の一致(具体的には14歳への引き下げ)
  3. 投票ボイコットの継続:
    • これらの改革が実現されない限り、原則として投票ボイコットの方針を継続

この文書は極端な政治的立場を示しており、民主主義の基本原則に反する提案も含んでいます。特に「学力試験による制限選挙制」の提案は、普通選挙の原則に反し、差別的な性質を持っています。また、組織の名称や主張には注意が必要です。これらの提案は、現代の民主主義社会では一般的に受け入れられないものです。

Q(koshix):
普通選挙の原則とはどんなものでしょうか。

A(Claude 3.5 Sonnet): 普通選挙の原則は、民主主義の基本的な要素の一つで、選挙権の平等と普遍性を保証するものです。主な特徴は以下の通りです:
  1. 普遍性:成人した市民は、原則としてすべての人に選挙権が与えられます。
  2. 平等性:「一人一票」の原則。すべての投票は同じ価値を持ちます。
  3. 無差別:人種、性別、社会的地位、教育レベル、財産などによる差別なく選挙権が与えられます。
  4. 秘密投票:投票の内容は秘密が守られ、外部からの圧力や影響を受けずに自由な意思表示ができます。
  5. 直接性:有権者が直接投票することで、間接的な方法(例:選挙人団)を介さずに代表者を選びます。
  6. 自由性:強制や不当な影響を受けずに、自由意思で投票できます。

普通選挙の原則は、19世紀後半から20世紀にかけて多くの国で段階的に導入されました。それ以前は、財産や教育レベル、性別などによる制限選挙が一般的でした。

日本では、1925年に男子普通選挙法が成立し、1945年に婦人参政権が認められて完全な普通選挙制となりました。

この原則は、民主主義における政治参加の平等を保証し、多様な意見を政治に反映させるための重要な基盤となっています。ただし、未成年者や重度の精神障害者、一部の重罪犯などには制限が設けられる場合があります。


年齢制限やドメイン投票に関わる部分はまだ十分考える時間がないが,外山恒一の提案で検討に値するのが,a) 期日前投票の廃止または選挙期間制の廃止,b) 供託金制度の廃止と「立候補同意署名」制度の導入,e) 戸別訪問や公開討論会などの自由化 である。

外山は,立候補同意署名制度について,現在の供託金没収ラインである有効投票数÷(議員定数×10)に対応して,有権者総数÷(議員定数×20)という数字を提案している。例えば人口6万人の天理市の市長選挙では,5万÷20 = 2500人,市議会議員選挙では 5万÷(16×20)≒150人というオーダーになる。

ここから私見: 立候補予定者があらかじめ,自分の履歴・経験や政策をまとめたこの政策ドキュメント(ダイジェストA4判1pと詳細版8p)およびビデオクリップ(ダイジェスト1分と詳細版10分)を提出し,それに対応するクローズドなサイトをつくる。有権者のうち立候補同意署名を依頼されて同意した人は,マイナンバーカードを用いた個人認証でこのサイトにログインし,同意欄にチェックすることで自動的に同意署名カウントが可能になる。なお,1人の有権者が複数の候補者に同意署名をすることはできない。

立候補同意署名の収集がクリアできた候補者は,この政策ドキュメントとビデオクリップをそのまま公開することになる。これらはネットでオープンにするため,ポスター掲示板は不要となる。なお,ビデオクリップはノーカットでなければならず,候補者本人のみが素顔で登場ことができる。手話通訳や翻訳は外部のAIツールにまかせる。


図:政策のマッチングサイト

P. S. 東京都民でもないのに,選挙ドットコムの運営している投票マッチングを試してみた。エントリーしているのは33人で,清水国明ら参加していない候補もいる。20個ほどの政策への賛否を5段階で選択して,候補者と比較するものだ。一番マッチしたのがあの橋下徹のDVしぐさと屁理屈をデッドコピーしていて辟易とする石丸伸二だった,オヨヨ。蓮舫は四番目,小池は何度試しても最下位。そうだよね。

[1]公職選挙法

2024年6月18日火曜日

スマホソフト競争促進法

スマートフォンにおいて利用される特定ソフトウェアに係る競争の促進に関する法律が,6月12日に参議院本会議で可決された。

発端は,AppleやGoogleのアプリストアが独占的で,他のベンダーの参入を妨げているということだ。AppleのApp Storeでは,登録されたアプリの安全性を慎重に審査しているので,これがなくなることによるセキュリティ上の問題点が懸念されるとの声が広がっていた。完全にそれはぬぐえていないが,とりあえず,ウェブからのアプリの直接ダウンロードを義務づけるまでには至らなくてよかった
スマートフォンが国民生活及び経済活動の基盤となっていることに鑑み、スマートフォンを利用した事業に係る競争環境を整備するため、スマートフォンの利用に特に必要な特定ソフトウェアの提供等を行う事業者を指定し、特定ソフトウェアに係る競争を制限するおそれのある行為を禁止する等の措置を講ずる必要がある。これが、この法律案を提出する理由である。
法案から用語の定義を抜き出してみると。
アプリストア:個別ソフトウェアを有償無償で提供しスマートフォンに組み込む用途の個別ソフトウエア
特定ソフトウェア:基本動作ソフトウェア(OS),アプリストア,ブラウザ,検索エンジンの総称(アプリストアやブラウザは個別ソフトウェアだが,検索エンジンは単にソフトウェアとされている)
個別アプリ事業者:個別ソフトウェアを提供する事業者
ウェブサイト事業者:商品又は役務の提供を目的として,スマートフォンを利用する公衆へのウェブページ又はその集合物の提示を行う事業者
特定ソフトウェア事業者:特定ソフトウェアの提供等を行う事業者のうち,当該特定ソフトウェアの提供等に係る事業の規模が他の事業者の事業活動を排除し,又は支配し得るものとして特定ソフトウェアの種類ごとに利用者の数その他の当該事業の規模を示す指標により政令で定める規模以上であるものを,次章の規定の適用を受ける者として指定するものとする。
特定ソフトウェア事業者(AppleやGoogleのこと)には,特定ソフトウェアの種類ごとに公正取引委員会に指標に関連する事項を届け出る必要がある。ということは,最初にどうやって指標を調べて特定ソフトウェア事業者を指定するのかが微妙なのだけれど,そこま目をつぶるのかな。

法案はわかりにくいので,特定ソフトウェア事業者について,第九条から第五条の禁止される行為と第十条から第十三条の講ずべき措置を,ChatGPT-4oに教えてもらうことにする。もちろん正しいかどうかは保証の限りでない。

A(GPT-4o):
スマートフォンにおいて利用される特定ソフトウェアに係る競争の促進に関する法律案」第五条から第九条で禁止される行為について、具体的な例を挙げて分かりやすく説明します。

第五条:取得したデータの不当な使用の禁止
禁止行為: 指定事業者は、取得したデータを競争上有利に利用してはならない。
具体例:
基本動作ソフトウェア:スマートフォンのOSを提供する事業者が、他のアプリ事業者のアプリ利用データを収集し、そのデータを基に自社の類似アプリを優位に展開すること。
例:OS事業者が他社の地図アプリの利用データを利用して、自社の地図アプリを優位にする。
アプリストア:アプリストアを運営する事業者が、他のアプリの売上データを利用して自社のアプリを優位に販売すること。
例:アプリストア運営者が他社ゲームアプリの売上情報を元に、自社ゲームアプリをプロモーションする。
ブラウザ:ブラウザ提供者が、他のウェブサイトの閲覧データを利用して、自社のサービスを優位に提供すること。
例:ブラウザ事業者が他社のニュースサイトの閲覧履歴を利用して、自社のニュースサイトを優先的に表示する。

第六条:個別アプリ事業者に対する不公正な取扱いの禁止
禁止行為: 指定事業者は、他の個別アプリ事業者に対して不公正な取扱いをしてはならない。
具体例:
不当な差別的扱い:アプリストア運営者が、特定のアプリ開発者だけに不利な条件を課すこと。
例:アプリストアが特定のアプリ開発者にだけ高額な手数料を設定する。

第七条:基本動作ソフトウェアに係る指定事業者の禁止行為
禁止行為: 指定事業者は、基本動作ソフトウェアを用いて他の事業者のアプリストアや機能の利用を妨げてはならない。
具体例:
アプリストアの限定:OS提供者が、自社のアプリストアのみを利用可能にすること。
例:スマートフォンメーカーが自社のアプリストア以外をインストールできないようにする。
機能の制限:他社のアプリがスマートフォンの機能を利用できないようにすること。
例:他社の音声アシスタントアプリがスマートフォンのマイクを利用できないようにする。

第八条:アプリストアに係る指定事業者の禁止行為
禁止行為: 指定事業者は、アプリストアにおいて他の支払手段や商品情報の表示を制限してはならない。
具体例:
支払手段の制限:アプリストア運営者が、自社の支払手段のみを使用させること。
例:アプリストアが自社の決済システム以外を利用できないようにする。
価格情報の制限:他の販売チャネルでの価格情報をアプリ内で表示させないようにすること。
例:アプリストアが、ウェブサイトでの価格情報をアプリ内で表示できないようにする。

第九条:検索エンジンに係る指定事業者の禁止行為
禁止行為: 指定事業者は、自社のサービスを不当に優先表示してはならない。
具体例:
検索結果の操作:検索エンジン提供者が、自社のサービスを他社よりも優先的に表示すること。
例:検索エンジンが自社のショッピングサイトを検索結果の上位に表示する。
これらの禁止行為は、特定ソフトウェアの提供者が市場で不当に優位に立つことを防ぎ、公正な競争環境を維持することを目的としています​​。


A(GPT-4o):
スマートフォンにおいて利用される特定ソフトウェアに係る競争の促進に関する法律案」の第十条から第十三条で指定事業者が講ずべき措置について、具体例を挙げて分かりやすく説明します。

第十条:データの取得等の条件の開示に係る措置
措置内容: 指定事業者は、特定ソフトウェアの利用に伴い取得するデータに関する条件を開示する。
具体例:
基本動作ソフトウェア:スマートフォンのOS提供者が、アプリ開発者に対して、OS利用に伴い取得するアプリの利用状況データやその管理方法を明示する。
例:OS提供者がアプリ開発者に、取得するデータの種類(例:クラッシュログ、使用頻度)やその保存方法を開示する。
アプリストア:アプリストア運営者が、アプリ提供者に対して、アプリストアの利用に伴い取得するデータ(例:ダウンロード数、評価)の取得条件を開示する。
例:アプリストアがアプリ提供者に、ユーザーの評価データの取得方法や利用条件を説明する。

第十一条:取得したデータの移転に係る措置
措置内容: 指定事業者は、利用者が求めに応じて取得したデータを移転できるようにする。
具体例:
基本動作ソフトウェア:スマートフォンのOS提供者が、ユーザーが求めた場合に連絡先データを他のアプリに移転できるようにする。
例:ユーザーが新しいメッセージングアプリを使うために、連絡先を一括で移動できるようにする。
アプリストア:ユーザーが他のアプリストアに移行する際に、購入履歴データを新しいアプリストアに移転できるようにする。
例:ユーザーがGoogle PlayからApp Storeに移行する際に、購入済みアプリの情報を移行できるようにする。

第十二条:標準設定等に係る措置
措置内容: 指定事業者は、標準設定におけるユーザーの選択を容易にする。
具体例:
基本動作ソフトウェア:スマートフォンのOS提供者が、ユーザーが標準の検索エンジンを簡単に変更できるようにする。
例:ユーザーがデフォルトの検索エンジンをGoogleからBingに簡単に変更できるようにするオプションを提供する。
ブラウザ:ブラウザ提供者が、ユーザーが標準設定された検索エンジンを簡単に選択・変更できるようにする。
例:ブラウザの設定メニューで、ユーザーが簡単に検索エンジンを選択できるようにする。

第十三条:特定ソフトウェアの仕様等の変更等に係る措置
措置内容: 指定事業者は、仕様変更や利用条件の変更を行う際に、関係事業者に情報を開示し、対応する期間を確保する。
具体例:
基本動作ソフトウェア:OS提供者が、アップデート前にアプリ開発者に新機能や仕様変更を通知し、適切な対応期間を提供する。
例:新しいOSバージョンがリリースされる前に、アプリ開発者に詳細な変更内容を提供し、テスト期間を確保する。
アプリストア:アプリストア運営者が、ストアポリシーの変更を行う際に、アプリ提供者に通知し、対応期間を設定する。
例:新しいセキュリティ基準の導入前に、アプリ開発者に通知して準備期間を与える。
これらの措置は、公正な競争環境を維持し、利用者と他の事業者が適切に対応できるようにすることを目的としています​​。
これで,実際にサードパーティのアプリストアが登場するのだろうか。ゲームメーカーが独自のアプリストアと課金システムを導入することは,フォートナイトのエピックゲームズの例からもありそうである。それ以外は,ちょっと難しいのではないか。

図:サードバーティーアプリストアのデザインをDALL-Eにまかせてみるが,
全然ダメッぽいのであった。ダメ出し数回してもやっとこの程度(右)

2024年6月11日火曜日

マイナンバーカード

マイナンバーカードは,だいぶ前に大学から取得を促す連絡がきたので,2020年の2月に市役所で手続きした。そもそも,デザインも設計も最悪だった。顔写真はまともに識別できないし,ペラペラのフィルムケースで番号を隠すという分けのわからない仕様になっていた。そのうえ,たった4桁のPINコードを含み,4種類?も暗証番号が意味不明に設定されている。アホなの?

さらに,このマイナンバーカードに,健康保険証や運転免許証を統合しようという悪らつな企みが現在進行中である。そういいながらも,コロナ期間中のエサにつられて,健康保険証としての利用OKモードに申請したのは私です。いや,必要性は認めているのだけれど,設計がおかしいだけだ。

情報システム学会では,2023年10月に,「マイナンバーカードの問題点と解決策」に関する提言を出している。2013年にはマイナンバーカードの導入に賛成していたが,その後の運びがあまりにもグダグダだったので,こういうことになる。どうして政府にはまともな専門家の意見を聞く能力がないのだろうか。まあ,日本学術会議を壊したがっているような人々に期待するのは無理な話かもしれない。

最近,GoogleのGemini Pro 1.5 をベースにした,NotebookLMが登場した。研究論文や取材記録,仕事でのドキュメントなどの参照文献(ソース)をアップロードすると,NotebookLM がそれらの重要な資料を理解し,必要なサポートを提供してくれるという優れものだ。GPT-4oでもある程度はできるのだが,より使いやすくなっている。早速,マイナンバーカードの提言を読み込ませてみた。

最初に,テキストの概要が出てきて,よくありそうな質問項目もあらかじめ用意されている。もちろん,対話的に必要な質問をすることができ,その答えがオリジナル文書のどこにかかれているかを示すリンクも含まれている。
概要

情報システム学会マイナンバー制度研究会は、「マイナンバー制度の問題点と解決策」に関する提言を2023年10月10日に発表しました。本提言は、マイナンバー制度の目的やデジタル化推進そのものを否定するものではなく、制度設計の根本的な問題点とその解決策を提示しています。 具体的には、制度導入初期に発生した誤った名寄せやコンビニでの証明書誤発行問題、3つの本人確認機能を1枚のカードに集約した設計の矛盾、保険証・運転免許証との一体化に伴うリスクなどを指摘しています。 その上で、名寄せ基準の明確化、ITガバナンスの強化、用語定義の見直し、3つの本人確認機能の分離、番号とカードの再設計、記載内容の精査などを提言し、国民目線に立った、より安全で効率的な制度への再構築を訴えています。

Q:マイナンバー制度の根本的な設計不良とは何か?

マイナンバー制度の根本的な設計不良は、制度で実現したいことが多すぎて議論が混乱し、目標が曖昧なままシステム設計をしてしまったことである。 その結果、システム設計が多岐にわたり、矛盾や齟齬が発生している。 さらに、すべての機能を1枚のマイナンバーカードに搭載したため、カード実装が複雑化した。
具体的には、以下の2つの問題点が挙げられる。
・1枚のマイナンバーカードに3つの本人確認機能(身元確認機能、当人確認機能、真正性確認機能と属性情報確認機能)を入れたこと。
・1枚のマイナンバーカードに保険証機能と運転免許証機能を入れ込み、保険証と運転免許証を廃止する構想であること。
これらの問題点により、国民はマイナンバーとマイナンバーカードの取り扱い方を理解できず、制度設計自体に不安を抱いている。 また、カードの紛失や盗難、なりすまし犯罪のリスク増加、高齢者施設でのカード管理の問題など、多くの社会問題を引き起こす可能性がある。

Q:マイナンバーカードの取り扱いに関する矛盾点を具体的に説明しなさい。

マイナンバーカードの取り扱いについては、国民にとって非常に分かりにくいという問題点があります。 具体的には、マイナンバー(番号)は「特定個人情報」であるため、他人に見せてはいけないとされています。 しかし、マイナンバーカードは身分証明書として使用するため、他人に見せる機会が多いという矛盾があります。 さらに、マイナンバーカードにはマイナンバーが記載されており、QRコードを読み取ることで他人が簡単にマイナンバーを読み取ることができてしまいます。
このため、国民はマイナンバーとマイナンバーカードのどちらをどのように取り扱うべきか混乱しています。 政府はマイナンバーカードを大切に扱うように促していますが、マイナンバー自体をどのように取り扱うべきかについては明確な指示を出していません。
このように、マイナンバーカードの取り扱いに関する矛盾は、国民の混乱を招き、マイナンバー制度への不信感を増大させる要因となっています。

 


写真:デザイン最悪のマイナンバーカード

P. S. マイナンバーカードのデザインは改善されるらしい。さらに,iPhoneにもマイナンバーカード機能が実装されるとのこと。ただ,健康保険証問題は未解決のまま突っ張るらしい・・・orz。

2024年4月7日日曜日

たぬき

滋賀県といえば,琵琶湖。琵琶湖の回りに少しだけ陸地がくっついていて,そこに人が住んでいるというのが普通の滋賀県のイメージだ。ちがう?ところが,地図をみると琵琶湖はそれほど大きくなくて,南東側に大きな面積の土地が拡がっている。その中心の甲賀市は,2004年の平成の大合併で信楽町や甲賀町など5町が統合してできた。

さて信楽といえば,信楽焼のたぬきの置物だ。最近ゲットした情報によれば,どうやら滋賀県にある家の95%には,信楽焼のたぬきが置いてあるらしい。しらんけど。そこで比較のため,奈良県における朝の散歩の途中で,どのくらいたぬきに遭遇するかを確かめてみた。

結構多いぞ。50分の間に13件くらい発見した。たぶんこちらに移住してきた隠れ滋賀県民に違いない。これを皆さんにお知らせしようとすると,13枚の写真から1枚の写真を作る必要がでてきてしまった。たぬきの置物ごときに10枚以上の写真データを使うのはもったいないからだ。

さっそく,ChatGPTに聞いて見ると正しい答えを得ることができた。やはり,小学校ではプログラミングの授業は不要である。むしろ正しい日本語で問いを立てられるようになることや,様々なアプリケーションによるマルチメディア情報処理過程の具体的イメージをよく知ることの方がよほど大事だ。ブラックボックス化された手順を知る必要はそこまでないのでは。
Q:koshix
写真データがHEIC形式で15ファイルあります。これを,jpgに変換して,5×3の並びにした1枚のjpgファイルに変換したいのです。imagemagikはインストール済みです。具体的なコマンドを教えてください。

A:ChatGPT
以下の手順に従って、15個のHEIC形式の写真ファイルをjpgに変換して、5×3の並びにした1枚のjpgファイルに変換するコマンドを示します。

まず、HEIC形式のファイルをjpgに変換します。
magick mogrify -format jpg *.HEIC
次に、変換されたjpgファイルを5×3の並びにします。
magick montage -tile 5x3 -geometry +0+0 *.jpg output.jpg
これらのコマンドを順番に実行すると、15個のHEICファイルがjpgに変換され、5×3の並びにされた1枚のjpgファイルが生成されます。

その結果が次のファイルである。 


写真:朝の散歩で出会った13たぬき(撮影 2024.4.7)

P. S. 同じ質問を,GeminiとClaudeとPerplexityに投げてみたところ,先の2つはダメ。Perplexityは,縦一列のファイルが出力された。これに関してはChatGPTの勝ち。

2024年1月8日月曜日

GO

大阪・関西万博2025の際に,大阪でライドシェアを実現しようと吉村が動いている。背後に菅義偉や河野太郎がいるので,どう考えても怪しいということになってしまう。地域ごとのタクシー事業者との合理的な棲み分けや調整さえうまく図られればよいのだろうが,複雑に絡み合った利権の縺れた糸を解きほぐすのはそう簡単ではなさそうだ。

世界的には,ライドシェアといえばUberであり,サンフランシスコでドリキンが普通に使っているのを見ていると,いつかはそれがあたりまえの風景になっていくのかもしれない。

日本では,まだライドシェアが法的に認められていないので,Uberは大都市に特化したタクシー配車サービスのUber Taxiの展開にとどまっている。一方タクシー配車アプリは昔からちらほらiPhoneで見かけたけれど,使ったことはなかった。

この度,なら歴史芸術文化村MINAMI(吉田南)のコンサートがあるというので,孫の風葉ちゃんたちと一緒に,タクシー配車サービスに挑戦することになった。日本で最も普及しているスマートフォンのタクシー配車アプリが,GOである。10万台が登録されているということで,単純計算すると1万人当たり8台になるので,天理市だと50台以上は利用可能になるはずだった。

ところで,GOアプリに登録してタクシーを呼び出してみると,タクシーの姿はあって,4-12分で来るというメッセージは出るのだけれどいっこうに来る気配がない。仕方がないので地元の天理タクシーに直接電話してきてもらう。

天理タクシーにはタブレットがついていて,GOサービスが使えそうな雰囲気がある。運転手さんに聞いて見ると,支払いはGOで可能なのだけれど,このあたりではGOでの配車予約はできないとのことだった(どの程度確かなことかはよくわからない)。とりあえず,GOアプリとNFC接続することで,QRコードスキャン無しで支払うことができた。


写真:GOアプリのアイコン(AppStoreから引用)

2023年11月8日水曜日

レジカート

近所のマーケットに行ったら,レジカートなるものが導入されていた。

新しもの好きなので,早速トライアルしてみた。セルフレジは使ったことがある。重さを検知していて待たされたり,やり直しになったりと,一見便利そうなのだけど実際には店員さんが入力したほうが早く終る。

レジカートは普段のカートより大きめで,タブレットサイズの入力チェック画面とがっちりしたバーコードスキャナーがついている。使い方は特に教わる必要もなくスイスイと入力できる。なかなかいいぞ。キーウィ6個パックをカゴに入れたところで,隣に半値の4個パックがあった。早速前者を取り消したが,これも問題なくできた。スキャンしてカゴに入れた商品はタブレット画面で確認できるし,総額も常にわかって便利だ。

問題は,プリペイドカードで払う必要があることだけれど,これもアプリに切り替わりつつある。いいような悪いような。ICOCAもiPhoneにしているので,何かのときに困るような気もする。とりあえず,チャージしてレジカート専用窓口に並んだところ,対応のお姉さんが一瞬でチェックして通過することができた。

設備投資にはコストがかかりそうだし,レジカートがかさ張るのが問題かもしれないが,労働人材不足の折り,さらにこの手のシステムの普及は進むのだろう。


写真:はじめてのレジカート(撮影 2023.11.6)


2023年6月28日水曜日

モバイルICOCA

ついこの間,ICOCAからスマートICOCAに引っ越したばかりなのに,もうモバイルICOCAがiPhoneに対応してしまった。

Suicaは以前からモバイル対応だったのでうらやましかったが,ICOCAも3月のAndroid端末に続いてようやくiOSまで順番が回ってきた。夕方のニュースで見かけて早速トライしたら皆が殺到していた。少しだけ待たされたが,案内行列に並んでいたらしばらくしてOKとの通知があった。

iOSのウォレットを開いて,追加の+メニューから交通系カードを選ぶと,トップにICOCAがでてきたので,SMART ICOCAカードを取り出してiPhoneをかざすだけだ。情報の転送が必要だからだろうか,普通のICカードでの読み取りに比べるとちょっと時間がかかる。

ICOCAアプリのインストールに誘導されたので,こちらもインストールしたけれど,役割分担が今一よくわかっていない。とにかく,ICOCAアプリは使えるようになり待望のオンラインチャージも可能になった。チャージ上限は2万円というのも確認できた。ところで,旧のモバイルICOCAカードのほうはそのまま使えるのだろうか。WESTER アプリで残高確認すると,一応残っているのだ。どういうこと?

検索してもあまり要領を得ない。世界はどんどん複雑になっていって,年寄りはついていくのが大変になる。これに新幹線のスマートEXを組み合わせて使うことになったらどうしようかと思うのだけれど,もう東京に通うこともなくなったので,心配御無用であった。


写真:引き続き使えるのかどうかよくわからなくなった SMART ICOCA

追伸:JRおでかけネットをちゃんと読むと,移行後のICOCAは使えなくなるので破棄せよとのことだった。

推察:夕方にApple Payの障害で,モバイルSUICAが使えなくなっていた。たぶん,アクセスが集中したICOCAのせいではないかと睨んでいるのだがどうだろう。

付録:モバイルICOCAはAndroid用の名前であって iPhoneのそれは ICOCA  Pay らしい。