mathematikの すうがく ブログ

機械学習とかRとかPythonを中心に書いていく予定です

唐突にRemminaでRDP接続ができなくなった話

Abstruct: 数カ月前の話ですが、突然LinuxからRemminaを通じてRDPでWindowsに接続してもエラーがおきてログインできなくなったことがありました。

コマンドラインでRemminaを起動するとフィンガープリントが不一致であると表示されました。
どうもフィンガープリントが変わったらしく、 ~/.freerdp/known_hostsの該当情報を削除すると接続はできた。


本文
家のLinux PCから家にあるルーターを介してWindows PCにRDP(リモートデスクトップ)でログインしようとしたところ、接続できませんといわれ、ログインできませんでした。
数日前までは特に問題なくログインできていました。
一応以下のサイトで設定を確認しましたが、特に問題はありませんでした。

Enable or Disable the Remote Desktop Firewall Rule: Windows Firewall (WF)


接続エラーということで一旦ファイヤウォールを無効化して接続を試みましたが、やはりログインはできませんでした。

ふと思い立ち、端末(terminal)からRemminaを起動してみました。
以下がそのときの出力です(一部情報はマスクしています。)


math2tik@tgoot:
$remmina
Remmina plugin RDP (type=Protocol) registered.
Remmina plugin RDPF (type=File) registered.
Remmina plugin RDPS (type=Preference) registered.
Remmina plugin SFTP (type=Protocol) registered.
Remmina plugin SSH (type=Protocol) registered.
connected to aaa.aaa.aaa.aaa:port
The host key for aaa.aaa.aaa.aaa has changed
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the host key sent by the remote host is
ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff
Please contact your system administrator.
Add correct host key in ~/.freerdp/known_hosts to get rid of this message.
Host key for aaa.aaa.aaa.aaa has changed and you have requested strict checking.
Host key verification failed.
SSL_write: Failure in SSL library (protocol error?)
Authentication failure, check credentials.
If credentials are valid, the NTLMSSP implementation may be to blame.
^C

これを見るとどうも接続先(Remote)の証明書が過去の情報と違い、通信を切っていたということのようです。
sshでもたまに見るやつです。
でそんなファイル(~/.freerdp/known_hosts)があるのかと確認すると、ありました。


math2tik@tgoot:
$cat ~/.freerdp/known_hosts
aaa.aaa.aaa.aaa 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

幸い一個しか登録されていないので、これを削除します。

math2tik@tgoot:
$rm ~/.freerdp/known_hosts

さらにここから再度RDPでログインします。

math2tik@tgoot:
$remmina
Remmina plugin RDP (type=Protocol) registered.
Remmina plugin RDPF (type=File) registered.
Remmina plugin RDPS (type=Preference) registered.
Remmina plugin SFTP (type=Protocol) registered.
Remmina plugin SSH (type=Protocol) registered.
connected to aaa.aaa.aaa.aaa:port
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: CERTIFICATE NAME MISMATCH! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The hostname used for this connection (aaa.aaa.aaa.aaa)
does not match the name given in the certificate:
user-PC
A valid certificate for the wrong name should NOT be trusted!

これで無事ログインできました。
しかし、なぜ証明書が変わったのか、謎です。
エラーメッセージでは接続エラーみたいな感じで出てくるので、Windows側のファイヤウォールなどの設定が変わったことを疑いました。(エラーの記録を取っていなかった...)
ちょっとだけエラーメッセージが解り難いな、と思いました。

困ったときにはとりあえず詳細な動作ログをみるといいですね〔自戒〕

とりあえず Linux Mint上のMeCabでテキストマイングできるようにする方法

とりあえず Linux Mint上のMeCabでテキストマイングできるようにする方法


メモがてら、Linux Mint上での環境設定の方法を記載します。
ただしこのドキュメントはあくまでも「とりあえず動くようにする」ためのドキュメントです。
例えばMeCabの辞書を生成するためのcsvファイルのフォーマットの意味などについては解説しませんし、現状私も出来ません。
ただ一点「とりあえず単語を単語として認識してもらう」ことに主眼をおいたものです。

機会があればcsvファイルの設定値などについて書きたいと思います。


前提条件
mathのLinux環境は以下のとおりです。

$uname -v -s -r -i
Linux 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64
$mecab --version
mecab of 0.996

 



ユーザー辞書とは


以下のようなテキストを形態素解析しても正しく表示されません。

$mecab
清霜は俺の嫁
清    名詞,固有名詞,地域,国,*,*,清,シン,シン,,
霜    名詞,一般,*,*,*,*,霜,ジモ,ジモ,,
は    助詞,係助詞,*,*,*,*,は,ハ,ワ,,
俺    名詞,代名詞,一般,*,*,*,俺,オレ,オレ,,
の    助詞,連体化,*,*,*,*,の,ノ,ノ,,
嫁    名詞,一般,*,*,*,*,嫁,ヨメ,ヨメ,,
EOS

 
「清霜」を正しく単語として認識されていません。これは由々しき事態です。
よって辞書を更新します。
一般にシステムの辞書とユーザー辞書があるそうです。システムの辞書を壊すと面倒だけでなく、解析そのものもできなくなるので今回はユーザー辞書を更新する方法を取りました。

以下に公式のマニュアルがあります。
参考サイト:単語の追加方法
http://taku910.github.io/mecab/dic.html

本マニュアルのとおりには行かなかったので補足しておきます。
基本的は以下のとおりです。
1. 辞書ファイルの環境の構築
2. 辞書のコンパイル
3. ユーザ辞書の登録
4. mecabの起動
5. 解析の実施



1. 辞書ファイルの環境の構築


作業ディレクトリは ~/Documents/text_mining/mydict/kancolle としました。
必須ファイルは csvファイルです。
内容は以下のようにしました。

$cat mydict_source.csv
清霜,1,1,500,名詞,固有名詞,人名,名,*,*,きよしも,キヨシモ,オレノヨメ


2. 辞書のコンパイル


参考サイトでは「/usr/local/libexec/mecab/mecab-dict-index -d/usr/local/lib/mecab/dic/ipadic -u foo.dic -f euc-jp -t euc-jp foo.csv」となっていますが、私の環境では以下のコマンドで実行しました。

/usr/lib/mecab/mecab-dict-index -d/var/lib/mecab/dic/debian -u kancolle.dic  -f utf-8  -t utf-8   mydict_source.csv

なお、複数dicディレクトリが在るかもしれませんが、MeCabの設定ファイル「/etc/mecabrc」は「/var/lib/mecab/dic/debian」を参照していたので、同様に本コマンドもvar以下のファイルを参照しました。

3. ユーザ辞書の登録

次は2のファイルをMeCabから参照するようにします。参考サイトを参考にします。
設定ファイルは/etc/mecabrcです。まずはこれをホームにコピーします。
別解として/etc/のmecabrcを変更してもいいですが、今回はユーザディレクトリに辞書ファイルをおいているので、こちらの方法を取りました。
cp /etc/mecabrc ~/.mecabrc
次に~/.mecabrcに先ほどの辞書ファイル「kancoole.dic」をuserdicとして追加します。この時パスは「~/」の表記ではなく「絶対パス」でないと駄目です。
以下のような一文を追加します。

userdic = /home/math2tik/Documents/text_mining/mydict/kancolle/kancolle.dic

diffでは以下のようになります。

$diff -U1  /etc/mecabrc  ~/.mecabrc
--- /etc/mecabrc    2013-12-30 08:15:30.000000000 +0900
+++ /home/math2tik/.mecabrc    2015-07-30 03:02:19.911727462 +0900
@@ -8,2 +8,3 @@
 ; userdic = /home/foo/bar/user.dic
+userdic = /home/math2tik/Documents/text_mining/mydict/kancolle/kancolle.dic


4. mecabの起動

ここまでできたらコマンドを起動します。

mecab


5. 解析の実施

解析を実施します。

$mecab
清霜は俺の嫁
清霜    名詞,固有名詞,人名,名,*,*,きよしも,キヨシモ,オレノヨメ
は    助詞,係助詞,*,*,*,*,は,ハ,ワ,,
俺    名詞,代名詞,一般,*,*,*,俺,オレ,オレ,,
の    助詞,連体化,*,*,*,*,の,ノ,ノ,,
嫁    名詞,一般,*,*,*,*,嫁,ヨメ,ヨメ,,
EOS



無事「清霜」を1単語として認識してくれました。

以上です。
これを行えばpythonからimport MeCabした場合でも「清霜」をmath2tikの読めと認識します。

python用 MeCabのインストール

ちょっとハマったのでメモがてら。

前提条件

私はlinux mint 環境です。apt-getでmecabをインストールしています。

またpythonPython 2.7.6です。

 

MeCabのインストール

 

まずはMeCabをインストールする必要があります。

本当はビルドするのが正しいのかもしれませんが、面倒なのでapt-getで私はインストールしました。

すでにMeCabのインストールが終わっている人は「mecab-config」が存在すればスキップして大丈夫です。

 apt-get install mecab
 apt-get install mecab-ipadic
 apt-get install mecab-utils
 apt-get install mecab-ipadic-utf8
 apt-get install libmecab-dev

どうもmecabのインストールだけでは後述するmecab-configが無いためpython用のMeCabをbuild時にエラーになります。

あと「 apt-get install mecab-utils」や「apt-get install mecab-ipadic-utf8 」が必要十分なインストールかは未検証です。本当は必要ないかもしれません。。。。

 

MeCabpython用のライブラリをインストール

公式サイトからMeCabpython用ライブラリを落とします。

以前はgoogle code が公式サイトだったようですが、本サービスの終了に伴い、githubに移動されたようです。

Google Project Hosting

MeCab: Yet Another Part-of-Speech and Morphological Analyzer

 

 

こちらの「perl/ruby/python/java バインディング 」と書かれているところの「ダウンロード」とあるところからGoogle Driveに移動します。

こちらから私は「mecab-python-0.996.tar.gz」を入手して、展開しました。

こちらの「README」に従い、ビルドすると私の時は以下のエラーが発生しました。

$python setup.py build
sh: 1: mecab-config: not found
Traceback (most recent call last):
  File "setup.py", line 13, in <module>
    version = cmd1("mecab-config --version"),
  File "setup.py", line 7, in cmd1
    return os.popen(str).readlines()[0][:-1]
IndexError: list index out of range

mecab-configが無いためエラーとなっている様子です。

ではmecab-configとはなんぞ、とコマンドを実行してみると

mecab-config
The program 'mecab-config' is currently not installed. You can install it by typing:
sudo apt-get install libmecab-dev

といわれます。ですので前述「MeCabのインストール」の

 apt-get install libmecab-dev

 が必要でした。

MeCabのソースからビルドすればそもそもそんなエラーにはぶつからないかもしれません。

そして

python setup.py build

sudo python setup.py install

python test.py

 でビルドとインストールおよびテストの実行が行えました。

短いですが、以上です。

 

sqliteの.dbファイルにsqliteコンソールにはいらずにシェルでデータを確認する方法。

要は

sqlite3 dbname.db 

 

sqliteのコンソール(?)に入ってselect 文などを実行しなくてもシェルでデータが取れますよ、という話。

結論を言えば以下のような感じで行ける。

echo "select * from table;"|sqlite3 ./dbname.db 

 今作っているツイッターのつぶやきデータをsqliteで保存しているので、実際にデータが更新されたかを確認するときに重宝しています。

こんなSQLではDBおじさんに助走をつけてグーパンされそう

以上短いですが。

次はSQLのindexあたりを触れられたらいいな(予定は未定)

Androidでadb pullできないデータをスマフォからパソコンに取り出す方法

統計とは全く関係ない話題ですが。

たまにAndroidアプリをデバッグしている時に、InternalStrageに保存されているファイルについて確認したくなる時がありますよね?

SDカードカードにある場合は

adb pull /sdcard-path/filename .

でPCに転送できますが、InternalStrageの場合は、adb pull はできないと思います。(むしろ出来る場合は僕もすごく助かります!)

僕の記憶の限りでは以前は

adb shell run-as my.package.name dd if=myfile of=outfile

のようにddとかでコピーができていた気がしますが、Nexus7の2013版、Lollipopではどうもddができないようです。

※adb shell run-as <pachagename>  <command>  はpachagenameで指定されたAndroidにインストールされているアプリのandroid::debuggableがtrueに指定されている時、

<command>を「アプリのユーザ」権限で実行するコマンドです。

面倒なので 

adb shell run-as  my.package.name chmod 777 -R . 

をしてもダメでした。(むしろ変なエラーが出るようになりました)

ほかにadb shell で端末にログイン後、run-as でアプリのユーザになってddとかcatしたあとリダイレクトしてもSDカードには書き込めませんでした。

ExternalStrageに対するWriteパーミッションをアプリに与えても状況は変わらず。

では

adb shell run-as my.package.name cat /file-path/filename > out

と、ファイルの内容を出力して内容をPC上にリダイレクトで保存してみました。

しかしファイルのハッシュ値を確認すると端末上のファイルとPCにcatの結果として保存したファイルは別物でした。

嫌な予感がしたのでxxdでファイルの内容を確認したら、Android端末上で「0x0a(\n)」であったのが「0x0d 0x0a(\r\n)」に直されていました。

 かなしみに打ちひしがれながら「adb shell cat \r\n 」と検索をかけると偉い人がすでにやっていました。

stackoverflow.com

偉い人に心のなかで感謝を述べながらsedを利用すると、またまたエラーが()

必殺perl

adb shell run-as my.package.name cat /file-path/filename | perl -ne 's/\r$//' > out

で、無事アプリInternalStrageにあるアプリのディレクトリにあるファイルをコピー出来ました。

TwitterのRTの回数を調べてみた

Rの勉強も兼ねて、TwitterのRT回数をカウントしてみました。

以前からTwitterのつぶやきについて、投稿したあと、投稿してからの経過時間とRT数の関係性について調査したいと思っていました。今回はその過程で経過時間ではなく、時刻とRT数との間に面白い関係性が見えたため、これについて簡単に記事を書きます。

 

測定方法は、自分のタイムラインにあらわれていたつぶやきを中心にいくつかピックアップして、一定時間ごとにRT回数を測定しました。

下のグラフは3月のある金曜日のRT数の時間遷移の様子です。

縦軸にはRT数を少し加工した値を採用しています。

 

f:id:mathematik:20150327003517p:plain

 

複数のつぶやきをのRT回数を見ていましたが、RT数が1万を超えるものと1000程度のものが同時にプロットされるので、各IDのRT数を同じグラフに描くと特徴が掴みにくくなりました。

しかし最大RT回数で割れば各つぶやきを同じ「ものさし」で図れるのではないかと考え、最大RT回数で割りました。このおかげでRT回数と時間の関係性が見やすくなったと思います。

 

例えばID-01のプロットのy軸は

y=(RT回数)/(ID-01のRT回数の最大値)

 

とRT回数の最大値でID-01の測定した各RT数を割っています。

このように各IDごとにIDごとの最大RT数で測定した各RT数を割っています。

 

 

15時ごろから測定を開始しましたが、一旦1時頃にRTの伸びは一旦緩やかになり、1時以降はほとんどされなくなります。

そして8時頃から再びRTが増え始めます。

つまり多くの人が23時以降からTwitterから離れ始め、1時ごろから就寝、8時頃に起床という生活パターンをしている人が多い、のかもしれません。

 

当然このつぶやきは「旬」を過ぎたRTであり、時間経過と共にRTの伸びがゆっくりになります。

一部IDが抜けていますが、RT数が極端に少なく、ほぼy=1のようにx軸に並行にあるようなつぶやきがいくつかあったのでいくつか棄却しています。

 

今回少し各RT数を最大RT数で割ることに手間取りました。

やってみれば割と単純でした。

イマイチRのデータ選択の方法がわかっていなかったのが原因でした。

 基本は以下のようなコマンドで行いました。

> rtdata=read.table("twdata.tsv",sep="\t",header=T)
> library(ggplot2)
> library(digest)

> for(i in 1:length(rtdata$id)){
+      rtdata$dived.rt[i]=rtdata$rt[i]/max(rtdata[rtdata$id==rtdata$id[i],"rt"])
+ }

> ggplot(rtdata,aes(x=daytime,y=dived.rt,colour=id))+geom_line()

 

 

 

 

Rで分析しようとしてちょっとハマった

データサイエンティストになりたいと考え最近Rの勉強をしたりしています。

 

一行目とは全く関係ないですが、最近9G近く準備しているLinux Mintのswapに空きが恒常的に0で、気持ち悪いのでいろいろやっています。

sudo sysctl vm.swappiness=10

を実行しましたが、swapサイズに変化がありませんでした。
swapoff -aをしてswapon -aをするといいよ、という記事を見たので早速実行してみると、確かにswapの割り当てが減っていっている。

 

が、

 

 

お、遅い。

 

 

swapのサイズ減少が遅々として進みません。

どれくらいかかるのか気になってRの勉強も兼ねて計算することにしました。

$date +%s;free

というコマンドを複数回実行して、現在時刻とswapのサイズを取得、データを加工して、Rでtsv形式にして読み込んでみました。(今までは計算はLibreOfficeのCalcでやってました)

 

$cat ~/swapsize.tsv
time    swap
1426429000    8812360
1426429006    8811788
1426429012    8809144
1426429015    8808752
1426429019    8803304
1426429029    8798456

 

 

これを以下の様にRで読み込みます。

> swapsize=read.table("~/swapsize.tsv",sep="\t",header=T)

で、time-swapsizeのグラフを描いて回帰曲線も描いてみます。

 

> ggplot(swapsize,aes(x=time,y=swap))+
+ geom_point()+
+ theme_bw(16)+
+ geom_smooth(method="lm")

 

するとこんなグラフに

 

f:id:mathematik:20150316130441p:plain

 

何かがおかしい。多分青い線はx軸ではなく、回帰直線。

おそらくtime(UNIX time)の大きさに対してswapの変化量が小さいのが原因かと考え、以下のようにして時間を補正(UNIX timeでなく、経過時間(s)をx軸に採用)

> swapsize$time=swapsize$time-min(swapsize$time)

そしてプロットをし直す。

 

f:id:mathematik:20150316130442p:plain

 

今度は、そんなもんかなというデータ。ミリ秒とかではなくて1秒というとり方もあってか、綺麗に直線には乗らなかった。

 

あとはswapさんがいなくなるまでの時間をざるに計算する。まずは回帰直線の傾きと切片を教えてもらう。

> swapsize.lm=lm(swap~time,data=swapsize)

> summary(swapsize.lm)

Call:
lm(formula = swap ~ time, data = swapsize)

Residuals:
      1       2       3       4       5       6
-1818.6   666.2  1079.1  2215.6 -1194.5  -947.7

Coefficients:
              Estimate Std. Error  t value Pr(>|t|)    
(Intercept) 8814178.65    1258.67 7002.757  2.5e-15 ***
time           -509.48      76.91   -6.624  0.00269 **

 あとはy(swap)がゼロになる=処理が終わる時間を推測。

y=ax+bでy=0で解くので、今回の場合は0=(time)*x+(intercept)を解いて、秒を3600で割って時間単位に変換する。

$echo "scale=4;8814178.0/509.4/60/60"|bc
4.8064
 

5時間....だと !!!!

待っていられないので一旦swapoff -aはキャンセルしてすぐにswapon -aを実行。

元に戻しました。

朝起きてみると一旦7.5G付近まで下がっていたswapの使用料が7.8Gまで拡大。今後の経過を見守りたい