質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

285閲覧

コードの解説をしてください:データサイエンスハンドブック(オライリー社)より

takashim

総合スコア124

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1グッド

0クリップ

投稿2019/11/13 05:31

機械学習の勉強のため、オライリー社出版の「データサイエンスハンドブック」を写経しています。

質問(依頼)事項

「5.10.1 多様体学習:HELLO」 にあるコードが理解できません。
質問として乱暴なのは承知ですが、どなたか解説いただけないでしょうか。

該当コード

分からないのは、関数make_hello中の、"data = imread"から"return"までです。
X * data.shapeなんて、shapeが全然違うのでなぜ掛けられるか判りません。
他も何をやっているのか具体的につかめません。

python3

1%matplotlib inline 2import numpy as np 3import matplotlib.pyplot as plt 4import seaborn as sns; sns.set() 5from matplotlib.image import imread 6 7def make_hello(N=1000, rseed=42): 8 fig, ax = plt.subplots(figsize=(4, 1)) 9 fig.subplots_adjust(left=0, right=1, bottom=0, top=1) 10 ax.axis('off') 11 ax.text(0.5, 0.4, 'HELLO', va='center', ha='center', weight='bold', size=85) 12 fig.savefig('hello.png') 13 plt.close(fig) 14 15 data = imread('hello.png')[::-1, :, 0].T 16 rng = np.random.RandomState(rseed) 17 X = rng.rand(4 * N, 2) 18 i, j = (X * data.shape).astype(int).T 19 mask = (data[i, j] < 1) 20 X = X[mask] 21 X[:, 0] *= (data.shape[0] / data.shape[1]) 22 X = X[:N] 23 return X[np.argsort(X[:, 0])] 24 25X = make_hello(1000) 26colorize = dict(c=X[:, 0], cmap=plt.cm.get_cmap('rainbow', 5)) 27plt.scatter(X[:, 0], X[:, 1], **colorize) 28plt.axis('equal');

(参考)コードの実行結果

イメージ説明

tiitoi👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

正直、意図がなかなかわかりづらいコードですね。
やっていることは Hello の文字の部分にランダムに点を生成しているだけになります。
この関数で作成したデータセットを使って、このあとなにかアルゴリズムを試したりするのだと思います。

以下、コメントを入れました。

python

1 # 画像を読み込む。 2 # ::-1 は高さ方向を反転させる。左上原点の画像座標から左下原点の標準座標にするため。 3 # 最後の0 は RGBAチャンネルのうち、Rチャンネルを取り出す。 4 # T は縦横を入れ替える。axis=0 を x 座標、axis=1 を y 座標とするため。 5 data = imread("hello.png")[::-1, :, 0].T 6 7 # 乱数のシードを初期化する。 8 rng = np.random.RandomState(rseed) 9 10 # [0, 1] の一様分布に従う乱数で 4 * N 個の点を作成する。 11 # つまり、長方形 [0, 1] x [0, 1] の中にランダムに点を作成する。 12 X = rng.rand(4 * N, 2) 13 14 # X の形状は (4 * N, 2), data の形状は (2,) なので、ブロードキャストして乗算される。 15 # x は [0, 1] -> [0, 288], y は [0, 1] -> [0, 72] にスケールされる。 16 # つまり、長方形 [0, 288] x [0, 72] の中にランダムに分布する点が得られる。 17 i, j = (X * data.shape).astype(int).T 18 19 # 各点における Hello の画像の画素値を参照する。 20 # 値が1 (白) でない画素は文字の部分なので、文字の部分に存在する点だけ取り出す。 21 mask = data[i, j] < 1 22 X = X[mask] 23 24 # x = x * 幅 / 高さ とすることで元のアスペクト比に戻す。 25 X[:, 0] *= data.shape[0] / data.shape[1] 26 # X のうち、先頭 N 個を取り出す。 27 X = X[:N] 28 # x 座標が小さい順にソートして返す。 29 return X[np.argsort(X[:, 0])]

投稿2019/11/13 06:26

編集2019/11/13 07:01
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takashim

2019/11/13 06:55

いつもありがとうございます。 maskのあたり、私のnumpyの知識不足があったようにも思いますがおかげさまでやっていることは分かりました。 もしお分かりでしたら、以下、追加で教えて頂けませんか。 dataのshapeは逆行列にする前で(72, 288)であり、figsize=(4, 1)に従った大きさとなっています。 ・72*288の単位はpixelと言って間違いないでしょうか? ・なぜ72を掛けて、72*288になるのでしょうか?
takashim

2019/11/13 07:04

聞いてから調べました。 1 inch=72 ptみたいですね。 figsizeはinch単位のようなので、(4, 1)inch * 72 pt/inch = (288, 72) pt 間違っていなければ自己解決しました。お手数おかけしました。
tiitoi

2019/11/13 07:05

一部、コメントの文言がおかしい箇所があったので回答を修正しました。 全体の流れを整理すると、以下のようになります。 1. Hello の画像を作成する。文字の画素は [0, 1) の範囲の値、背景の画素は1となっている。 2. 画像中に一様に分布する点を沢山作成する。 3. 文字の部分に含まれる点だけ取り出す。 4. 以上で Hello の文字の部分に分布する点が生成できた。 > ・72*288の単位はpixelと言って間違いないでしょうか? はい > なぜ72を掛けて、72*288になるのでしょうか? これはどこのことを指していっていますか。
takashim

2019/11/13 07:27

>> なぜ72を掛けて、72*288になるのでしょうか? >これはどこのことを指していっていますか。 figsize=(4, 1)を指定した結果、dataのshapeが(72, 288)となることです。 上述の通り、(4, 1)inch * 72 pt/inch = (288, 72) ptということで理解しました。 ありがとうございます(以前は「中」じゃなかったですか??)。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問