RでPISA2015〈その2〉

RでPISA2015」というエントリーで、いくつかのWeb記事に触発されて、OECDという国際機関が3年間隔で行なっている国際学力調査「PISA」の2015年実施データを、統計向けプログラミング言語「R」を使って触り始めたことを書きました。

R言語の基礎知識が無いまま、サンプルを見様見真似でデータファイルの読み込みからグラフの描画までやってみましたが、まだまだ未完成状態でした。

その後、R言語のリファレンス書籍を購入した上で、さらにプログラムを修正し、思い描いていたグラフを一通り描けるところまで辿り着きました。

PISA2015_IC013Q12NAのグラフ

作成中気になっていたことの一つとして、PISA2015データを日本語で扱うための情報が、明石書店発行のPISA正規報告書(有償)しかないことがあります。

PISA2015関連の情報については、「PISA2015関連」(ICTのある学び)にまとめておきましたが、日本語版を作成して調査協力をした国立教育政策研究所のWebページでさえ報道機関向けレベルの公表資料が掲載されているだけで、PISAに関する正規の日本語情報は明石書店が契約して発行している日本語版報告書くらいしかありません。

そのため、背景指標を得る質問調査(ICT活用調査を含む)の日本語は、販売されている報告書を手に入れないと知ることができません。いくつかのWeb記事で分析・紹介されている調査結果の質問や回答の文章は、OECDがWebサイトで無償公開している英語版報告書を各自で翻訳している状態です。

PISAの趣旨や目的からすれば、調査結果をもとに各国の教育政策に関する議論が様々に誘発されることが大事であるにも関わらず、日本の場合、どうしても日本語要約された報道発表範囲の限られた話題しか扱われず、それ以外は英語原文か有償の日本語版報告書を得なければならない壁があります。

今回のように調査の生データを処理して視覚化する際も、質問文や回答選択肢文を日本語で表示した方が圧倒的に理解がしやすいわけですが、そのためのリソースはネット上に存在しません。

日本語によるPISA調査作業量の大変さとそれを担われている関係者の労力には敬意を持ちますし、それを踏まえて発行される日本語報告書が有償販売されることは理解できます。ただ、もう少し社会的な議論が進むよう無償部分の情報流通量を増やす努力も必要かなと思います。

少なくとも調査データを自前で処理する際に使えるリソースは欲しいものです。

そこで、プログラム処理する際に使えるようPISA2015における「国別コードと国名」「ICT活用調査の質問文」「ICT活用調査の回答選択肢文」をcsvファイルにしておきました。

国別コードと国名
(csv)http://www.edufolder.jp/files/pisa2015/ISO3166_pisa.csv
(xlsx)http://www.edufolder.jp/files/pisa2015/ISO3166_pisa.xlsx
ICT活用調査の質問文
(csv)http://www.edufolder.jp/files/pisa2015/pisa2015_ICT_Familiarity_Questionnaire.csv
(xlsx)http://www.edufolder.jp/files/pisa2015/pisa2015_ICT_Familiarity_Questionnaire.xlsx
ICT活用調査の回答選択肢文
(csv)http://www.edufolder.jp/files/pisa2015/pisa2015_ICT_Familiarity_Questionnaire_answercode.csv
(xlsx)http://www.edufolder.jp/files/pisa2015/pisa2015_ICT_Familiarity_Questionnaire_answercode.xlsx

(csv形式の方は)UTF-8コードで日本語も含めてありますので、英文と日本文を切り替えて利用するのにも便利です。データ構造の解説は今回省略します(ごめんなさい)。

(修正20170116:「〜」を「-」に修正し,xlsx形式も用意しました。)

ちなみに,OECDが用意しているコード表は「Codebooks for the main files」としてダウンロードページに用意されています。これの日本語版があったらいいのになという感じです。

上記のデータファイルを利用したプログラムを作成してみました。質問番号(と表示順序)を設定したら半自動でグラフが出力されるところまで動くようになったと思います。

設定した質問についてグラフ化するR言語ソースコードは以下が現在の進捗です。今回はファイルやライブラリの読み込み(Base部分)と質問ごとに集計してグラフ描画する部分(ICT部分)を分けてみました。Base部分は最初の一回だけ実行すれば、あとは読込み済みのデータで処理できます。

(追記20170114:macOSでの導入を前提としたスクリプトのため,Windows等の他環境では,日本語フォント指定の部分等について改変する必要あり。)

# For PISA2015 Base (※最新のものが下方のリンクに有り)
# K.RIN

library(readr)
library(haven)
library(ggplot2)
library(plyr)
library(tidyverse)

question_items <- read_csv("pisa2015_ICT_Familiarity_Questionnaire.csv", col_names = TRUE, col_types = list(col_character(), col_character(), col_character()))
answer_items <- read_csv("pisa2015_ICT_Familiarity_Questionnaire_answercode.csv", col_names = TRUE, col_types = list(.default = col_character(), items_count = col_character()))
country_code <- read_csv("ISO3166_pisa.csv", col_names = TRUE, col_types = list(col_character(), col_character(), col_character(), col_character()))

student_raw <- read_sav("Cy6_ms_cmb_stu_qqq.sav")
school_raw <- read_sav("Cy6_ms_cmb_sch_qqq.sav")

pisa2015_base.R (←こちらの方が最新版)

# For PISA2015 ICT (※最新のものが下方のリンクに有り)
# K.RIN
#
# ★設定項目
# ・質問ID(「selected_question = " "」の部分)
# ・表示順序の組合わせ(「mutate('list_order' = `1`)」の部分)

#★質問番号
selected_question = "IC010Q09NA"
selected_question_big = substring(selected_question, 1,5)

#質問文読込
q_title <- paste(question_items$questions_ja[grep(selected_question_big, question_items$questions_no, value = FALSE, fixed = FALSE)][[1]])

#質問文整形
q_width = 39
q_title_disp <- character()
q_title_length <- nchar(q_title)
for(i in 1:q_title_length%/%q_width+1) {
 q_title_disp[i] <- paste(substring(q_title, ((i-1)*q_width+1), ((i-1)*q_width+1)+(q_width-1)), '\n')
}
q_title_disp[i+1] <- paste("\n", selected_question,"\n", question_items$questions_ja[grep(selected_question, question_items$questions_no)])
q_title_all <- paste(q_title_disp, collapse="")

#回答選択肢読込
ans_item_count <- as.integer(answer_items$items_count[grep(selected_question, answer_items$questions_no)])
ans_item_colcount <- as.integer(answer_items$items_count[grep(selected_question_big, answer_items$questions_no)][1])

#回答選択肢設定
ans_limits <- as.character(answer_items[grep(selected_question_big, answer_items$questions_no),][1,3:sum(ans_item_count+2)])
ans_labels <- as.character(answer_items[grep(selected_question, answer_items$questions_no),][1,sum(ans_item_colcount+3):sum(ans_item_colcount+ans_item_count+2)])

#ラベル
y_label <- "パーセント %"
x_label <- "国"
legend_label <- "回答"

#回答データ抽出
stu_tmp <- subset(student_raw, student_raw[[selected_question]] != "NaN")
#scl_tmp <- subset(school_raw, school_raw$[[selected_question]] != "NaN")
country_ans_table <- table(stu_tmp[["CNT"]],stu_tmp[[selected_question]])

#縦長dfへ変換
country_ans_long <- as_tibble(country_ans_table,validate = FALSE)
colnames(country_ans_long) <- c("CNT", "answer", "count")
#横長df版クロス表
country_ans_wide <- spread(country_ans_long, answer, count)

#★表示順序用対象項目設定(回答の場合) `1`+`2`
country_ans_wide <- country_ans_wide %>% rownames_to_column('num') %>% mutate('list_order' = `1`)

#文字から数値にモード変換
mode(country_ans_wide$id) <- "integer"

#国名変換
country_ans_wide <- ddply(country_ans_wide, 'CNT', transform, country_name = country_code$Name_ja[grep(CNT, country_code$Alpha3)])

#表示順序用対処数値設定(ナンバリングの場合)
#country_ans_wide <- ddply(country_ans_wide, num, transform, list_order = num * -1)
#ラベルが"X1"などになった場合も想定して…
colnames(country_ans_wide) <- c("num", "CNT", ans_limits, "list_order", "country_name")

#国名付き縦長df
country_ans_long <- gather(country_ans_wide, answer,count,-num,-CNT,-list_order,-country_name)

#並べ替え
country_ans_long <- arrange(country_ans_long, desc(CNT), desc(answer))

#列名変更
colnames(country_ans_long) <- c("num", "CNT", "list_order","country_name","answer", "count")

#パーセント計算(描画計算用)
country_ict <- ddply(country_ans_long, "CNT", transform, percent = count / sum(count) * 100, 0.1)
#小数点以下1桁処理(表示用)
country_ict <- ddply(country_ict, "CNT", transform, percent_rounded = round_any(count / sum(count) * 100, 0.1))

#リスト順序(パーセント計算)
country_ict <- ddply(country_ict, "CNT", transform, list_percent_order = round_any(list_order / sum(count) * 100, 0.1))

#ラベル位置計算
country_ict <- ddply(country_ict, "CNT", transform, percent_label_y = cumsum(percent)-0.5*percent)

country_ict <- arrange(country_ict, CNT, desc(answer))

#フォントファミリー設定(macOS用)
quartzFonts(HiraKaku = quartzFont(rep("HiraginoSans-W3", 4)))
par(family = "HiraKaku")

#グラフ描画
graph <- ggplot(country_ict, aes(x = reorder(country_name, list_percent_order), y = percent, fill = factor(answer))) + 
 ggtitle(sprintf("%s", q_title_all)) + 
 ylab(y_label) + 
 xlab(x_label) + 
 labs(fill = legend_label) + 
 coord_flip(expand = FALSE) + 
 geom_bar(stat = "identity", position='stack') + 
 geom_text(aes(y = percent_label_y, 
 label = paste(format(percent_rounded, nsmall = 1),"")), color = "white", size = 3) + 
 scale_y_reverse(breaks = c(100.0,75.0,50.0,25.0,0.0), 
 labels = c("0%","25%","50%","75%","100%")) + 
 scale_fill_discrete(limits = ans_limits, labels = ans_labels) + 
 scale_color_manual(values = rainbow(7)) + 
 theme_bw() + 
 theme(plot.margin = margin(1, 1, 1, 1, "cm"), 
 plot.title = element_text(family = "HiraKaku", size = 10), 
 plot.caption = element_text(family = "HiraKaku", size = 10),
 legend.title = element_text(family = "HiraKaku", size = 10), 
 legend.text = element_text(family = "HiraKaku", size = 7), 
 axis.title = element_text(family = "HiraKaku", size = 9), 
 axis.title.y = element_text(angle = 0, vjust = 0.5), 
 axis.text.x = element_text(family = "HiraKaku", size = 9), 
 axis.text.y = element_text(family = "HiraKaku", size = 10)) 

print(graph)

#ggsave("pisa2015_graph.png", graph)

pisa2015_ict.R (←こちらの方が最新版)

文部科学省トップページリニューアル

文部科学省Webサイトのトップページがリニューアルしています。

おそらく1月5日更新からの変更と思います。今回の変更は,タブレットやスマートフォンで操作しやすくデザインされたものといえます。今のところトップページのみで,下部ページは従来を踏襲しているようです。

スライドして切り替わるローテーションバナーの時間間隔が短いためか,若干落ち着きがない印象を受けますし,空白を活かしたレイアウトに慣れないため一覧性が落ちたように感じるところも無くはありません。タブレットとスマートフォンでの表示も最適化が十分でないような気もします。

伝えなければならない情報がたくさんあるので,これを上手に情報デザインしていくのは大変ですし,サイトデザインされた方の苦労をお察しします。Webデザインもさることながら,今後も各種の情報や資料を迅速に公開し続けていただくこと期待したいと思います。

360度撮影カメラの新顔

りん研究室でも注目している360度撮影カメラ。 私たち一般の人間でも手に入るものとしては,リコー社THETAシリーズGiroptic社360camハコスコ社販売代理Insta360 nanoなどが出ていました。

一方,VR(バーチャルリアリティ)技術を視聴するヘッドマウントディスプレイ(HMD)という機器が有名ゲーム機の周辺機器として登場することで,360度映像自体への関心も高まりつつあります。

「撮影」と「視聴」に用いる機器がそれぞれに発展しようとしているわけです。そして360度映像の撮影カメラも,さらにいくつかの新顔が登場しています。

Nikon社 KeyMission 360

老舗カメラメーカーのNikon社が手がけた360度アクションカム。価格帯が6万円強のため,他の比較すると入手の敷居は高く,同社として初めての部類の製品のためか改善の余地が多い様子。

Arashi Vision社 Insta360 Air

従来のInsta360 nanoがiPhoneのLightningコネクタに直接差すことができるタイプの製品だったのに対して,マイクロUSBコネクタ対応でAndroidスマホだけではなくパソコンにも接続できるようにした製品。

Giroptic社 Giroptic iO

従来の360camがSDカードやWiFiで端末に映像を転送するタイプの製品だったのに対して,iPhoneやiPadのLightningコネクタに差して使用することができるように開発した製品。Insta360 nanoの対抗商品。

リコー社 RICOH R Development Kit

THETAシリーズとは別系統で,米国CESで発表されたデバイス。まだ発売されておらず,開発者向けのものが先行公開されるとの情報(一般でも購入できそうな様子)。360度映像のストリーミング配信(ネット中継)を主な使途として想定していて,THETA Sと違いスティッチング処理をカメラ自身で行なうようになっています。HDMI出力はできるものの配信処理は別途デバイスが必要。

Arashi Vision社 Insta360 Pro

こちらも米国CESの合わせて発表されたもののようです。もはやプロ用。8Kという解像度で360度撮影できるようです。360度撮影カメラは解像度の高いものが少なく,高ければそれだけ映像処理の負担が増えるため機器のコストも高くなってしまいます。とはいえ,VR市場の拡大が期待され,品質の良いVRコンテンツの需要が高まることは必至ですから,8Kレベルの撮影ができるカメラもどんどん登場すると思います。

以上,各社からいろんなアプローチの製品が登場しています。価格や性能なども様々で,ジャンルとしては切磋琢磨が始まった段階です。過度な期待は保留した上で,可能性を育てていくことが大事だと思います。

学校教育の現場では,タブレット端末を「大きなデジタル」として利用する基礎的な利用方法がありますが,360度撮影カメラもその一環に組み入れて,学校周辺や社会見学先等の様子を記録する用途で活用ノウハウを溜めていくこと,そしてその用途でさらに必要と思われる機能をフィードバックしてメーカー各社に要請していくことが大事になると思います。

(追記20170106:Insta360 Proを追加しました。)

(修正20170107:リコー社の製品名を正しました。)

前提を疑う

学習指導要領改訂審議や教育情報化を推進する動きは,現在や今後の分析や社会的要請等を吟味して組み立てられます。

2030年に向けて「第4次産業革命」や「人工知能」の発展が加速していく世の中で生きる力を育成するとはどういうことなのか。「資質・能力」や「主体的・対話的で深い学び」が求められていると説かれたりします。

それらを実現するためにも,これからは「社会に開かれた教育課程」「カリキュラム・マネジメント」の考え方のもとで学校運営していかなければならないことも主張されています。

「情報活用能力」は「言語能力」とともに教科等を越えた全ての学習の基盤として育む資質・能力として挙げられています。必要なICT環境等の話は「「2020年代に向けた教育の情報化に関する懇談会」最終まとめ」が方向性を示しているとされています。

最終まとめではICT環境について,パソコン教室の整備から普通教室への端末整備という方向性のもと,「教員自身が授業内容や子供の姿に応じて自在にICTを活用しながら授業設計が行なえるようにする」ことが重要とされています。

その他にもさまざまな文書が登場したのが2016年でした。そうした文書に関する情報は様々なところで発信されています。それについては,このブログでもまたゆっくりと参照できればと思います。

そうした様々な文書に直接関係するわけではないのですが,昨年話題になった本を手にする機会があったので読んでみています。

ジェフリー・フェファー『悪いヤツほど出世する』(日本経済新聞社)
https://www.amazon.co.jp/dp/453232081X

もともとはリーダーシップ・ビジネススクール(リーダー教育産業)に対する懐疑から出発して,こうした教育産業が流布するリーダー像の「ウソ」を指摘する本です。「ウソ」を暴くというのは書籍の帯的な文句で,むしろリーダー神話(リーダーに必要とされる「謙虚さ」「自分らしさ」「誠実」「信頼」「思いやり」)に対する言葉面通りではない現実的な理解を事例や研究成果を踏まえて示していく内容になっています。つまり前提を疑ってみることがこの本の面白味です。

本を読みながら,上に掲げた様々なキーワードについても同様に前提を疑って考えたり,現実的な理解で考えた場合にどうなるのか,いろいろ考えを巡らしていました。

文部科学省が出してきた文書は,今回は特に,とても頭の回転が速い人たちが作成したものになっていて,整合性を崩さないよう言葉を上手に選んで継ぎ足してながら,ある意味で「全部盛り」なのです。

それを踏まえて,甘味な解説がたくさん書かれることになるのですが,そうした理想を現実的に適用していく場合には,理想と反したことを展開しなければならない場合があるというジレンマについては,途端に根性論的な話へと堕ちてしまいがちです。

そうした構図自体が悪で,変えなければならないと主張したいわけではありませんが,そうした現実がある中で,どうしたらよりマシになるのかを考えていくことが大事なのだろうなと思う次第です。

本自体は,会社経営分野の話なので,関心がないと面白くないのかも知れません。図書館か書店でパラパラと読んでみるくらいでいいのかも知れません。

初めてのプログラミング言語

実家の部屋を整理していましたら、『はじめて読む8086』(1987)と『はじめて読むMASM』(1988)が出てきました。マシン語(機械語)とそれに対応したアセンブリ言語の解説書です。基本図書といってもよい書籍です。

私自身も最初はBASICを雑誌や学習マンガで学んだ一人ですが、初めて開発したパブリックドメインソフト(PDS)はアセンブリ言語で作りました。MS-DOSに標準添付されていたのがMASMというアセンブラしかなかったからです。当時はシステムコールに興味があって、いろいろ技術書を買い込んでいたことを思い出します。

その後、比較的安価なTURBO-Cを手に入れて、C言語の世界へと入っていくことになります。それもPDS開発のためでした。

というわけで、私のプログラミングスキルは独学の好き勝手学習で身につけたものです。そのため、ちゃんとしたソフトウェア工学を学んだ人のようにプログラミング教育などを語ることはできません。

けれども、素人プログラマーなりにプログラミング教育についてはいろいろ考えていきたいと思います。