WSL(Ubuntu)にRStudio Serverをインストールする機会があったので、その手順をまとめておく。
2021年11月28日日曜日
WSL(Ubuntu)にRStudio Serverをインストールする
2021年3月7日日曜日
LDAの最適なトピック数を決めたい
トピックモデルのひとつとしてLDA(潜在的ディリクレ配分法)がある。文書に複数の潜在的なトピックがあることを仮定したモデルで、文書分類などに使われる。以前には国会会議録の発話を分類してみたこともある(PythonとLDAで国会会議録の発話を分類して可視化する)。LDAモデルを作成する時には事前にトピック数を指定する必要があが、これがけっこう悩ましい。今回はこのトピック数を決める方法を試してみる。
PerplexityとCoherence
LDAモデルを作成するときのトピック数を決める指標としてよく登場するのがPerplexityとCoherence。Perplexityは低い数値、Coherenceは高い数値が良いとされている。トピック数を変えてモデルを作成し、それぞれの値を算出して最適なトピック数を決めることになる。
ただ、PerplexityもCoherenceも絶対的な指標ではなく、これらを使ったからといって最適なトピック数が必ず決められるわけではない。今回は青空文庫にある夏目漱石の『こころ』のテキストを章ごとに分割してLDAモデルを作成し、PerplexityとCoherenceを求めてみる。
環境
テキストデータの準備
テキストデータを準備する。青空文庫にある夏目漱石の『こころ』を章ごとに形態素解析する。この処理には青空文庫にある夏目漱石の『こころ』のテキストを章ごとに分割して形態素解析するのコードを使う。このコードを実行すると、以下のように章ごとの単語リストが作成される。
[['人', '常に', '先生', '呼ぶ', '先生', '書く', '本名', '打ち明ける', '世間', 'かる', '遠慮', 'いう', '自然', '人', '記憶', '呼ぶ', '起す', '先生', 'いう', 'なる', '筆', '執る', '心持', 'よそよそしい', '頭文字', '使う', 'なる', '先生', '知り合い', 'なる', '鎌倉', '若々しい', '書生', '暑中', '休暇', '利用', 'する', '海水浴', '行く', '友達', 'ぜひ', '来る', ...
PerplexityとCoherenceの値を算出
続いてトピック数5から150まで5ずつ増やしてPythonライブラリのGensimでLDAモデルを作成し、算出したPerplexityとCoherenceの値をグラフ化する。Gensimには4種類のCoherence算出方法がある(Topic coherence pipeline)が、今回はu_massを使う。
%matplotlib inline
import pandas as pd
from gensim.corpora import Dictionary
from gensim.models import LdaModel, CoherenceModel
import matplotlib.pyplot as plt
from preprocess_kokoro import preprocess
# 『こころ』のテキストを章ごとに形態素解析
texts = preprocess()
dct = Dictionary(texts)
corpus = [dct.doc2bow(t) for t in texts]
def compute_metrics(model, texts, corpus, dct):
# Perplexity算出
pp = np.exp2(-model.log_perplexity(corpus))
# Coherenceの算出
cm = CoherenceModel(model=model, texts=texts, dictionary=dct, coherence='u_mass')
ch = cm.get_coherence()
return pp, ch
# トピック数を5から150まで5ずつ増やしてPerplexityとCoherenceを算出
perplexity = []
coherence = []
num_topic_range = range(5, 151, 5)
for num_topics in num_topic_range:
model = LdaModel(corpus=corpus, id2word=dct, num_topics=num_topics, minimum_probability=0.0, random_state=0)
pp, ch = compute_metrics(model, texts, corpus, dct)
perplexity.append(pp)
coherence.append(ch)
metrics = pd.DataFrame({'num_topic': num_topic_range, 'perplexity': perplexity, 'coherence': coherence})
# PerplexityとCoherenceをグラフ化
fig, ax1 = plt.subplots(figsize=(9, 6))
metrics.plot(x='num_topic', y='perplexity', color='b', legend=False, ax=ax1)
ax1.set_xlabel('num_topics')
ax1.set_ylabel('perplexity', color='b')
ax1.tick_params('y', colors='b')
ax2 = ax1.twinx()
metrics.plot(x='num_topic', y='coherence', color='r', legend=False, ax=ax2)
ax2.set_ylabel('coherence', color='r')
ax2.tick_params('y', colors='r')
fig.tight_layout()
plt.show()
結果は以下の通り。Perplexityは低い数値、Coherenceは高い数値が良いとされているが、それを適用するとトピック数最小の5が最適なトピック数ということになる。この結果を見る限り、今回のテキストデータについてはPerplexityとCoherenceは使えなさそう。
ldaturningによるトピック数の決定
ldaturningというRのパッケージがあって、これを使うとトピック数を決める指標となる4種類の値を算出してくれるらしい。Select number of topics for LDA modelにそのサンプルコードがある。このパッケージを使って、最適なトピック数を求めてみる。
データの準備
PerplexityとCoherenceを算出したときと同じデータを使いたいので、Pythonでベクトル化したデータをcsvに出力して、それをRで読み込む。以下はPythonでベクトルデータ(kokoro_vec.csv)を作成するコード。
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from preprocess_kokoro import preprocess
# 『こころ』のテキストを章ごとに形態素解析
texts = preprocess()
# 単語リストをタブ区切りテキストに変換
tab_separated = ['\t'.join(t) for t in texts]
# tokenizerでタブで分割するように指定
vectorizer = CountVectorizer(lowercase=False, tokenizer=lambda x: x.split('\t'))
vec = vectorizer.fit_transform(tab_separated)
df = pd.DataFrame(vec.toarray(), columns=vectorizer.get_feature_names())
display(df.head())
df.to_csv('kokoro_vec.csv', index=False, header=True)
PandasのDataFrameの中身は以下のとおり。
R環境の準備
これでJupyter LabでRが使える。
ldaturningで指標の算出
Rのライブラリldaturningを使うにはdocument-term matrix形式のデータ(DocumentTermMatrix)が必要。まずはPythonで作成したベクトルデータ(kokoro_vec.csv)からDocumentTermMatrixを作成し、ldaturningでトピック数が5から150まで5ずつ増やしていき指標値を算出する。さらにその結果をグラフ化する。
library("ldatuning")
library("dplyr")
library("tm")
# Pythonで作成したベクトルデータ読み込んでDocumentTermMatrix形式に変換
dtm <- read.csv("kokoro_vec.csv") %>% as.DocumentTermMatrix(weighting = weightTf)
# 4種類の指標値の算出
result = FindTopicsNumber(
dtm,
topics = seq(from = 5, to = 150, by = 5),
metrics = c("Griffiths2004", "CaoJuan2009", "Arun2010", "Deveaud2014"),
method = "Gibbs",
control = list(seed = 77),
mc.cores = 2L,
verbose = TRUE
)
# 結果のグラフ化
ldatuning::FindTopicsNumber_plot(values = result)
結果は次の通り。4つの指標のうちCaoJuan2009とArun2010は小さいほど、Griffiths2004とDeveaud2014は大きいほどよい。この結果をみるとトピック数20あたりがよさそう。
2019年6月17日月曜日
rpy2でPythonのPandasデータフレームをRのデータフレームに変換する
環境
Windows10のWSL(Ubuntu 18.04)。
さらに、Rを以下のコマンドでインストールしておく。
rpy2のインストール
pipでrpy2をインストール。
Pandasのデータフレームを扱うにはtzlocalも必要なのでインストールしておく。
Pandasデータフレームの作成
まずはRのデータフレームに変換するPandasデータムレームを用意する。
import pandas as pd
import numpy as np
# 日付データのインデックス作成
dates = pd.date_range(
start = '4/1/2019',
periods=30
)
# 乱数の固定
np.random.seed(100)
# 0-9の乱数で配列データ作成
y = np.random.randint(10, size=30)
x1 = y + np.random.randint(10, size=30)
x2 = np.random.randint(10, size=30)
values = np.stack([y, x1, x2], 1)
# データフレーム作成
df = pd.DataFrame(values, index=dates, columns=['y', 'x1', 'x2'])
print(df)
以下のようなデータフレームが作成される。
PandasデータフレームをRデータフレームに変換
作成したPandasデータフレームをrpy2でRデータフレームに変換してみる。
import rpy2.robjects as ro
from rpy2.robjects import pandas2ri
# PandasデータフレームをRデータフレームに変換
with ro.conversion.localconverter(ro.default_converter + pandas2ri.converter):
df_r = ro.conversion.py2rpy(df)
print(df_r)
結果は以下の通り。
PythonからRのlm関数を使って重回帰分析をする
Rのデータフレームに変換したものを、Rのlm関数で重回帰分析する。
import pandas as pd
import numpy as np
import rpy2.robjects as ro
from rpy2.robjects import pandas2ri, globalenv
from rpy2.robjects.packages import importr
# Rライブラリのインポート
base = importr('base')
stats = importr('stats')
# 日付データのインデックス作成
dates = pd.date_range(
start = '4/1/2019',
periods=30
)
# 乱数の固定
np.random.seed(100)
# 0-9の乱数で配列データ作成
values = np.random.randint(10, size=(30, 3))
# データフレーム作成
df = pd.DataFrame(values, index=dates, columns=['y', 'x1', 'x2'])
#print(df)
# PandasデータフレームをRデータフレームに変換
with ro.conversion.localconverter(ro.default_converter + pandas2ri.converter):
df_r = ro.conversion.py2rpy(df)
#print(df_r)
# Rのグローバル環境変数を設定
globalenv['df_r'] = df_r
# 重回帰分析
lm_model = stats.lm('y ~ x1 + x2', data=base.as_symbol('df_r'))
print(base.summary(lm_model))
計算過程のようなものがずらずらと出力されるが、最後にはちゃんと結果が出力される。
2019年1月14日月曜日
PythonでRのスクリプトを実行する
PythonからRを使う方法としてはPypeRなどがあるらしいが、Rで検定を実行してその結果を表示するだけなら、Pythonのsubprocessモジュールでも十分。Pythonのsubprocessでコマンドを実行するのようにPythonからコマンドを実行できるので、RscriptをPythonから実行する。
環境
Raspberry PiとRaspbian Stretch with Desktop。
RスクリプトをPythonで実行する
Rスクリプトをコマンドラインで実行するにはRscriptコマンドを使う。このコマンドは引数を受け取れるので、PythonでRスクリプトファイルを作成して、引数を含めてsubprocessモジュールで実行する。
以下のコードでは、平均が異なる正規分布に従う値を10ずつ生成してt検定を行うRスクリプトファイルを作成し、Rscriptで実行した結果を表示する。
※Rスクリプトがエラーのときにメッセージを出力するようにコード変更(2019.2.11)
結果は以下の通り。
2019年1月3日木曜日
Raspberry Piに最新のR(3.5.2)をインストールする
環境
Raspberry PiとRaspbian Stretch with Desktop。
必要パッケージのインストール
最新のRをインストールするためにソースコードからビルドするが、まずはビルドに必要なパッケージをインストールする。
ソースコードのダウンロード
ソースコードはRStudioのCRANミラーサイトからダウンロードできる。
ダウンロードしたファイルを解凍しておく。
ソースコードからインストール
Install the Latest Version of R (3.5.1) on Raspberry Pi from Sourceによると、configureファイルの修正が必要らしいので、ビルドの前に修正しておく。バージョン3.5.2のconfigureでは27539行の「::」を「;;」に修正する。viでは「:27539+Enterキー」で27539行へ移動できる。
configureファイルを修正したら、ビルドしてインストールする。
インストールが完了したらバージョンを確認。
Rの動作確認
インストールしたRで、正規分布に従う乱数を10出力してみる。




