接着剤の精進日記

競プロでの精進や研究に関係したことを書いていきます。

グラフィカルなエンティティリンキングサイト「Serelex」

はじめに

面白そうなサイトを知ったのでただ紹介すると言うだけです
serelex.cental.be

どんなサイト?

「Serelex」というサイトで Finds semantically related wordsとあるように
ある単語を入力すると、その単語と意味的に繋がりのある語がグラフィカルに表示されるというサイトです。
f:id:tkm-kyudo:20180416191549p:plain

使ってみる

個人的な趣味でtouhou(東方project)と入力してみる。
結果は以下のようになる。
f:id:tkm-kyudo:20180416192222p:plain

ちゃんとvideo gameと紐付いているのがわかる。
個人的にこれが面白いと思った。
darkstalkers(ヴァンパイアシリーズの英題らしい)と
紐付いているのは、レミリアやフランドールが吸血鬼(ヴァンパイア)だからだろうか。

表示されているエンティティをクリックすると、
クリックしたエンティティの繋がりが表示される。
(ここではdarkstalkersをクリックした)
f:id:tkm-kyudo:20180416192603p:plain
litelary classicsやtitleは『吸血鬼ドラキュラ』繋がりだろう。
yatsura(うる星やつら)はよくわからなかったのでググったところ
どうもドラキュラ伯爵が出てくる話があったみたいで、それでリンクが繋がっているのだと思う。

使ってみて

今回はtouhou(東方project)という、かなり限定された単語を入力してみた。
かなり有名とは言え、同人ゲームというジャンルの1ゲームではあったが、
それなりにエンティティリンキングがされていた。
一般的に使われる語句などはもっとリンクが多いし、有用なのではないかと思う。

使いみち

純粋に単語を入力して、どんな繋がりがあるかを見るだけでも結構楽しいと思う。
APIが公開されているので、機械学習とかをさせる際に知識ベースとして利用できるかもしれない。
個人的には、後者の使い方を模索してみたいと思った。

終わりに

本当はtwitterで簡単に呟いて終わるつもりだったのだが、
何故か何回やってもエラーが起こってしまったので(リンクの問題か?)
内容は薄いがブログとして書くことにしました。
なぜこのサイトのURLはhttpなのだろう、そこは割と疑問ではある。
興味が湧いたのならぜひ使ってみてください。

言語処理学会第24回年次大会(NLP2018)に参加してきました.

はじめに

f:id:tkm-kyudo:20180317143710j:plain
3/12(月)~3/16(金)の間行われていた言語処理学会(NLP2018)に参加してきました。
言語処理学会への参加は聴講自体初めてでしたが、
いつのまにやら発表することになっていて、発表もしてきました。
初めての学会の参加+5日間フル参加したので疲れましたが、
勉強になることも多く、たくさんの刺激を受けて楽しかったです。

www.anlp.jp

岡山について

NLP2018に参加するにあたって、初めて岡山に来ました。
感想としては、思ってた以上に都会でした。
駅付近には飲み屋とか、大きなショッピングモールとかがたくさんあって純粋にいいなと思いました。
最初の3日間は教授たちに連れられて(学生は自分だけ)ご飯を食べました。
学生1人が教授6人に囲まれてご飯を食べるというなかなかない状況もありましたが、
色々なお話(教授たちの裏話とかも笑)聞けたので貴重な体験だったかなと思います。
学生ではまずいかないようなお店にも連れて行っていただきました。
ごちそうさまです・・・。美味しかった。

f:id:tkm-kyudo:20180317143742j:plainf:id:tkm-kyudo:20180317143800j:plain

言語処理学会

自分は初めての参加でしたが、今回は参加者が今までで一番多かったらしく約1000人規模だったとか。
学生の参加だけではなく、企業の方の一般参加なんかも多かったみたいですね。
初日の最後にはスポンサーイブニングなるものがあって、企業が学生と飲み物片手に歓談してました。
教授から聞くに今年が初めて?だったらしく、企業が言語処理に精通している学生が欲しいというのはあるみたいですね。
最近は売り手市場の傾向もありますし、データサイエンティストなんかも引く手数多ですね。

発表

2日目の午後に自分の発表がありました。
口頭発表ではなく、ポスター発表だったので、特に緊張はしませんでした。
参加者が多かったためか、80分間ずっと立ちっぱなし、話しっぱなしで大変疲れました・・・。
f:id:tkm-kyudo:20180316090407j:plain
『地方議会会議録における発言文の推定』というタイトルで
発表させていただきましたが、意外と興味持っていただけてよかったです。
発表してる時に色々質問や意見も頂きましたが、無難にはできたかな。
聞きに来てくださった方々ありがとうございました。

他の方の発表を聞いて

自分の研究したい分野が対話なので、主に対話セッションを聞いてました。
他にも面白そうな発表が多かったので対話セッションだけではなくて
いろんな分野をつまみ食いするような感じで会場を転々としながら聴講しました。
言語処理学会は結構レベルが高いらしく、聞いてて面白い発表が多かったです。
自分が気になったり、面白いなと思ったものは、
Twitterの多軸的感情情報を利用した株価の予測』
『RNN系列変換モデルを用いた高階論理式からの文生成』
『自然な対話継続のための推移する話題推定』
『感情を含む特徴変化情報付き対話コーパスの構築とそれを用いた対話の自然さ推定』
などがありました。
上記以外にもたくさん面白いものがあったり、
気になったけど時間的に聞けなかったものも多くありましたので、
論文の方で確認してみようと思います。

ワークショップ

ワークショップは『形態素解析の今とこれから』に参加しました。
ワークショップでは形態素解析開発者(解析機や辞書作成者)の方々の
開発した経緯や、こういう人に使って欲しいなど、
普段あまり知ることのできない開発側の意図を知ることができて有意義でした。
あとはSudachiが結構注目を浴びていたかなという印象。
Sudachiは名前だけしか知らなかったので、調べたり、実際に使ってみたりします。
ワークショップのタイトル通り、形態素解析のこれまでの経緯や生まれた意図、
そして今後の課題も含めてより深く知ることができました。

全体的な感想

初めてこのような学会に参加して、他の方々の発表を聞いた感想としては
機械学習などはRNNが流行っているような感じがありました。
エンコーダ・デコーダ、アテンションを使ってというようなものが
結構多く見かけたのが記憶に残ってます。
自分のやりたいことに使えそうな手法とか考え方も多くあったので
上手く自分の研究に生かしたいと思いました。
それと同時に自分のやりたいことと近いことをしている人もいなかったので
チャンスかなと思うので、他の人にやられる前にやりたいですね笑。

つらつらと述べてきましたが、参加してよかったと思いました。
とても勉強になったとともに楽しんで参加できました。
来年も発表か、聴講のみかわからないけれど参加したいです。

Xonshを導入してみた

はじめに

なぜ、Xonshを導入しようかと思ったかと言うと
TwitterのTLで話題に上がってて気になったので導入してみることに。
何やら日本語の記事が少ないので売名ができるらしい
自分と同じように興味を持った人へのハードルを下げるために導入記事を書いてみることにします。

この記事は Xonsh Advent Calendar 2017 の記事です。

Xonshとは

導入する前にXonshとはなんぞやと言うことを簡単に調べてみる。
XonshはPythonで作られたもので、Unixライクなシェル言語でコマンドプロンプトらしい。
クロスプラットフォームでもあるとか。
vaaaaaanquish.hatenablog.com

環境

Window10Home
Anaconda4.4.0
Python3.6.3
Anaconda Prompt使用

導入

早速導入していくために公式のインストール手順を見ていこう。
Windows Guide — xonsh 0.6.0.dev151 documentation
condaパッケージマネージャーを使うと簡単らしい。
Anacondaは使っているから、せっかくなのでそちらの方法を試してみよう。
Python3.4以降にしか対応していないようなので注意。
legacy Python (2.7)には対応していないと言っているので
みんなも小学生に馬鹿にされないように3系を使おう!

さて、インストールするには以下のコマンドを叩けばいいみたい。

conda config --add channels conda-forge
conda install xonsh

無事インストールが終わったので起動。

f:id:tkm-kyudo:20171216231540p:plain

無事導入が終わりました。

使ってみる

導入が思いの外簡単でしたね。
せっかくなので使ってみよう。
Tutorial — xonsh 0.6.0.dev151 documentation

1 + 1
>2
import sys
print(sys.version)
>3.6.3 |Anaconda custom (64-bit)| (default, Oct 15 2017, 03:27:45) [MSC v.1900 64 bit (AMD64)]

こんな感じでPythonインタプリタとしても使えるみたい。
もちろん関数の定義も可能

def f():
    return "xonsh"

f()
>'xonsh'

インデントを勝手にやってくれるのでいちいちスペースやTABを叩かなくて良いのは地味に便利。

環境変数

環境変数も使うことができる。
使うには環境変数の名前の前に$をつける。

$PWD
'C:/Users/username'

好きなように環境変数を作ったり消したりもできる。

$GOAL = 'Pythonista'
print($GOAL)
>Pythonista
del $GOAL
print($GOAL)
>KeyError: 'Unknown environment variable: $GOAL'

導入してみた感想

導入してみて、チュートリアルをやった程度であるが、
これはなかなか面白そうだと感じた。
ただ、シェルスクリプトにあまり詳しくないので
他の方のAdvent Calendarの記事を見て勉強してみようと思う。

終わりに

今回はWinで導入してみて、思っていたよりも簡単に導入できた。
しばらく勉強や使ってみたりして、使えそうならMacにも導入してみたいと思う。
みんなもこれでXonshライフをエンジョイしよう。

他の方の記事は以下から。
qiita.com

Kaggleのtitanic問題に挑戦

はじめに

機械学習やデータサイエンスの勉強をし始めてなんとなくわかってきたので、
アウトプットとしてKaggle初心者がTitanicチュートリアルに挑戦してみました。

Kaggleとは

Kaggleは、世界中のデータサイエンティストに対し、企業からコンペ形式でお題を与えられます。
お題に関するデータが与えられるのでデータサイエンティスト達はそれらを分析して、予測結果を提出します。
その予測結果が高かったものが、上位者となり、順位によっては賞金がもらえるというものです。
https://www.kaggle.com/

Titanicチュートリアル

今回は、Titanicチュートリアルに挑戦しました。
あの有名なタイタニック号の乗船者たちのデータから、
生存者たちを予測するというものです。

分析環境

言語:Python3.6.1(anaconda4.4.0)
環境:jupyter notebook

データの前処理

各問題では、train.csvファイルとtest.csvファイルが提供されるので、それらをダウンロードした後、データを読み込みます。

import pandas as pd
import numpy as np
df_train = pd.read_csv("train.csv")
df_test = pd.read_csv("test.csv")
df_train.head(3)

f:id:tkm-kyudo:20171203160257p:plain

一先ず欠損データの確認をします。

df_train.isnull().sum()
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64

上記のようにAge,Cabin,Embarkedに欠損値があることがわかりました。
今回は、Cabinを除外、Embarkedの欠損値がある行を除外、Ageは平均値で補完することにしました。

Cabinの除外

df_train = df_train.drop('Cabin',axis=1)
df_test = df_test.drop('Cabin', axis=1)

Embarkedの欠損値がある行を除外

df_train = df_train.dropna(subset=['Embarked'])
df_test = df_test.dropna(subset=['Embarked'])

Ageの欠損値を平均値で補完

df_train['Age'].fillna(df_train['Age'].mean(),inplace=True)
df_test['Age'].fillna(df_test['Age'].mean(),inplace=True)

欠損値の確認

df_train.head(3)
PassengerId    0
Survived       0
Pclass         0
Name           0
Sex            0
Age            0
SibSp          0
Parch          0
Ticket         0
Fare           0
Embarked       0
dtype: int64

これで欠損値はなくなりました。

先程のデータを確認すると、Name,Sex,Ticketが文字データなので
これらも処理しなければいけません。
まず、male=0,female=1と置き換えます。

df_train= df_train.replace("male",0).replace("female",1).replace("S",0).replace("C",1).replace("Q",2)
df_test= df_test.replace("male",0).replace("female",1).replace("S",0).replace("C",1).replace("Q",2)

NameとTicketについては、今回は除外することにしました。
NameとTicketの列を除外

df_train = df_train.drop('Name',axis=1)
df_test = df_test.drop('Name', axis=1)
df_train = df_train.drop('Ticket',axis=1)
df_test = df_test.drop('Ticket', axis=1)

以上で、trainデータは以下のようになりました。
f:id:tkm-kyudo:20171203162231p:plain
trainデータは大丈夫そうです。

念のためtestデータを確認しておきましょう。

df_test.isnull().sum()
PassengerId    0
Pclass         0
Sex            0
Age            0
SibSp          0
Parch          0
Fare           1
Embarked       0
dtype: int64

testデータではFareが1つ欠けていたので、これも補完します。

df_test["Fare"].fillna(df_test["Fare"].mean(),inplace=True)
<||

*データの読み込み
前処理が完了したので、データを読み込ませます。
>||
x_train = df_train.values[:, 2:]#Pclass以降の変数
y_train  = df_train.values[:, 1]#正解データ
x_test = df_test.values[:, 1:]

データ解析・モデリング

データの処理、読み込みが終わったので、モデリングして、データの解析をします。
今回は線形SVMをしようしました。
ランダムフォレストやK近傍法なども試しましたが、線形SVMが一番精度が高く出ました。
線形SVMでは入力データを標準化(平均0,標準偏差1)します。

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(x_train)
x_train_std = sc.transform(x_train)
x_test_std = sc.transform(x_test)

標準化したデータを線形SVMに適用し、生存を予測する。

svm = SVC(kernel='linear', random_state=0, gamma=0.05, C=1.0)
svm.fit(x_train_std, y_train)
svm_accuracy = svm.predict(x_test_std)

予測したものをCSVファイルに書き出す

import csv
with open("svm_predict_result_data.csv", "w") as f:
    writer = csv.writer(f, lineterminator='\n')
    writer.writerow(["PassengerId", "Survived"])
    for pid, survived in zip(df_test.values[:,0].astype(int), svm_accuracy.astype(int)):
        writer.writerow([pid, survived])

予測結果

先程のCSVデータをKaggleに提出すると、
f:id:tkm-kyudo:20171203163751p:plain
正答率0.79904,順位1766(9525人中)と上位18.5%に入ることができました。(2017/12/03時点)

やってみた感想

今回は、初めてということで、拙くてもいいのでデータ分析した結果を提出するということを目標にやってみた。
これまでの過程を見て分かる通りそれほど難しいことはしておらず、データもかなり除外している。
しかし、それでも上位18.5%と悪くない結果を得ることができた。

今後の挑戦について

今回は自力でやることを重視していたので、Kernelには目を通していない。
Kernelとは、Kaglleの強い人達が、どう分析したらスコアが上がったなどの情報を共有してくれているものである。
今後は、コンペなどに参加しつつ、Kernelを見ながら、上位者たちの考え方、解法を学んでいく。
一先ずの目標として、コンペでメダルを1つ取るのを目標に頑張りたい。

Pythonでニコニコ動画をスクレイピングしてまとめてみた。

はじめに

完全に趣味用だが、ニコニコ動画スクレイピングしてみた。
内容としては、昨日一日で投稿された動画の一覧を取得し、
タイトル(動画への直リン付き)とサムネイルを表示するというものだ。
以下の画像のようなサイトとなっている。

f:id:tkm-kyudo:20171122000803p:plainf:id:tkm-kyudo:20171122000806p:plain
琴葉姉妹動画なのは趣味です。
せっかく作ったので、簡単に説明してみる。
コードの説明とかは需要あったら書くかも。

簡単に構造の説明

まず、ディレクトリの関係としては、

--index.html
 |-akane_aoi-2017-11-21.html...
 |                 
 |-honobono-2017.11.21.html...
 |           
 ...    
 |
  -img

のようになっている。
index.htmlの存在する階層にそれぞれの検索ワードのディレクトリがある。
また、そのティレクトリに日付で名前のつけたhtmlファイルが存在している。
imgディレクトリには動画のサムネイル画像が入っている。

index.html

index.htmlでは検索ワードごとの最新ページへとリンクしている。
また、スクレイピングのコードを実行するごとに最新版へリンクを更新するようにしている。

各htmlファイル

各htmlファイルは各検索ワードごとに最新の検索結果を取得して表示している。
タイトルは、その動画の直リンク(http://www.nicovideo.jp/watch/sm*)、
サムネイルは、imgディレクトリに保存したものを参照して使用している。

API用パラメータの指定、検索ワードなどの用意

q = ""
targets = "targets=tags"
fields = "fields=contentId,title,description,startTime"
filters = "filters[startTime][gte]=" + str(yesterday) + \
"T00:00:00%2B09:00&filters[startTime][lt]=" + str(today) + \
"T00:00:00%2B09:00
&_sort=-viewCounter&_offset=0&_limit=100&_context=apiguide"

詳しい説明は先ほどのAPIガイド(http://site.nicovideo.jp/search-api-docs/snapshot.html)を
参照していただくとして、簡単な説明をする。
qは検索ワードで、パーセントエンコードしたもので指定する。
qについては次に説明する。
今回はタグ検索したものを取得したいのでtarget="targets=tagsとしている。
filtersのところは昨日から今日までに投稿された動画を、
再生数が高い順に100件取得するという指定をしている。
today,yesterdayにはdatetime型の値が入っている。

検索ワードのエンコード

qで指定する検索ワードのエンコードについては、以下のサイトを利用するか
URLエンコード・デコード|日本語URLをサクッと変換 | すぐに使える便利なWEBツール | Tech-Unlimited
もしくは、

import urllib.parse as parse
search_word = "琴葉茜・葵実況プレイ"
parse.quote(search_word)

のようにurllibparse.quoteを利用することで
パーセントエンコード(urlエンコード)できる。

APIの利用

上記のような手順で出来たurlが以下である(少々長いので便宜上改行している)。

http://api.search.nicovideo.jp/api/v2/snapshot/video/contents/search?
q=%E7%90%B4%E8%91%89%E8%8C%9C%E3%83%BB%E8%91%B5%E5%AE%9F%E6%B3%81%E3%83%97%E3%83%AC%E3%82%A4
&targets=tags&fields=contentId,title,description,startTime
&filters[startTime][gte]=2017-11-20T00:00:00%2B09:00&filters[startTime][lt]=2017-11-21T00:00:00%2B09:00
&_sort=-viewCounter&_offset=0&_limit=100&_context=apiguide

ここまでで、API用のURLにパラメータを指定してきた。
上述のURLにアクセスすることで検索結果のデータがjson形式で渡される。
そのjson形式のデータを上手く活用することで今回のhtmlが作成できた。

終わりに

今回は、思っていた以上に文字数がかかってしまったので、
作成したサイトの説明だけに留めた。
json形式のデータの扱いについては、次あたりに書く予定。
これでアカネチャンアオイチャンカワイイヤッターができる。