OmniAICreator/Qiita-1.07M huggingface dataset:
sinatra development?について

# まえがき
sinatraを使っててそりゃそうだわ、という単純な理解ミスをしていたので
戒めとして記事にしておく


# sinatraのメソッド
sinatraでdevelopmentで起動したときにのみ分岐させる方法で下記記述がある。

```Ruby:クラシックスタイル
require 'sinatra'
require 'sinatra/reloder' if development?

get '/' do
  'hello world'
end
```

これはわかりやすいと思って僕も導入した
実際に書いたのが下記だ

```Ruby:モジュラースタイル
require 'sinatra/base'
require 'sinatra/reloder' if development?

class App < Sinatra::Base
  get '/' do
    'hello world'
  end
end

#=> undefined method `development?' for main:Object (NoMethodError)
```
上記書き方だとそんなメソッドはありませんと怒られる
rubyを嗜んでる方は速攻気づいて何やっってんねんと突っ込まれそうだが僕は最初気づかず
なにか別の方法があるのかな？とか思ってた

この原因はsinatraのクラシックスタイルなのかモジュラースタイルなのかの差分だ
sinatraのコードを見ながら説明しよう

# クラシックスタイルの動作
クラシックスタイルのrequire時の動作を追っていくことでこの謎は解明する
クラシックスタイルでは下記のような形でsinatraをrequireする。

```ruby
require 'sinatra'
```
上記は内部でさらに'sinatra/main.rb'を読んでいる。

そのmain.rbにこのような記述がある。

https://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb

```ruby
# include would include the module in Object 
# extend only extends the `main` object 
extend Sinatra::Delegator
```
この記述はコメントの通り、`main` オブジェクトにSinatra::Delegatorのメソッドを追加している。
ではこのDelegatorの中身を見てみよう

https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb

```ruby
module Delegator #:nodoc:
  def self.delegate(*methods)
    methods.each do |method_name|
      define_method(method_name) do |*args, &block|
        return super(*args, &block) if respond_to? method_name
        Delegator.target.send(method_name, *args, &block)
      end
      private method_name
    end
  end
  delegate :get, :patch, :put, :post, :delete, :head, :options, :link, :unlink,
	   :template, :layout, :before, :after, :error, :not_found, :configure,
	   :set, :mime_type, :enable, :disable, :use, :development?, :test?,
	   :production?, :helpers, :settings, :register

  class << self
    attr_accessor :target
  end

  self.target = Application
end
```
このコードが実施していることは `main` オブジェクトにdelegateへ渡したsymbolの名前のメソッド群を生成している
そのメソッドの呼び出し先はSinatra::Applicationの同名メソッドだ
ちなみにApplicationクラスはBaseを継承しているので正確にいうとSinatra::Baseの同名メソッドを呼んでいる

```ruby
class Application < Base

  set :logging, Proc.new { !test? } 
  set :method_override, true 
  set :run, Proc.new { !test? } 
  set :app_file, nil 

  def self.register(*extensions, &block) #:nodoc: 
    added_methods = extensions.flat_map(&:public_instance_methods) 
    Delegator.delegate(*added_methods) 
    super(*extensions, &block) 
  end 
end 
```

つまり、冒頭のdevelopment?はSinatra::Base#development?を読んでいることになる。
また、`main` オブジェクトにdevelopment?というメソッドを生成している為
自分では記述していないのに該当のメソッドが使えるというわけだ（get等も同様）

モジュラースタイルの場合、上記動作はしないため、`main` オブジェクトには何も生成されない
よってdevelopment?なんてないよというエラーになるのである

ただrequireしてるだけなのに、こうも動作が変わる
Rubyの黒魔術恐ろしい


# おまけ
development?ってなに比較してるの？と気になる方向け
動作は下記だ

```ruby
def development?; environment == :development end
def production?;  environment == :production  end
def test?;        environment == :test        end
```
それぞれenvironmentの比較をしている
environmentには下記が入ってる。

```ruby
set :environment, (ENV['APP_ENV'] || ENV['RACK_ENV'] || :development).to_sym
```
環境変数APP_ENVかRACK_ENVの値をsymbolで格納している
何も入っていなければdevelopmentになる。
Laravel 五十音順でコレクションを取得する

#やりたいこ
- 五十音順に並び替えてコレクションを取得する
- name_kanaが NULL場合は、nameの五十音順でデータをけつにつける

#参考記事
SQLで検索する時、空白やNULLのデータを後ろに並べたい
https://qiita.com/AkihikoIkeda/items/0f926f023b06066dc759
#確認環境
- Laravel5.6
- PHP7.3
- MySQL 5.6.39

#コード
```php
<?php

namespace App\Http\Controllers;
use App\User;

class UserController extends Controller
{
    const PAGINATION_PER_PAGE = 50;
    
    $users = User::orderBy(DB::raw(
    "case when name_kana is NULL then '2'" . // 1. NULLの場合は2番目
    " when name_kana = '' then '1'" .        // 2. '' の場合は1番目
    " else '0' end, " .                      // 3. 値が入っていたら0番目
    "name_kana, " .                          // 4. ひらがな五十音順 *1
    "name"                                   // 5. 記号、数字、アルファベット、ひらがな(カナ)、漢字の順
    ))->paginate(self::PAGINATION_PER_PAGE);
}
```

#要点
```php
// 一行で書くと…
$users = User::orderBy(DB::raw("case when name_kana is NULL then '2' when name_kana = '' then '1' else '0' end, name_kana, name"))->paginate(self::PAGINATION_PER_PAGE);
```

#やったこと
- コレクションを取得してsortBy('name_kana')とか…　だめだった。
- *1の記述がないと、適当なならびにならなかった。
nodenv経由でインストールしたnodeにyarnをインストール

タイトルのとおりです

[nodenv-yarn-install](https://github.com/pine/nodenv-yarn-install)を使って、yarnを`.nodenv/plugins`以下にインストールします。

フォルダがなければ以下のコマンドを実行して作成(もともとあれば必要ありません)

```
mkdir -p "$(nodenv root)/plugins"
```

その後、[nodenv-yarn-install](https://github.com/pine/nodenv-yarn-install)をそのフォルダの中にダウンロード

```
$ git clone https://github.com/pine/nodenv-yarn-install.git "$(nodenv root)/plugins/nodenv-yarn-install"
```

このプラグインはあくまでnodenv経由でnodeをインストールしたときに、一緒にyarnもインストールするというものなので、この時点ではyarnはインストールされていません。
なので、すでにnodeがnodenv経由でインストールされている場合は、他のバージョンをインストールするか今のバージョンを再インストールします。今回は後者でやります。

以下のコマンドを実行。(`.nodenv/plugins`以下に`node-build`というプラグインがなければエラーが出るかも)

```
nodenv uninstall 11.11.0
nodenv install 11.11.0
```

すると、nodeのあとに自動的にyarnがインストールされます。



##確認

```
yarn -v
1.13.0

which yarn
/Users/[USER_NAME]/.nodenv/shims/yarn
```
node、npmのコマンドの場所がわけわからなくなってたのでnodenvで整理した

brew経由やらndenvやらでnodeやnpmの場所が複雑になっていたので
[nodenv](https://github.com/nodenv/nodenv#how-nodenv-hooks-into-your-shell)1本に絞って、node関連の管理を整備した。

homebrew経由のnodeやnpmをアンインストール (デフォルトでは`/usr/local/bin`に入っている)

```
brew uninstall npm
brew uninstall node
```


[nodenv](https://github.com/nodenv/nodenv#how-nodenv-hooks-into-your-shell)経由でnode、npmを管理する。
[nodenv-installer](https://github.com/nodenv/nodenv-installer#nodenv-installer)というのを使えば自動でインストールしてくれるらしいが、今回はマニュアルインストールする
ホームディレクトリで

```
git clone https://github.com/nodenv/nodenv.git ~/.nodenv
```
こうすると、ホームディレクトリに`./nodenv`フォルダが作られ、これからはnode関連(バージョン、パッケージ、コマンド、パス)においてこのフォルダ以下のことだけ考えれば良い。

オプションとして、以下のコマンドを入力すると、nodenvの処理が早くなる。

```
cd ~/.nodenv && src/configure && make -C src
```

インストールしたコマンドにパスを通す

```
echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile
```

続いて、`.bash_profile`に`eval "$(nodenv init -)"`を加える
`nodenv init`はnodenvをいい感じに設定してくれるコマンド

ターミナル再起動

ここで一旦、パスが通っているか確認

```
echo $PATH
```
で、`/Users/[YOUR_USER]/.nodenv/shims:/Users/[YOUR_USER]/.nodenv/bin:`という感じで追加されていればOK

正しくインストールされているか診断

```
curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash

Checking for `nodenv' in PATH: /Users/[YOUR_USER]/.nodenv/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /usr/local/bin/nodenv-install (node-build 4.4.4)
Counting installed Node versions: none
  There aren't any Node versions installed under `/Users/[YOUR_USER]/.nodenv/versions'.
  You can install Node versions like so: nodenv install 2.2.4
Auditing installed plugins: OK
```
OKになっていれば完了。

その後、nodenv経由で簡単に各バージョンのnodeがインストールできるコマンドを提供する、[node-build](https://github.com/nodenv/node-build#readme)もインストールしておく。
ここでもまたhomebrew経由でインストールできるが、今回はnodenvのプラグインとして`.nodenv`フォルダ下にインストールする

```
mkdir -p "$(nodenv root)"/plugins
git clone https://github.com/nodenv/node-build.git "$(nodenv root)"/plugins/node-build
```

これでやっとnodenvのインストールが完了。
ここからようやく、nodenv経由でnodeをインストールする。

```
nodenv install -l
```
で、インストールできるnodeのバージョンが一覧で表示されるので、自分が欲しいものをインストール。

```
nodenv install 11.11.0
```

`node -v`で確認しようとすると、

```
nodenv: node: command not found

The `node' command exists in these Node versions:
  11.11.0
```
というメッセージが出た。これはインストールしたnodeがグローバルに設定されていないからで、以下のコマンドで設定する。

```
nodenv global 11.11.0
node -v
v11.11.0
```

以上でnodenvでのnode環境の設定完了。

最終確認

```
which node 
/Users/[YOUR_USER]/.nodenv/shims/node

which npm
/Users/[YOUR_USER]/.nodenv/shims/npm

nodenv versions
* 11.11.0 (set by /Users/[YOUR_USER]/.nodenv/version)
```

これで、これからは.nodenvフォルダ以下だけをみてnode関連(バージョン、パッケージ、コマンド、パス)を管理していけば良くなった。
macでgnu-sedを使う

gnu-sedをインストール(元々macにはsedが入っているが、これを使った方がコマンドが簡潔らしいです)
```$ brew install gnu-sed```

テキストファイルを作成
```$ vim fruits.txt```

```text:fruits.txt
orange
banana
apple
grape
```

```$ gsed -i “s/orange/orange melon/g” fruits.txt```

変更できてるか確認
```$ vim fruits.txt```

```text:fruits.txt
orange melon
banana
apple
grape
```

おまけ
.shファイルで更新してみた

```$ vim a.sh```

```sh:a.sh
#!/bin/sh
used -i "s/apple/applepen/g" fruits.txt
```

を作成して、

```$ ./a.sh```

を実行

参考：
https://qiita.com/akameco/items/804970cd6655e69cc537
http://blog.katty.in/1352
http://zashikiro.hateblo.jp/entry/2012/09/22/125953
CSS だけでアスペクト比を維持しながら幅と高さをビューポートに合わせる (IE11, Edge 対応)

タイトルを一見すると「なんだ、よくある記事じゃん」と思われるかもしれませんが、違います。よくある内容ではないのです…。
結局、自力で解決することになりました…。

# 1. 目的

![image.png](https://qiita-image-store.s3.amazonaws.com/0/232067/75870afd-2827-d138-6af3-597817815c02.png)

上の画像のように、ある要素のアスペクト比を維持しつつ、ブラウザの画面サイズ (ビューポートのサイズ) に合わせてギリギリの大きさに表示したいとします。

「幅に合わせて高さを変える」記事ならあるのですが、幅と高さの両方を考慮するものは見当たりませんでした…。

# 2. やり方

## 2.1. 方法1: `object-fit: contain;` を使う

<font color="#f88">※この方法は、特定の要素かつ IE と Edge を除いたブラウザでのみ使用することができます</font>

これは `<img>` や `<video>`, `<canvas>` などの置換要素と呼ばれる要素でのみ使用することができます。

参考「[object-fit - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/object-fit)」

以下は `<canvas>` での例です。

```html:方法1&#058;&nbsp;object-fit&#058;&nbsp;contain;&nbsp;を使う
<style>
html, body, div {
  margin: 0;
  padding: 0;
}

html, body {
  width: 100%;
  height: 100%;
}

#content {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
</style>

<canvas id="content" width="1600" height="1200">
</canvas>

<!-- 可視化 -->
<script>
const canvas = document.getElementById('content');
const context = canvas.getContext('2d');
context.fillStyle = '#000';
context.fillRect(0, 0, 1600, 1200);
context.fillStyle = '#cfc';
context.fillRect(20, 20, 1600 - 20 * 2, 1200 - 20 * 2);
</script>
```

Chrome や Firefox など、大体のブラウザでは思い通りに動作しますが、IE と Edge は上手くいきません。
(IE はともかく Edge で動かないことはちょっと気になります…。)

JS を使用するなら以下のような Polyfill がありますが、今回は JS に頼らない方法を探してみました。

参考「[GitHub - bfred-it/object-fit-images: 🗻 Polyfill object-fit/object-position on <img>: IE9, IE10, IE11, Edge, Safari, ...](https://github.com/bfred-it/object-fit-images)」

## 2.2. 方法2: `vw`, `vh` と `max-width`, `max-height` を合わせて使う

`width` に `vh`、`height` に `vw` を指定すれば行けるのでは…？ と思ったら本当に行けました…！
ただしそのままでは幅と高さの大きいほうが画面外にハミだしてしまうので、`max-width`, `max-height` で制限する必要があります。

以下は `<div>` での例です。他の要素でも同様にできると思います。

```html:方法2&#058;&nbsp;vw,&nbsp;vh&nbsp;と&nbsp;max-width,&nbsp;max-height&nbsp;を合わせて使う
<style>
html, body, div {
  margin: 0;
  padding: 0;
}

html, body {
  width: 100%;
  height: 100%;
}

#wrapper {
  width: 100%;
  height: 100%;
  /* 上下左右中央寄せ */
  display: flex;
  justify-content: center;
  align-items: center;
}

#content {
  max-width: 100vw;
  max-height: 100vh;
  width: calc(100vh * 4 / 3);
  height: calc(100vw * 3 / 4);
  /* 可視化 */
  background-color: #ffc;
  border: 10px solid #000;
  box-sizing: border-box;
}
</style>

<div id="wrapper">
  <div id="content">
  </div>
</div>
```

`object-fit: contain;` と違って自動で中央寄せにはなってくれないので、ここではフレックスボックスにして簡単に中央寄せしています (※ IE11, Edge でも動作します) 。

アスペクト比に対応した大きさになるように、ここでは `calc()` 関数を用いました。`vh` と `vw` を逆に指定しているのもポイントです。

もしアスペクト比が 1:1 固定なら `vmin` が使えるのですが、1:1 でないと単純な `100vw` と `100vh` の比較だけでは上手くいかないので、実用的ではないかなと思います…。

(蛇足になりますが、上記の二つの例では可視化するときのボーダーの太さがそろっていません。単にサンプルコードの手を抜いているだけなので、リサイズが上手くいかずにハミだしたりしているわけではないです…。)

# 3. まとめ

欲を言えば「ビューポートに合わせる」だけではなく、「任意の親要素に合わせる」ところまでやりたかったのですが、難しそうだったのであきらめました…。

IE は段階的にサポートを終了していますし、Edge はいずれ `object-fit` に対応すると思うので、将来的には「方法1」の方がスマートでしょうが、それまではとりあえず「方法2」を使うといいと思います。
Visual Studio Codeで今開いているファイルのフルパスを統合ターミナルに渡す

## 手順

キーバインドに下記を追加し、ctrl+shift+tを押す。

```json
{
  "key": "ctrl+shift+t",
  "command": "workbench.action.terminal.sendSequence",
  "args": { "text": "'${file}'" }
}
```

## 結果

確認環境はWindows 10 / Visual Studio Code 1.32.1

現在testfile.mdを開いている。

![test1.PNG](https://qiita-image-store.s3.amazonaws.com/0/198108/eb4c803a-1f4b-517e-8ecc-4d684295bf9c.png)

ctrl+shift+tを押すと、

![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/198108/3d5d7d9d-8c72-92a6-857a-3537d0625dcc.png)

現在開いてるファイルのフルパスが統合ターミナルに入力される。


## 参考

How to refer to current file from Integrated Terminal in Visual Studio Code
https://stackoverflow.com/questions/46004397/how-to-refer-to-current-file-from-integrated-terminal-in-visual-studio-code
NuxtでKeycloakの初期化タイミングが遅くて困る場合

# はじめに

KeycloakのJavaScript Adapterを使っているとき、Keycloakの初期化がiframe経由になって若干遅い。そうするとまだAccess Tokenが取れていないのに`asyncData`が呼ばれて悲しいことになる。なんとかしたい。

# 対応

https://qiita.com/takyam/items/40067c3f7de2e041e378 にあるようにNuxtのPlugin初期化はawaitをつけて呼ばれるので、Promiseを返すようにすればKeycloakの初期化まで待つようにできる。

keycloak-jsには`onReady`というキーが取れて準備完了したら呼ばれるコールバックがあるので、そのタイミングで解決させれば良い。

# 例

pluginsディレクトリにこんなのを置いてnuxt.config.jsで使うようにする。ここではkeycloak-jsを直接使わずにvue-keycloak-jsを使った。

```JavaScript:plugins/keycloak.js
import Vue from "vue";
import VueKeycloak from "@dsb-norge/vue-keycloak-js";

export default function({ app, env, isServer }) {
  if (isServer) {
    return true;
  }

  const pluginInstalled = new Promise((resolve, reject) => {
    Vue.use(VueKeycloak, {
      config: env.keycloakConfig,
      onReady: function(keycloak) {
        resolve(keycloak);
      }
    });
  });

  return pluginInstalled;
}
```

べんり。
The Vision/統計・機械学習日誌～斯くして、私はデータサイエンティストになるのか～

# 統計学を学びはじめる　#1

こんちは！
本日から、統計の学習を進めていきましょう。！

本日は第1回なので、

⑴宣伝
⑵目標
⑶統計学習の進め方
⑷学ぶべき理論と実装（Python、R）の手順　



を主に説明するって感じで進めていこうかと。






因みに筆者のスペックは[リンク](https://qiita.com/earthcontrol)を参照。

　
　

[YouTubeもみてね☆](https://www.youtube.com/watch?v=BgTe0wE58po&list=PLk7eC6WqGi90InQsnVF5OyBETvCiJNKz8&index=2)





あい、⑴終わり。次いきまっしょう！



⑵
まず統計の学習するにあたってなんですが、
　

目標設定として前半は、統計検定2級程度（大学課程1、2年程度）を目指していこうかと思います。

後半は、いざ、実践を通してKaggleやっていきましょう。たまに集計を簡単にする意味でExcel使います。

この程度の知識があれば、データ分析職についた時の最初の2週間程度はお話についていけるからです。

えっ？たった2週間だって。そうなんです。たった2週間分しかついていけないそうなんです（データサイエンティスト友人5名談）
理由としては、業務内容にもよりますが、ほとんどの分析計の業務は

”未知のデータに対しての解析や、解析した結果の実装、果てには論文の実装”

までこなすことがたいていの業務で行っているからなんだって。

つまり、大学生の学ぶ統計なんてのはマジで一歩目に過ぎないのですね。
いやーなんともお金稼ぐのは大変だこと。

というわけで、そのぐらいのことだと思ってサクッと気合入れて頑張っていきましょう。


⑶進め方なんですが、以下の4冊使って進めます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/377205/86e2af5a-bc78-abf8-707f-64a6450b36d3.png)


[大学4年間の統計学が10時間でざっと学べる]



これは、導入にはぴったり。1～2週間毎日1時間読めば2周はできます。ここで貯金を作りましょう。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/377205/1d0c73b8-5c93-5cd7-b692-96fcab4943ca.png)


[スバラシク実力がつくと評判の統計学キャンパス・ゼミ―大学の数学がこんなに分かる!単位なんて楽に取れる!](https://www.amazon.co.jp/%E3%82%B9%E3%83%90%E3%83%A9%E3%82%B7%E3%82%AF%E5%AE%9F%E5%8A%9B%E3%81%8C%E3%81%A4%E3%81%8F%E3%81%A8%E8%A9%95%E5%88%A4%E3%81%AE%E7%B5%B1%E8%A8%88%E5%AD%A6%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%91%E3%82%B9%E3%83%BB%E3%82%BC%E3%83%9F%E2%80%95%E5%A4%A7%E5%AD%A6%E3%81%AE%E6%95%B0%E5%AD%A6%E3%81%8C%E3%81%93%E3%82%93%E3%81%AA%E3%81%AB%E5%88%86%E3%81%8B%E3%82%8B-%E5%8D%98%E4%BD%8D%E3%81%AA%E3%82%93%E3%81%A6%E6%A5%BD%E3%81%AB%E5%8F%96%E3%82%8C%E3%82%8B-%E9%A6%AC%E5%A0%B4-%E6%95%AC%E4%B9%8B/dp/4944178778)

大学生の間では有名ですが、なぜか持っていると後ろ指をさされます笑

簡単な教科書に逃げようとなんだろうと、最後は知識を得たものが勝者です。



恐れず取り組み毎日90分1か月程度で終えましょう。


特にF分布と呼ばれる推定の分野は説明が簡潔になっているので、あまり突っ込まず、数式に慣れることベースで進みます。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/377205/80487da5-ce50-81d9-878a-e5a1a8280c18.png)

[改訂版 日本統計学会公式認定 統計検定2級対応 統計学基礎](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E7%89%88-%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A%E5%85%AC%E5%BC%8F%E8%AA%8D%E5%AE%9A-%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A2%E7%B4%9A%E5%AF%BE%E5%BF%9C-%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%9F%BA%E7%A4%8E-%E7%94%B0%E4%B8%AD%E8%B1%8A/dp/4489022271/ref=pd_lpo_sbs_14_img_1?_encoding=UTF8&psc=1&refRID=8PEZDYY9GTP1QJ11WK79)

最後は体系的に演習を通して学びます。
説明がざっぱな点もあるので、そこをこの記事で補ってきます。


以上の流れより、基本的には
用語、考えになれる⇒数式になれる⇒理論・使い方になれる
の方針で行きます。
やはり、最後は問題演習のアウトプットが必要ですよね！


⑷実装
⑵の後半にも書きましたが、具体的な実装はKaggleのデータを使って行ってきます。
使い方や進め方なんかは、後々書いてきます。興味ある方はどんどん進めていきましょう。


本日はこんなとこで。



Go beyond the limits!
【Processing】つくばエクスプレスの一日

# 概要
・授業の課題
・つくばエクスプレス（TX）の一日の動きを描写的にみれるのは地味に面白い
![tx.gif](https://qiita-image-store.s3.amazonaws.com/0/377231/e40b862c-6007-4106-eb87-1d34dd6774e2.gif)

・黒：各駅停車
・赤：急行
・青：準急行
・緑：忘れた
![tx.jpg](https://qiita-image-store.s3.amazonaws.com/0/377231/1fc80ca6-ed59-6b84-d4bc-850a9e7684b6.jpeg)

・朝と夕方にかけて頻繁に出ているのがわかる．
・コード一式は[Github](https://github.com/shutokawabata0723/TX_simulator)へ
・入力は，時刻表と航空写真
flask-sqlalchemyでhelloworldしたい

# 目的
* DB読み込み結果をflaskで表示したい
* 2レコード取得する
* 参考サイトのサンプルを改変
* cssは使わない
* android(termux)でテスト
* windowsやraspiとはちがうかも

# 構成
```
+--- hellosqlite.py
+--- setupdb.py ...事前にDB作成する用のpy
+--- templates
     +--- hellosqlite.html
+--- static ...空
```
# 結果
降順ソートを試したのでworldが先に出る。

### Hello,Alchemy World!
* world!
* hello!

# hellosqlite.py

* flask_sqlalchemy だと降順のorder byが```order_by(Word.id.desc()```だった。

```
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy 

app = Flask(__name__)

# DB設定
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hellosqlite.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)


# db.Model を継承して Word クラスを定義
class Word(db.Model):
	__tablename__ = 'words'
	id = db.Column(db.Integer, primary_key=True)
	word = db.Column(db.String(10))

	def __init__(self, id , word):
		self.id = id
		self.word = word


@app.route("/")
def hello():
    # wordsをid降順で取得
    words = Word.query.order_by(Word.id.desc()).all()
    print(words[0])
    print(words[1])
    
    # テンプレートにwordsを渡す
    return render_template('hellosqlite.html', words=words)

if __name__ == '__main__':
	app.run(debug=True)

```

# hellosqlite.html

```
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello,Alchemy World!</title>
</head>
<body>
  <div>
    <h1>Hello,Alchemy World!</h1>
    <!-- ul でwordsを表示 -->
    <ul>
    <!-- 配列 words の件数分、li の表示を繰り返す -->
    {% for worddata in words %}
      <li>{{ worddata.word }}!</li>
    {% endfor %}
    </ul>
  </div>
</body>
</html>
```

# setupdb.py

```
#setup

# DB 周りを import
from hellosqlite import db, Word

# DB ファイル本体を作成し、テーブル作成まで行う
db.create_all()

# word のリストを作成
word_list = [(1,'hello'),(2,'world')]
words = [Word(d[0],d[1]) for d in word_list]


# 複数インサート
db.session.add_all(words)
db.session.commit()
```

# 参考
https://blog.mobming839.net/entry/flask-sqlalchemy-tutorial-02
仮想通貨を使ったサービスのアーキテクチャを真剣に考える

仮想通貨を使用したサービスについての記事が存在する中、ほとんどの記事は、非集権的なアーキテクチャを取っており、実際のプロダクションベースのサービスに多い集権的なサービスについては全く考えていない。そこで、仮想通貨について、また英語で書かれた集権的なサービス構築方法などを調べ尽くした私が解説したい。

## 仮想通貨の仕組み
まず、account basedの仮想通貨(代表例ethereum),UTXO basedの仮想通貨(代表例 bitcoin)が存在することを事前に確認したい。ここでは詳しく解説しない。

## 両タイプの通貨共通

## 開発言語はこれを選べ！
開発言語選択についてのtipsについては、Node.jsを選べこれ一択しかない。理由としては、仮想通貨の開発チームが提供するライブラリのほとんどがnode.jsで書かれているからだ。サービスを早く開発したい、特にスタートアップにとっては、一からライブラリを書くなど愚行であるから、特に留意したい。

## Nodeは、絶対自分で立てるな！
仮想通貨のNodeのコストはブロックチェーンの特性上、日々上がり続けている、つまり、自分で建てればメンテナンスなども考えると無駄でしかない。代わりにblockexploerを使え、なおBlock explorerは、bitpayなど信頼されているものに限る。しかし、サービスが成長している場合は例外でnodeを立てても良いと思う、理由はチェーンが改竄されている可能性が否定できないからだ。

## NodeのJSON-RPCは、絶対に使うな！
前章に関係するが、秘密鍵を伴う機能(アドレス生成、送金)を使って開発する場合は、NodeのJSON-RPCを使えば確かに早く開発でき楽である。しかし、これには問題があり、Nodeを直接バックエンドととして利用Nodeは、秘密鍵を保持するこれは簡単に外部からアクセスして、覗き放題である。つまり、容易にGoxしてしまう。

##送金はサイン済みのHEX形式の文字列をblockexploerに投げろ！
サーバー内でデータベース上に暗号化された状態で保存した秘密鍵を用いてサインしたトランザクションを生成し、block Explorerに投げることで、秘密鍵に関わるハッキングを防げるのである

##追記中
## 実際の手順

##UTXO basedの場合
Falseの証明（その2）

Coqで、次の述語を考えてみます。

```coq
Inductive is0P : nat -> Prop := is0P_0 : is0P 0.
```

`is0P`は、「自然数が0である」という意味の述語になります。

# `is0P 1 -> False`の証明

`is0P 1`は成り立たないのですが、`not (is0P 1)`すなわち`is0P 1 -> False`を証明してみましょう。

通常の方法で証明すると次のようになります。

```coq
Example not01 : is0P 1 -> False.
Proof.
  intros. inversion H.
Qed.
```

証明項を直接作ろうとすると次のようになります。

```coq
fun H : is0P 1 =>
  match H in (is0P n)
    return
      match n with
        | 0 => True
        | S _ => False
      end 
    with
      | is0P_0 => I
  end
    : is0P 1 -> False
```

なぜこれで証明ができるのかを、私の理解している範囲で説明します。`match`は次の順番で処理されているようです。

1. `match H ...`となっているので`H`の型から対応する`Inductive`を割り出し、コンストラクタを思い出す
2. 1.で思い出したコンストラクタのすべてが`with`の後に来ていることを確認。`H`の型は`is0P 1`なのでコンストラクタは`is0P_0`のみ。
3. コンストラクタ毎に指定された式を分岐と呼ぶ。この場合は`I`のみ。
4. それぞれの分岐が`in ... return ...`で指定された型になっているかを確認する。`in`と`return`を使って分岐の型を確認する方法は後述する。ここでは`I`が`in ... return ...`で指定された型になっている。
5. `H`の型と`in ...`を見比べて`return ...`に出てくる`n`を求める。この場合、`H`の型は`is0P 1`で、`in`で指定されているのは`is0P n`なのでこれらを見比べると`n`は`1`となる。
6. 5.で求めた`n`を`return ...`に当てはめて、この`match`式の型とする。今回は、`return`で指定された部分の`n`を`1`とすることで、型は`match 1 with
        | 0 => True
        | S _ => False
      end`となる。これは`Check`コマンド等では`False`と表示される式である。

上記の手順で使っている「分岐の型の確認方法」は次の通り。

1. 分岐に対応するパターンの型と`in ...`を見比べる。今回は、パターンは`is0P_0`でその型は`is0P 0`である。また、`in`には`is0P n`が指定されているので`n`は`0`となる。
2. 1.で求めた`n`を`return ...`に当てはめて、分岐の型とする。この場合は、`match 0 with
        | 0 => True
        | S _ => False
      end`となる。
3. 2.で求めた型を分岐が持っているかを確かめる。この場合は`I`が`match 0 with
        | 0 => True
        | S _ => False
      end`という型かを調べ、OKということになる。

`return ...`で指定する式は変数`n`を含んでいて、分岐の型を確認する際には分岐毎に`n`の値を変えながら確認するというのがポイントのようです。
if式の基本

# if式
ある条件に沿って処理が分かれることを**『条件分岐』**と言います。
if式は条件分岐で使用される制御構造の一つです。

## 基本の形

```
if 条件式 then
　条件に当てはまった時に行って欲しい動作
end
```
**注意点**
<br>endを必ずつけること。endが無いとエラーが出ます。

**example**
<br>

入力

```
i=5
if i>0 then
 puts("#{i}は正の整数です。") #見やすいように、行頭を字下げ（インデント）しておく
end
```
出力<br>

```
5は正の整数です。
```

## 条件に当てはまらない場合の動作も設定する
先ほどの例では条件に当てはまる場合のみの出力でした。<br>
条件に当てはまらない場合の動作も設定してみましょう。
### if ~ elseを使う
そのような場合、`else`を使用します。
### 基本の形
```
if 条件式　then
　条件に当てはまった時に行って欲しい動作
else
　条件に当てはまらなかった時に行って欲しい動作
end
```
- 条件に当てはまった場合の行動をif以下に
- 条件に当てはまらなかった場合の行動をelse以下に記入します

**example**<br>
入力

```
puts("数字を入力して下さい")
number = gets.to_i #gets.to_iは1行だけ整数を取得してくれるメソッド
if number>5 then
  puts("#{number}は5よりも大きい")
else
  puts("#{number}は5以下")
end
```

出力

```
数字を入力して下さい
7
7は5よりも大きい
```
```
数字を入力して下さい
2
2は5以下
```
### 行って欲しい動作が３つ以上
さらに動作を分岐させたいときは、`elsif`を使用します。
<br>

**注意点**
<br>
elseifではなく、`elsif`です。

### 基本の形
```
if 条件式1 then
 行って欲しい動作
elsif 条件式2 then
 行って欲しい動作
else
 条件2に当てはまらなかった時に行って欲しい動作
end
```
**example**
<br>

入力

```
puts("数字を入力して下さい")
number = gets.to_i
if number>5 then
  puts("#{number}は5よりも大きい")
elsif number<5 then
  puts("#{number}は5よりも小さい")
else
  puts("#{number}です")
end
```
出力

```
数字を入力して下さい
7
7は5よりも大きい
```
```
数字を入力して下さい
2
2は5よりも小さい
```
```
数字を入力して下さい
5
5です
```

条件が多くなってくると分かりにくいですが、分岐を一つ一つ丁寧に考えていきましょう。
ubuntuでNight Shift(暖色画面)ができないときの対策法

ubuntuでNightShiftにできなかったので調査しました．

参照は[こちら](https://www.computercorrect.com/2018/operating-systems/linux/ubuntu/ubuntu-night-light-tips-tweaks/)．

また，ubuntuのバージョンは18.04.1 LTSです．

# dconf-editorのインストール

```terminal
sudo apt install dconf-editor
```

# dconf-editorの実行

```terminal
dconf-editor
```

# 設定場所
実際に実行すると下のようなウィンドウが出るので，

org/gnome/settings-daemon/plugins/color/night-light-temperature

の順に進む．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/355593/7b198145-774c-3cf0-2009-6b054ae4ff92.png)

# 色調の変更
Custom Valueの値を小さくすると色があたたかくなり，大きくすると冷たい色になる．デフォルトは4000なので，3000から3500くらいの値が良いと思います．

# 設定の変更
次にUbuntuの設定画面を開き，Devicesを選択し，Night LightをOnにすることで無事NightShiftできるようになります．
DataFrameを整形して表示する


### DataFrameのデータを整形したい
Pandasを使っているとDataFrameのデータをそのままmarkdownに貼りたいとか、slackに貼りたいって時がって、その時に使います。

```python

import pandas as pd
from tabulate import tabulate


df=pd.DataFrame.from_dict({
    'A': [1,2,3],
    'B': [4,5,6],
    'C': [7,8,9],
    })

print(tabulate(df, df.columns,tablefmt='github', showindex=False))

```

```
#出力結果
|   A |   B |   C |
|-----|-----|-----|
|   1 |   4 |   7 |
|   2 |   5 |   8 |
|   3 |   6 |   9 |
```

これでデータをメール、チャットに貼り付けたりしてる。

- [tabulate](https://pypi.org/project/tabulate/)
PostCSS 入門

![スクリーンショット 2019-03-15 11.04.45.png](https://qiita-image-store.s3.amazonaws.com/0/242655/0d2e8766-bfe9-9e08-ed23-7048ebeb06d4.png)

# PostCSS とは
- [PostCSS · A tool for transforming CSS with JavaScript](https://postcss.org/)
- PostCSS自体は、CSSパーサの機能のみを提供する
- プラグインを利用し、CSSを加工したり、構文チェックを行う

# おすすめプラグイン

- [Autoprefixer](https://github.com/postcss/autoprefixer)
最も有名なPostCSSプラグイン。
指定されたブラウザ対応に必要なベンダープリフィックスの付与を自動的に行うことができる。

- [PostCSS Flexbugs Fixes](https://github.com/luisrudge/postcss-flexbugs-fixes)
Flex Boxの記述方法によっては、ブラウザのバグによりうまく反映されない場合があるため、
ブラウザのバグを防ぐ記述に変換する

- [cssnano](https://qiita.com/syannu/items/3f04f0e962df42cf25f7)
CSSを圧縮することができる

- [stylelint](https://stylelint.io/)
CSSの文法チェック用プラグイン。
stylelintのプラグインを追加することで、文法チェックのルールを追加できる。

# とりあえず使ってみる
```console:
$ npm init -y
$ npm install --save-dev postcss-cli autoprefixer
$ npx postcss src/**/*.css --use autoprefixer -d src
```

# 設定を行う

```JavaScript:.postcssrc.js

module.exports = ctx => {
  return {
    plugins: {
      'autoprefixer': {
        // 'env': ,
        // 'cascade': true,
        'cascade': false,
        // 'add': true,
        // 'remove': true,
        'remove': false,
        // 'supports': true,
        // 'flexbox': true,
        // 'grid': false,
        // 'stats':,
        // 'browsers': ,
      }
    }
  }
}
```
```:.browserslistrc
last 4 versions
```

```console:
$ npx postcss src/**/*.css -d src
```
PostCSSは、自動的に.postcssrc.jsを参照するため、CLIで使用するプラグインを指定しなくてよい。

# サンプルコード
https://github.com/ohnaka0410/nodejs-samples/tree/main/postcss

# 最後に
実践編はこちら
　→ [PostCSS 実践](https://qiita.com/ohnaka0410/items/b54a2d3efe93eb786a46)
【UiPath】ライセンス費用一覧

- UiPath Studio Named User・・・＊円～＊円
- UiPath Studio Node Locked・・・＊円～＊円
- UiPath Attended Robot Named User・・・＊円～＊円
- UiPath Attended Robot Node Locked・・・＊円～＊円
- UiPath Attended Robot Concurrent・・・＊円～＊円
- UiPath Unattended Robot Node Locked・・・＊円～＊円
- UiPath Unattended Robot Concurrent・・・＊円～＊円
- UiPath Orchestrator・・・*円～*円


※価格情報はUiPath社要請により非開示となりました。

## 参考リンク
※それぞれのライセンス区分の詳細や、ライセンスを安く買う方法については下記のリンクを参照。

RPAコンサルティング合同会社 - UiPathライセンスについて
https://www.rpacons.com/blog/cons/License
【超初心者】GCP上のWordpressのHTTPS対応とテーマ変更などの備忘録

##もくじ
・4日目（どうでもいい部分）
・Let's Encryptを用いて[GCP](https://console.cloud.google.com/start?hl=ja)上のWordpressをHTTPS対応（ググった通り）
・Wordpressのテーマ変更（Cocoon）（ググった通り）
・それ以外の諸々初期設定（ググった通り）
・終わりに

#4日目
4日目です。
昨日は更新が出来ませんでした。

そう。
あの[春の悪魔達](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%AE%E8%8A%B1%E7%B2%89%E7%97%87)のせいです。
昨日は死ぬかと思いました。

と言う訳で、昨日8時間睡眠を取得した僕は、気力に満ち溢れています。~~**今なら何だってできる。**~~

冗談はともかく、昨日やろうと思って出来なかったSSL対応などを実践していきたいと思います。
Google検索して実施したところ、**びっくりするほど無価値な記事**になってしまいました。申し訳ございません・・・。

#Let's Encryptを用いて[GCP](https://console.cloud.google.com/start?hl=ja)上のWordpressをHTTPS対応
HTTPS対応のためには、通常、第三者機関にお金を払ってサーバ認証の証明書等を発行してもらう必要があるようですが、
2015年頃からLet's Encryptという無料のサーバ証明書発行のシステムが人気のようです。

[Wikiの記事](https://ja.wikipedia.org/wiki/Let%27s_Encrypt)を読んでみると、MozillaやGoogleなどが出資して全てのWebページの暗号化を目指したプロジェクトのようですね。
それまで手作業だった認証書発行プロセスを自動化し、**無償で**サーバ証明書を発行しているようです。
本当、世界のIT企業の皆さんは一体何をどう考えてこのようなプロジェクトを進められているのでしょうかね。ほんとすごい。

では早速1つずつやっていこう・・・と思ったのですが、ググるとあまりにも参考になる記事が多いので、寸分違わずこちらの通りにやりました。非常に分かりやすかったです。
[参考とさせていただいた記事：「GCPで作成したWordpressのSSL対応」](https://qiita.com/Yuya_Nishizaki/items/4a2413fc2c07aca5d193)
10分も掛からずに終わりました。ありがとうございます。

唯一間違えたところは、下記の証明書作成時でした。
自分のサイトのURLを`www.yourdomain.com`のようにしていたのですが、下記のまま実行してしまい・・・

```
./certbot-auto certonly --webroot -w /var/www/html/ -d yourdomain.com
```

この結果・・・

```
Challenge failed for domain yourdomain.com
http-01 challenge for yourdomain.com
Cleaning up challenges
Some challenges have failed.
```

と怒られてしまいました。。
`www.`が足りなかったのですね。
これを修正して・・・

```
./certbot-auto certonly --webroot -w /var/www/html/ -d www.yourdomain.com
```

とすれば無事うまく進みました。
とりあえず進んだので良しとします。
![GCP004.png](https://qiita-image-store.s3.amazonaws.com/0/329008/42de05d5-de9a-0c03-3b63-4b498950c6a9.png)
ということでHTTPS化されました！！

#Wordpressのテーマ変更
続いてはテーマ変更に挑戦です。
Wordpressはテーマ変更することで見栄えを簡単に変えられるのがメリットと聞きます。
この辺りは、もともとの社内で利用する際にもよく言われていたところ。積極的に勉強していきたいところです。

ひとまずブログを書けるようにすべく、人気そうな無料テーマを活用させて頂くことにしました。
Cocoonと言うテーマがおすすめされていたので、下記手順の通りに実施してみます。
[Cocoonテーマをインストールする方法](https://wp-cocoon.com/theme-install/)
あっけなく2分ほどで完了・・・。

#それ以外の諸々初期設定（ググった通り）
####アクセス解析（[Google Analytics](https://marketingplatform.google.com/about/)）の導入
とりあえず入れておいた方が後々楽しいということで。
どのページを何人が見てくれたか、等が分かるようになるらしいですね。
これも[ご説明のページ](https://wp-cocoon.com/google-analytics/)がありましたのでその通りに・・・。

####パーマリンク設定
もう脳死状態で[こちら](https://wp-cocoon.com/permalink-setting/)の通りにやりました。

####サイト名と説明文の編集
直感で書き換えてみました。
![GCP007.png](https://qiita-image-store.s3.amazonaws.com/0/329008/07b6042c-ded8-ac14-79b0-e576bf00e8cf.png)
とりあえずブログっぽい何かを目指してみようと思います。
![GCP008.png](https://qiita-image-store.s3.amazonaws.com/0/329008/a2290ae1-6e00-82ae-acf8-7e397efa28b7.png)

#終わりに
そんなこんなで、とりあえず日記を垂れ流すような場が出来上がりました。
4日目となりますが、実質作業に掛けた時間は1時間ちょっとのような気がします。
世間で言われるような[GCP](https://console.cloud.google.com/start?hl=ja)自体のメリットを活かしていない気もしますが、とにかくワンクリックでWordpressが使える事は非常に楽でした。

Qiitaに技術レベル最底辺の記事を投稿してしまって、ただただ申し訳ない限りですが、自分の備忘録的には大変役に立っています。。

今後は勉強内容等もなるべく今回作ってみた日記帳に書いていこうと思っていますが、ちゃんと技術的な内容が書けるようになったら、今度こそQiitaに投降したいですね。
今後も、ただ皆様の記事を読むだけではなく、自ら手を動かして触ることを意識して、スキルを身に付けられるようにしていきたいと思います。
ではでは。
自然言語処理を用いたチャットボット開発の流れ

##概要
自然言語とは、日本語や英語などの我々が普段使う言語のこと
自然言語処理（NLP Natural Language Processing)とは、自然言語をコンピュータで処理する技術のこと

##使われているところ
・検索エンジン
・機械翻訳
・予測変換
・スパムフィルタ
・音声アシスタント
・小説の執筆
・対話システム
など

##自然言語処理の技術
######形態素解析
・文書を単語に分割する技術
######word2vec
・文書内での関係性を踏まえて、単語をベクトル化する技術
######リカレントニューラルネットワーク(RNN)
・時系列を扱うのが得意なニューラルネットワークの一種
######seq2seq
・RNNをベースとした、文章を生成可能なモデル

##チャットボット開発の流れ(機械学習型)
###前処理
大量の対話文コーパスを用意する
コーパスは大きいほどいいが、学習に時間がかかるのが難点
以下は収集元の例
・研究所や大学が提供するコーパス
・青空文庫などにある著作権フリー文庫
・SNSのログ
・顧客とのやりとりのログ
データがデジタルであれば様々な文書からコーパスを収集することができる
###学習過程
RNNなどのニューラルネットワークを構築する
ニューラルネットワークに対話文コーパスを学習させる
###システム構築
学習済みのニューラルネットワークを使って、チャットボットのシステムを構築する
##チャットボットのプラットフォーム
Colaboratoryに構築
コマンドラインに構築
サーバーに構築し、APIとして呼び出す
スマホアプリとして
音声認識、発生が可能なIoT機器に
Dialogflowなどの既存のサービスを使うのもあり

##ニューラルネットワーク
####RNN Recurrent Neural Networkとは
時系列データを扱うニューラルネットワーク
中間層の出力が再帰的に行われる

###キーワード
####バックプロパケーション
順伝搬：予測
逆伝搬：学習

####one-hot表現
分散表現
####word2vecのニューラルネットワーク
CBOW(continuous bag-of-words)
skip-gram

####doc2vecのニューラルネットワーク
dmpv(distributed memory)
DBOW(distributed bag-of-words)

####RNNで扱う時系列データの例
文書、音声データ、音楽、株価、産業機器の状態など

####RNNは再帰型ネットワークともよばれる
中間層の再帰入力を行うことで過去の記憶を保持することができる

####勾配爆発
学習時に相をさかのぼるにつれて勾配が大きくなりすぎる問題
勾配クリッピングが有効

####勾配消失
勾配が小さくなりすぎる問題
LSTMが有効

####LSTM(Long Short-Term Memory)は、RNNの一種
通常のRNNでは、難しい長期の記憶保持が得意
LSTM層では「ゲート」とよばれる仕組みを導入。これにより、過去の情報を「忘れるか忘れないか」を判断しながら、必要な情報だけを次の時刻に引き継ぐことができる

####GRU(Gated Recurrent Unit)は、LSTMを改良したもの
SLTMと比べて、全体的にシンプルな構造で、計算量が少ない
入力ゲートと忘却ゲートが統合され、「更新ゲート(Update gate」になっている
記憶セルと出力ゲートはない
値をゼロにリセットする「リセットゲート(Reset gate)」

##Seq2Seqとは
系列(sequence)を受け取り、別の系列へ変換するモデル
自然言語処理でよく利用される
文章などの入力を圧縮するencoderと、出力を展開するdecoderからなる
機械翻訳、文章要約、対話に使われる

####Seq2Seqによる対話文の生成
大量の対話文コーパスを用意
encoderに文章を入力すると、decoderから返事が出力されるように、Seq2Seqに学習させる
訓練では、ある時刻におけるdecoderの出力が、次の時刻の入力に近づくよう学習を行う(教師強制)
訓練済みのモデルを使用する際は、ある時刻におけるdecoderの出力を次の時刻におけるdecoderの入力として使う

##チャットボットの未来
###チューリングテスト
人工知能の父の一人、アランチューリングによって考案された、ある機会に知性があるかどうかを判定するためのテスト
会話をしている姿の見えない相手が、機械化人間に判別できなければ、このテストにパスしたことになる

###チューリングテストをパスするためには？
訓練のフェーズのみだけではなく、会話中にも学習する
遠い昔の記憶を保持し、必要に応じて取り出す仕組み
バックプロパケーションに代わる、学習の仕組み
ニューラルネットワーク同士が会話し、学習する仕組み
ニューラルネットワークが「内部世界」を持つ
機会に意識を持たせる「人工意識」

######出典元
こちらの記事は以下の学習サイトを元にして作成しました
https://www.udemy.com/ai-nlp-bot/
正規表現とかのメモ

拡張（Perl）正規表現`-P`はMacだと標準では使用できなかったり。。。

```zsh:
find ./ | grep "(?! \.[a-z]+$)\."

echo "fe[eff])(bv#f/e{^w@w}t'_e~f-w ef.ewf.wef." | grep -P "[#@_{([\]\)\}\-\~\^\'\s]"
```
```zsh:正規表現対象として余計なやつを置換えして除外しちゃうやつ
cat list.csv | sed 's/^.\//$HOME\//g' | sed 's/\.[^\.]*$/<EXT>/g'

cat list.csv | sed 's/^.\//$HOME\//g' | sed 's/\.[^\.]*$/<EXT>/g' | grep -P "\]|\_|\."
```

```zsh:先頭の「./」とファイルの拡張子前の「.」を除く文字列中の「.」にマッチする
grep -P '(?!((\.\/)|(\.[^.]*$)))\.'

端末の状態によってクォーテーションが
ダブル（or シングル）じゃないとだめだったり
あと、空ディレクトリは対象外になるので注意
```

```zsh:特定の文字列の前後を対象にする
## ABCDEFGHIJK

(.*)(?=G)
#　「G」の手前が対象
# ABCDEF

(?<=G)(.*)
#　「G」の後が対象
# HIJK
```

```zsh:特定の文字列以外を対象にする
# words を含まない行すべてが対象になる
^(?!.*words).*$
```

# 参考
[正規表現サンプル集](https://www.megasoft.co.jp/mifes/seiki/meta.html)
[正規表現で文字列を含まない、否定の記述 | UX MILK](https://uxmilk.jp/50674)
[bashの変数展開によるファイル名や拡張子の取得 - Qiita](https://qiita.com/mriho/items/b30b3a33e8d2e25e94a8)
[正規表現でクオート文字列をエスケープする - 原色奈良阪](https://narazaka.net/o/konata/computing/re_escape.html)
[sedでダブルクォーテーション・シングルクォーテーションの置換・削除を行う | 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2016/07/sedでダブルクォーテーション・シングルクォーテ-2/)
[grepの-oオプションと-Pオプションの組み合わせが便利 - Gre's Blog](http://greymd.hatenablog.com/entry/2014/09/27/154305)
[ストレイライトエンジニア: 正規表現で特定の文字より前／特定の文字より後を抜き出す](http://straylight-engineer.blogspot.com/2014/01/blog-post.html)

https://style.potepan.com/articles/9251.html
uninitialized constantが出てた原因がモデル作成がうまくいってなかっただけという話

# 初歩的なform_forで躓き、早速くじけそうになる
form_forでフォームを作り、rails sで立ち上げたけど、
何をやっても↓のエラーが表示される・・・:sob:
![スクリーンショット 2019-03-16 0.14.19.png](https://qiita-image-store.s3.amazonaws.com/0/374100/3bd003cb-d194-c0f2-cb5c-2d38cf4249a7.png)

ルーティングがダメなのかも、form_forの書き方がよくないのかも、インスタンス変数が・・・とガチャガチャやってみたけど改善せず、いろんな記事を見て回ってもよくわからず。
わかったことはuninitialized constantが出るということは、「定義したクラスが読み込まれていない」ということ。でも定義したクラスってなんだ・・・


# 原因はモデルが作られていないことがわかった経緯
とりあえず、落ち着いてform_forの機能はなんだったけと振り返ることから再スタート。
form_forはデータベースに書き込む作業。
↓
データベースを取り扱うのは、モデルだったはず。
↓
モデルが正しく作られているか確認しよう。
↓
詳しくはわからないけど、モデル作成する時にファイルがいくつか作られているはず。
↓
とりあえず、app/models/以下に「モデル名+rb」のファイルが作られているか確認
↓
作られていない！多分ここが原因だ！

# つーことで、モデルを作り直す
一番最初にモデルを作成したはずだけど、とりあえず結果として作られてなかったので、作り直し
下記のコードでモデルとテープル設計書（カラム）を作成し、
`$ rails g model モデル名 title:string body:text`

下記の処理が流れたらOK！
![スクリーンショット 2019-03-16 0.41.54.png](https://qiita-image-store.s3.amazonaws.com/0/374100/ffbeff63-3e57-a8b3-f187-f9d98d4aab3f.png)
次に下記のコードでデータベースに反映させ、
`$ rails db:migrate`
下記の処理が流れたら完了！
![スクリーンショット 2019-03-16 0.44.30.png](https://qiita-image-store.s3.amazonaws.com/0/374100/5af1d045-2c40-9adf-7561-8e8823772030.png)

# 表示された！
逸る鼓動を抑えつつ、再度rails sで立ち上げ、当該ページを表示。
![スクリーンショット 2019-03-16 0.47.48.png](https://qiita-image-store.s3.amazonaws.com/0/374100/e944386b-d319-9c07-b6ba-b8deba9dd8ab.png)
わーい！

# 他にも原因がある場合もあるよ
今回の場合、単純にモデルが作成されてないだけでしたが、
他にも原因がある場合があるので、あしからずです。

ちなみに、今回モデルが作成されていなかった原因として考えられるのが
・メモをとることに集中しすぎていて、ターミナルでコードを書いてなかった
（今回は復習用に手順のメモを取りながら開発してた）
・↑の手順メモを見てみたら、モデル作成のコードが間違っていたので、コードを間違えて打っていた

どちらにしてもやばい間違えですね。
今後はきをつけようと思います
はじめてのC++【19日目】

#はじめに
wifi繋がるって最高ですね！
昨日は死ぬかと思った。
昨日のコメントで、「is-a関係とhas-a関係」と「継承よりコンポジション」を聞いたので調べてみました。
##is-a関係とhas-a関係
is-a関係とhas-a関係というのは、一般的な物事の本質を捉えるための分析の仕方、考え方についてのメタファ（隠喩）である。

**is-a関係**
「is-a関係=継承」と言われることがあるが少し違う。
例えば、
・猿と人は哺乳類の一種
・動物と植物は生物の一種
・管楽器と弦楽器は楽器の一種
このように、物事を分析していくことで、その物事の本質をつかもうと分析する```分類法```である。

**has-a関係**
「has-a関係=コンポジション」と言われることがあるが少し違う。
例えば、
・人間は頭、腕、脚、胴体を含んでいる.
　腕は上腕、下腕、手を含んでいる
　手は手の甲、手のひら、指を含んでいる
このように、より小さく物事を分析していくことで、その物事の本質を掴もうとする```分割法```である。

**継承よりコンポジション**

継承よりコンポジションとはどういうことなのか。
派生クラスとは大きく分けて２つある。
機能が明確とした基底クラスを作成して、さらに追加機能を実装したいときに作る派生クラス。
ぼんやりとした機能の基底クラスを作成して、そこからいろいろな機能を明確に記述していく派生クラス。
前者がis-aの継承で後者がhas-aのコンポジションということ。
つまり、後者の方法を使えってこと

(参考文献)
https://qiita.com/mikamikuh@github/items/1cdcd8b25a2e23f10525
https://qiita.com/turanukimaru/items/0b1396393908b7e22618#再利用には継承よりもコンポジションを使うべき


**まとめ**
is-aとhas-aの違いを継承とコンポジションと言われるがこれは間違い。
is-aとhas-aの違いは、**分類法**、**分割法**にあり、継承やコンポジションは表層にすぎない。
is-aは視野を広くして物事の本質をみることで、has-aは視野を狭くして物事の本質をみるって感じかな。
派生クラスを作る多くの場合は、ぼんやりとした機能の基底クラスを作成して、そこからいろいろな機能を明確に記述することをおすすめする。

##ロベールのC++
###07-02 protected　アクセス指定子
privateメンバは派生クラスにも公開されない。
protected　外部には公開されないが、派生クラスには公開される。
C++のアクセス指定子は、publicとprotectedとpublicしかないので、メンバの意味や役割を明確にししっかり使い分ける。

#終わりに
今日は、オブジェクト指向の考え方が
今更ながらコンテナ仮想化を独習する（tensorflow-gpuとjupyter notebookが使えるまで）

# はじめに
注意：ほぼ備忘録で、新しい情報はありません。深く理解したいなら、インターネット上にたくさんある有用な記事を参照しましょう。

## Motivation
[2018年の最先端バックエンドエンジニアに必要なスキルについて考えてみました。](https://qiita.com/poly_soft/items/fb649573c19b7a5c0227)によると、

> 現在業務でまだDockerを使用したことがないという方は強烈な危機感を持った方が良いと思いますし、

とのことだったので（バックエンドエンジニアではないが当該分野は興味あり）。また、研究開発環境が楽に整いそうだとも思ったので。~~もうUbuntu, CUDA, cuDNN, Tensorflowのバージョン合わせは疲れたよ…~~

## コンテナ仮想化
ざっくりいうとVMみたいなもん。VMでは、ホストOSの上にゲストOSを立てる。これに対し、コンテナ仮想化では、ホストOSの上にコンテナエンジン (not OS) があって、複数のコンテナが管理されており、それぞれの中でプロセスを持つ。VMよりイケてると感じたのは、OSからインストールする必要がないことと、競合しそうな環境が共存できること、インターネット上にイメージ（コンテナのもと）が公開されていて動作実績のある環境がすぐに手に入ること。

## Envirionment
- OS: Ubuntu 18.04 LTS
- GPU: NVIDIA GeForce GTX 1080Ti

# セットアップ
## Docker
[Get Docker CE for Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/)を参考にインストール。"Install using the repository"の方。hello-worldコンテナが立ち上がるところまで確認した。

## docker groupの作成
[nvidia-docker でポータブルな機械学習の作業環境を作る](https://qiita.com/legokichi/items/7bf3862569cfca122d73)を参考に、dockerグループを作成し、自分ユーザを追加。これでsudoをつけなくてもdockerのコマンドが叩けるようになった。

## nvidia-docker
[GitHub](https://github.com/NVIDIA/nvidia-docker)のQuickstartを参考に。nvidia-smiがコンテナで実行されるところまで確認した。

## Tensorflow
さて、ネット上の記事でも見ながらDockerfileを書くか…と思いきや、[イメージが公開されている。](https://www.tensorflow.org/install/docker)jupyter notebookも使いたいので、それ込みのimageをpullしてくる。

```bash
$ docker pull tensorflow/tensorflow:nightly-gpu-py3-jupyter
```

eagerモードはlatestでは対応していないらしいので、nightlyのイメージを指定した。

# 実践
## コンテナを立ち上げてみる
```bash
$ docker run -it --rm tensorflow/tensorflow:nightly-gpu-py3-jupyter bash
```
コンテナに入り、bashが立ち上がった。

`docker run --help`でコマンドラインオプションを確認する。

`-i`は`--interactive`. ターミナルの標準入力を開く。
`-t`は`--tty`. 疑似ttyを利用する。つまり、`-it`でターミナルからコンテナを利用できる。
`--rm`オプションはコンテナから抜けると自動的にコンテナを削除する。通常（このオプションを指定しない場合）、bashをexitしてもコンテナは残り続ける。気が付かないうちにコンテナがたっぷり立ち上がっていることもあるので注意。このオプションを付けるか、`--name`オプションでコンテナに名前を付けておくと、前述の悲劇が回避できる。

## jupyter notebookでTensorflowのチュートリアルを遊んでみる
```bash
docker run -it -p 8888:8888 tensorflow/tensorflow:nightly-gpu-py3-jupyter
```

`-p`オプションはポートフォワードをする。

出力されたURL (http://127.0.0.1:8888/?token=...) にブラウザでアクセスし、チュートリアルを進めてみる。それにしても、jupyter notebookはやはり便利。

## ホスト側のディレクトリをマウントする
[公式ドキュメント](https://docs.docker.com/storage/bind-mounts/#choosing-the--v-or---mount-flag)によると、`-v`オプションと`--mount`オプションの両方で実現可能だが、後者を推奨とのこと。

```bash
$ docker run -it --rm --mount type=bind,source="$(pwd)"/work,target=/work -u $(id -u):$(id -g) tensorflow/tensorflow:nightly-gpu-py3-jupyter bash
```
sourceにはホスト側のディレクトリ（絶対パス）、targetにはコンテナ内のディレクトリを指定する。

`-u`オプションはログイン後のユーザ（グループ）を設定する。このオプションがない場合、rootとなる。その状態でファイルを作成すると、ホストに戻ったときもファイルのオーナーがrootになっている。場合によっては不都合が生じることに注意。

## その他、常用しそうなコマンド
```bash
# コンテナを一覧する（-aオプションがないと、動いているコンテナしか見えないので注意）
$ docker ps -a

# コンテナを削除する
$ docker rm CONTAINER

# イメージを削除する
$ docker rmi IMAGE
``` 

# 参考にしたサイト
- [nvidia-docker でポータブルな機械学習の作業環境を作る](https://qiita.com/legokichi/items/7bf3862569cfca122d73)
Angularプロジェクトをブラウザでデバッグするとき、ファイルを簡単に探す方法

## はじめに
この記事では、Angularプロジェクトをブラウザでデバッグする時、ファイルを簡単に探す方法を説明します。一般的に知られているのかもしれませんが、人に教えたら喜ばれたのでどなたかの役に立てば良いなということでメモ。

## 環境
Google Chrome: 73.0.3683.75
Angular CLI: 7.1.4
Angular: 7.1.4

`ng new [プロジェクト名]` で新規作成したプロジェクトを使ってキャプチャを取っています。

## 手順

1.アプリを立ち上げ画面を表示して、Chrome DevTools を開く
2.Sourcesタブを選択して矢印の箇所をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103464/8f882842-380f-a651-9ac5-ac0711319693.png)

3.「Open file」を選択
（2、3の操作はショートカットで可能。Mac は commandキー + P で開く。windowsなら ctrl + P で開く。)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103464/4649349c-936c-fb81-65eb-0a43f5f5bc9e.png)

4.矢印の箇所にファイル名を入力して検索
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103464/cd724c77-6d58-1a07-df52-9bda0816d5f9.png)

## おわりに
以上、小ネタでした。この方法だと `webpack://` 配下を辿るよりだいぶ楽です。でも、IDEでデバッグすればもっと楽なのかな？と思って設定して少し触ってみました。（ちなみにIDEはIntelliJ IDEAを使っています。）

結局、今のところ慣れないし、ブラウザで不便を感じていないのでブラウザでデバッグしています。皆どうしてるんだろう。この辺は好みの問題なのかなぁというのがちょっと気になる。
RHELのisoを使用してyumをする！

# 初めに
RHELに追加でパッケージをインストールしたい！！
だけどインターネットに接続されておらず、
更にDVDドライブもなくメディアも使えない場合に
ローカルのisoファイルからyumを使いたい！！(vm使っているときとか)
そんな時の備忘録
*※rootで作業していますが、気になる方は適宜違うユーザで作業してください*


#前提条件
/root配下にRHEL.isoを配置済みである事
　→WinSCPとかTeratermのsshscp転送とか
　 scpコマンドとかrsyncコマンドとかで適当に配置しておく


#手順

###1．ローカルのRHEL.isoを/mediaにマウントする

```
# mount -o loop -t iso9660 /root/RHEL.iso /media
```

###2．マウント確認

```
# ls -l /media

dr-xr-xr-x.  3 root root   2048 10月 20  2016 EFI
-r--r--r--.  1 root root   8266  4月  4  2014 EULA
-r--r--r--.  1 root root  18092  3月  6  2012 GPL
dr-xr-xr-x.  2 root root   2048 10月 20  2016 LiveOS
dr-xr-xr-x.  2 root root 858112 10月 20  2016 Packages
-r--r--r--.  1 root root   3375  9月 27  2016 RPM-GPG-KEY-redhat-beta
-r--r--r--.  1 root root   3211  9月 27  2016 RPM-GPG-KEY-redhat-release
-r--r--r--.  1 root root   1568 10月 20  2016 TRANS.TBL
dr-xr-xr-x.  4 root root   2048 10月 20  2016 addons
dr-xr-xr-x.  3 root root   2048 10月 20  2016 images
dr-xr-xr-x.  2 root root   2048 10月 20  2016 isolinux
-r--r--r--.  1 root root    114 10月 20  2016 media.repo
dr-xr-xr-x. 24 root root   6144 10月 20  2016 release-notes
dr-xr-xr-x.  2 root root   4096 10月 20  2016 repodata
```

###3．yumリポジトリの追加登録をする
1行目echo～6行目.repoまでコピーして貼り付けてください

```
# echo "[RHEL-Server-DVD]
name=Red Hat Enterprise Linux $releasever - $basearch (DVD)
baseurl=file:///media/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" > /etc/yum.repos.d/RHEL-Server-DVD.repo
```

###4.yumのキャッシュをクリアしておく([RedHat](https://access.redhat.com/solutions/1355683 "RedHat")で推奨みたい)

```
# yum clean all && subscription-manager clean
```

###5.お好きなパッケージをインストール
※3で登録したリポジトリだけを参照する

```
# yum install --disablerepo=\* --enablerepo=RHEL-Server-DVD `お好きなパッケージ名`
```
スプレッド構文を使った可変長引数メモ


よく忘れるので忘れないようにメモメモ。
引数は無限大だぜという事を心に刻みました。

#関数の引数に（...）をたくさんつかいたい

引数の数の制限なしにいろいろくっつけるにはargumentsやらforやら使えばいいじゃないか！
と言われそうなものの、でも使いたいんですよ。としか答えません。
##配列でGo
配列に配列足すならとりあえずpush()しとけ感はありますよね。

```javascript:test.js

 const arry1 = [1,2];
  const arry2 = [3,4];

  arry1.push(...arry2);
  console.log(arry1);　// →[1, 2, 3, 4]
```
(...)をつかうとお手軽andスマート。

##配列で可変長引数
今回は関数にたくさんぶち込みたいので可変長引数として、関数の引数に(...)を入れます。
concatは通用しないぞ！


```javascript:test.js

//  配列についてのスプレッド構文--------
  
  const arry1 = [1,2];
  const arry2 = [3,4];

  function arryMerge (...arry) {
    
//  可変引数で配列をくっつける
    let merged = [];
    arry.forEach((v) => merged.push(...v) );
    console.log(merged);　//　→[1, 2, 3, 4]

//    くっつけたものから数字の一番高いものを抽出
    let max = Math.max(...merged);
    console.log(max);　// →　4

//    配列ををたしてみる
    let sum = merged.reduce((a,b) => a + b );
    console.log(sum);　//　→　10
  }

  arryMerge(arry1,arry2);

```
後半は出来上がった配列をいじって遊んでます。
for文系で一つずつこまめに空の配列に押し込んで行くぜ！
**押し込むときも(...)で細かくするぜ！**

引数受け取ったときに2つの配列を持ってるのでそれをループに回してます。
空のmergedに入れるときにそのままだと配列mergedにさらに配列を2個入れてしまうというよくわからないことになるので、(...v)としてしっかり値を分解して個別に入れてます。

ちなみにmerged.concat(arry)　みたいにconcatでやろうとしても駄目でした。


##スプレッド構文で分解しまくるタイプ
でもforって何か違いますよね？そうじゃないんだよなぁ~。
もっとこう(...)だけで適当に押し込ませてくれないかなぁ~。

ummmmmmmmm....そや！関数に渡す時点で分解しとけばええんや！

```javascript:test.js

  const arry1 = [1,2];
  const arry2 = [3,4];

 function arryMerge0 (...arry) {
   let merged = [];
   merged.push(...arry);
   console.log(merged);
 }

  arryMerge0(...arry1,...arry2); //→[1, 2, 3, 4]

```
ひたすら分解したらpush()オンリーで出来ましたやったね。


##オブジェクトでGo
普通にオブジェクトをくっつけるだけならこんな感じ。

```javascript:test.js
  const objectA = {a:"a"};
  const objectB = {b:"b"};

  let merge = {
    ...objectA,...objectB
  };

  console.log(merge);　//→　{a: "a", b: "b"}
```
引数の数決まってるなら置き換えるだけですね。

##オブジェクトでの可変長引数を試みる

でもやっぱり無限大という言葉に男の子は惹かれるもんですよね。
オブジェクトは配列のpush使えないのでforやらで順々にくっつけられない！
まあそもそももっといい方法あるので…

```javascript:test.js
//  オブジェクトについてのスプレッド構文----

  const objectA = {a:"a"};
  const objectB = {b:"b"};

//  可変引数でオブジェクト同士をつなげる関数
  function objectMerge (...ob) {
    let merged = {};
    Object.assign(merged,...ob);
    console.log(merged);
  }

  objectMerge(objectA,objectB);//　結果　→{a: "a", b: "b"}
```
空のmergedにObject.assignで(...)で細かくして突っ込むだけ。
逆に配列みたいにループ処理入れるとややこしくなりました。

assignを使わなくてもよくなる(...)なのに結果使ってしまったジレンマ。
温故知新。

##おわり
もっといろいろ方法があるとは思いますが、ああ何かしっくり来るという方法でした。
基本的に関数の中で操作するときに(...)を使用しないと、配列・オブジェクトごとに格納できます。
そもそもそんなに可変長引数を使うのかと。
そんなに無限大になにか引っ張って来れるのかと。
でもそんじょそこらの夢を追うバンドマンよりスプレッド構文の方が無限大だと思います。
django#メールを送る

Djanagoはメール送信の機能もありまして、(使っているのはPythonのsmtplibモジュール)ですが、ここで簡単でメモしておきますね。
##setting.pyでEMAILのバラメータを作成
まずはsetting.pyの中に以下のコードを追加しますー

```
EMAIL_HOST='smtp.gmail.com'
EMAIL_HOST_USER='MyExample@gmail.com'
EMAIL_HOST_PASSWORD='MyExamplePassword'
EMAIL_PORT=587
EMAIL_USE_TLS=True
```

send_mailを呼び出しだけです！らくちん！

```
from django.shortcuts import render
from django.http import HttpResponse
from django.core.mail import send_mail

debug=False
def homepage(request):
	try:
		if debug:
			send_mail(
				subject='*****Testing email*******',
				message='Some Text Message',
				from_email='MyExample@gmail.com',
				recipient_list=['MyExample@XXX.jp', 'MyExample2@XXXX.jp'],
				fail_silently=False,

				)
	except Exception as er:
		print(er)
```
3日目: Censoring Representations with Multiple-Adversaries over Random Subspaces

# Censoring Representations with Multiple-Adversaries over Random Subspaces 要約
## 読んだ論文
Censoring Representations with Multiple-Adversaries over Random Subspaces
Yusuke Iwasawa, Kotaro Nakayama, Yutaka Matsuo
https://openreview.net/forum?id=ByuP8yZRb
上記の論文を読んだので簡単にまとめます．ICLR2018のWorkshopにて発表されている様子です（[松尾研究室](https://weblab.t.u-tokyo.ac.jp/iclr2018-workshop%E3%81%AB%E5%BD%93%E7%A0%94%E7%A9%B6%E5%AE%A4%E3%81%AE%E8%AB%96%E6%96%87%E3%81%8C5%E4%BB%B6%E6%8E%A1%E6%8A%9E%E3%81%95%E3%82%8C%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82/)）．
みんな大好き松尾研究室の，岩澤先生の論文です．
## 3行でまとめる
- とあるドメインの情報を抑制しつつ．別ドメインの情報を極力落とさない表現学習の研究分野がある（Censoring Representation Learning）．
- 学習には敵の設定が重要になるがこれが容易ではないので，アンサンブルな敵対手法を提案する．
- 公開データセットの匿名化タスクに適用した結果，分類精度を著しく損なわず，これまでより良い匿名化を実現した．

## 提案手法
### AFL
![20190315_001.png](https://qiita-image-store.s3.amazonaws.com/0/376859/910d2e2e-3ab3-6dd0-bc0d-e3d095fa89a6.png)
AFL(Adversarial Feature Learning)とは，敵対的訓練により特徴表現を制御する表現学習手法である．図中(a)は一般的なAFLモデルである．例えば，前々回あたりでも引用した「[ユーザ敵対型ニューラルネットワーク](https://www.jstage.jst.go.jp/article/tjsai/32/4/32_A-GB5/_article/-char/ja/) [^1]」が良い例で（というか著者が同じで），センサデータから行動認識精度を保ちつつ個人情報を削除した特徴表現を学習したいという事例である．
[^1]: ユーザ敵対型ニューラルネットワーク: ウェアラブルセンサを利用した行動認識におけるユーザ汎化とプライバシーへの配慮のためのユーザ独立な表現の学習手法, 岩澤 有祐, 矢入 郁子, 松尾 豊, 人工知能学会論文誌, 32(4), 2017.

これを図中(a)に当てはめると，入力Xがセンサ生データ，エンコーダEが特徴抽出器，分類器Mが行動認識モデル，弁別器（しっくりこないがDiscriminatorのこと）Dが個人認識モデルとなる．Mの損失関数$L_M(R)$と，Dの損失関数$L_M(R)$は一般的な分類器のように最小化される．一方，Eの損失関数$L_E(X)$は，$L_M(E(X))$を最大化，$L_D(E(X))$を最小化するように学習する．
要するに，行動認識精度を上げつつ，個人認識精度を下げるようにX->Rを変換するエンコーダを学習する．それと敵対するようにDも学習する．と，競い合うことで当初の目的を達成するのである．
### MARS
図中(b)が本稿の提案するMARS(Multiple Adversaries over Random Subspaces)の構造である．図を見れば一目瞭然だが，Dをアンサンブルにすることによって，Dに柔軟性をもたせる．今回はEによって出力される特徴ベクトルRからk個の特徴をランダムに抽出して，複数のDを構築し，それぞれのDの損失関数を最小化する．最終的には複数の損失の平均をとっている様子．
![20190315_002.png](https://qiita-image-store.s3.amazonaws.com/0/376859/cac993f1-2fd9-7640-709c-811e50f9876a.png)
エンコーダの損失関数は式(3)（論文より引用）にて与えられる．第一項が$L_M$を最小化することを示し，第二項（と言っても∑だが）が複数のDの平均損失関数で，これは最大化するために符号が正である．

## 評価実験
### 実験設定
- 3つの公開データセット（Opp-G，Opp-L，USC-HAD）を用いた匿名化タスクで評価を行う．
- Eは3階のConvで実装し，Mはロジスティック回帰でやるらしい．重み係数ラムダはEpochで徐々に増加．
- Dは800unitsのMLPで実装される．

### 実験結果
![20190315_003.png](https://qiita-image-store.s3.amazonaws.com/0/376859/6ba556b7-ef5f-b3ab-6fed-7f1657dbff5e.png)

- 右下以外の3表が個人認識の精度（低いほうが良い）．右下が行動認識の精度（高いほうが良い）．
- 多分横方向（$LR$，$MLP_1$，$MLP_2$，$DNN$）がDのモデル構造？なので，高性能なモデル（$DNN$）において個人認識の精度を抑えられていると，貢献が大きいと思われる．
- そう考えると，State of the artな手法に比べ，全体的にMARSが個人認識精度を下げられていることが確認できる．
- 一方，右下の行動認識精度に着目すると，3データセットどれもNoneの状態から大きな下落はない．
 - 要するに，行動認識精度を下げずに，個人認識精度を下げる表現学習ができている！

## まとめ
- Censoring Representation問題のAFLの手法をアンサンブル手法により改良した提案．
- アイデアはシンプルにも思えるが，やはり論文のレベル（しっかりとした検証）が高い．

## 所管
本日は前提知識（引用論文）があったので，1時間半くらいでまとまりました．松尾研究室から出る論文は論文の書き方としてすごい参考になるので今後もぜひ読んでいきたいところです．もっと積極的に学んでAdversarialな行動認識を研究していきたいなぁと思う次第です．