新学習指導要領に対応した2025年からの大学入学共通テストの試作問題等が2022-11-09に公開された(2022-12-23一部訂正)。この中の「情報I」の試作問題の第4問は、いわゆるデータサイエンスの問題である。
この元データをT.Matsushima先生が見つけてくださった(令和7年度大学入学共通テスト 情報Ⅰ参照):
社会生活基本調査 / 平成28年社会生活基本調査 / 調査票Aに基づく結果 生活時間に関する結果 生活時間編(地域)
ここからダウンロードできるExcelファイル(ファイル名 a059_4.xlsx)を読めば、表1-A・表1-Bができる。
import pandas as pd df = pd.read_excel("a059_4.xlsx", skiprows=18, na_values=["...","-"], keep_default_na=False) df1 = df.iloc[:, [5,6,7,8,9,10,19,20,21,22,24,33]] df1.columns = ['曜日', '地域区分', '男女', '就業状態', '使用時間', '年齢', '睡眠', '用事', '食事', '通学', '学業', '趣味'] # df1.dropna(inplace=True) dfa = df1.query("曜日 == '2_平日' and 地域区分 != '00_全国' and 男女 == '0_総数' and 就業状態 == '0_総数' and 使用時間 == '21_1時間未満' and 年齢 == '01_15~19歳'") dfa = dfa[['地域区分', '睡眠', '用事', '食事', '通学', '学業', '趣味']] dfb = df1.query("曜日 == '2_平日' and 地域区分 != '00_全国' and 男女 == '0_総数' and 就業状態 == '0_総数' and 使用時間 == '23_3~6時間未満' and 年齢 == '01_15~19歳'") dfb = dfb[['地域区分', '睡眠', '用事', '食事', '通学', '学業', '趣味']] dfa.to_csv("1a.csv", index=False, encoding="utf_8_sig", lineterminator="\r\n") dfb.to_csv("1b.csv", index=False, encoding="utf_8_sig", lineterminator="\r\n")
以下では見やすくするためCSVファイル中の .0
は一括削除した。
1a.csv: 表1-A:スマートフォン・パソコンなどの使用時間が1時間未満の人の生活行動時間に関する都道府県別平均値
地域区分,睡眠,用事,食事,通学,学業,趣味 01_北海道,439,74,79,60,465,8 02_青森県,411,74,73,98,480,13 03_岩手県,442,61,87,98,539,8 04_宮城県,425,56,114,41,400, 05_秋田県,447,73,85,42,501,8 06_山形県,,,,,, 07_福島県,,,,,, 08_茨城県,407,61,80,79,552,11 09_栃木県,433,76,113,50,445,57 10_群馬県,411,77,108,79,418,7 11_埼玉県,431,68,82,79,370,14 12_千葉県,499,63,96,64,374,63 13_東京都,454,71,80,99,520,27 14_神奈川県,380,71,89,102,518,3 15_新潟県,,,,,, 16_富山県,429,41,76,100,578,1 17_石川県,423,59,75,64,582,2 18_福井県,362,60,83,48,752,3 19_山梨県,427,65,73,69,527,5 20_長野県,393,81,98,50,487,25 21_岐阜県,421,68,86,70,481,19 22_静岡県,425,79,73,81,543,42 23_愛知県,436,78,92,69,318,95 24_三重県,449,60,91,104,530,2 25_滋賀県,,,,,, 26_京都府,451,95,96,105,375,4 27_大阪府,342,69,96,90,544,14 28_兵庫県,457,58,77,73,463,43 29_奈良県,440,53,97,70,483,17 30_和歌山県,466,60,68,71,481,16 31_鳥取県,,,,,, 32_島根県,433,69,81,58,445,8 33_岡山県,448,77,77,71,447,21 34_広島県,423,87,92,58,469,17 35_山口県,422,83,84,58,561,64 36_徳島県,400,74,85,62,520,23 37_香川県,443,79,72,60,620,21 38_愛媛県,383,126,74,81,524, 39_高知県,,,,,, 40_福岡県,410,84,88,81,594,6 41_佐賀県,418,100,86,52,403,0 42_長崎県,398,57,106,78,483,22 43_熊本県,444,40,85,65,568, 44_大分県,386,41,76,43,419,6 45_宮崎県,407,52,80,105,496,20 46_鹿児島県,407,58,88,56,537,9 47_沖縄県,447,67,90,72,482,13
1b.csv: 表1-B:スマートフォン・パソコンなどの使用時間が3時間以上6時間未満の人の生活行動時間に関する都道府県別平均値
地域区分,睡眠,用事,食事,通学,学業,趣味 01_北海道,436,74,88,63,411,64 02_青森県,461,57,83,55,269,44 03_岩手県,442,70,76,54,366,63 04_宮城県,426,64,86,89,285,44 05_秋田県,430,68,76,96,340,41 06_山形県,426,69,67,64,509,54 07_福島県,422,51,77,55,379,53 08_茨城県,443,80,81,82,423,63 09_栃木県,386,120,79,77,504,33 10_群馬県,427,76,60,65,442,69 11_埼玉県,431,69,99,98,400,24 12_千葉県,411,69,98,104,391,60 13_東京都,428,98,101,87,406,59 14_神奈川県,415,94,81,113,390,53 15_新潟県,434,79,80,63,363,107 16_富山県,476,70,68,63,401,29 17_石川県,417,59,91,84,475,82 18_福井県,452,73,77,68,378,70 19_山梨県,466,69,100,60,263,84 20_長野県,446,63,76,75,424,88 21_岐阜県,426,64,82,59,442,32 22_静岡県,415,79,79,68,410,82 23_愛知県,409,76,89,83,371,68 24_三重県,465,83,87,57,334,67 25_滋賀県,433,89,98,116,341,73 26_京都府,462,31,68,83,365,18 27_大阪府,448,57,86,80,369,70 28_兵庫県,448,67,68,83,378,36 29_奈良県,468,62,82,102,347,48 30_和歌山県,442,51,66,60,315,76 31_鳥取県,425,73,78,112,255,96 32_島根県,422,68,81,61,407,108 33_岡山県,451,58,78,70,374,69 34_広島県,452,69,72,68,414,57 35_山口県,441,54,89,68,350,68 36_徳島県,412,56,83,86,486,22 37_香川県,456,44,67,79,462,61 38_愛媛県,463,84,72,48,404,125 39_高知県,452,87,86,64,393,81 40_福岡県,418,63,84,77,445,56 41_佐賀県,453,67,75,67,360,49 42_長崎県,423,56,82,42,432,80 43_熊本県,442,29,68,47,481,49 44_大分県,415,42,69,57,436,62 45_宮崎県,421,64,86,71,316,56 46_鹿児島県,407,82,79,69,424,50 47_沖縄県,450,52,103,50,417,49
いったんCSVファイルができてしまえば、これを読むほうが早い:
import pandas as pd dfa = pd.read_csv("https://okumuralab.org/~okumura/python/data/1a.csv") dfb = pd.read_csv("https://okumuralab.org/~okumura/python/data/1b.csv")
p.26に「ただし,表1-A,表1-Bにおいて一か所でも項目のデータに欠損値がある場合は,それらの都道府県を除外したものを全体として考える」とあるので、欠損値が一つでもある行を削除したものも作っておく:
dfA = dfa.dropna() dfB = dfb.dropna()
欠損値を削除しない dfa
、dfb
も残しておくのは、あとで回帰分析をする際に、dfa
のほうを使わないと結果が合わないためである。問題作成者が混乱しているのかもしれない。
p.26で「なお,以下において,データの範囲については,外れ値も含めて考えるものとする」という指示があるのは、一部で(例えば2σ以上離れた)外れ値は機械的に削除するといった指導がされていることに対応するためなのだろうか。
p.27「図1 睡眠の時間の分布」の箱ひげ図:
import matplotlib.pyplot as plt plt.boxplot([dfB['睡眠'], dfA['睡眠']], vert=False, labels=['表1-B', '表1-A'])
Seabornを使う場合:
import seaborn as sns sns.boxplot(pd.DataFrame({"表1-A": dfA["睡眠"], "表1-B": dfB["睡眠"]}), orient="h")
p.27「図2 学業の時間の分布」の箱ひげ図:
plt.boxplot([dfB['学業'], dfA['学業']], vert=False, labels=['表1-B', '表1-A'])
p.29「図3 生活行動時間の差」の箱ひげ図:
plt.boxplot([(dfa['睡眠'] - dfb['睡眠']).dropna(), (dfa['学業'] - dfb['学業']).dropna()], labels=['睡眠', '学業'])
図4 表1-Aの学業の時間と睡眠の時間の散布図:
plt.plot(dfa['学業'], dfa['睡眠'], 'o')
回帰直線:
import pingouin as pg pg.linear_regression(dfa[['学業']], dfa['睡眠'], remove_na=True)
names coef se T ... r2 adj_r2 CI[2.5%] CI[97.5%] 0 Intercept 491.165521 27.408073 17.920469 ... 0.13757 0.115456 435.727460 546.603581 1 学業 -0.136434 0.054700 -2.494202 ... 0.13757 0.115456 -0.247076 -0.025792
回帰式 y = -0.14x + 491.17 が確認できる。傾き -0.136 は、95% 信頼区間 [-0.247, -0.026] が 0 をまたがないので、5% 水準で有意である。
残差は次のようにして求められる:
lm = pg.linear_regression(dfa[['学業']], dfa['睡眠'], remove_na=True, as_dataframe=False) r = lm['residuals']
図6 睡眠の時間(推定値)と残差の変換値との関係:
import numpy as np plt.plot(lm['pred'], (r - r.mean()) / r.std(), "o")
散布図と回帰直線(95%信頼区間付き)を描くには seaborn のほうが便利である:
import seaborn as sns sns.regplot(dfa, x="学業", y="睡眠")
ただし、一番右の点(福井県、752分)を含めなければ、傾きは有意でなくなる:
dfx = dfa.query("地域区分 != '18_福井県'") pg.linear_regression(dfx[['学業']], dfx['睡眠'], remove_na=True)
names coef se T ... r2 adj_r2 CI[2.5%] CI[97.5%] 0 Intercept 472.905958 31.48758 15.018809 ... 0.058038 0.03325 409.162686 536.649230 1 学業 -0.097699 0.06385 -1.530144 ... 0.058038 0.03325 -0.226956 0.031558
散布図と回帰直線をさきほどの図に重ね書きする。青が全体、オレンジが福井県を除いたものである:
sns.regplot(dfx, x="学業", y="睡眠")
このことから、右端の福井県こそが外れ値というべきであろう(問5の後半の議論とは裏腹に)。
福井県を除けば傾きが有意でなくなることに加え、都道府県ごとの平均値の傾向は必ずしも個人の傾向を表すものではないこと(生態学的誤謬、ecological fallacy)を考慮して、この種のデータは慎重に扱う必要がある。
また、学業の時間と睡眠の時間との関連を調べる際に、なぜスマホ・パソコンの利用時間が1時間未満という条件を付ける必要があったのかもよくわからない。