強化学習について
強化学習について調べた際のメモです。
- 達成したいゴールがあるが、各行動に対する評価は与えられない場合
- 「行動の選択肢」と「報酬」
- 強化学習という名前は脳の学習メカニズムであるオペラント学習に由来する
- 報酬は「連続した行動の結果」に対して与えられる(フィードバックに時間差がある)
- 報酬から各行動に対する評価を自分で与える
- ステップごとの評価を与えなくて良いので教師あり学習よりも複雑な問題を扱える
- 学習に時間がかかる
- 状態S、モデルT(状態遷移の関数)、行動A、報酬Rでモデル化 → Markov Decision Process (MDP)
- 時間的な制約下で報酬を最大化するような、ポリシーπ(S → Aの関数)を獲得する問題
- 時間割引をすることでローリスクな行動ばかり取ってしまうのを防ぐ
- Value Iteration (幅優先探索?), Policy Iteration (深さ優先探索?)
- Q値 = 状態行動価値 = 「状態 s で行動 a を選択後、ずっと最適政策をとりつづけるときの利得の期待値」
- Sarsa
- 実際行動してみて一番価値が大きい行動を探す
- モンテカルロ法
- 報酬が得られるまで行動してみて、報酬を分配して各行動を評価する
- Q-Learning
- Tが不要
- 期待値(実際の報酬)と見込みの差分から学習する → TD学習
- 「状態sを離散化した数」×「行動の種類」の表
- 次の状態の価値を現在推定される値の最大値とする
- 探索と活用のトレードオフ (exploration and exploitation dilemma)
- ε-greedy法、Boltzmann分布を使った方法
- Deep Q-Leaning (DQN)
- A3C (Asynchronous Advantage Actor-Critic): 並列計算、Advantageによる報酬の計算、Actor-Critic
- TRPO, Generalised Advantage Estimator, UNREAL, PPO
Refs
- 強化学習で参考になったサイトまとめ - Qiita
- DQNの生い立ち + Deep Q-NetworkをChainerで書いた - Qiita
- ゼロからDeepまで学ぶ強化学習 - Qiita
- これから強化学習を勉強する人のための「強化学習アルゴリズム・マップ」と、実装例まとめ - Qiita
- Pythonではじめる強化学習 - Qiita
- DQNをKerasとTensorFlowとOpenAI Gymで実装する
- 強化学習入門 ~これから強化学習を学びたい人のための基礎知識~ - Platinum Data Blog by BrainPad
- これさえ読めばすぐに理解できる強化学習の導入と実践 - DeepAge
- 強化学習とは?(What is Reinforcement Learning?)
- 強化学習
- 強化学習で〇×ゲームに強いコンピュータを育てる(深層学習 Deep Learning) | 株式会社フォワードネットワーク
- 強化学習とは?ALPHAGOでも使われている強化学習を丁…|Udemy メディア
- 第1回 強化学習とは|Tech Book Zone Manatee
- 「AlphaGo Zero」の衝撃と強化学習の進化 | 日経 xTECH(クロステック)
- Deep Reinforcement Learning | DeepMind
- Machine Learning for Humans, Part 5: Reinforcement Learning
- Reinforcement Learning: 10 Breakthrough Technologies 2017 - MIT Technology Review
- Beginner's guide to Reinforcement Learning & its implementation in Python
- A brief introduction to reinforcement learning
- Reinforcement Learning Introduction
- Introduction to Learning to Trade with Reinforcement Learning – WildML
- Introduction to Various Reinforcement Learning Algorithms. Part I (Q-Learning, SARSA, DQN, DDPG)
- Deep Reinforcement Learning: Pong from Pixels
- Deep Reinforcement Learning Doesn't Work Yet
- Teaching
- 強化学習入門
- 深層強化学習:ピクセルから『ポン』 – 前編 | POSTD
- CartPoleでQ学習(Q-learning)を実装・解説【Phythonで強化学習:第1回】
- 【強化学習初心者向け】シンプルな実装例で学ぶSARSA法およびモンテカルロ法【CartPoleで棒立て:1ファイルで完結】 - Qiita
- http://sysplan.nams.kyushu-u.ac.jp/gen/papers/paper2012/A_BasisOfRL.pdf
- 強化学習 カテゴリーの記事一覧 - いものやま。
- http://www.sakurai.comp.ae.keio.ac.jp/classes/infosem-class/2009/12RL.pdf
- http://mikilab.doshisha.ac.jp/dia/seminar/2001/pdf/ec_03.pdf
【追記】 - ゼロから始める深層強化学習(NLP2018講演資料)/ Introduction of Deep Reinforcement Learni…
GANについて
GAN(Generative Adversarial Network)について調べた際のメモです。
GANとは
- Ian Goodfellow (@goodfellow_ian)が2014年に発表1
- 生成モデル: 訓練データの分布と生成データの分布が同じになるよう学習
- 訓練データに対してパラメータが小さく、重要な特徴を学習する
- GeneratorとDiscriminatorに分かれる
- Generatorは訓練データと同じようなデータを生成するように学習
- Discriminatorは与えられたデータが訓練のものか、生成されたものかを見分けるように学習
- Generatorの学習 → Discriminatorの学習 → Generatorの学習 → ...、とイタチごっこをする
- Dの学習をk回繰り返したらGを1回学習する、の繰り返し(k=1が多い)
- Generatorはノイズを元にデータを生成する
- DCGAN(Deep Convolutional GAN): CNNを使ったモデル → 画像の生成 (元の論文2ではベッドルームの画像の生成)
- プーリングしない、全結合しない、BatchNormalization、Leaky ReLU
- LAPGAN, SRGAN, pix2pix, StackGAN, SimGAN, 3D-GAN, CycleGAN, DiscoGAN...
- MSEだと平均的な(ぼやけた)画像になる(VAE)が、GANだとシャープな画像が生成できる
- 4Kイメージを8Kにしたり
- 生成した画像に和や差の演算ができる
- Deep Learningで課題である「教師なし学習」「タグ無しデータ」を解決する可能性がある
Refs
- はじめてのGAN
- Generative Adversarial Networks (GAN) とは何か、どんなブレークスルーが期待でき如何なる危険性があるか « Emerging Technology Review
- Generative Adversarial Network とは――トップ研究者が解説 | NVIDIA
- できるだけ丁寧にGANとDCGANを理解する - 午睡二時四十分
- ディープラーニングネットワーク (GAN と Siamese) を組み合わせハイクオリティでリアルなイメージを生成 | Amazon Web Services ブログ
- GAN(と強化学習との関係)
- GANとDCGANの論文を読んだ。 - rkgkpyrk
- 人工知能の注目トレンド「GAN:敵対的生成ネットワーク」とは | ROBOTEER
- GAN(Generative Adversarial Networks)を学習させる際の14のテクニック - Qiita
- 人工知能による画像認識/生成アルゴリズムとして浸透しつつある「GAN」とは | SiTest (サイテスト) ブログ
- [DL輪読会] GAN系の研究まとめ (NIPS2016とICLR2016が中心)
- Conditional GANをchainerで実装した - Qiita
- Conditional DCGANで画像生成 - kumilog.net
- Conditional GANをMNISTとCIFAR-10で試してみる - 緑茶思考ブログ
- NVIDIAら、Conditional GANを用いて任意の画像から2048×1024高解像度のフォトリアリスティックな画像合成モデルを生成できる手法を論文にて発表 | Seamless
- KerasでDCGAN書く - Qiita
- GitHub - eriklindernoren/Keras-GAN: Keras implementations of Generative Adversarial Networks.
- [1701.00160] NIPS 2016 Tutorial: Generative Adversarial Networks
- Chainerで顔イラストの自動生成 - Qiita
- TensorFlowによるDCGANでアイドルの顔画像生成 - すぎゃーんメモ
- なんちゃって!DCGANでコンピュータがリアルな絵を描く - PlayGround
- Chainerを使ってコンピュータにイラストを描かせる - Qiita
VSCodeでのGOPATH設定
{ "go.inferGopath": true, "go.gopath": "/your/path/for/specific/project" }
この順番じゃないとダメ。逆にするとinferGopathがgopathを上書きしてしまう1っぽい。
やっぱり上書きされてしまった。ちゃんとgo.gopathを書いてあげないといけないみたい。。。
{ "go.gopath": "${workspaceRoot}:${workspaceRoot}/vendor" }
-
「Setting go.inferGopath overrides all of the above」– GOPATH in the VS Code Go extension · Microsoft/vscode-go Wiki · GitHub↩
Seq2Seqを使った英日翻訳機
RNN(Recurrent Neural Network)の実例の一つに翻訳機があります。 今回はkerasのRecurrentレイヤーを使い、Seq2Seq(Encoder-Decoder)モデルの英日翻訳機を実装してみます。
データセット
Kerasのexampleでは文字単位での英仏翻訳が行われていますが、今回は英日の翻訳なので田中コーパス1をデータセットとして使い、単語レベルでの翻訳を行います。
1.田中コーパスのダウンロード
$ wget ftp://ftp.monash.edu/pub/nihongo/examples.utf.gz $ gunzip examples.utf.gz
2.整形
田中コーパスのデータは以下のようになっています。
$ head examples.utf A: ムーリエルは20歳になりました。 Muiriel is 20 now.#ID=1282_4707 B: は 二十歳(はたち){20歳} になる[01]{になりました} A: すぐに戻ります。 I will be back soon.#ID=1284_4709 B: 直ぐに{すぐに} 戻る{戻ります} A: すぐに諦めて昼寝をするかも知れない。 I may give up soon and just nap instead.#ID=1300_4727 B: 直ぐに{すぐに} 諦める{諦めて} 昼寝 を 為る(する){する} かも知れない A: 愛してる。 I love you.#ID=1434_4851 B: 愛する{愛してる} A: ログアウトするんじゃなかったよ。 I shouldn't have logged off.#ID=1442_4858 B: ログアウト~ 為る(する){する} の{ん} だ{じゃなかった} よ[01]
このファイルに対し、1) Aの行を抜き出し 2) #以下を取り除いて 3) tabで区切り 4) それぞれ日本語(教師データ)・英語(学習データ)ファイルとして保存します。
(日本語の場合は一文字をデータの最小単位とするため、半角スペースを間にいれました。)
文章のベクトル化
入力である文章はそのままではモデルへの入力として使う事ができません。keras.preprocessing.text.Tokenizerクラスにより文章をベクトルに直します。 (文章の先頭と末尾には系列の先頭・終了を表すタグをつけておきます。)
from keras.preprocessing.text import Tokenizer def load_dataset(file_path): tokenizer = Tokenizer(filters="") texts = [] for line in open(file_path, 'r'): texts.append("<s> " + line.strip() + " </s>") tokenizer.fit_on_texts(texts) return tokenizer.texts_to_sequences(texts), tokenizer train_X, tokenizer_e = load_dataset('tanaka_corpus_e.txt') train_Y, tokenizer_j = load_dataset('tanaka_corpus_j.txt')
これにより、
<s> Muiriel is 20 now. </s>
→[1, 16504, 7, 1851, 170, 2]
<s> ム ー リ エ ル は 2 0 歳 に な り ま し た 。 </s>
→[2, 142, 38, 93, 328, 71, 4, 134, 106, 505, 8, 9, 33, 21, 11, 7, 1, 3]
と表現することができました。
モデル
学習時
Encoderの入力にtrain_Xデータ、Decoderの入力にtrain_Yデータを使い、教師データとしては入力として用いたtrain_Yの一時刻先のデータを使います。
from keras.models import Model from keras.layers import Input, Embedding, Dense, LSTM emb_dim = 256 hid_dim = 256 ## エンコーダ encoder_inputs = Input(shape=(seqX_len,)) # Embed処理: https://keras.io/ja/layers/embeddings/ encoder_embedded = Embedding(word_num_e, emb_dim, mask_zero=True)(encoder_inputs) encoder = LSTM(hid_dim, return_state=True) # 内部状態を返すよう、return_state=Trueとしておく _, state_h, state_c = encoder(encoder_embedded) # outputsは捨てる ## デコーダ decoder_inputs = Input(shape=(seqY_len,)) decoder_embedding = Embedding(word_num_j, emb_dim) decoder_embedded = decoder_embedding(decoder_inputs) decoder = LSTM(hid_dim, return_sequences=True, return_state=True) # 一入力ごとの出力を得るため、return_sequences=Trueとしておく # initial_stateにencoder_statesを与えることでエンコーダとデコーダを繋ぐ decoder_outputs, _, _ = decoder(decoder_embedded, initial_state=encoder_states) decoder_dense = Dense(word_num_j, activation='softmax') decoder_outputs = decoder_dense(decoder_outputs) model = Model([encoder_inputs, decoder_inputs], decoder_outputs) model.compile(optimizer='rmsprop', loss='sparse_categorical_crossentropy')
学習
## 教師データの用意 # 1. 各データ先頭を捨てる next_inputs = train_Y[:, 1:] # 2. 末尾を0でパディングする decoder_target_data = np.hstack((next_inputs, np.zeros((len(train_Y),1), dtype=np.int32))) # 3. 出力は(系列の数, 入力の数, 単語のベクトル)の3次元なので一次元上げる decoder_target_data = np.expand_dims(decoder_target_data, -1) model.fit([train_X, train_Y], decoder_target_data, batch_size=128, epochs=15, verbose=2, validation_split=0.2)
予測時
予測時はt-1時点でのデコーダの出力がtの入力となるため、RNNのループを手で回します。
モデル
# エンコーダ:最終的な状態を返す encoder_model = Model(encoder_inputs, encoder_states) decoder_state_input_h = Input(shape=hid_dim,) decoder_state_input_c = Input(shape=hid_dim,) decoder_state_inputs = [decoder_state_input_h, decoder_state_input_c] decoder_inputs = Input(shape=(1,)) decoder_embedded = decoder_embedding(decoder_inputs) decoder_outputs, state_h, state_c = decoder( decoder_embedded, initial_state=decoder_state_inputs ) decoder_states = [state_h, state_c] decoder_outputs = decoder_dense(decoder_outputs) # デコーダ decoder_model = Model( [decoder_inputs] + decoder_state_inputs, # t-1での出力・状態を受け取る [decoder_outputs] + decoder_states )
出力
def decode_sequence(input_seq): # エンコーダから最終的な状態を得る states_value = encoder_model.predict(input_seq) bos_eos = tokenizer_j.texts_to_sequences(["<s>", "</s>"]) # 最初の入力として先頭文字<s>を与える target_seq = np.array(bos_eos[0]) output_seq = bos_eos[0] # ループを回す while True: # 前回の出力と状態ベクトルで予測 output_tokens, h, c = decoder_model.predict( [target_seq] + states_value ) sampled_token_index = [np.argmax(output_tokens[0, -1, :])] output_seq += sampled_token_index if (sampled_token_index == bos_eos[1] or len(output_seq) > 1000): break # 入力・状態の更新 target_seq = np.array(sampled_token_index) states_value = [h, c] return output_seq detokenizer_e = dict(map(reversed, tokenizer_e.word_index.items())) detokenizer_j = dict(map(reversed, tokenizer_j.word_index.items())) input_seq = pad_sequences([test_X[0]], seqX_len, padding='post') print(' '.join([detokenizer_e[i] for i in test_X[0]])) # 英文 print(' '.join([detokenizer_j[i] for i in decode_sequence(input_seq)])) # 予測 print(' '.join([detokenizer_j[i] for i in test_Y[0]])) # 正解
結果
データセットを50,000にし、5エポック回してみます。
<s> he never makes a show of his learning. </s> <s> 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は 彼 は <s> 彼 は 決 し て 自 分 の 学 識 を 見 せ び ら か せ な い 。 </s>
うーん。。。
コード全体
Next Step
- Attentionモデルの導入
- 日本語を正しくトークナイズ
- 入力を逆から与えてみる
- 日本語と英語だと語順が大きく違うのでうまくいくか疑問
Ref
kerasを使ったreuter記事分類のexampleをなぞる
今回はその中からReuter記事データの分類をしてみます。 基本的にはこちらのexampleに示されているコードをなぞる形です。
kerasのインストール
pythonは3系を使います。
TensorFlowのインストール
keras自身のインストールに先立ち、バックエンドとして使用する機械学習ライブラリをインストールする必要があります。TensorFlowやTheano,CNTKなどから選ぶ事ができますが2、今回はTensorFlowを利用します。
$ sudo apt-get install python3-pip python3-dev $ sudo pip3 install tensorflow
kerasのインストール
$ sudo pip3 install keras
Reuter記事の分類
データセットのロード
from keras.datasets import reuters (x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=1000, test_split=0.2)
記事のデータセットはエンコードされ、配列になっています。それぞれの単語にはデータセット全体の中で頻度の多い方から順にインデックス番号が振られています。
x_train.shape # (8982,) x_train[0][:10] # [1, 4, 2, 2, 9, 697, 2, 111, 8, 25]
引数のnum_words
は最頻出上位○○位の値、test_split
はtrainデータとtestデータの割合(今回は4:1)を指定しています。
データの前処理
入力データ(x)は配列から行列の表現に変換する必要があります。
from keras.preprocessing.text import Tokenizer tokenizer = Tokenizer(num_words=1000) x_train = tokenizer.sequences_to_matrix(x_train, mode='binary') x_test = tokenizer.sequences_to_matrix(x_test, mode='binary')
tokenizer
のイニシャライザには先ほどと同じ値を指定します。sequences_to_matrix
のmode
にbinaryを指定すると、文中にインデックス番号の単語が含まれていれば1、そうでなければ0が値となるベクトルに変換されます。
教師データ(y)はone-hot表現に変換します。
from keras.utils import to_categorical y_train = to_categorical(y_train) y_test = to_categorical(y_test)
モデルの構築
exampleよりもシンプルなモデルにします。出力のサイズ(分類の数)は46です。
from keras.models import Sequential from keras.layers import Dense model = Sequential() model.add(Dense(512, input_shape=(1000,), activation='relu')) model.add(Dense(256, activation='relu')) model.add(Dense(128, activation='relu')) model.add(Dense(46, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
学習
model.fit(x_train, y_train, batch_size=32, epochs=5, verbose=2, validation_data=(x_test, y_test))
(メモ: GCEのn1-standard-1タイプインスタンスで各エポックあたり6s)
評価
score = model.evaluate(x_test, y_test, verbose=0) score[0] # 損失関数の値: 1.0874391948125879 score[1] # 正答率: 0.7738201247191493
コード全体 → reuter_mnist.py · GitHub
疑問
- modeの値にbinary以外を指定するとどうなるんだろう...
Refs
publickeyを使ったsshの設定
1.鍵を用意する
$ ssh-keygen -t rsa
2.公開鍵をインスタンス上の ~/.ssh/authorized_keys
に追記する
$ cat ~/.ssh/ssh_test.pub | ssh ([USER]@)[HOSTNAME] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys"
$ ssh -i ~/.ssh/ssh_test ([USER]@)[HOSTNAME]
4.~/.ssh/config
を設定する
Host ssh-test HostName [HOSTNAME] User [USER] IdentityFile /path/to/home/.ssh/ssh_test
$ ssh ssh-test
Refs
Solrについて
Solrとは
Solr is the popular, blazing-fast, open source enterprise search platform built on Apache Lucene™.
- オープンソースの全文検索エンジン
- 検索プログラムのLuceneがベース
- Standaloneモードとクラウド運用に特化したSolrCloudモードがある
- データセットはcore(standalone)またはcollection(SolrCloud)と呼ばれる
- データをインポートする際スキーマは指定しなくても自動で解析してくれる
- 転置インデックスという方式でインデックスを作成する
- トークナイズの方法には形態素解析やN-gramがある
- SQLのGROUP BYのような検索をする、ファセット機能をもつ
- 地理空間検索ができる
こちらの記事が要点を抑えていてわかりやすいです。
文章を単語ごとに分解する方法。
例:「東京特許許可局」 →「東京」「特許」「許可局」
意味のわからないトークンが作られない一方、例えば「京特」で調べた時に引っかからないという事が起こる。
文章をN文字で機械的に分解する方法。
例:「東京特許許可局」N=2 →「東京」「京特」「特許」「許許」「許可」「可局」
検索する文字に対して漏れなく結果を返せる反面、それが全く関連のないノイズとなりえる。
データソースとトークンの間のM:N関係。
動かしてみる
こちらの記事を参考にdockerで動かしてみます。
$ docker pull solr $ docker run -d --name=solr -p8983:8983 solr
NOTE: docker run
をすると8983ポートでsolrが起動します。もし以下のTutorialのようにSolrCloudを試したい場合は違うポートを繋いでおき、コンテナ内で別プロセスを立ち上げるのが楽です。またその後任意のコマンドを実行する際にはポートを指定する必要があるので注意。
疑問
- Schemaの書き方
- 検索の適合度
- 地理検索機能の実例