偏差値20くらいのブログ

はるみちゃんのブログだよ。えへへ。

ブログ移転の報告と意識改革。

挨拶

はじめまして。さかたはるみちゃんです。

東京で底辺エンジニアをやっていて、今は広告配信系の開発に携わっています。

昨年までは大学生でした。
学生時代はSwift、JavaScriptPython辺りをよく書いていましたが、社会人になってからはScalaが多いです。

移転した理由

DEEPTONEWorks活動するのもう無理

このブログの移転元は、私が大学生の頃に立ち上げたサークル DEEPTONEWorksのWebサイトです。
自分たちの作品を公開する場が欲しかったので細々と続けていました。

ただ、もう皆社会人になっちゃって、今後活動できる見込みがありません><><

なので、やめました。

ほんと、社会人ってクソですね。

でもアウトプットの場は欲しい

ただ、自分も一応エンジニアやってるので、知識のアウトプットの場は大切なわけです。(全然記事書いてなかったけど)
と、いうわけで、今回技術系ブログが集まるはてブに、ブログ機能だけ移転しました。

エンジニアは全員技術系ブログを書くべきみたいな論調、ありますよね。

今後の目標

ブログ移転にあたり、こんな目標を掲げたいと思います。

週1ペースで記事更新

正直、かなり厳しいです。今まで半年に一回でも更新したら良い方だったので。
でも、 SOFT SKILLS ソフトウェア開発者の人生マニュアル には(たしか) 最低週1で更新しろ って書いてましたしね。

社会人になってから、休日は寝てるか下半身弄ってるか、という大変意識の低い生活(※1)を送ってたので、(底辺→人間目指して) 意識改革 頑張ります。

Twitterの方も、 声優への求婚 (※2)以外の事をつぶやくようにしていきたいですね。

(※1 意識の低い生活)

(※2 声優への求婚)

よろしくおねがいします。

マルコフモデル,隠れマルコフモデルとコネクショニスト時系列分類法

マルコフモデル,隠れマルコフモデルとコネクショニスト時系列分類法についての資料。 EMアルゴリズムについて、HMMのパラメータの最尤推定について、コネクショニスト時系列分類法についてはもう少し詳しくこのブログで書けたらいいなって思ってます(願望)

参考

DEEPTONEWorksのWebサイトをリニューアルしました

DEEPTONEWorksのWebサイトをリニューアルしました!2年以上ぶりです。

リニューアル前はこんな感じ。

で、今はこう。

ブログだけでも定期的に更新していけるように頑張ります。

LSTMの解説(をしようと思った)

LSTMの解説をしようと思ったけど、なかなか重い腰があがらなかった。 なので、以前に輪講で使用した資料をそのまま貼り付けて記事にしようと思う。。。

間違っている点もあると思います。随時ご指摘願えたら嬉しいです。 他にも、不明な点などがありましたらいつでもコメント下さい。

MAMPのPHPにphp-mecabを導入する

MAMPPHPphp-mecabを導入する方法ってあまり載ってないようなので書いておこうと思います。 mecab自体は入っている事を前提としているので注意。

環境OSX 10.11.6

mecab 0.996 MAMP 4.0.6 PHP 7.0.12

MAMPが4系じゃない場合はアップデートして下さい。

導入

(1)php-mecabをダウンロード

git clone https://github.com/rsky/php-mecab.git

(2)mecabディレクトリに入る cd php-mecab/mecab

(3)phpizeを実行 ここで、MAMPで使っているPHPphpizeを実行する必要がある。 フルパスで指定する。

/Applications/MAMP/bin/php/php7.0.12/bin/phpize

(4)./configureを実行 ここでも、MAMPで使っているPHPphp-configを指定する必要がある。

./configure –with-php-config=/Applications/MAMP/bin/php/php7.0.12/bin/php-config –with-mecab

(5)makeの実行

make
make test
sudo make install

(6)php.iniの修正 php.iniを開いて以下の一行を加える

php.iniを開く

vi /Applications/MAMP/bin/php/php7.0.12/conf/php.ini

以下の行を追加

extension=mecab.so

(7)php-mecabが導入されている事の確認 phpinfoの出力を参照し、mecabで検索してみましょう。 導入が成功していれば、以下のような部分があるはずです。

f:id:deeptoneworks:20161124114037p:plain

php-mecabを使用してみる

PHP7でphp-mecab名前空間を用いられるようになったため、これまで通りmecab_split()等と書いても使えないので注意。

Ex1 形態素に区切る

単純に形態素にだけ区切る場合は[Mecab](http://d.hatena.ne.jp/keyword/Mecab)\split()を使う。

$query = "トマトを5cm大に切る。";
$result = \Mecab\split($query);
print_r($result);

実行結果

Array ( [0] => トマト [1] => を [2] => 5 [3] => cm [4] => 大 [5] => に [6] => 切る [7] => 。 )

Ex2 より詳細な情報を得る

$query = "トマトを5cm大に切る。";
$mecab = new \Mecab\Tagger();
$nodes = $mecab->parseToNode($query);
foreach($nodes as $node){
echo($node->getSurface()."<br/>"); #形態素の表示
echo($node->getFeature()."<br/>"); #解析結果の表示
}

実行結果

BOS/EOS,*,*,*,*,*,*,*,*
トマト
名詞,一般,*,*,*,*,トマト,トマト,トマト
を
助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
5
名詞,数,*,*,*,*,*
cm
名詞,一般,*,*,*,*,*
大
名詞,接尾,一般,*,*,*,大,ダイ,ダイ
に
助詞,格助詞,一般,*,*,*,に,ニ,ニ
切る
動詞,自立,*,*,五段・ラ行,基本形,切る,キル,キル
。
記号,句点,*,*,*,*,。,。,。
BOS/EOS,*,*,*,*,*,*,*,*

SQLAlchemyのback_populatesとbackref

SQLAlchemyのback_populatesとbackrefって何がどう違うの?っていうかどっちも書かないとどうなるの?という疑問に対する答え。

結論から書くと、

(1)backrefを使用した場合

双方向のリレーションを自動的に組んでくれる。

(2)back_populatesを使用した場合

双方向のリレーションを自分で組む必要がある。

(3)back_populatesもbackrefも使用しない場合
トランザクション中、逆方向のフィールドが自動更新されない。

ということになる。

では、具体例を見ていく。

例としてEventモデルとTicketモデルを考える。

1つのEventは複数のTicketをもっている、One to Manyの関係。

backrefを使用した場合

class Event(Base):
    __tablename__ = ‘event’
    id = Column(Integer, primary_key=True)
    title = Column(String(255))
    tickets = relationship("Ticket",backref="event")
class Ticket(Base):
    __tablename__ = ‘ticket’
    id = Column(Integer,primary_key=True)
    title = Column(String(255))
    value = Column(Integer)
    event_id = Column(Integer,ForeignKey(‘event.id’))

event = Event(title="test")
ticket = Ticket(title="test_ticket",value=5000)
event.tickets = [ticket] event.tickets #Ticket Objects
ticket.event #Event Object

back_populatesを使用した場合

back_populatesを使用する場合は、双方向のリレーションを組まないと動作しない。

class Event(Base):
    __tablename__ = ‘event’
    id = Column(Integer, primary_key=True)
    title = Column(String(255))
    tickets = relationship("Ticket",back_populates="event")
class Ticket(Base):
    __tablename__ = ‘ticket’
    id = Column(Integer,primary_key=True)
    title = Column(String(255))
    value = Column(Integer)
    event_id = Column(Integer,ForeignKey(‘event.id’))
    event = relationship("Event",back_populates="tickets")

event = Event(title="test")
ticket = Ticket(title="test_ticket",value=5000)
event.tickets = [ticket] event.tickets #Ticket Objects
ticket.event #Event Object

どちらも使用しない場合

class Event(Base):
    __tablename__ = ‘event’
    id = Column(Integer, primary_key=True)
    title = Column(String(255))
    tickets = relationship("Ticket")
class Ticket(Base):
    __tablename__ = ‘ticket’
    id = Column(Integer,primary_key=True)
    title = Column(String(255))
    value = Column(Integer)
    event_id = Column(Integer,ForeignKey(‘event.id’))
    event = relationship("Event")

event = Event(title="test")
ticket = Ticket(title="test_ticket",value=5000)
event.tickets = [ticket] event.tickets #Ticket Objects
ticket.event #None

この場合、ticket→eventがNoneになっている。

つまり、トランザクション内ではticketにeventが紐付いていない事がわかる。

勿論、トランザクション終了後(eventオブジェクトをインサートした後)なら双方向で紐付いている。

event = self.session.query(Event).filter(Event.id==1).one()
ticket = self.session.query(Ticket).filter(Ticket.id==1).one()
event.tickets #Ticket Objects
ticket.event #Event Object

Xcode8でFirebaseのCrash Reportingを使う

Xcode8でFirebaseのCrash Reportingを使おうとしたらハマったのでその時の話をメモっときます。

(1) Firebaseの導入

まずは、https://firebase.google.com/docs/ios/setup に書いてある通りにFirebaseを導入していきます。

そして、iOSシミュレータ上でRUNしてみると、以下のようなエラーが出ました。

<FIRInstanceID/WARNING> STOP!! Will reset deviceID from memory.

<FIRInstanceID/WARNING> Failed to fetch default token Error Domain=com.firebase.iid Code=6 “(null)”

f:id:deeptoneworks:20161121133109p:plain

明らかにうまくいってないです。どうやらこれKeyChain周りのせいで発生するっぽいです。
というのも、Xcode8のシミュレータからはKeyChainにアクセスできないというバグがあるらしいのです。。><

これに対処するために、 CaoabukutuesのKeychain sharingをONにします。
f:id:deeptoneworks:20161121133942p:plain

これでうまくいくはずです。

(2) Crash Repotingの導入

次に、Crash Reportingを導入します。
これも、先と同様に https://firebase.google.com/docs/crash/ios を眺めながら勧めていきます。

そして、最後のスクリプトの追加をする部分、ドキュメントには以下のように書いています。

# Replace this path with the path to the key you just downloaded
JSON_FILE=Path/To/ServiceAccount.json
# Replace this with the GOOGLE_APP_ID from your GoogleService-Info.plist file
GOOGLE_APP_ID=1:my:app:id
defaults write com.google.SymbolUpload version -integer 1 # creates file if it does not exist
JSON=$(cat "${JSON_FILE}")
/usr/bin/plutil -replace "app_${GOOGLE_APP_ID//:/_}" -json "${JSON}" "$HOME/Library/Preferences/com.google.SymbolUpload.plist"
"${PODS_ROOT}"/FirebaseCrash/upload-sym

・・・しかし、これで実行すると下記のようなエラーが発生し、クラッシュ情報を送信することができません。 f:id:deeptoneworks:20161121144200p:plain

そこで、スクリプトを以下のように書き換えます。(勿論、JSONFILEとGOOGLEAPP_IDは適切なものに書き換えて下さい)

# Replace this path with the path to the key you just downloaded
JSON_FILE=Path/To/ServiceAccount.json
# Replace this with the GOOGLE_APP_ID from your GoogleService-Info.plist file
GOOGLE_APP_ID=1:my:app:id
defaults write com.google.SymbolUpload version -integer 1
JSON=$(cat "${JSON_FILE}")
/usr/bin/plutil -replace "app_${GOOGLE_APP_ID//:/_}" -json "${JSON}" "$HOME/Library/Preferences/com.google.SymbolUpload.plist"
"${PODS_ROOT}"/FirebaseCrash/upload-sym "${JSON_FILE}"

これで動きます。

実際にassert(false)を実行しクラッシュさせた後、この行を消して再起動すると・・

f:id:deeptoneworks:20161121144703p:plain

クラッシュ情報が送信できました!
20分程度経つと、無事ダッシュボードにも反映されました。よかった。

参考

ios - Firebase upload symbol files build error: Unexpected argument 'ServiceAccount.json' - Stack Overflow

Google Developers Japan: iOS 10、Xcode 8、Swift 3

[iOS 10] Xcode8のシミュレーターでは、Keychainへのアクセスがエラーとなる | Developers.IO