2022-12-31

三冊の伝説本を一気読み

年末年始の休暇が始まって、久しぶりに三省堂書店 神保町本店(小川町仮店舗)に寄って本をあれこれ物色していたところ、気になる三冊の本を見つけました。衝動買いをしたくなる心をグッと抑え、帰宅してから Amazon.co.jp で Kindle 版を買いました。

MZ-80K2E で始まった PC とのおつきあい

高校生だっところのことですから、ずいぶん昔のことになりますが、当時はまだマイコンと呼ばれていた「パーソナルコンピュータ」をはじめて買ったのは、SHARP MZ-80K2E [1] でした。搭載されていた CPU は、当時のパソコンで多く採用されていた 8bit の Zilog Z80 のセカンドソース品、SHARP LH0080(2MHz で動作)でした。ゲームやりたさで無機質な機械語入力に励んでいました。インターネットで情報を収集できる時代ではなかったので、Z80 関連書籍を買い漁りました。おかげで、Z80 の命令セットもすっかりおぼえてしまいました(当時)。

閑話休題、思い出話を語り出せば延々と続くので、ここで止めておきます。🤭

そんなわけで Zilog Z80 の開発にまつわる話は多少は知っている気になっていますが、それより世代が少し前の Intel 8080 や Motorola 6800 については、ほとんど知らなかったので、この機に三冊まとめて読んでしまおうと考えたのでした。

教科書的ではないおもしろさ

これらの本は、「今」の視点で当時のエピソードを紹介するスタイルを取っています。その内容は実に詳細です。単に事実をまとめた教科書的な記述ではなく、当時の熱い「事情」も語られています。

「インテル8080伝説」の「はじめに」に書かれているように、当時の出来事を、資料に照らし、技術的に検証し、なるべく正確に紹介しようとする姿勢が三冊を通じて感じられるので、とても好感が持てます。きっと膨大な資料に基づいているんだろうなと思われる大変多くの関連エピソードがちりばめられており、実に楽しく読めました。

今だからなるほどと思うことも、その当時ではなかなか判らなかったという、そんな内容が満載です。あとになって振り返ることで良く判るということがあるものです。それに Z80 について多少は知っているつもりになっていましたが、知らないことばかりでした

例えば、今ではなかなか考えられないことですが、当時のセカンドソースの存在は、安定供給するためには必要だったこと、そして、Z80 の場合は、競合の Intel と Motorola がどちらも米国企業だったことから、セカンドソースを日本とイタリアの企業に求めたことを知りました。いままで、セカンドソースの存在は、なんとなくネガティブに捉えていました。そもそも、開発当時、半導体製造ラインを持っていなかった Zilog の Z80 は、Mostek で製造されていたことすら知りませんでした。

こうして三冊をまとめて読むと、8080, 6800, Z80 それぞれのエピソードが少なからずどの本でも重複していましたが、それが却ってそれぞれの状況を時系列的に確認することにつながりました。特に 6800 の開発視点で語られるエピソードは初めて知ることばかりで新鮮でした。また 6800 では、1975 年ごろに、製造プロセスにイオン注入工程が導入されたことを知りました。

※ 自分は 1988 年に大学を卒業して、今は社名が消滅してしまった某半導体デバイスメーカーに入社しましたが、もちろんイオン注入工程はフツーにありましたので、当時は、それがいつから、ということを考えたことがありませんでした。

著者は、当時の CPU(あるいは同等品)および周辺チップを買い集め、CPU ボードを設計し、Tiny BASIC を走らせることまでやっています。すごいです。😮

当時はパソコンのスイッチを入れると、まず BASIC が起動するのが一般的だったことを懐かしく思い出しました。

Z80 の末裔

Z80 を開発した Zilog 社は現在、Littelfuse 社の傘下に入っています。1976 年に発表された Z80 は今も製造され、FPGAIP コアでも利用されているそうです[Wikipedia より]。また Z80 とバイナリ互換な eZ80 があります。

この eZ80 は、テキサス・インスツルメンツ社が製造するグラフ関数電卓、TI-84 Plus シリーズに搭載されています。Wikipedia によると、このシリーズの電卓は米国ののグラフ関数電卓市場で高いシェアを占めているそうです。

参考サイト

  1. MZ-80K2E | 計算機室
  2. 回路保護、ヒューズ、電力制御、センサーソリューション - リテルヒューズ
  3. Zilog
  4. TI-SmartView™ Emulator Software for the TI-84 Plus Family - Texas Instruments - US and Canada

 

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2022-12-29

EPEL 利用と RHEL 互換ディストロの人気度

Fedora EPEL, Extra Packages for Enterprise Linux は、Red Hat Enterprise Linux (RHEL) や、AlmaLinux, Rocky Linux など、RHEL 互換ディストロ上向けのアドオンパッケージです [1]。例えば、Windows から RDP でリモートデスクトップ接続するには、RHEL 系の OS では EPEL が提供している xrdp を利用します。

RHEL 互換ディストロの人気度

RHEL を使うとサブスクリプション費用が掛かるので、RHEL 互換ディストロを採用するというケースでは、以前はほぼ CentOS 一択だった状況だったと思います。しかし、CentOS 8 が開発中止となった後 [2]、AlmaLinux、Rocky Linux など、複数の互換ディストロが無料で利用できるようになりました。選択肢が増えたことは歓迎すべきか、あるいは、採用のための評価内容が増えたと嘆くべきか…。

RHEL 互換のディストロを採用する事情は色々あると思いますが、どの互換ディストロの人気が高いか、という情報はひとつの参考情報にはなるでしょう。

人気度を測るひとつの尺度として、Fedora プロジェクトの EPEL を利用しているディストロ(= RHEL 互換)を集計してランキングする、というのはおもしろい視点だと思い、比較的最近のニュースをピックアップしました。

どうやら Rocky Linux による EPEL の利用が増えているようです。もっとも、RHEL 互換ディストロを利用したソフトウェア製品全てが EPEL を利用しているというわけではないので、あくまでひとつの側面に過ぎませんが、参考にはなる情報です。

Rocky Linux 9.1 のデスクトップ

個人的には、RHEL のリリースに追従するのが早い AlmaLinux に注目していますが、世間のニーズは企業色の無い、あるいは薄いディストロに向かうのかもしれません、あくまで推測ですが…。

ちなみに、RHEL 互換のディストロでは上記のような古い CPU を積んだ PC にインストールしても、特に警告は出ませんが、RHEL の場合は Red Hat Insights で、サポートしていない、あるいはサポートを終了する予定の CPU を使っているという警告が出ます [3]。😢

参考サイト

  1. Extra Packages for Enterprise Linux (EPEL) :: Fedora Docs
  2. CentOS Project shifts focus to CentOS Stream – Blog.CentOS.org [2020-12-08]
  3. What does it mean when hardware is classified as "unmaintained" in Red Hat Enterprise Linux 8.6+, 9.0 and newer? - Red Hat Customer Portal
  4. 【Infostand海外ITトピックス】「二度と開発停止の混乱は起こさない」 その後のRocky Linux - クラウド Watch [2020-09-12]

 

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2022-12-28

【備忘録】主成分分析 ~ R ~

主成分分析 (Principal Component Analysis, PCA) は、1観測あたり多数の次元/特徴を含む大規模データセットを分析し、最大限の情報量を保持しながらデータの解釈可能性を高め、多次元データの可視化を可能にする手法としてよく利用されています。形式的には、PCA はデータセットの次元を減少させる統計的手法です。これは、データの変動(の大部分)が、初期データよりも少ない次元で記述できるような新しい座標系にデータを線形変換することにより達成できます。

Wikipedia より引用、翻訳・編集

データ解析で頻繁に主成分分析 (PCA) を利用しています。主成分分析をはじめ、よく使用する機械学習の処理部分などは、いつも過去に使ったスクリプトから必要部分をコピペして使い回してしまっているので、思い違いや間違いがあれば、そのままずっと引きずってしまう可能性があります。ちょっと心配になってきたので、簡単なサンプルを使ってスクリプトを整理しようとしています。

今回は R で主成分分析を扱います。これは、本ブログ記事にまとめた Python / Scikit-Learn における主成分分析のやり方あるいは結果と比較するためです [1]

下記の OS 環境で動作確認をしています。

Fedora Linux 37 Workstation x86_64
R 4.2.2

今回は JupyterLab の Notebook 上で動作確認をしています。JupyterLab 上で R を利用するには、本ブログの記事 [2] を参照してください。

最初にプロット関連のモジュールを読み込んでおきます。

library(ggplot2)
library(GGally)

解析用のサンプルデータを読み込みます。解析用のサンプルは有名な Iris のデータセットを使っています。Kaggle のサイトで公開されている CSV データ Iris.csv [3] をダウンロードして使用しています。

filename <- "Iris.csv"
df <- read.csv (filename)
head(df)

 

複数の変数(説明変数)x とターゲット(目的変数)y のカラムを定義しておきます。

cols.x <- colnames(df)[2:5]
print(cols.x)
col.y <- colnames(df)[6]
print(col.y)
[1] "SepalLengthCm" "SepalWidthCm"  "PetalLengthCm" "PetalWidthCm" 
[1] "Species"

元データ(説明変数)の分布を散布図にして確認しておきます。

p <- ggpairs(
    data = df,
    columns = cols.x,
    mapping = aes(color = Species, alpha = 0.5)
)
ggsave(
    filename = "iris_011_scatter.png", 
    plot = p, 
    width = 20, 
    height = 20, 
    units = "cm"
)
show(p)

 

主成分分析 (PCA) は、ここでは prcomp で計算します。

pca <- prcomp(df[cols.x], scale. = TRUE)
pca
Standard deviations (1, .., p=4):
[1] 1.7061120 0.9598025 0.3838662 0.1435538

Rotation (n x k) = (4 x 4):
                     PC1         PC2        PC3        PC4
SepalLengthCm  0.5223716 -0.37231836  0.7210168  0.2619956
SepalWidthCm  -0.2633549 -0.92555649 -0.2420329 -0.1241348
PetalLengthCm  0.5812540 -0.02109478 -0.1408923 -0.8011543
PetalWidthCm   0.5656110 -0.06541577 -0.6338014  0.5235463

計算した結果のオブジェクト pca の構造は以下の様になっています。

str(pca)
List of 5
 $ sdev    : num [1:4] 1.706 0.96 0.384 0.144
 $ rotation: num [1:4, 1:4] 0.522 -0.263 0.581 0.566 -0.372 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "SepalLengthCm" "SepalWidthCm" "PetalLengthCm" "PetalWidthCm"
  .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4"
 $ center  : Named num [1:4] 5.84 3.05 3.76 1.2
  ..- attr(*, "names")= chr [1:4] "SepalLengthCm" "SepalWidthCm" "PetalLengthCm" "PetalWidthCm"
 $ scale   : Named num [1:4] 0.828 0.434 1.764 0.763
  ..- attr(*, "names")= chr [1:4] "SepalLengthCm" "SepalWidthCm" "PetalLengthCm" "PetalWidthCm"
 $ x       : num [1:150, 1:4] -2.26 -2.08 -2.36 -2.3 -2.38 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4"
 - attr(*, "class")= chr "prcomp"

pca の summary は次の様になっています。

summary(pca)
mportance of components:
                          PC1    PC2     PC3     PC4
Standard deviation     1.7061 0.9598 0.38387 0.14355
Proportion of Variance 0.7277 0.2303 0.03684 0.00515
Cumulative Proportion  0.7277 0.9580 0.99485 1.00000

上表の3行目の Cumulative Proportion が、そのまま累積寄与率に使えそうです。summary(pca) の構造を確認します。

s <- summary(pca)
str(s)
List of 6
 $ sdev      : num [1:4] 1.706 0.96 0.384 0.144
 $ rotation  : num [1:4, 1:4] 0.522 -0.263 0.581 0.566 -0.372 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "SepalLengthCm" "SepalWidthCm" "PetalLengthCm" "PetalWidthCm"
  .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4"
 $ center    : Named num [1:4] 5.84 3.05 3.76 1.2
  ..- attr(*, "names")= chr [1:4] "SepalLengthCm" "SepalWidthCm" "PetalLengthCm" "PetalWidthCm"
 $ scale     : Named num [1:4] 0.828 0.434 1.764 0.763
  ..- attr(*, "names")= chr [1:4] "SepalLengthCm" "SepalWidthCm" "PetalLengthCm" "PetalWidthCm"
 $ x         : num [1:150, 1:4] -2.26 -2.08 -2.36 -2.3 -2.38 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4"
 $ importance: num [1:3, 1:4] 1.706 0.728 0.728 0.96 0.23 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "Standard deviation" "Proportion of Variance" "Cumulative Proportion"
  .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4"
 - attr(*, "class")= chr "summary.prcomp"

行列 (matrix) s$importance を使えばよさそうです。

s$importance

 

累積寄与率の x 軸を 0 から始めたいので少し加工してプロットします。

contrib <- append(0, s$importance[3, ])
contrib
png("iris_012_contrib.png", width = 500, height = 500)
plot(c(0:4), contrib, type="l", col="blue", xlab="Principal Component", ylab="Cumlative Contribution Ratio", cex.lab=1.5, cex.axis=1.5)
grid(col="black")
dev.off()

 

ちなみに、主成分毎の寄与率をプロットするのであれば、screeplot(pca) で簡単にプロットできます。

png("iris_12_screeplot.png", width = 500, height = 500)
screeplot(pca)
dev.off()

 

主成分得点のプロットには pca$x を利用します。

head(pca$x)

 

プロット用に pca$x と Species を加えたデータフレーム df.pca を用意します。

df.pca <- as.data.frame(pca$x)
cols.pc <- colnames(df.pca)
print(cols.pc)
df.pca <- cbind(df.pca, df[col.y])
head(df.pca)

 

主成分を軸とした散布図を作成します。PC1 と PC2 だけで十分ですが、そもそも主成分は4つ(= 説明変数の数)までしかないので、全部の組み合わせをプロットしてしまいます。

p <- ggpairs(
    data = df.pca,
    columns = cols.pc,
    mapping = aes(color = Species, alpha = 0.5)
)
ggsave(
    filename = "iris_013_PCA_scatter.png", 
    plot = p, 
    width = 20, 
    height = 20, 
    units = "cm"
)
show(p)

 

主成分に対する説明変数の寄与を確認します(主成分負荷量)。行列 (matrix) pca$rotation に情報が入っています。

pca$rotation

 

 

biplot 関数を使えば、主成分分析のスコアと主成分負荷量を一緒にプロットできます。

png("iris_014_loading.png", width = 500, height = 500)
biplot(pca, cex = 1)
dev.off()

 

Python / Scikit-Learn で主成分分析を扱った本ブログの記事 [1] の結果と比べると PC1 以外は符号が逆になっていますが、主成分分析の計算を考えると、主成分軸の正負の取り方で符号変わるのは仕方がないことなのでしょう。処理系によって符号の違いが出てくるかもしれないと認識しておく必要があります。

GUI やデータ解析でもなんでも Python でできてしまうので、重宝してよく使うようになりましたが、久しぶりに R を使って同じことをやってみると、R の方が便利だなと感じる点もあります、なにより、このように検証用に別の環境でできるようにしておくことが必要だと感じています。JupyterLab 上で Python も R も、おまけに Julia も使えるようになったので、今後もこうやって簡単なサンプルを使って、複数のプログラミング言語で比較を続けていく予定です。

参考サイト

  1. bitWalk's: 【備忘録】主成分分析 ~ Python / Scikit-Learn ~ [2022-12-27]
  2. bitWalk's: JupyterLab で R を使う [2022-12-16]
  3. Iris.csv | Kaggle

 

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2022-12-27

【備忘録】主成分分析 ~ Python / Scikit-Learn ~

主成分分析 (Principal Component Analysis, PCA) は、1観測あたり多数の次元/特徴を含む大規模データセットを分析し、最大限の情報量を保持しながらデータの解釈可能性を高め、多次元データの可視化を可能にする手法としてよく利用されています。形式的には、PCA はデータセットの次元を減少させる統計的手法です。これは、データの変動(の大部分)が、初期データよりも少ない次元で記述できるような新しい座標系にデータを線形変換することにより達成できます。

Wikipedia より引用、翻訳・編集

データ解析で頻繁に主成分分析 (PCA) を利用しています。主成分分析をはじめ、よく使用する機械学習の処理部分などは、いつも過去に使ったスクリプトから必要部分をコピペして使い回してしまっているので、思い違いや間違いがあれば、そのままずっと引きずってしまう可能性があります。ちょっと心配になってきたので、簡単なサンプルを使ってスクリプトを整理しようとしています。

今回は Python による主成分分析についてです。

下記の OS 環境で動作確認をしています。Fedora Linux 37 のデフォルトの Python のバージョンは 3.11.x ですが、新しすぎて一部のライブラリがまだ対応していない場合があるので、バージョン 3.10.y を使っています。

Fedora Linux 37 Workstation x86_64
Python 3.10.9

今回は JupyterLab の Notebook 上で動作確認をしていますが、これをブログの記事に載せるにあたって、Gist を利用する方法よりは、スクリプトをブログ上にコピペする方が記事が作りやすいと考えたのですが、参考サイト [1] で紹介されている方法を使って、スクリプトの見映えを変えています。また、本記事作成用にデータフレームをイメージとして出力するために dataframe_image [2] というモジュールを使用しています。

最初にプロット関連のモジュールを読み込んでおきます。また、フォントサイズは大きめに設定しています。

import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.size'] = 14

解析用のサンプルデータを読み込みます。解析用のサンプルは有名な Iris のデータセットを使っています。

Python のみで評価するのであれば、Scikit-Learn などで Iris のデータセットを利用できますが、Python 以外の言語でも確認したいと考えているので、同じデータソースを利用できるように、Kaggle のサイトで公開されている CSV データ Iris.csv [3] をダウンロードして使用しています。

import pandas as pd
import dataframe_image as dfi

# https://www.kaggle.com/datasets/saurabh00007/iriscsv
filename = 'Iris.csv'
df = pd.read_csv(filename, index_col=0)
dfi.export(df.head(), 'table_001_iris.png')
df.head()

 

複数の変数(説明変数)x とターゲット(目的変数)y のカラムを定義しておきます。

cols_x = list(df.columns[0:4])
print('cols_x', cols_x)
col_y = df.columns[4]
print('col_y', col_y)
cols_x ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']
col_y Species

元データ(説明変数)の分布を散布図にして確認しておきます。

g = sns.pairplot(df, hue=col_y, corner=True)
g.fig.suptitle('Iris scatters', y=1.02)

plt.savefig('iris_001_scatter.png')
plt.show()

 

Scikit-Learn の StandardScaler と PCA をパイプラインでつなげて、モデルを定義します。

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

pipe = Pipeline(steps=[
    ('scaler', StandardScaler()),
    ('PCA', PCA()),
])

カラム x の説明変数のデータ(特徴量 features)でモデルの訓練をします。ここでは訓練データとテストデータには分けていません。ここではモデルの評価をしないので、説明変数のデータ全てを訓練データとして扱っています。

features = df[cols_x]
pipe.fit(features)

 

算出された主成分のばらつき(分散)に対する累積寄与率を計算してプロットします。

import numpy as np
import matplotlib.ticker as ticker

contribution_ratios = pipe['PCA'].explained_variance_ratio_
cumulative_contribution_ratios = np.hstack([0, contribution_ratios.cumsum()])

fig, ax = plt.subplots()
ax.plot(cumulative_contribution_ratios)
ax.set_xlabel('Principal Component')
ax.set_ylabel('Cumlative Contribution Ratio')

# this locator puts ticks at regular intervals
loc = ticker.MultipleLocator(base=1.0)
ax.xaxis.set_major_locator(loc)

plt.grid()
plt.savefig('iris_002_contrib.png')
plt.show()

 

最初の主成分 (PC1) と次の主成分 (PC2) だけで、データのばらつきの9割以上を説明できていることが判ります。

主成分得点をまとめたデータフレームを作成します。

scores = pipe.transform(features)
df_pca = pd.DataFrame(
    scores,
    columns=["PC{}".format(x + 1) for x in range(scores.shape[1])],
    index=df.index
)
df_pca.insert(0, col_y, df[col_y].copy())

dfi.export(df_pca.head(), 'table_002_iris_PCA.png')
df_pca.head()

 

主成分を軸とした散布図を作成します。PC1 と PC2 だけで十分ですが、そもそも主成分は4つ(= 説明変数の数)までしかないので、全部の組み合わせをプロットしてしまいます。

g = sns.pairplot(df_pca, hue=col_y, corner=True)
g.fig.suptitle('Iris PCA score scatters', y=1.02)

plt.savefig('iris_003_PCA_scatter.png')
plt.show()

 

主成分に対する説明変数の寄与を確認します(主成分負荷量)。

components = pipe['PCA'].components_
df_load = pd.DataFrame(components.T,  index=features.columns, columns=["PC{}".format(x + 1) for x in range(len(components))])

dfi.export(df_load, 'table_003_iris_PCA_loading.png')
df_load

 

軸(PC1 と PC2)についてプロットしてみます。

pc_x = 'PC1'
pc_y = 'PC2'

fig, ax = plt.subplots()
for x, y, name in zip(df_load[pc_x], df_load[pc_y], df_load.index):
    ax.plot([0, x], [0, y])
    ax.text(x, y, name)

ax.set_xlabel(pc_x)
ax.set_ylabel(pc_y)
ax.set_title('Principal Component Loading')
ax.set_aspect('equal')

plt.grid()
plt.savefig('iris_004_loading.png')
plt.show()

 

参考サイト

  1. Bloggerでソースコードをカッコ良く表示する方法-趣味がダイイチ!備忘録!! [2019-08-28]
  2. dataframe-image · PyPI
  3. Iris.csv | Kaggle

 

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加