ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示

2024年11月22日金曜日

置換可能素数

レピュニットからの続き

プログラミングの例題として次のようなことを考えた。「ある素数があって,その各桁を入れ換えてできる全ての数が素数になるものを考える。その最大の素数はどんなものだろうか。」

で,実際に自分でプログラムを書くかというと,それは面倒なので,いつものようにAIに頼ることにする。軟弱だ。脳細胞のフレイルだ。OpenAI o1とかPerlexity Proに頼ってみたが,正しい答えがでない。PythonをJuliaに書き換えても,さらにドツボにはまるだけ。

一度リセットしてから,再度挑戦した。

Q(koshix):
n桁の素数が与えられたとき,その各桁の数字を入れ替えてできるすべての数が再び素数になるようなもので,できるだけ大きな数を探したい。桁数nを与えたときに,この条件を満たす最大の数を求めるプログラムを作成してください。

A(Perplexity Pro):
この問題を解決するために、以下のようなプログラムを作成しました。このプログラムは、与えられた桁数nに対して、条件を満たす最大の素数を見つけます。

import itertools
from sympy import isprime

def find_large_permutational_prime(n):
    lower_bound = 10**(n-1)
    upper_bound = 10**n
    primes = [p for p in range(lower_bound, upper_bound) if isprime(p)]
    largest_permutational_prime = -1
    for prime in primes:
        permutations = set(int(''.join(p)) for p in itertools.permutations(str(prime)))
        if all(isprime(p) for p in permutations):
            largest_permutational_prime = max(largest_permutational_prime, prime)
    return largest_permutational_prime

そして,ChatGPT-4oでJuliaに変換したものが次の通りである。
using Primes
using Combinatorics

function find_large_permutational_prime(n)
    lower_bound = 10^(n - 1)
    upper_bound = 10^n - 1
    largest_permutational_prime = -1
    
    for prime in primes(lower_bound, upper_bound)
        perms = Set(parse(Int, join(p)) for p in Combinatorics.permutations(string(prime)))
        if all(isprime(p) for p in perms)
            largest_permutational_prime = max(largest_permutational_prime, prime)
        end
    end
    
    return largest_permutational_prime
end
これを実行すると,n=3で991が得られる。n=4,5,6では結果なしということになった。これから,nが4以上では条件を満たす素数が存在しないと証明できないかと考えたけれど,そんな簡単な話ではなかった。もちろん,現在の生成AIでは証明できない。

調べてみるとこのような素数は,置換可能素数として既によく知られているものだった。911の上にある素数はレピュニット素数だった。これは無限個あると推定されているがまだよくわかっていないのだ。もちろん,3,7,9 の1種類だけが並んだ数は素数にはならない。

2024年10月26日土曜日

政党マップ

YouTubeで,衆議院選挙向けの政治教養的な話をしていた。天理教の人だったので,思わずみてしまったが,意外にまともな説明だった。政党(および自民党総裁選の三候補)を政治的な対立軸と経済的な対立軸で2次元のマップ上に書いていた。前者は,国家主義・全体主義と個人主義・自由主義,後者は,資本主義・新自由主義と社会主義・共産主義というものだ。

なかなか面白かったのだけれど,最後に本人の支持政党が日本維新の会ということでがっくり。まあそんなものだ。

同じようなことをしてみようと,AIチャットボットに次の質問をいれてみる。

Q(koshix):
日本の政党の主張を分析して,経済軸と政治軸の2軸で あらわされる平面上の矩形領域で表わしたいと思います。 経済軸(X軸)は,-1から1の値をとり,左(-1)が社会主義や共産主義的な 考え方,右(+1)が資本主義や新自由主義的な考え方に対応します。 政治軸(y軸)は,-1から1の値をとり,下(-1)が自由主義や個人主義的な 考え方,上(+1)が国家主義は全体主義的な考え方に対応します。 例えば,アメリカ合衆国は (1,-1)の近傍に位置し,中華人民共和国は (-1,1)の近傍に位置します。 日本の政党としては,以下の10党を選びます。 自由民主党,公明党,日本維新の会,参政党,日本保守党, 国民民主党,立憲民主党,れいわ新撰組,社民党,日本共産党 結果は,政党名:(-0.9〜-0.6,0.4〜0,8) のように表現してください。

ChatGPT-4o,Gemini 1.5 flash,Perplexity Pro ,Claude 3.5 Sonnet で試してみるとそれらしい結果が出てきたが,まちまちだったので,適当に平均した後に主観的に修正してみる。これを図示するプログラムもPerplexity ProやChatGPT-4oに任せてみたところ,なんとか結果が得られた(日本語フォントコードはこちらで修正追加,USAとChinaも追加している)。あとは,適当なアルゴリズムで尺度さえ決まればよいということになるが,そのあたりを具体的に表現するのは難しい。ちなみに,OpenAI o1 では期待するようなそれらしい結果がでなかった。

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.font_manager as fm
from matplotlib import rcParams

# フォントの設定
font_path = '/System/Library/Fonts/ヒラギノ丸ゴ ProN W4.ttc'  # 適切な日本語フォントファイルを指定してください
font_prop = fm.FontProperties(fname=font_path)
rcParams['font.family'] = font_prop.get_name()

# 政党名とそれぞれの位置(Avarage?)
parties = {
    '自由民主党': ((0.1, 0.9), (0.1, 0.9)),
    '公明党': ((-0.1, 0.3), (0.0, 0.5)),
    '日本維新の会': ((0.6, 1.0), (0.2, 0.8)),
    '参政党': ((-0.2, 0.2), (0.7, 0.9)),
    '日本保守党': ((0.6, 0.9), (0.8, 1.0)),
    '国民民主党': ((0.0, 0.4), (-0.1, 0.2)),
    '立憲民主党': ((-0.6, 0.2), (-0.5, 0.1)),
    'れいわ新撰組': ((-0.7, -0.3), (-0.7, -0.3)),
    '社民党': ((-0.9, -0.5), (-0.6, -0.3)),
    '日本共産党': ((-0.9, -0.7), (-0.3, -0.1)),
    'U.S.A.': ((0.75, 1.0), (-1.0, -0.20)),
    'China': ((-1.0, -0.25), (0.75, 1.0)),
    # 修正された位置
}

# グラフの設定
plt.figure(figsize=(8, 6))

# 軸の設定
plt.axhline(0, color='black', linewidth=0.5, ls='--')  # x=0
plt.axvline(0, color='black', linewidth=0.5, ls='--')  # y=0
plt.grid(color='gray', linestyle='--', linewidth=0.5)

# 政党ごとに異なる色を設定
colors = {
    '自由民主党': 'blue',
    '公明党': 'yellow',
    '日本維新の会': 'green',
    '参政党': 'orange',
    '日本保守党': 'purple',
    '国民民主党': 'brown',
    '立憲民主党': 'cyan',
    'れいわ新撰組': 'magenta',
    '社民党': 'pink',
    '日本共産党': 'red',
    'U.S.A.': 'gray',
    'China': 'gray',
}

# データプロット
for party, ((x_min, x_max), (y_min, y_max)) in parties.items():
    rect = patches.Rectangle(
        (x_min, y_min),
        x_max - x_min,
        y_max - y_min,
        alpha=0.3,
        color=colors[party],  # 色を設定
        label=party
    )
    plt.gca().add_patch(rect)
    plt.text((x_min + x_max) / 2, (y_min + y_max) / 2, party,
             fontsize=9, ha='center', va='center')

# 軸の範囲
plt.xlim(-1.1, 1.1)
plt.ylim(-1.1, 1.1)

# タイトル
plt.title('日本の政党の経済軸と政治軸')
plt.xlabel('経済軸 (左: 社会主義, 右: 資本主義)')
plt.ylabel('政治軸 (下: 自由主義, 上: 国家主義)')
plt.grid()

plt.show()


図:日本の政党マップ(ひとつのイメージ)

[2]政治的スペクトル(Wikipedia)

2024年7月20日土曜日

プログラミング的思考(3)

プログラミング的思考(2)コンピューテーショナル・シンキング(4)からの続き

Q(koshix):
プログラミング的思考とComputational Thinkingの共通点と相違点をおしえてください。情報教育において,どちらが有用でしょうか。

A(Perplexity PRO):
プロサーチ
・プログラミング的思考の定義を検索する
・Computational Thinkingの定義を検索する
・プログラミング的思考とComputational Thinkingの共通点と相違点を比較する
・情報教育においてプログラミング的思考とComputational Thinkingのどちらが有用かを評価する

回答
プログラミング的思考とComputational Thinkingの共通点と相違点 
共通点
・目的達成のための論理的思考: 両者とも、目的を達成するために論理的に手順や方法を考える力を重視しています。これは問題解決において非常に重要です。
・抽象化と分解: どちらも、問題を小さな部分に分解し、それぞれを抽象化して理解する能力を必要とします。このプロセスにより、複雑な問題を扱いやすくします。
・シミュレーションと試行錯誤: どちらも、シミュレーションや試行錯誤を通じて、最適な解決策を見つけることを重視します。 
相違点
プログラミング的思考
効率の重視: 目的達成のために最適な方法を見つけることに重点を置きます。例えば、洗濯の手順を効率的に行う方法を考える。
具体的な手順の構築: 具体的な手順やアルゴリズムを作成し、それを実行することに焦点を当てます。
プログラミング教育の一環: 主にプログラミング教育の中で教えられ、具体的なプログラムの作成を通じて学びます。
Computational Thinking
広範な適用: 計算論的思考は、プログラミングだけでなく、日常生活や他の学問分野にも適用されます。例えば、データの整理やパターン認識。
概念的な理解: 計算論的思考は、問題を解決するための概念的な枠組みを提供し、広範な問題に適用可能です。
コンピュータ科学の基盤: コンピュータ科学全般の基盤として教えられ、プログラミング以外の多くの分野にも応用されます。

情報教育における有用性
どちらが情報教育において有用かは、教育の目的や対象によって異なります。
・プログラミング的思考は、具体的なプログラムを作成する能力を養うために非常に有用です。プログラミングの基礎を学ぶことで、論理的思考力や問題解決能力が向上します。
・Computational Thinkingは、より広範な問題解決能力を養うために有用です。これは、プログラミングだけでなく、データ分析やシステム設計など、他の多くの分野にも応用可能です。

したがって、初等教育やプログラミングの基礎を教える場合には「プログラミング的思考」が有用です。一方で、より広範な問題解決能力やコンピュータ科学全般の理解を深めるためには「Computational Thinking」が有用です。

両者をバランスよく取り入れることで、学生は具体的な技術スキルと広範な問題解決能力の両方を身につけることができます。

Sources:
1: https://kids.athuman.com/cecoe/articles/000178/
2: https://www.koov.io/column/210
3: https://products.sint.co.jp/topsic/blog/computational-thinking
4: https://www.cs.cmu.edu/afs/cs/usr/wing/www/ct-japanese.pdf

 


図:Computational Thinking のイメージ(Nord Anglia から引用)


2024年7月11日木曜日

サイコロの雌雄

70年以上生きていても知らないことがたくさんある。サイコロには雌雄がある(普通のサイコロは雌)というのだ。まあ,いわれてみれば,サイコロの鏡像は自分自身とは重ならない。学部の4回生のセミナーでLeeとYangのパリティ非保存の論文をさんざん読み込まされた割には,自らの不明を恥じるしかない。

さっそく,図示するため生成AIに頼るのだが,これが一筋縄では行かない。最近,巷で流行る石○構文のようなもので,空気が読み切れない部分的に論理的な無駄なやりとりの行き違いが山のように蓄積していく。ときどき一発で正解がでることもあるが,ちょっと相手の機嫌を損ねると,三途の河原送りで石を積み上げ続ける羽目に陥る。
Q(koshix):
立方体のサイコロの展開図を描画するpythonプログラムを下さい。
展開図は6つの正方形の面が接して並ぶものです。
各面には1〜6の数が適当は大きさの小丸(ドット)で表現されます。
展開図を組み立てたときに向かいあう面の数の和が7になるように配置されます。
1の面の小丸は少し大きい赤色ですが,他の面の2-6の小丸は黒です。 
A(Claude 3.5 Sonnet):
→SVGファイルが生成されて保存されるはずが失敗
→画面にも表示されないので,pngファイルに変更
→画面に出力された(OK)ので,雌雄を判定させる。

Q(koshix):
以下の定義からこのサイコロの展開図の雌雄を判定してください。

サイコロの目の割り振りは、ほぼ「天一地六東五西二南三北四」(雌サイコロ)と決まっている。これは、日本だけの特徴ではなく、世界的な共通点である。ただし、「南三」でなく「北三」になっているサイコロもあり、「南三」を雌サイコロ、「北三」を雄サイコロと呼ぶこともある(異性)。サイコロの雌雄の見分け方は、1・2・3の面が集まる頂点を正面に置き、1→2→3の順に見たときに時計回りになるのが雄サイコロ、反時計回りになるのが雌サイコロである。

→ただしく雌であると判定できた,エライ
→雌雄の両方の展開図を上下に出力させる
→日本語ラベルが文字化けしているので修正させる
→なかなか修正できず何度も失敗する
→こちらから日本語設定のサンプルコードを与える
→できた!日本語ラベルと展開図が重なっているので右シフトを依頼
→Claude 3.5 Sonnetの無料制限オーバーで停止,PROへの移行を勧められる

ChatGPT-4oに移動
Q(koshix):
サイコロの雌雄の展開図を表示する以下のpythonプログラムで,日本語ラベルと展開図が少し重なっているので,展開図を少し右に動かしてください。
Q(koshix):
今度は,展開図の右側が画面からはみ出して欠けてしまいました。なんとかなりませんか。
Q(koshix):
雄サイコロの方は向かいあう目の数の和が7になっていないところがあります。
4の目と5の目を入れ替えてください。
Q(koshix):
いや、そうではなくて,1,2,3の配置は元のままでよかったのです。それらと6はそのままで,4の目と5の目だけを入れ替えてという意味です。
Q(koshix):
雄のサイコロの2の目と3の目も入れ替わりましたよ。そこは元のままなのです。
Q(koshix):
雄サイコロはまだ直っていませんよ
この辺で,人間のほうが力尽きてしまったので,自分で修正したのが以下のコードである。賢いような・・・そうでもないような・・・プログラミングにおいて人間に最も必要とされるのは忍耐強い対話力だ。いわゆるプログラミング的思考力や論理的思考力ではない。

from PIL import Image, ImageDraw, ImageFont
from IPython.display import display
from matplotlib import rcParams
import matplotlib.font_manager as fm

def create_dice_face(draw, x, y, size, number):
    # 正方形を描画
    draw.rectangle([x, y, x + size, y + size], outline="black", width=2, fill="white")
    
    dot_positions = {
        1: [(0.5, 0.5)],
        2: [(0.25, 0.75), (0.75, 0.25)],
        3: [(0.25, 0.75), (0.5, 0.5), (0.75, 0.25)],
        4: [(0.25, 0.25), (0.25, 0.75), (0.75, 0.25), (0.75, 0.75)],
        5: [(0.25, 0.25), (0.25, 0.75), (0.5, 0.5), (0.75, 0.25), (0.75, 0.75)],
        6: [(0.25, 0.25), (0.25, 0.5), (0.25, 0.75), (0.75, 0.25), (0.75, 0.5), (0.75, 0.75)]
    }    
    dot_size = int(size * 0.15) if number == 1 else int(size * 0.1)
    dot_color = "red" if number == 1 else "black"
    
    for px, py in dot_positions[number]:
        cx, cy = int(x + px * size), int(y + py * size)
        draw.ellipse([cx - dot_size//2, cy - dot_size//2, cx + dot_size//2, cy + dot_size//2], fill=dot_color)

def create_dice_net(draw, start_x, start_y, size, is_female):
    # 展開図の配置: 
    #     [4]
    # [2][1][5][6]
    #     [3]
    faces_female = [
        (4, size, 0),        # 上面
        (2, 0, size),        # 左面
        (1, size, size),     # 前面
        (5, size * 2, size), # 右面
        (6, size * 3, size), # 後面
        (3, size, size * 2)  # 下面
    ]    
    faces_male = [
        (5, size, 0),        # 上面(4と5を入れ替え)
        (3, 0, size), # 左面
        (1, size, size),     # 前面
        (4, size * 2, size), # 右面(4と5を入れ替え)
        (6, size * 3, size), # 後面
        (2, size, size * 2)  # 下面
    ]    
    faces = faces_female if is_female else faces_male
    
    for number, x, y in faces:
        create_dice_face(draw, start_x + x, start_y + y, size, number)

def create_both_dice_nets(size=100):
    # フォントの設定
    font_path = '/System/Library/Fonts/ヒラギノ丸ゴ ProN W4.ttc'  # 適切な日本語フォントファイルを指定してください
    font_prop = fm.FontProperties(fname=font_path)
    rcParams['font.family'] = font_prop.get_name()
    
    # PILで使用するフォントを設定
    pil_font = ImageFont.truetype(font_path, 20)

    # 展開図の全体サイズを設定
    img_width, img_height = size * 5, size * 7 # 高さを2倍+余白に
    img = Image.new('RGB', (img_width, img_height), color='white')
    draw = ImageDraw.Draw(img)
    
    # 雌サイコロの展開図を描画
    create_dice_net(draw, 50, 20, size, True)
    draw.text((10, 10), "雌サイコロ", fill="black", font=pil_font)
    
    # 雄サイコロの展開図を描画
    create_dice_net(draw, 50, 20 + size * 3 + 50, size, False)  # 50ピクセルの余白を追加
    draw.text((10, size * 3 + 60), "雄サイコロ", fill="black", font=pil_font)
    
    return img

# 画像を生成し、Jupyter Notebookに表示
both_dice_nets = create_both_dice_nets(size=100)
display(both_dice_nets)

# PNG画像として保存(オプション)
both_dice_nets.save("both_dice_nets.png")
print("both_dice_nets.png が生成されました。")


図:サイコロの雌雄(雌 1→2→3 反時計回り,雄 1→2→3 時計回り)

P. S. 上記の配置はサイコロキャラメルで確認した。実際には,2の目,3の目,6の目の配置がそれぞれ2パターンあるので,1つの性別に対して8パターンの配置がある。普通のサイコロは,1-2-3の頂点から見て,2や3の目が頂点から放射状に配列するのではなく,頂点のまわりを取り囲むように配列していることになる。

2024年7月9日火曜日

東京都知事選挙(5)

東京都知事選挙(4)からの続き

NHKが,出口調査で得た年代別の主要候補者支持率(それほど正確ではない)を出している。これを用いて,各年代区分のサイズを投票率×年代人口で正規化した人口比例面積表示のグラフを描いた。

生成AIを使ってプログラムを作ろうとしたが,(1) Pythonでは違うロジックの図がでてきたので,修正をあきらめた。(2) ChatGPTで,設定を簡単にした説明を入れ,Juliaプログラミングをすると,概ねできたが途中でつまづいた。(3) Claude 3.5 Sonnetで日本語の修正を含めて,最終版まで行き着いた。やはり,プログラミング経験なしでスイスイとはいかないのだ。

最初のChatGPTへの入力と,最終のJuliaコードを示す。
Q(koshix):
次のように正方形の領域を分割して色を塗るJuliaプログラムをつくってください。
 (1) 6個の世代人口データがあります。この値に比例して正方形を水平線で分割します。 つまり,上から,20代,30代,40代,50代,60代,70代の人口に比例した長方形 ができます。
 (2) 各長方形を,n人の候補者(A,B,C,...)の支持率をつかって垂線で分割します。 つまり,各年代ごとに,Aの支持率,Bの支持率,Cの支持率,その他の支持率と なります。これらの支持率の和は100%であり,それが正方形の横軸の長さになります。
 (3) 各年代のAの支持率のブロックは色#28A745,Bの支持率のブロックは色#F39C12, Cの支持率のブロックは色#3498DB,その他の支持率のブロックは色#CA8888 とします。
 (4) 各世代の人口数は,{48,68,100,133,132,117}とします。
 (5) 20代の支持率は,{0.27,0.44,0.11,0.18}とします。 
      30代の支持率は,{0.30,0.31,0.18,0.21}とします。 
      40代の支持率は,{0.36,0.32,0.15,0.16}とします。
      50代の支持率は,{0.42,0.25,0.16,0.16}とします。 
      60代の支持率は,{0.41,0.22,0.26,0.11}とします。 
      70代の支持率は,{0.51,0.11,0.31,0.08}とします。

A(Claude 3.5 Sonnet):
using CairoMakie

# データの準備
populations = [48, 68, 100, 133, 132, 117]
total_population = sum(populations)

support_rates = [
    [0.27, 0.44, 0.11, 0.18],  # 20代
    [0.30, 0.31, 0.18, 0.21],  # 30代
    [0.36, 0.32, 0.15, 0.17],  # 40代
    [0.42, 0.25, 0.16, 0.17],  # 50代
    [0.41, 0.22, 0.26, 0.11],  # 60代
    [0.51, 0.11, 0.31, 0.07]   # 70代
]

colors = ["#28A745", "#F39C12", "#3498DB", "#CA8888"]
age_labels = ["18-", "30-", "40-", "50-", "60-", "70-"]

# プロットの作成
fig = Figure(size=(800, 600))
ax = Axis(fig[1, 1], ylabel="人口割合", xlabel="支持率")

current_y = 0.0
for (i, pop) in enumerate(populations)
    segment_height = pop / total_population
    rates = support_rates[i]
    
    current_x = 0.0
    for (j, rate) in enumerate(rates)
        poly!(ax, [current_x, current_x+rate, current_x+rate, current_x], 
              [current_y, current_y, current_y+segment_height, current_y+segment_height], 
              color=colors[j])
        current_x += rate
    end
    
    # 年代ラベルを追加
    text!(ax, -0.05, current_y + segment_height/2, text=age_labels[i], 
          align=(:right, :center), fontsize=14)
    
    current_y += segment_height
end

# 軸の設定
ax.yticks = (collect(0:0.2:1), ["0%", "20%", "40%", "60%", "80%", "100%"])
ax.xticks = (collect(0:0.2:1), ["0%", "20%", "40%", "60%", "80%", "100%"])

# 凡例の追加
elements = [PolyElement(polycolor = c) for c in colors]
Legend(fig[1, 2], elements, ["小池百合子", "石丸伸二", "蓮舫", "その他"], 
       "候補者", tellheight=false, tellwidth=true)

# タイトルの追加
Label(fig[0, :], "年代別支持率", fontsize = 24)

# グラフの表示
display(fig)

図:東京都知事選年代別支持率(人口比例面積表示)

50代以上が6割,40代以下が4割なので,若年層の石丸効果はそれほど効かず,中年層が実数を担っている。蓮舫は60代以上でしっかりと受け止められているが,若年中年層にはまったく浸透していない。

P. S. NHKの年代別支持率のグラフをキャプチャーして,画像ファイルを生成AIに読み込ませて,各候補の支持率%の数値を読み取ろうとした。それらしい数字は出てくるのだけれど,残念ながら,正しい答えは得られなかった。仕方がないので,プリントアウトして,15cmのプラスチック物差しで測って,エクセルに入力して最終的なデータを導いた。

P. P. S. 奥村先生のところに関連するグラフなどがあった。

[1]2024年の東京都知事選挙(奥村晴彦)

2024年6月14日金曜日

合計特殊出生率(3)

合計特殊出生率(2)からの続き

物理学者の白石さんが,合計特殊出生率の件で強い主張をしていたので確認してみる。ようは,合計特殊出生率を決めているのは有配偶率であって,人口学的に確かめられている。それ以外の恣意的な原因を持ち出しているのはみんな出鱈目だ。ということだった。

仮にそうであっても,有配偶率自身を規定する原因は考えられるのだから,そこまで強く主張する必要はまったくないのに,と思う。まあいつものことだ。

都道府県別の合計特殊出生率と直近の国勢調査で得られた都道府県別の15-49歳女性の有配偶率を散布図にしてみる。1953年から2022年までの両者の関係も出せないかと調べるのだけれど,必要な情報はデータの海に埋もれてしまっていて,簡単には見つかりそうになかった。どの生成AIも簡単には探しだしてはくれない。

とりあえず,Juliaでコーディングしてみる。
using Gadfly
using Compose
using DataFrames
X = [46.6,47.4,49.4,47.7,49.9,51.2,50.0,50.4,50.9,49.9,49.3,49.0,44.2,49.0,50.4,52.0,50.4,52.3,49.5,51.7,51.4,51.6,51.9,51.4,52.2,44.4,43.5,48.8,47.0,48.5,49.2,51.9,48.9,50.7,49.9,49.3,51.1,49.6,46.1,46.2,48.5,48.6,48.5,49.5,49.4,49.2,45.8]
Y = [1.06,1.23,1.16,1.07,1.10,1.22,1.21,1.22,1.19,1.25,1.14,1.14,0.99,1.13,1.23,1.35,1.34,1.46,1.32,1.34,1.31,1.25,1.29,1.29,1.38,1.11,1.19,1.29,1.21,1.33,1.44,1.46,1.32,1.33,1.40,1.36,1.40,1.31,1.30,1.26,1.46,1.49,1.47,1.39,1.49,1.48,1.60]
Labels = ["北海道","青森","岩手","宮城","秋田","山形","福島","茨城","栃木","群馬","埼玉","千葉","東京","神奈川","新潟","富山","石川","福井","山梨","長野","岐阜","静岡","愛知","三重","滋賀","京都","大阪","兵庫","奈良","和歌山","鳥取","島根","岡山","広島","山口","徳島","香川","愛媛","高知","福岡","佐賀","長崎","熊本","大分","宮崎","鹿児島","沖縄"]

plot(x=X, y=Y, label=Labels, Geom.point, Geom.label, Theme(major_label_font="CMU Serif",minor_label_font="CMU Serif",major_label_font_size=12pt,minor_label_font_size=12pt), Guide.xlabel("女性有配偶率"),Guide.ylabel("合計特殊出生率"))

沖縄は特異点になっているが,合計特殊出生率とこれに対応する年代の女性の有配偶率には正の相関がみられる。

図:女性の有配偶率と合計特殊出生率の関係

P. S.  x軸とy軸の日本語ラベルのつけ方は,ChatGPT-4oに教えてもらった。

2024年6月7日金曜日

合計特殊出生率(2)

合計特殊出生率(1)からの続き

去年の今ごろ,奥村晴彦さんの合計特殊出生率Rプログラムを写経していた。すっかり忘れていたけれど,2023年の新しい合計特殊出生率が過去最低の1.20人を記録したいうニュースで思い出すことになった。

都道府県別でみれば,東京都の0.99や北海道の1.06をはじめ,大都市部や東北地方で低く,沖縄の1.60を筆頭に,九州,山陰,北陸などで高い。

今年は,コマンドラインで実行すべく,Rプログラムを修正した。あいかわらず日本語表示でつまづいたので,ChatGPT-4oに聞きながら試行錯誤した結果,何とか解決できた。なお,スタートを自分が生まれた1953年にしてみた。

修正したRプログラムのtfr.rの内容(注:remove \ before copy and paste)は

library(showtext)

font_add("Hiragino", "/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc")

showtext_auto()


X <- read.table('/Users/koshi/Desktop/birth.txt', header = TRUE)

par(family = "Hiragino")  # 利用可能なフォントを指定

plot(X\$年, X\$合計特殊出生率, type="o", pch=16, xlab="", ylab="")

t = c(range(X\$合計特殊出生率), X\$合計特殊出生率[length(X[,1])])

axis(4, t, t)

title("合計特殊出生率", line=0.5)

#title("Total Fertility Rate", line=0.5)


# x軸とy軸のメモリの位置を手動で指定

x_ticks <- pretty(X$年, 15)  # 15個のメモリを生成

y_ticks <- pretty(X$合計特殊出生率, 16)  # 16個のメモリを生成


# x軸に対してグリッド線を描画

for (i in x_ticks) {

  abline(v = i, col = "lightgray", lty = "dotted")

}


# y軸に対してグリッド線を描画

for (i in y_ticks) {

  abline(h = i, col = "lightgray", lty = "dotted")

}

これで,Rscript tfr.r とすると,pdfの出力,Rplots.pdf が得られる。なお,showtextというライブラリは,コマンドラインで R として立ち上げたプロンプトに,install.packages("extrafont") としてインストールしておく。また,データは birth.txt にあらかじめ入れてある。

年    出生数 合計特殊出生率

1953 1868040           2.70

1954 1769580           2.48

1955 1730692           2.37

1956 1665278           2.22

1957 1566713           2.04

1958 1653469           2.11

1959 1626088           2.04

1960 1606041           2.00

1961 1589372           1.96

1962 1618616           1.98

1963 1659521           2.01

1964 1716761           2.05

1965 1823697           2.14

1966 1360974           1.58

1967 1935647           2.23

1968 1871839           2.13

1969 1889815           2.13

1970 1934239           2.13

1971 2000973           2.16

1972 2038682           2.14

1973 2091983           2.14

1974 2029989           2.05

1975 1901440           1.91

1976 1832617           1.85

1977 1755100           1.80

1978 1708643           1.79

1979 1642580           1.77

1980 1576889           1.75

1981 1529455           1.74

1982 1515392           1.77

1983 1508687           1.80

1984 1489780           1.81

1985 1431577           1.76

1986 1382946           1.72

1987 1346658           1.69

1988 1314006           1.66

1989 1246802           1.57

1990 1221585           1.54

1991 1223245           1.53

1992 1208989           1.50

1993 1188282           1.46

1994 1238328           1.50

1995 1187064           1.42

1996 1206555           1.43

1997 1191665           1.39

1998 1203147           1.38

1999 1177669           1.34

2000 1190547           1.36

2001 1170662           1.33

2002 1153855           1.32

2003 1123610           1.29

2004 1110721           1.29

2005 1062530           1.26

2006 1092674           1.32

2007 1089818           1.34

2008 1091156           1.37

2009 1070036           1.37

2010 1071305           1.39

2011 1050807           1.39

2012 1037232           1.41

2013 1029817           1.43

2014 1003609           1.42

2015 1005721           1.45

2016  977242           1.44

2017  946146           1.43

2018  918400           1.42

2019  865239           1.36

2020  840835           1.33

2021  811622           1.30

2022  770759           1.26

2023  727277           1.20

図:1953-2023  の合計特殊出生率の推移