技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

集合おさらい

このあたりの数学はどっちかと言えば概念に近い。
hatena で tex 書式使う練習がてら

基本


A = \left\{ 2, 4, 6, 8, 10 \right\}
A = \left\{ 2, 4, 6, 8, 10 \right\}

このような範囲がはっきりしたデータの集まりを 集合 といい、個別の値を 要素 という。
集合はただのあつまりなので、順番に意味はない(配列ではない)


\left\{ 2, 4, 6, 8, 10 \right\} = \left\{ 10, 4, 2, 6, 8 \right\}
\left\{ 2, 4, 6, 8, 10 \right\} = \left\{ 10, 4, 2, 6, 8 \right\}

また、 x が集合  X の要素であるということを以下の様に書く


x \in X
x \in X

逆に含まれない場合は


x \notin X
x \notin X

集合要素は無限を定義できるのでこんな感じで関数も突っ込めるし


X = \left\{ x \mid P(x) \right\}

こんな感じで定義してもいい。


E = \left\{ x \mid x は偶数 \right\}
E = \left\{ x \mid x は偶数 \right\}

集合同士の関係

ある集合(ここではA)がもう一つの集合(B)の一部に含まれているときに、この関係を 包含関係 といい、A は B の部分集合という言い方ができる。


A \subset B
A \subset B

ただし  \subset = の可能性もある。
他の関係としては、

  • 積集合: A, B 両方に含まれている部分的な集合

A \cap B =   \left\{
    x \mid x \in A かつ x \in B 
\right\}
  • 和集合: A, B どちらかには含まれているという集合
 
A \cup B = \left\{   x \mid x \in A または x \in B   \right\}
  • 差集合: A の範囲ではあるが、B との共有部分は含まない集合

A - B = \left\{   x \mid x \in A かつ x \notin B   \right\}

特殊な集合シリーズ


\mathbb{Z} = \left\{ x \mid x は整数 \right\} \\
\mathbb{N} = \left\{ x \mid x は自然数 \right\} 
    = \left\{ x \mid x \in \mathbb{Z} かつ x \ge 1 \right\}  \\
\mathbb{Q} = \left\{ x \mid x は有理数 \right\} 
    =  \left\{ \frac{p}{q} \mid p \in \mathbb{Z}, q \in \mathbb{Z} - \left\{ 0 \right\} \right\} \\
\mathbb{R} = \left\{ x \mid x は実数 \right\}  \\
\mathbb{C} = \left\{ x \mid x は複素数 \right\}
    = \left\{ u + v \sqrt{-1} \mid u, v \in \mathbb{R} \right\}
\mathbb{Z} = \left\{ x \mid x は整数 \right\} \\
\mathbb{N} = \left\{ x \mid x は自然数 \right\} 
    = \left\{ x \mid x \in \mathbb{Z} かつ x \ge 1 \right\}  \\
\mathbb{Q} = \left\{ x \mid x は有理数 \right\} 
    =  \left\{ \frac{p}{q} \mid p \in \mathbb{Z}, q \in \mathbb{Z} - \left\{ 0 \right\} \right\} \\
\mathbb{R} = \left\{ x \mid x は実数 \right\}  \\
\mathbb{C} = \left\{ x \mid x は複素数 \right\}
    = \left\{ u + v \sqrt{-1} \mid u, v \in \mathbb{R} \right\}

とよく使う特殊集合系。
因みに


\mathbb{N} 
\subset \mathbb{Z} 
\subset \mathbb{Q} 
\subset \mathbb{R} 
\subset \mathbb{C}

Salesforce開発の基礎編3

データインポート

trailhead.salesforce.com

データのインポートの概要 : データインポートウィザードとデータローダの二つがある。

データインポートウィザードは f:id:white-azalea:20210512200730p:plain ここから f:id:white-azalea:20210512200823p:plain ということで。
こんな感じにインポートしていきます。
こいつは標準オブジェクトにしかデータを突っ込めない。

f:id:white-azalea:20210512201042p:plain

データローダは外部ツールで、この辺 Help | Training | Salesforce からインストールできる。
見ての通り Java を使う。
f:id:white-azalea:20210512201603p:plain
こんな感じで表示されるので、通常はバッチファイルから起動する。

因みにこいつ何を元に Java を参照しに行ってるのか不明で、環境によってはこんなメッセージを吐く。
f:id:white-azalea:20210512202039p:plain
思わず クソが! とぼやいたが、仕方ない、この場合は java -jar dataloader-51.0.1-uber.jar で起動できる。

f:id:white-azalea:20210512202147p:plain

こんなツール。
多分重要なのは データインポートウィザード 5 万件リミット、データローダ は 500 万件リミット。
この回の演習はデータインポートウィザードを利用してデータを取り込む演習です。

データのエクスポート

データエクスポートは データエクスポートサービスデータローダ の二つが選べる。
まぁデータローダは↑の画像見ればわかりそうなものなので。

f:id:white-azalea:20210512203904p:plain

データエクスポートはこんな画面から実行します。
エクスポートを開始するとこんな画面に

f:id:white-azalea:20210512204120p:plain

まぁ見ての通りか…

数式と入力規則

trailhead.salesforce.com

数式項目の使用

利用可能な数式はコレ Help | Training | Salesforce

カスタム項目

数式のカスタム項目を作成できますという話。
これは例えば 年齢 項目を参照して、60 以上で true になる「IsOld__c」みたいなカスタム項目を作れる。

これで作成したカラムは 「Formula」型となり、手動で設定することができない。更新は、レコードの保存/更新を行ったタイミングで自動設定される。
そのため、Apex でレコード作成するときは、Insert した後に SELECT してやらないと項目が設定されない。

設定はオブジェクトマネージャに項目がある。

f:id:white-azalea:20210512205528p:plain

積み上げ集計項目の実装

二つのオブジェクトが主従関係(主:取引先 - 商談 : 従 など)にある時、子レコードの特定フィールドを集計した項目を親に作ったり、子レコードの件数を親レコードのカラムにできる。
こうしたカラム(項目)を「積み上げ集計項目」と呼ぶ。

  • 合計
  • カウント
  • 最小値
  • 最大値

何かが設定できる。
因みに、こいつも子要素を INSERT/UPDATE/DELETE 等すると、保存実行時に親項目も更新で UPDATE される。なので、トリガーを仕掛けてたりするとこのタイミングで呼び出されるので、ちょっと注意。

入力規則

オブジェクトマネージャの項目内にこっそりある。

f:id:white-azalea:20210512211848p:plain

こんな感じで作成できる。
f:id:white-azalea:20210512212531p:plain

実行してみると
f:id:white-azalea:20210512212612p:plain

Apex でレコード操作してて、突然起こられるときは大体こいつ…一応複数項目評価もできるので、 「XXX が YYY の時は ZZZ は --- でなければならない」 みたいな制限もつけれる。

DeepLerning らしいDeepLerning実装

white-azalea.hatenablog.jp

ここに、Dropout 層とか色々積んでみたというもの。
尚、この記事初めて見た人は突然何のことやらだと思うので、この辺の 2021/2 月あたりから継続してるのでその辺見ると良いかも?

white-azalea.hatenablog.jp

やってみてわかったことは、大量のデータセットでいきなり学習させるとかではなくて、そこそこ小さなデータセットで 1 層づつ増やしていった方が無難だと思った。

いきなり層を増やしてエラー起こすと、何層目で設定ミスしたのか本気で分からなくなるので…。
行列計算の問題なので、行列サイズ(input / output) の形状一つでもミスすると、即エラーです。

尚、im2col 変換や col2im は以前の記事参照で。

畳み込み層

画像の特徴抽出層。
内部でフィルタを持っていて、フィルタによって特徴を拾う。

尚、ニューロンからのリクエスト(backpropagation)を受けて、よりリクエストに合ったフィルタに形状変更していく。

class ILayer:
    def forward(self, x, is_test):
        pass
    def backward(self, grad_y):
        pass
    def update(self, eta):
        pass

class ConvLayer(ILayer):
    def __init__(self, x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad, wb_width):

        # パラメータをまとめる
        self.params = (x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad)
        
        # フィルタとバイアスの初期値
        self.w = wb_width * np.random.randn(n_flt, x_ch, flt_h, flt_w)
        self.b = wb_width * np.random.randn(1, n_flt)
        
        # 出力画像のサイズ
        self.y_ch = n_flt  # 出力チャンネル数
        self.y_h = (x_h - flt_h + 2*pad) // stride + 1  # 出力高さ
        self.y_w = (x_w - flt_w + 2*pad) // stride + 1  # 出力幅
 
        # AdaGrad用
        self.h_w = np.zeros((n_flt, x_ch, flt_h, flt_w)) + 1e-8
        self.h_b = np.zeros((1, n_flt)) + 1e-8
        
    def forward(self, x, is_test):
        n_bt = x.shape[0] 
        x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad = self.params
        y_ch, y_h, y_w = self.y_ch, self.y_h, self.y_w
        
        # 入力画像とフィルタを行列に変換
        self.cols = im2col(x, flt_h, flt_w, y_h, y_w, stride, pad)
        self.w_col = self.w.reshape(n_flt, x_ch*flt_h*flt_w)
        
        # 出力の計算: 行列積、バイアスの加算、活性化関数
        u = np.dot(self.w_col, self.cols).T + self.b
        self.u = u.reshape(n_bt, y_h, y_w, y_ch).transpose(0, 3, 1, 2)
        self.y = np.where(self.u <= 0, 0, self.u)
        return self.y
    
    def backward(self, grad_y):
        n_bt = grad_y.shape[0]
        x_ch, x_h, x_w, n_flt, flt_h, flt_w, stride, pad = self.params
        y_ch, y_h, y_w = self.y_ch, self.y_h, self.y_w
        
        # delta
        delta = grad_y * np.where(self.u <= 0, 0, 1)
        delta = delta.transpose(0,2,3,1).reshape(n_bt*y_h*y_w, y_ch)
        
        # フィルタとバイアスの勾配
        grad_w = np.dot(self.cols, delta)
        self.grad_w = grad_w.T.reshape(n_flt, x_ch, flt_h, flt_w)
        self.grad_b = np.sum(delta, axis=0)
        
        # 入力の勾配
        grad_cols = np.dot(delta, self.w_col)
        x_shape = (n_bt, x_ch, x_h, x_w)
        self.grad_x = col2im(grad_cols.T, x_shape, flt_h, flt_w, y_h, y_w, stride, pad)
        return self.grad_x

    def update(self, eta):
        self.h_w += self.grad_w * self.grad_w
        self.w -= eta / np.sqrt(self.h_w) * self.grad_w
        
        self.h_b += self.grad_b * self.grad_b
        self.b -= eta / np.sqrt(self.h_b) * self.grad_b
続きを読む

メモ書き:ディスプレイを破棄するにあたり

在宅で使ってたディスプレイが壊れたので、これどうするかなーと思ってみたら、破棄方法が結構めんどくさかったので忘れる前にメモ。
(因みに、調べてみたらAmazonで買って1年以内だったので、無事修理に出せた)

ディスプレイは普通には捨てれない

燃えないゴミに出したらアカン。液晶ディスプレイは「リサイクル家電法」という法律があり、単純に捨てることができない。
なので、原則としては以下いずれかの手段で手放す必要があります。

  1. 自治体の回収
  2. メーカーの回収
  3. 一般社団法人 3R 推進協会 or 破棄業者に頼む

自治体の回収

自治体によってやってるかどうかが決まる。
例えば自分の自治体は対応してなかった。

パソコンの出し方Q&A | 市川市公式Webサイト

この手のページは大体の自治体にあるので探すと良いと思う。

メーカーの回収

パソコンを製造・販売または輸入・販売する全ての事業者には回収・再資源化の義務があります

これは法律、ルールの問題なので、会社が生きている場合は基本的に対処してもらえる。
しかも、以下のマークがついているものについては、破棄費用はタダになる。

f:id:white-azalea:20210422191407p:plain

つっても送料位はかかるんだろうけど…一般的メーカーの窓口一覧はこっち

www.pc3r.jp

PCモニターの回収 各メーカーのPCリサイクル案内ページ - カラーマネジメント実践ブログ 〜フォトレタッチの現場から〜

一般社団法人 3R 推進協会 or 破棄業者に頼む

メーカーが存在しない、個人輸入品だなどの場合、回収メーカーがない事がある。(自作とかも含む)
破棄業者でもいいとは思うのだけど、一応法人にしとくのが一番安全だと思う。

申し込みURLは 家庭から排出されるパソコンの回収申込み | ご案内

英語勉強したい人に「Subtitles for Language Learning」

Amazon Prime Video。コロナ禍ではこういうのがお供になるはず。
ついでに英語の勉強もしてみようか。

www.subtitlesfll.com

ということで入れてみた図

f:id:white-azalea:20210421221153p:plain

アマプラの画面はキャプチャできない様になっているので、そこはあきらめで(汗

尚、再生しているのはファンタビ(字幕版)で、日本語字幕の下の黒枠に英語字幕、画面右にその字幕とカーソルを合わせたときに単語の意味が出てくる。
加えて、右の字幕をクリックするとその場面まで自動スキップもしてくれる。

これは…捗るねw

Salesforce開発の基礎編2

Aura コンポーネントの基本概念

trailhead.salesforce.com

日本語が長ったらしく意味不明なので、調訳。

  • バンドルと要求のライフサイクルについて
    • 根本的にブラウザ側で動作するコンポーネントである。
    • ハンズオン内容は、ほとんど空っぽの Aura Component を作成してデプロイするだけなので、特にハマることはないはず
  • アーキテクチャ概念について
    • 概念: 複数ページアプリケーションと単一ページアプリケーション:
      VFみたいに画面をページ遷移して処理する…様な扱いではなくて、画面状態を変更するという形で画面を変えていく。単一ページ内で状態を変えながら処理していくモデルを単一ページアプリとここでは定義してる。
    • 概念: ページとコンポーネント:
      Aura Component は一つ一つ独立した小さなコンポーネントを、1ページ内に複数配置して動作させるイメージになる。
      • コンポーネント間はイベントを飛ばしあって通信する。コントローラでは特定のイベントに反応して処理するような作りをしていく。
      • 上記の様にコンポーネント間の繋がりが薄いので、グループ的に組み合わせて作成できる。
      • Aura コンポーネントは色々なところで使える
    • 概念: アプリケーションコンテナ
      Aura コンポーネントは Lightning Experience をはじめとした色々な箇所で利用できる。
      Salesforce Classic, VF, Salesforce アプリケーション, Lightning Experience ... これら動作させる環境を「コンテナ」と呼んでるっぽい。
      コンテナによってイベントを飛ばしても処理されないことがある。
      コンテナは入れ子構造にできるが、実行する Aura コンポーネントが利用できる機能は直近の親コンテナの機能だけだ。
  • コーディング概念について
    • 概念: コントローラ
      Aura コントローラはブラウザ上で動く。データ操作とか欲しければ Apex のコントローラを挟め。
    • 概念: アクション
      JavaScript で関数書く。class とかそういう言語機能のない時代の産物なので、オブジェクトプロパティとして関数を追加していく。
      「,」に注意は、後の問題にも出る。
      • コンポーネントの属性
        aura:attribute で属性宣言しなけばならず、コントローラからのアクセスも component.get('v.属性名') component.set('v.属性名', 値) しないといけない。
        この「component」 は環境の暗黙変数(暗黙とかクソやんと恨み言を吐きたい)。
        一応、「component.変数名 = 値」で突っ込みもできなくない(JavaScript Expando)けど、非推奨。
    • 概念: メソッドコールとイベント
      コントローラと画面は直接的にメソッドコールできない。やるならイベント経由。

なんというか長いうえに冗長過ぎてわかりにくい。

データモデリング

trailhead.salesforce.com

  • カスタムオブジェクトと標準オブジェクトについて
    • オブジェクトの概要
      データベーステーブルはオブジェクト、列は項目、行はレコード これ以上言うことがない。なんでこんな長く説明するんだ…
    • オブジェクトについて知る
      Salesforce ビルトインの 標準オブジェクト と、会社や業種、またはアプリ固有の カスタムオブジェクト がある。
      カスタムオブジェクトは名称の後ろに __c が追加される。カスタムオブジェクトには自動で以下の項目が追加される
      • ID : 自動生成ユニークプライマリキー (個人的にカスケード嫌いなので個の仕様は好き)
      • システム系統項目 : CreatedDate, UpdatedDate CreatedBy, UpdatedBy, OwnerId, LastModifiedDate など。システムなので自動更新項目。
      • 名前 : Name フィールド、自動採番にもできる。 カスタム項目は文字列とかテキストエリアとかも指定できるが、独特なのに Datetime(UTC でしか保存されない) と、Date (こっちはローカル日時)、数式(レコード保存時に数式を評価して自動設定される型)、複数選択項目(保存時; で文字列保存されてる型)がある。
  • オブジェクトリレーションの作成
    • リレーション系は 参照関係主従関係 がある。参照は普通のデータベーステーブルの外部キー。主従関係にすると親子関係をかなり厳密に処理する。二つ以上主従できないとか親が消えると子がすべて消えるとか(カスケード)。
  • スキーマビルダーの使用
    使い方の説明と試しだけです。

WSL から sfdx の認証を通す

前回対応した内容でいざ開発しようと思ったら、認証で行き詰ったのでその対処方法を記録する。

white-azalea.hatenablog.jp

まず、そのまま force:auth:web:login すると、失敗してしまう。
これは VSCode から行っても(Remote WSL している限りは)一緒で、これがなぜかというと、URL 認証を開始しておきながら、ブラウザを起動することができないから。

しかし、WSL には画面もクソもないわけで、まさかコンソールブラウザで認証するわけにもいかない…。
そこで、WSL の機能に頼り、Windows のアプリを WSL bash から呼び出せるように設定する。

  1. apt install xdg-utils でデスクトップアプリ由来のソフトを呼び出す機能をインストールする。WSL には GUI が無いのだから、当然入ってない。
    Debian -- sid の xdg-utils パッケージに関する詳細
  2. 適当なパスに、シェルを記述する。まぁめんどくさいので今回はユーザホーム直下に書いた。シェル名は start_chrome.sh で、中身はこんな感じ。mnt/ 以降は Windows のパスなので、ブラウザのパスを突っ込もう
    sh "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" $1:$2
  3. chmod +x start_chrome.sh で実行権限を与えとこうか。
  4. pwd で今のパスを拾っとく。今回打ったら /home/azalea だった。ここにシェルを書いたので、シェルのパスは /home/azalea/start_chrome.sh だ。
  5. .bashrc を開いて、最後に export BROWSER="/home/azalea/start_chrome.sh" と突っ込んでおく。
  6. source .bashrc を叩いて、設定を読み込む。

検証してみるにはコマンドラインxdg-open https://www.salesforce.com と打ち込んでみよう。
正しく設定されていれば、WindowsChrome が立ち上がるはずだ。

これが出来たら sfdx auth:web:login でブラウザを起動して認証しよう。

f:id:white-azalea:20210420204944p:plain