中野智文のブログ

データ・マエショリストのメモ

拡大推計とはHorvitz–Thompson推定量のこと

たまに拡大推計とは何って聞かれる。正しい定義は、Horvitz–Thompson推定量

ja.wikipedia.org

層化抽出法があるが、データが層化抽出されたものとして、その逆確率重みを計算し、その逆確率重みによりサンプルデータが拡大されたと考えれば、拡大推計とは、Horvitz–Thompson推定量のこととなる。

M1 mac で sdカードの消えた写真を無料で復活させるまでの長い道のり

背景

  • 運動会で撮った (micro) sdカードが読み取れない!
  • 無料(Free)と書いてある全てのソフトが有料だった!
  • TestDiskというコマンドラインだけど無料のソフトが見つかった!
  • M1 Macに対応していない(涙 イマココ

方法

準備

git clone https://git.cgsecurity.org/testdisk.git

Install を読むと、Xcodeが必要と書いてあった。 開発マシンという名目のマシンに今更Xcodeをインストール(ダウンロードに結構時間がかかる)

$ autoreconf --install -W all -I config
zsh: command not found: autoreconf

aotoreconf 入っていないエラー。そんなコマンド名20年ぶりに聞いたよ。

$ brew install autoconf automake

build

(本当は作業用のディレクトリで作業するのかもしれんが)

$ autoreconf --install -W all -I config
$ ./config
$ make
$ sudo make install

色々警告が出ていたかもしれない(数百行以上)が、 インストール完了。

こうなっていたら無事インストールされている。

$ ls /usr/local/bin
fidentify   photorec    testdisk

本当必要なのは、photorec コマンド

適当な保存ディレクトリを作成しておく。

次のコマンドで対象となるデバイスパーティション)を(サイズなどをヒントに)選び、抽出開始。

sudo photorec

結構時間がかかる(1時間くらい?)

まとめ

一月1万近いサブスクリプション費用を払わずに済んだ。Freeといっているのに、Freeじゃないから、サブスクリプション費用を払っても、Pro買えみたいな詐欺の可能性もあるので、1万円よりもっと高かったかもしれない。(まとめじゃない)

wordle をruby のワンライナーでズルする

背景

wordle をエンジニアっぽく rubyワンライナーでズルしたい

戦略

  • /usr/share/dict/words を使う
  • ヒントから可能性のある単語のリストを抽出する。ヒントがない場合は5文字の全単語。
  • もし単語が一語であればそれが解で終了。
  • そうでない場合、その可能性のある単語のリストから頻度の高いアルファベットを抽出し、
  • それらのアルファベットを含む語彙を全体の単語のリスト(可能性のある単語のリストではない)から見つけ出して使う。
  • これを繰り返す。

方法

5文字単語のリスト

$ ruby -ne 'puts $_ if $_=~/^[a-z]{5}$/' < /usr/share/dict/words

本当は複数形を除きたいし、コーパスなどから出現頻度を求めたいが、今後の課題ということで。

どのアルファベットが最も多く出現するか

$ ruby -ne 'puts $_ if $_=~/^[a-z]{5}$/' < /usr/share/dict/words | ruby -ne 'BEGIN{$w=Hash.new(0)}; $_.chomp.chars.each{|x|$w[x]+=1}; END{puts $w.sort_by{|_,v|-v}.to_h;}'
{"a"=>4467, "e"=>4255, "r"=>3043, "o"=>2801, "i"=>2581, "s"=>2383, "t"=>2381, "l"=>2368, "n"=>2214, "u"=>1881, "y"=>1605, "c"=>1546, "d"=>1399, "h"=>1323, "m"=>1301, "p"=>1293, "b"=>1162, "g"=>1102, "k"=>882, "w"=>685, "f"=>661, "v"=>466, "z"=>250, "x"=>189, "j"=>163, "q"=>84}

特定のアルファベットが含まれる単語

下記の場合、["a", "e", "r", "o", "s"]の5つのアルファベットが含まれる単語を抽出。

$ ruby -ne 'puts $_ if $_=~/^[a-z]{5}$/' < /usr/share/dict/words | ruby -ne 'puts $_ if "aeros".chars.all?{|x| $_.chomp.chars.include?(x)}'
arose

特定の位置に特定のアルファベットがあり、かつ、特定のアルファベットが含まれない単語を抽出

下記は、a_o__ である単語で、"r", "s", "e" が含まれない語彙のリスト。

$ ruby -ne 'puts $_ if $_=~/^a[a-z]o[a-z]{2}$/' < /usr/share/dict/words | ruby -ne 'puts $_ if "rse".chars.all?{|x| not $_.chomp.chars.include?(x)}'
abody
...
...
azoxy

その、アルファベットの頻度

$ ruby -ne 'puts $_ if $_=~/^a[a-z]o[a-z]{2}$/' < /usr/share/dict/words | ruby -ne 'puts $_ if "rse".chars.all?{|x| not $_.chomp.chars.include?(x)}'|ruby -ne 'BEGIN{$w=Hash.new(0)}; $_.chomp.chars.each{|x|$w[x]+=1}; END{puts $w.sort_by{|_,v|-v}.to_h;}'
{"o"=>52, "a"=>51, "l"=>16, "n"=>14, "y"=>13, "d"=>11, "t"=>11, "i"=>9, "m"=>8, "c"=>7, "b"=>6, "f"=>6, "g"=>6, "z"=>5, "h"=>5, "p"=>5, "u"=>4, "x"=>3, "w"=>1, "k"=>1, "v"=>1}

"o", "a" は既出なので、"l", "n", "y", "d", "t" が含まれる単語を抽出したい。

特定の位置に特定のアルファベットがあり、かつ、特定のアルファベットが含まれず、かつ、どこかに特定のアルファベットが含まれる単語

下記は、a_o__ である単語で、"r", "s", "e", "i", "n", "y" が含まれず、どこかに"l", "t"が含まれる単語

$ ruby -ne 'puts $_ if $_=~/^a[a-z]o[a-z]{2}$/' < /usr/share/dict/words | ruby -ne 'puts $_ if "rseiny".chars.all?{|x| not $_.chomp.chars.include?(x)}' | ruby -ne 'puts $_ if "lt".chars.all?{|x| $_.chomp.chars.include?(x)}'
a?o??
a?o??

敢えて隠しました。どっちかは運と思います。 自分は運に負けました。

まとめ

どっちも知らない単語。

追記

修正版

最近ではこんな感じ。(情報量導入)

$ ruby -ne 'puts $_ if ($_=~/^[^a][^r][^o]..$/ and "se".chars.all?{|x| not $_.chomp.chars.include?(x)} and "aro".chars.all?{|x| $_.chomp.chars.include?(x)})' < wordles.txt | ruby -ne 'BEGIN{$w=Hash.new(0);$t=0}; $_.chomp.chars.uniq.each{|x|$w[x]+=1.0};$t+=1; END{puts $w.map{|k,v|[k,v/$t]}.map{|k,p| [k, -p*Math.log(p) + (p==1.0 ? 0 : -(1-p)*Math.log(1-p))]}.sort_by{|_,v|-v}.to_h}'

4文字の組み合わせを含む単語を見つける。

ruby -ne '"pvbwcdy".chars.combination(4).to_a.each{|y| puts $_ if ($_=~/^.....$/ and y.all?{|x| $_.chomp.chars.include?(x)})}' < wordles.txt

wordle の語彙は次でダウンロード

curl https://slc.is/data/wordles.txt

linux で文字化けしたときにやることメモ

背景

毎度Linuxを始めに使うとき文字化けしてググっているのでメモ。日本語を使わないという選択肢もあるけど、データの中身が日本語だったりすると、結局やらなくちゃいけないことになる。

方法

locale コマンドで確認

$ locale -a

すると、こんな感じで日本語入っていない。(WSL2の場合)

locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
C
C.UTF-8
POSIX
en_US.utf8

locale.gen を編集

$ sudo vi /etc/locale.gen

で、

ja_JP.UTF-8 UTF-8

のコメントを外す。

locale-gen の実行

$ sudo locale-gen

これで有効化されるはず、念の為、locale -a などで確認

まとめ

文字化けしたときに思い出したいコマンド locale

Dell の Ubuntu モデルを探す

背景

Dellのコンピュータで、Ubuntsu モデルを探したい。なかなか見つからない。

方法

build your own というのがOSなどが選べるモデルとなる。よってそれをキーワードサーチして検索する。 それが次のリンク。

www.dell.com

まとめ

14インチFULLHD、メモリ16GB、英語キーボード、Ubuntsu、だと、こんな感じ(133,760円)。

www.dell.com

15インチFULLHD、メモリ16GB、英語キーボード、Ubuntsuだと、こんな感じ(133,100円)

www.dell.com

いずれも、CPUをceleron にしてケチっていますが…。メモリをケチってビルド自体できないことがあるってのがいいわけ。

emacs の cask が "Missing dependency" とか表示されてうまく行かない

背景

emacs の package をガバっとインストールできてめちゃくちゃ便利な cask ですが、emacs version 26 以上になると調子悪い。

対策その1: もう cask に頼らない

emacs -q で起動後、

下記を eval する。

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")

その後、

(require 'package)

;; package-archivesを上書き
(setq package-archives
      '(("melpa" . "https://melpa.org/packages/")
        ;; ("melpa-stable" . "https://stable.melpa.org/packages/")
        ("org" . "https://orgmode.org/elpa/")
        ("gnu" . "https://elpa.gnu.org/packages/")))

;; 初期化
(package-initialize)

みたいな感じで package を読み込み、

の後、

M-x package-refresh-contents

その後、

M-x package-install <install したいパッケージ名>

で個別にインストール。

対策その2: やっぱり cask コマンドを使う

~/.cask/bin/cask.el

の初めの方の行に、

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")

を貼り付けて保存した後、cd ~/.emacs.d/ に移動し、cask を実行

gsutil compose で 32より多いファイルを結合したいとき

背景

gsutil compose はファイルを結合する便利コマンド。しかし32より多いファイルは結合できない。

解決策

xargs -L31 を使う。

 echo -n | gsutil cp - gs://your-bucket/total.gz
 gsutil ls gs://your-bucket/your_file*.gz | xargs -L31 | xargs -I{} echo gsutil compose gs://your-bucket/total.gz {} gs://your-bucket/total.gz | sh

ここで、your-bucketバケット、total.gz はコピー先、your_file*.gz はコピー元を示す。

詳細

本当は xargs を一つにまとめたかったのだが、-I オプション(リプレイス)を使うと、強制的に -L31-L1 に変更されてしまうので、こうなった。 また echo ... | sh になっているのは、リプレイス先がスペースを含んだ複数のファイルが一つのファイルと認識されてしまうため。