Triad sou.

行列のスカラー微分のメモ

$\mathbf{A}$, $\mathbf{B}$ について、スカラー $\theta$ で微分する場合を考える。
だたし、
\[
\mathbf{A}= \left\{ a_{ij} \right\}, \frac{\partial \mathbf{A}}{\partial \theta}= \left\{ \frac{\partial a_{ij}}{\partial \theta} \right\}
\] とし、$\mathbf{B}$ も同様に定義する。

行列積の微分

行列積 $\mathbf{A} \mathbf{B}$ が定義できる場合、
\[
\frac{\partial \mathbf{A}\mathbf{B}}{\partial \theta}= \frac{\partial \mathbf{A}}{\partial \theta}\mathbf{B} + \mathbf{A}\frac{\partial \mathbf{B}}{\partial \theta}
\]

逆行列微分

$\mathbf{A}$ が正方行列で逆行列が存在するならば、
\[
\frac{\partial \mathbf{A}^{-1}}{\partial \theta}= -\mathbf{A}^{-1} \frac{\partial \mathbf{A}}{\partial \theta} \mathbf{A}^{-1}
\]

逆行列微分の導出

\[
\begin{align*}
\frac{\partial \mathbf{A}\mathbf{A}^{-1}}{\partial \theta} &=
\frac{\partial \mathbf{I}}{\partial \theta} \\
\frac{\partial \mathbf{A}}{\partial \theta}\mathbf{A}^{-1} + \mathbf{A}\frac{\partial \mathbf{A}^{-1}}{\partial \theta} &=
\mathbf{0}\\
\mathbf{A}\frac{\partial \mathbf{A}^{-1}}{\partial \theta} &= -\frac{\partial \mathbf{A}}{\partial \theta}\mathbf{A}^{-1} \\
\frac{\partial \mathbf{A}^{-1}}{\partial \theta} &= -\mathbf{A}^{-1}\frac{\partial \mathbf{A}}{\partial \theta}\mathbf{A}^{-1}
\end{align*}
\]

正方行列 $\mathbf{A}$, $\mathbf{B}$ について、
\[
\begin{align*}
\frac{\partial \mathbf{A}^{-1}\mathbf{B}\mathbf{A}^{-1}}{\partial \theta} &=
\frac{\partial \mathbf{A}^{-1}}{\partial \theta}\mathbf{B}\mathbf{A}^{-1} + \mathbf{A}^{-1}\frac{\partial \mathbf{B}\mathbf{A}^{-1}}{\partial \theta} \\ &= -\mathbf{A}^{-1}\frac{\partial \mathbf{A}}{\partial \theta}\mathbf{A}^{-1}\mathbf{B}\mathbf{A}^{-1} + \mathbf{A}^{-1}\frac{\partial \mathbf{B}}{\partial \theta}\mathbf{A}^{-1} - \mathbf{A}^{-1}\mathbf{B}\mathbf{A}^{-1}\frac{\partial \mathbf{A}}{\partial \theta}\mathbf{A}^{-1} \\ &=
\mathbf{A}^{-1} \left( \frac{\partial \mathbf{B}}{\partial \theta} -\frac{\partial \mathbf{A}}{\partial \theta}\mathbf{A}^{-1}\mathbf{B} -\mathbf{B}\mathbf{A}^{-1}\frac{\partial \mathbf{A}}{\partial \theta} \right) \mathbf{A}^{-1}
\end{align*}
\]

$\mathbf{A}$ の要素が全て定数の場合、$\partial \mathbf{A} / \partial \theta = \mathbf{0}$ より $\mathbf{A}^{-1} (\partial \mathbf{B} / \partial \theta) \mathbf{A}^{-1}$。

ちらつかない JEditorPane クラス の setText メソッド

JEditorPane クラス の setText メソッド

public void setText(String t) {
  try {
    Document doc = getDocument();
    doc.remove(0, doc.getLength());
    if (t == null || t.equals("")) {
      return;
    }
    Reader r = new StringReader(t);
    EditorKit kit = getEditorKit();
    kit.read(r, doc, 0);
  } catch (IOException ioe) {
    UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
  } catch (BadLocationException ble) {
    UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
  }
}

のように実装されていて、いったんドキュメントをクリア

    Document doc = getDocument();
    doc.remove(0, doc.getLength());

してから、kit.read(r, doc, 0); する仕様です。


このせいで、Timer 中で回したりしていると、クリアしている部分が見えてしまうことがあって、画面がちらついてしまいます。
というわけで、

class ExtJEdit extends JEditorPane {
  public void setText(String t) {
    if (t == null || t.equals("")) {
      return;
    }
    Reader r = new StringReader(t);
    HTMLDocument doc = new HTMLDocument();
    HTMLEditorKit kit = new HTMLEditorKit();
    try {
      kit.read(r, doc, 0);
      this.setDocument(doc);
    } catch (IOException e) {
      UIManager.getLookAndFeel().provideErrorFeedback(this);
    } catch (BadLocationException e) {
      UIManager.getLookAndFeel().provideErrorFeedback(this);
    }
  }
}

こんな感じに変更してみたところ、ほぼちらつかなくなりました。

サンプル



ちらつかない場合もあるので、適当にボタンを押しまくってください。

New 'ByteCompile' field in the DESCRIPTION file

R 2.14.0 から DESCRIPTION ファイルに 'ByteCompile' フィールドを指定できるようになったらしい。
パッケージ中の R コードを自動的にバイトコンパイルしてくれるため、ものによっては高速化が見込めるという感じ。
試してみようかな。

The `ByteCompile' field controls if the package code is byte-compiled on installation: the default is currently not to, so this may be useful for a package known to benefit particularly from byte-compilation (which can take quite a long time and increases the installed size of the package).

Writing R Extensions / 1.1.1 The DESCRIPTION file

リンク

JTextArea to JTable / JTable to JTextArea

Java Swing でテキストエリア \Leftrightarrow テーブルの例を作ってみました。
csv っぽい形式で JTextArea 入力されているデータを JTable に読み込んだり、JTable のデータを csv っぽい形式に掃き出す事ができます。


ポイント

最初に作成した JTable クラス型のオブジェクト tableFirstnew JTable(data) 等を代入しても、テーブルの更新ができません。

// not work
JTable tableFirst = new JTable(datamatrixFirst, colnameFirst);
tableFirst = new JTable(datamatrixSecond, colnameSecond);


TableModel クラス型のオブジェクト tableModel で初期化し、tableModel の方を setDataVector メソッドで編集してあげると、テーブルがちゃんと更新されます。

// work
DefaultTableModel tableModel =
  new DefaultTableModel(datamatrixFirst, colnameFirst);

JTable tableFirst = new JTable(tableModel);
tableModel.setDataVector(datamatrixSecond, colnameSecond);

ソースコード

import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTable;
import java.awt.Rectangle;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;

import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.JButton;

public class myTable {

  /**
  * @param args
  */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        myTable application = new myTable();
        application.getJFrame().setVisible(true);
      }
    });
  }

  private String[] colName = {"x", "pdf", "cdf"};
  private Double[][] dataMatrix = {
    { -3.0, 0.00443, 0.00443},
    { -2.5, 0.01753, 0.01753},
    { -2.0, 0.05399, 0.05399},
    { -1.5, 0.12952, 0.12952},
    { -1.0, 0.24197, 0.24197},
    { -0.5, 0.35207, 0.35207},
    { 0.0, 0.39894, 0.39894},
    { 0.5, 0.35207, 0.35207},
    { 1.0, 0.24197, 0.24197},
    { 1.5, 0.12952, 0.12952},
    { 2.0, 0.05399, 0.05399},
    { 2.5, 0.01753, 0.01753},
    { 3.0, 0.00443, 0.00443}
  };
  private JTable dataTable = null;
  private JButton jButtonTable2Text = null;
  private JButton jButtonText2Table = null;
  private JPanel jContentPane = null;
  private JFrame jFrame = null;
  private JScrollPane jScrollPane = null;
  private JScrollPane jScrollPaneTextArea = null;

  public DefaultTableModel tableModel =
    new DefaultTableModel(dataMatrix, colName);
  public JTextArea tableText = null;

  /**
  * This method initializes dataTable
  *
  * @return javax.swing.JTable
  */
  private JTable getDataTable() {
    if (dataTable == null) {
      dataTable = new JTable(tableModel);
    }
    return dataTable;
  }

  /**
  * This method initializes jButtonTable2Text
  *
  * @return javax.swing.JButton
  */
  private JButton getJButtonTable2Text() {
    if (jButtonTable2Text == null) {
      jButtonTable2Text = new JButton();
      jButtonTable2Text.setBounds(new Rectangle(315, 135, 61, 31));
      jButtonTable2Text.setText("←");
      jButtonTable2Text.addActionListener(new java.awt.event.ActionListener() {
        @Override
        public void actionPerformed(java.awt.event.ActionEvent e) {
          textUpdate();
        }
      });
    }
    return jButtonTable2Text;
  }

  /**
  * This method initializes jButtonText2Table
  *
  * @return javax.swing.JButton
  */
  private JButton getJButtonText2Table() {
    if (jButtonText2Table == null) {
      jButtonText2Table = new JButton();
      jButtonText2Table.setBounds(new Rectangle(315, 90, 61, 31));
      jButtonText2Table.setText("→");
      jButtonText2Table.addActionListener(new java.awt.event.ActionListener() {
        @Override
        public void actionPerformed(java.awt.event.ActionEvent e) {
          tableUpdate();
        }
      });
    }
    return jButtonText2Table;
  }

  /**
  * This method initializes jContentPane
  *
  * @return javax.swing.JPanel
  */
  private JPanel getJContentPane() {
    if (jContentPane == null) {
      jContentPane = new JPanel();
      jContentPane.setLayout(null);
      jContentPane.add(getJScrollPane(), null);
      jContentPane.add(getJButtonText2Table(), null);
      jContentPane.add(getJButtonTable2Text(), null);
      jContentPane.add(getJScrollPaneTextArea(), null);
      textUpdate();
    }
    return jContentPane;
  }

  /**
  * This method initializes jFrame
  *
  * @return javax.swing.JFrame
  */
  private JFrame getJFrame() {
    if (jFrame == null) {
      jFrame = new JFrame();
      jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      jFrame.setSize(684, 283);
      jFrame.setContentPane(getJContentPane());
      jFrame.setTitle("Application");
    }
    return jFrame;
  }

  /**
  * This method initializes jScrollPane
  *
  * @return javax.swing.JScrollPane
  */
  private JScrollPane getJScrollPane() {
    if (jScrollPane == null) {
      jScrollPane = new JScrollPane();
      jScrollPane.setBounds(new Rectangle(390, 15, 271, 226));
      jScrollPane.setViewportView(getDataTable());
    }
    return jScrollPane;
  }

  /**
  * This method initializes jScrollPaneTextArea
  *
  * @return javax.swing.JScrollPane
  */
  private JScrollPane getJScrollPaneTextArea() {
    if (jScrollPaneTextArea == null) {
      jScrollPaneTextArea = new JScrollPane();
      jScrollPaneTextArea.setBounds(new Rectangle(15, 15, 286, 226));
      jScrollPaneTextArea.setViewportView(getTableText());
    }
    return jScrollPaneTextArea;
  }

  /**
  * This method initializes tableText
  *
  * @return javax.swing.tableText
  */
  private JTextArea getTableText() {
    if (tableText == null) {
      tableText = new JTextArea();
    }
    return tableText;
  }

  private void tableUpdate() {

    BufferedReader textInput = new BufferedReader(new StringReader(
          tableText.getText()
        ));

    ArrayList<String[]> list = new ArrayList<String[]>();
    String line = null;
    String[] arrayline = null;

    try {

      while ((line = textInput.readLine()) != null) {
        arrayline = line.split(",");
        list.add(arrayline);
      }
      textInput.close();

      String[] colName = list.get(0);

      list.remove(0);
      String[][] dataMatrix = list.toArray(new String[0][0]);

      tableModel.setDataVector(dataMatrix, colName);

    } catch (IOException e) {

    }

  }

  private void textUpdate() {

    String textUpdated = "";

    for (int j = 0; j < tableModel.getColumnCount(); j++) {
      if (j != tableModel.getColumnCount() - 1) {
        textUpdated =
          textUpdated + tableModel.getColumnName(j) + ",";
      } else {
        textUpdated =
          textUpdated + tableModel.getColumnName(j) + "\n";
      }
    }

    for (int i = 0; i < tableModel.getRowCount(); i++) {
      for (int j = 0; j < tableModel.getColumnCount(); j++) {
        if (j != tableModel.getColumnCount() - 1) {
          textUpdated =
            textUpdated + tableModel.getValueAt(i, j) + ",";
        } else {
          textUpdated =
            textUpdated + tableModel.getValueAt(i, j) + "\n";
        }
      }
    }

    tableText.setText(textUpdated);

  }

}

一般化線型モデルの復習

仮定

確率分布

確率変数 $Y_i$ が互いに独立に canonical form の指数型分布族、
\[
f_{Y_i}(y_i)=\exp\left\{ [y_i \theta_i - b(\theta_i)] / \phi^2 - c(y_i, \phi) \right\},
\] に従う事を仮定する ($Y_i \overset{\rm{i.i.d.}}{\sim} f_{Y_i}(y_i)$)。
また、$b(\theta_i)$ および $\phi^2$ は、仮定した確率分布によって "決まっている" 事に注意する必要がある (例えば、ポアソン分布を仮定した場合、$\phi^2=1$)。

リンク関数

確率変数 $Y_i$ の期待値を $E[Y_i]=\mu_i$ と書く。
この期待値に対して、既知のリンク関数、$g(\cdot)$、を用いて
\[
g(\mu_i)={\bf x}_i^{\mathrm t}\boldsymbol{\beta},
\] を仮定する。
${\bf x}_i$ は各標本のデザインベクトル、$\boldsymbol{\beta}$ はパラメータベクトルである。

対数尤度関数

対数尤度関数は、
\[
l=\sum_{i=1}^{n} [y_i \theta_i - b(\theta_i)] / \phi^2 - \sum_{i=1}^{n} c(y_i, \phi),
\] と書くことができる。

$\theta_i$ に対する尤度方程式から得られる性質

確率変数 $Y_i$ の期待値

$\theta_i$ をパラメータと見なし、スコア関数の期待値が $0$ になるという性質、
\[
\mathrm{E}\left[ \left\{ Y_i - \frac{\partial b(\theta_i)}{\partial \theta_i} \right\} \bigg/ \phi^2 \right] = 0
\] から、
\[
\mathrm{E}[Y_i]=\mu_i=\frac{\partial b(\theta_i)}{\partial \theta_i},
\] が分かる。

確率変数 $Y_i$ の分散

Fisher 情報行列の性質、
\[
\mathrm{Var}\left[ \left\{ Y_i - \frac{\partial b(\theta_i)}{\partial \theta_i} \right\} \bigg/ \phi^2 \right] = -\mathrm{E}\left[ -\frac{1}{\phi^2} \frac{\partial^2 b(\theta_i)}{\partial \theta_i^2} \right],
\] から、
\[
\mathrm{Var}(Y_i)=
\phi^2 \frac{\partial^2 b(\theta_i)}{\partial \theta_i^2} \equiv \phi^2 v(\mu_i),
\] であり、$v(\mu_i)$ は分散関数とも呼ばれている。

$\boldsymbol{\beta}$ の最尤推定

$\boldsymbol{\beta}$ に対するスコア関数は、
\[
\begin{align*}
\frac{\partial l}{\partial \boldsymbol{\beta}} &=
\frac{1}{\phi^2} \sum_{i=1}^{n} \left\{ y_i \frac{\partial \theta_i}{\partial \boldsymbol{\beta}} - \frac{\partial b(\theta_i)}{\partial \theta_i}\frac{\partial \theta_i}{\partial \boldsymbol{\beta}} \right\} \\ &=
\frac{1}{\phi^2} \sum_{i=1}^{n} (y_i - \mu_i) \frac{\partial \theta_i}{\partial \mu_i} \frac{\partial \mu_i}{\partial \bf{\beta}} \\ &=
\frac{1}{\phi^2} \sum_{i=1}^{n} (y_i - \mu_i) \frac{1}{v(\mu_i)} \left(\frac{\partial g(\mu_i)}{\partial \mu_i}\right)^{-1}{\bf x}_i \\ &=
\frac{1}{\phi^2} \sum_{i=1}^{n} (y_i - \mu_i) w_i \delta_i {\bf x}_i
\end{align*}
\] である。ただし、
\[
\delta_i = \frac{\partial g(\mu_i)}{\partial \mu_i}
\] であり、
\[
\frac{\partial \theta_i}{\partial \mu_i}=\left( \frac{\partial \mu_i}{\partial \theta_i}\right)^{-1}=\frac{1}{v(\mu_i)}
\] \[
\frac{\partial \mu_i}{\partial \boldsymbol{\beta}}= \frac{\partial \mu_i}{\partial g(\mu_i)}\frac{\partial g(\mu_i)}{\partial \boldsymbol{\beta}}= \left(\frac{\partial g(\mu_i)}{\partial \mu_i}\right)^{-1}\frac{\partial {\bf x}_i^{\mathrm t}\boldsymbol{\beta}}{\partial \boldsymbol{\beta}}= \left(\frac{\partial g(\mu_i)}{\partial \mu_i}\right)^{-1}{\bf x}_i
\] を用いた。
行列を用いて書くと、
\[
\frac{\partial l}{\partial \boldsymbol{\beta}}= \frac{1}{\phi^2}\bf{X}^{\rm{t}}\bf{W}\boldsymbol{\Delta}(\bf{y} - \boldsymbol{\mu})
\] であり、
\[
\frac{\partial l}{\partial \boldsymbol{\beta}} \bigg|_{\boldsymbol{\beta}=\hat{\boldsymbol{\beta}}} = \bf{0}
\] を満たす解、$\hat{\boldsymbol{\beta}}$、が最尤推定量である。
解析的に解けない場合の方がたぶん多い。

対数尤度関数の二階偏導関数は、
\[
\frac{\partial^2 l}{\partial \boldsymbol{\beta} \partial \boldsymbol{\beta}^{\rm{t}}} = -\frac{1}{\phi^2} \bf{X}^{\rm{t}} \bf{W} \boldsymbol{\Delta} \frac{\partial}{\partial \boldsymbol{\beta}^{\rm{t}}} (\bf{y} - {\boldsymbol \mu}) + \rm{\frac{1}{\phi^2}} \bf{X}^{\rm{t}} \frac{\partial \bf{W} \boldsymbol{\Delta}}{\partial \boldsymbol{\beta}^{\rm{t}}} (\bf{y} - \boldsymbol{\mu})
\] である。
これについて期待値をとり、マイナスを付けると
\[
I(\boldsymbol{\beta}) = -\mathrm{E}\left[ \frac{\partial^2 l}{\partial \boldsymbol{\beta} \partial \boldsymbol{\beta}^{\rm{t}}} \right]= \frac{1}{\phi^2} \bf{X}^{\rm{t}}\bf{W}\boldsymbol{\Delta}\frac{\partial \boldsymbol{\mu}}{\partial \boldsymbol{\beta}^{\rm{t}}} + \bf{0}= \rm{\frac{1}{\phi^2}} \bf{X}^{\rm{t}}{\bf W}\boldsymbol{\Delta}{\boldsymbol \Delta}^{-1}{\bf X} = \rm{\frac{1}{\phi^2}} \bf{X}^{\rm{t}}\bf{W}\bf{X}
\] が得られる。

追記

間違ってたら怖いな、特にベクトル二階偏微分のあたりを見直そう。
あとは、quasi-likelihood についても復習しようかな。