Windows11の新規インストールでのトラブル( install driver to show hard wear)の解決法
概要
新しいマシンにwin11を新規インストールした時に遭遇したエラーとその対処を以下に書きます
簡単に解法だけ先に書くと,win11を新規に入れようとして
install driver to show hard wear
という画面になって先に進まなくなったら, そのマザボに対応するLANドライバをwin11のインストールメディア(USB)に保存して,そのドライバを読み込めばよい.
たとえばASUSのPRIME H610M-A D4の場合(私のケース),ここ から Realtek LAN driver v1168.22.1118.2024 for Windows 11 64-bit. をDLしてwin11のインストールメディア(USB)に保存して,そのドライバを読み込むと解決する.
何が起こっているのか
win11のインストール時にmicrosoftと通信してプロダクトキーの確認を取る必要があるが,その通信のために必要なドライバがインストールメディアに入ってないらしい(推測).
マシンの構成
はじめに最低限のハードを繋げ,UEFIをチェックする.電源は入るものの画面が映らないので,おかしいなと思ったら内臓GPUがないCPUだった. マザボの一枚や二枚は部屋に転がっているので,適当なものを差すことで解決.
- GPU: GTX1060
win11のインストール
Amazonで購入したwin11インストールメディアをUSBに指し,マザボの電源を入れる.すると
install driver to show hard wear
という画面が出て,なにやらドライバのインストールを求められる. ここでしばらく悩んだ.
そもそもなんのドライバを入れればいいのか分からない. win11のインストールメディアの中に入っているのだろうか?と思い,あれこれ模索するも解決せず.
ASUSのQ&A
ひとまずメインマシンで検索したところ次の記事に到達する.
ここからさらにASUSのサポート記事に到達する.
https://www.asus.com/jp/support/faq/1047371/

たしかに該当する.というか,結構該当マザボが多いので,同じ問題で苦労している人がたくさんいるんじゃなかろうか? (このblogを書いた動機である)
とりあえずIntel® Ethernet Connection I219 用ドライバーとやらを探す.これがどこにあるのか分からず,やや苦労した.
結局ASUSのサポ-ト→ドライバDL→H610用ドライバと辿り,
にあることを発見する.
ドライバのインスト-ル
記事を読むとドライバをUSBメディアに記録せよとあるので,win11のインストールメディアでよかろうと,適当なフォルダに解凍したファイルをごそっとコピーする.
install driver to show hard wear
のエラーが出るところまで戻り,コピーしたフォルダを指摘する. これでようやく先に進んだ.
まあいつものことだが,もう一台ネットにつながるマシンを持っていない人は,どうやってこのトラブルを回避すりゃええの?
詰むがな.
install driver to show hard wear で検索すると次の動画にヒットした.
やっぱり相当数の人が困っているのではなかろうか.
パーティションエラー
しばらく順調に進んでいたが,win11をインストールするパ-ティションを選べという画面で,PCIe NVMe M.2で接続したSSDを指定すると,エラーが出る.
そもそも他にはドライブがないので,ここでまた困る.更新やら再フォーマットやらを試しても先に進まない.
ここで再びネットを検索すると,パ-ティションを削除したら治る,という情報にたどり着く.
まあそもそも空のSSDなんで,よかろうと思い,パ-ティションを削除したところ,うまくいった.
既存のマシンとの同期
最後にwin11を設定するところで,現在使用中のマシンのバックアップから復元が利用できるという. 試しにやってみると,winのアプリ周りの設定を引き継げるようだ.新マシンの環境設定が楽になった.
おまけ
マシンの設置はケースに入れる前に,電源スイッチだけをMBに取り付けると,便利である (高級なマザボは電源スイッチが基板上についている).つまり
マザボむき出し状態でwinインストール→PCケースに設置
が効率的である.
特に裏配線のオサレケースでは,ケースに設置した後に不具合が出たら,パーツを外すのが面倒なので,動作確認して 「あとは箱に収めるだけ」の状態を先に作ってからケースに収めるとよい.これを電源スイッチのないマザボでやるためには, フロントパネルコネクタに挿す電源ボタンが必須である*1.
ベイズファクタ計算用サンプルコード
必要なパッケージのロード
library(rstan) library(bridgesampling)
パッケージがなければ,
install.packages("bridgesampling")
でインストールします.
stanでのコンパイルの効率化のために,以下を指定します(いつものやつ).
rstan_options(auto_write=TRUE)#コンパイルを保存する設定 options(mc.cores=parallel::detectCores())#マルチコア計算用設定
データの生成
平均0分散1の正規分布にしたがう乱数を1000個生成し、stanコードでパラメタリカバリします. データの生成
set.seed(123) y <- rnorm(1000, mean = 0, sd = 1)
Stanコード
stanでモデルを定義します.コードは,BF比較用に事前分布も含めて全てtarget記法で書きます. stanファイルを使わずに,すべてR内で完結するように,Rコード上でstanモデルを定義します.
# Stan code for parameter recovery m0 <- " data { int<lower=0> N; vector[N] y; } parameters { real mu; real<lower=0> sigma; } model { target += normal_lpdf(mu | 0, 1); // prior for mu target += normal_lpdf(sigma | 0, 1); // prior for sigma target += normal_lpdf(y | mu, sigma); // likelihood } " # 平均位置がズレている m1 <- " data { int<lower=0> N; vector[N] y; } parameters { real<lower=0> sigma; } model { target += normal_lpdf(sigma | 0, 1); // prior for sigma target += normal_lpdf(y | 0.5, sigma); // likelihood } " # m0に比べて事前分布のサポートが広い場合 m2 <- " data { int<lower=0> N; vector[N] y; } parameters { real mu; real<lower=0> sigma; } model { target += normal_lpdf(mu | 0, 10); // prior for mu target += normal_lpdf(sigma | 0, 10); // prior for sigma target += normal_lpdf(y | mu, sigma); // likelihood } "
Prepare data for Stan
stan用にデータを定義します.
data <- list(N = length(y), y =y)
Compile the Stan model
stanモデルをコンパイルします
model0 <- stan_model(model_code = m0) model1 <- stan_model(model_code = m1) model2 <- stan_model(model_code = m2)
Fit the model
サンプリング結果を格納します.
fit0 <- sampling(model0, data = data, iter = 5000, chains = 3) fit1 <- sampling(model1, data = data, iter = 5000, chains = 3) fit2 <- sampling(model2, data = data, iter = 5000, chains = 3)
Bridge sampling
ブリッジサンプリングします
bs0 <- bridge_sampler(fit0) bs1 <- bridge_sampler(fit1) bs2 <- bridge_sampler(fit2)
自由エネルギー
ブリッジサンプリングした結果を使って自由エネルギを計算します
-logml(bs0) -logml(bs1) -logml(bs2)
Compare free energies
ベイズファクタを計算します.直感的に言うと,bf(bs0, bs1)はbs1(後ろ)に対してbs0(前)が,相対的にどれくらいよいのかを表します.
慣習的な目安として10より大きければ,強い支持を与えると考えられている.
bf(bs0, bs1) bf(bs0, bs2)
otreeトリートメントのアップロード作業メモ
作業メモ
必要なこと
- Heroku アカウント登録(アプリをアップするためのサーバ)
- Git CMDのインストール(Git を動かすためのシェル)
- Heroku CLIのインストール(Heroku関連コマンドをGit CMDで使うためのツール)
- otree hubのアカウント登録(必須ではない.Gitを経由せずにデプロイできる)
Herokuはアプリをクラウドで公開・実行するためのwebサービスである.部分的に無料で使えるが, 多人数がアクセスして利用する場合は料金プランの変更が必要となる*1. Heroku CLIはGit CMD 経由で Heroku にアプリをアップロード(デプロイ)するツールである.これ自体は基本は裏で動くので,インストール後は意識しなくて良い. Gitを経由せずにotree hubからデプロイできるようだが,かなり面倒くさい.Git CMD でコマンド入力するほうが手軽だろう.
手順
ブラウザでHerokuにログインして,web上でアプリ(のためのディレクトリ)を新規作成する.これがotreeトリートメントをアップロードするweb上のディレクトリになる. otree hubに登録して連携ができていれば,otree hubからもアプリ名を確認できる*2.
次にGit CMDからHerokuにログインする.ログインしたら,ローカルのotreeディレクトリ(つまり自分のPC内でotree関連のファイルを保存しているフォルダ)
を指定して,remoteする*3.
その後add, comit, pushと言う順番にgitコマンドを入力する.
push成功後にheroku openすると,webでアクセス可能なotreeトリートメントが公開される.
このとき発行されるURLはHerokuに登録した自分のアプリに固有のもので,トリートメントを更新してアップし直しても基本的には変わらない.
push成功するとアプリのヴァージョンも自動で更新されるので,アプリ開発気分を味わえる.
コマンドは概ね次のような順番だ
heroku login cd C:\Users\local\hoge(自分がローカルPC上に作ったotree関連のファイルがある場所に移動) heroku git:remote -a appname (appnameがHerokuに登録した自分のアプリ名) git add . git commit -am "make it better" git push heroku master(ここでビルドしてアップする.エラーが出るとしたここが多い.) heroku open heroku run "otree resetdb"
リモートのgitのリポジトリは,herokuのサーバ上(新規作成したアプリのディレクトリ)にできているらしい *4.
エラー対応
deploy時にやたらとアプリケーションエラーが頻出した.
などが主にエラーの要因だったようだ.ローカルホストで作動してもweb上にdeployするには設定が異なるようで,一つずつエラーを潰していく感じで対応するほかない.
といっても吐き出したエラーログをChat gptにコピペして「対応して」と頼むだけで,大抵は解決する.
たとえば
echo "/* dummy */" > _static/dummy.css git add _static/dummy.css git commit -m "Add dummy file to _static" git push heroku master
こんな感じで,staticフォルダにダミーファイルを入れたらアプリのエラーが解消された.
roomの設定
otreeをサーバにあげると,roomが設定できるようになる.sessionとの違いがよく分からなかったが,roomには複数のセッションを管理する機能があり,sessionの上位カテゴリといった概念だ.roomにはRoom-wide URLを発行する機能があり,これが便利である.
Room-wide URLはCookieによって新たなセッションを生成するので,一つのリンクで多人数を参加させることができる(一人ずつ使い切りのリンクを送ることもできるが,クラウドソーシングだと手間がかかる)
雑感
そもそもトリートメント自体もclaudeのbashコマンドで作らせたし,deploy時のデバッグもgpt任せなので,コードの細かい部分は理解せぬまま,環境だけが整った感じだ. まあ,研究目的からすれば,このあたりはどうでもいいのかもしれない. 人間は実験のアイデアだけを考え,実装環境の構築はいずれ全てAIまかせになるのだろう. というより多くの仕事が 「人間は抽象的な構造だけを理解して,細かい実装部分はAIに任せる」というスタイルに変わっていくのだろう. まあ,そういう意味では,これまでやってきたことと大きく違うわけではない.
Claudeでotreeトリートメントの作成
やること
Claudeを使って,全自動でotreeトリートメントつくってもらう.
例によって,忘れるので自分用のメモです.
準備
MacでJSをインストールしてからターミナルでclaudeをインストールする
こちらの記事を参照しました なおサファリでQiitaが読めないという謎の不具合が発生したので 今後Mac上ではブラウザはchromeを使うことにしました.
作成
ターミナルで作業用のディレクトリを作り,そこに移動する.
mkdir hoge cd hoge
hogeに移動したらそこにclaudeを召喚する.最初はいろいろと権限の許可を求められるので, 問題ない範囲で許可する.
はじめに実験の設定をプロンプトとして与え,あとは放置する.
時々「これやっていい?」と聞いてくるので,問題がなければ許可する.
デバッグ
準備できた,というのでローカルホストにアクセスすると思いっきりエラーを吐く.
ただし,ここからがclaudeの良いところである. ブラウザ上で吐かれたotreeのエラーをそのままターミナルにコピペして「直して」と お願いすると,黙々と試行錯誤を繰り返す.
ここが自動なのは大変ありがたい.
完成
大体30分くらいで,ちゃんとローカルサーバで動くdemoが完成した.
最後にMacからWinで使うためにdropboxに移動する. 最初からローカルのdropboxフォルダ内にclaudeを召喚すれば良かった. (macにdropboxが入ってなかった)
ただ,claudeが勝手にファイルを修正したり消したりしまくるので,使い方を 把握するまでは特定のディレクトリ内だけで作業させるのがよいのかもしれない.
出来上がったコードを見て「ここで格納した変数は?」みたいに聞くと ある程度仕組みも理解できる.特にotreeはユーザーからの入力と,受け取った入力を使った計算の 出力の同期がややこしいので,AIに教えてもらうと,助かる.
来たなあシンギュラリティ,という感じで楽しかった.
局所マルコフ性と忠実性
よく分からない注
パール『入門統計的因果推論』でDAG上のノードの従属性について説明している箇所に,「$Y$が$X$の影響を受けるのに,$X$と$Y$が独立になる」という意味の注があって,しばらく意味が分からないまま放置していた.
別の文献で忠実性についての説明を読んでいるうちに,これは
DAG上では依存関係があるように見えるし,構造的因果モデルもそのように定義しているけれど,$X$と$Y$が独立になるという,やや特殊な関数例が存在すること
について言及しているのだと思うに至った. 例のごとく,何かに記録しても,どこに書いたかすぐ忘れるのでここにmemoを残しておきます.
内容
注の内容は以下の通りである
$X, U_Y$が正常なコインで,$X=U_Y$が$Y=1$と同値であるとき,$P(Y=1 \mid X=1)=P(Y=1)$等が成立し,$X$と$Y$が独立になる場合がある. でも特殊なケースなのでそれほど気にしなく良い
とまあ,こんな感じである. これだけだと訳が分からないので,著者が言いたいであろうことを補足してみる
予想
$X, U_Y$が正常なコインで
の部分は,まあ $$ X \sim Bern(0.5), U_Y \sim Bern(0.5) $$ くらいの意味であろう.
構造的因果モデルは $$X=U_X $$ $$Y=f_y(X, U_Y) $$ でDAGは
$$X \to Y$$
と仮定する.外生変数同士は独立なので$X \perp U_Y$である. さて$Y$の定義であるが,「$X=U_Y$が$Y=1$」と同値とあるので,これを
もし$(X=1,U_Y=1)$か$(X=0,U_Y=0)$なら,そのとき$Y=1$
もし$(X=1 U_Y=0)$か$(X=0,U_Y=1)$なら,そのとき$Y=0$
と解釈する.つまりこれが構造的因果モデルのモジュール$f_y$の陽表的表現である. このXOR型関数は,この種の例としては定番なのかもしれない. 別の本で見たような気がしないでもない.
ともあれ,条件付き確率は $$p(Y=1 \mid X=1)=p(Y=1, X=1)/P(X=1)=0.25/0.5=0.5=p(Y=1)$$ $$p(Y=0 \mid X=1)=p(Y=0, X=1)/P(X=1)=0.25/0.5=0.5=p(Y=0)$$ $$p(Y=1 \mid X=0)=p(Y=1, X=0)/P(X=0)=0.25/0.5=0.5=p(Y=1)$$ $$p(Y=0 \mid X=0)=p(Y=0, X=0)/P(X=0)=0.25/0.5=0.5=p(Y=0)$$
となるから,独立性の定義を満たし,$X \perp Y$である. 構造的因果モデルの定義より,「YはXの影響を受けるがXとYは独立」が確かに成立する
局所マルコフ性と分解定理との関係
上記の例は「同時確率分布がグラフに忠実でないこと」の一例となっている. このような特殊な分布の存在が局所マルコフ性と分解定理に悪さをするのではと気になったが,問題はないようだ.
そもそも局所マルコフ性は親で条件付けた場合の非子孫との独立性を保障するものであり,忠実性とは関係なく成立する. そして分解定理の成立に必要な重要な仮定は,外生変数同士の独立性であり, 忠実性と「トポロジカル順序→チェーンルール→親による縮約→分解定理」の証明の流れとは関係が無い.
結局,分解定理が成り立たないDAGを不完全だと見なせば,分解定理をDAGの性質として定義する方針でもいけるのでは, と考え始めている(そもそもベイジアンネットワークは使いたくないので,構造的因果モデル+DAGから分解定理を導くのが一番自分の嗜好にあっている).
pdfファイルから特定位置のテキストを抽出する
やりたいこと
pdfファイルから複数ページにわたって特定位置にあるテキストを抽出したい
pdfファイルからのデータ抽出
方法
PythonのPyMuPDFパッケージを使う.
手順
PyMuPDFをpipでインストールする.- 指定pdf内の指定矩形領域からテキストを抽出する関数を定義する.
- 上記関数を使い,抽出結果をtxtに保存する
なお忘れていたがPythonのディレクトリの確認・設定方法は以下の通り
# Display the current directory import os os.getcwd() os.chdir('C:\\Users\\hoge\\hoge\\hogehoge\\hogee')
hogeの部分を読者の適当なディレクトリに変換して読んでください.
コード
コードはGitHub-Copilotに教えてもらった.
もはやPythonなどCopilotの助けを借りずには書けぬ.
import fitz # PyMuPDF def extract_text_from_multiple_pages(pdf_path, page_numbers, rect): """ Extract text from a specific rectangular area on multiple pages of a PDF. :param pdf_path: Path to the PDF file. :param page_numbers: List of page numbers to extract text from (0-indexed). :param rect: A tuple (x0, y0, x1, y1) defining the rectangular area. :return: Dictionary with page numbers as keys and extracted text as values. """ # Open the PDF file document = fitz.open(pdf_path) extracted_texts = {} for page_number in page_numbers: # Select the page page = document.load_page(page_number) # Define the rectangular area rectangle = fitz.Rect(rect) # Extract text from the defined area text = page.get_text("text", clip=rectangle) # Store the extracted text in the dictionary extracted_texts[page_number] = text return extracted_texts
PyMuPDFをインポートする際には,なぜかfitzという名前を使う.よく分からないが昔の名前(?)のようだ.
次に関数を定義する.引数はpdf_path, page_numbers, rectの三つである.
pdf_pathはpdfファイルの場所で,.pyファイルと同じ階層にある設定で話を進める.
page_numbers,はpdf内の,必要情報を記載しているページ数である.
rectはそのページ内の目的のテキストの位置である.
抽出元のpdfファイルのイメージはこんな感じとする.

関数を使って抽出すると,本文に含まれる余計な. . . .記号が残るので,次の関数で削除する.
またしても Copilot ありがとう.ただし最後に書いたように,数字位置だけを狙えば,このような調整は必要ない.
def clean_extracted_texts(extracted_texts): """ Clean the extracted texts by removing specific characters. :param extracted_texts: Dictionary with page numbers as keys and extracted text as values. :return: Cleaned dictionary with page numbers as keys and cleaned text as values. """ cleaned_texts = {} for page_number, text in extracted_texts.items(): cleaned_text = text.replace(". ", "") cleaned_texts[page_number] = cleaned_text return cleaned_texts
実行例
必要な引数(pdf_path, page_numbers, rectの三つ)を指定して実行してみる
# Example usage page_numbers = range(77,80) # 77page albania-211 ZIMBABWE pdf_path = "gtci-2023-report.pdf" rect = (10, 70, 600, 180) # Define the rectangular area (x0, y0, x1, y1) extracted_texts = extract_text_from_multiple_pages(pdf_path, page_numbers, rect) cleaned_texts = clean_extracted_texts(extracted_texts)
結果の確認
# check text for page_num, text in cleaned_texts.items(): print(f"Cleaned Page {page_num + 1}:\n{text}\n")

大体上手くいったようだ.矩形の座標は何回か試して目分量で調整した.
rect = (10, 70, 600, 180)
は左上の座標が((10, 70,)で右下の座標が(600, 180)らしい.
テキストファイルに書き出してみる.
# Save the cleaned texts to a txt file with open("cleaned_texts.txt", "w", encoding="utf-8") as file: for page_num, text in cleaned_texts.items(): file.write(f"Cleaned Page {page_num + 1}:\n{text}\n\n")

あとはこの情報をdataframeに変換すればOK
コードの作成に30分ほどかかりましたが,手作業でやるよりは時間を短縮できました.
おまけ
データフレームへと変換する際,リポートの刊行年によってrectで指定する範囲が変化するので,次のようにデータごとにファイルに書き込む方法を採用した.
# gdp ppp page_numbers = range(91,195) # 91:albania-194:vietnam rect = (150, 220, 330, 225) # Define the rectangular area (x0, y0, x1, y1) extracted_texts = extract_text_from_multiple_pages(pdf_path, page_numbers, rect) # check text len(extracted_texts) for page_num, text in extracted_texts.items(): print(f"\n{text}") # Save the cleaned texts to a txt file with open("gdp2013.txt", "w", encoding="utf-8") as file: for page_num, text in extracted_texts.items(): file.write(f"{text}") # p.134 ireland だけ空白行が少ないため,recを調整する # gtci page_numbers = range(91,195) # 91:albania-195:vietnam rect = (168, 250, 330, 260) # Define the rectangular area (x0, y0, x1, y1) extracted_texts = extract_text_from_multiple_pages(pdf_path, page_numbers, rect) # check text for page_num, text in extracted_texts.items(): print(f"\n{text}") # Save the cleaned texts to a txt file with open("gtci2013_0.txt", "w", encoding="utf-8") as file: for page_num, text in extracted_texts.items(): file.write(f"{text}")
データ位置の座標を確認するには,読み込む頁全体の縦横を次のコードで取得すると大体の位置が特定できる.
# 長さと幅を取得 pdf_path = "GTCI-2013-report.pdf" doc = fitz.open(pdf_path) page_num = 77 page = doc.load_page(page_num) page.rect.width page.rect.height
雑感
- webの解説ページを読むよりcopilotに聞いた方が早かった.
- 2013年,2023年のデータを使って10年間のパラメータの変化を確認してみた.まあまあおもしろい結果だったので,近いうちに学会等で報告する
分析結果の視覚化
はじめに
たとえば次のような分析結果の図を作りたいと考えたとしよう.

このとき「実際の計算」と,「図の作成」は別々にコード化すると効率が良い.
ひな形の作成
上記の図のイメージができたら,「その結果を生成するようなダミーのdata.frame」を準備する.
この場合,実際のデータが
post.p <- data.frame(mean=post[1:122,1],sd=post[1:122,3], age=c(c(20:80),c(20:80)),sex=c(rep("female",61),rep("male",61)), age.group=c(rep("20-39",20),rep("40-59",20),rep("60-80",21)))
であれば,ダミーのdata.frameは
post.p <- data.frame(mean=c(4,5,6),sd=mean-3, age=c(20,30,40),sex=c("female","male"))
くらい簡単なもので良い.
data.frameを受け取った後のplotは
g <- ggplot(post.p,aes(x=age,y=mean,linetype=sex))+ geom_line(position=position_dodge(0.2))+ geom_point(position=position_dodge(0.2),size=2)+ ylim(0,1)+ geom_errorbar(aes(ymin=mean-sd,ymax=mean+sd),width=.2,position=position_dodge(0.3))+ facet_wrap(~ age.group, scales="free_x",ncol = 1) g ggsave(file = "figure.pdf", plot = g, dpi = 300, width = 8, height = 12)
といった形である.このとき,計算は実際に実行する必要はない.シンプルな結果のダミーdata.frameさえあれば,図のお化粧は別に作業できるからである.
コードの抽象化
要するにこれはコードの抽象化であり,モデルである.
コードを書くのが面倒だなと思ったら,面倒な計算の部分と,それ以外の部分の構造を抽象化して切り分けると混乱しない.
コードを書くとき,ついつい癖で具体的で一般性のない手続きを書いてしまう場合があるが,結局はコードも抽象化によって可読性と再現性が高くなる.