【Python, sklearn】モデル名の表示
documentation読んでも上手く見つけられず、他人のコードを読み漁って発見したのでメモ。
from sklearn.linear_model import LogisticRegression # ロジスティック回帰 model = LogisticRegression() clf = model.fit(X_train,y_train) print(clf.__class__.__name__)
文字列型で"LogisticRegression"が返る。
Google Homeで「室内留学」のすゝめ
用途:「室内留学」
僕の場合の用途は、自宅(※独り暮らし)で英会話ができる「室内留学」環境の構築です。
Google Homeを利用する利点は、以下のようなものが挙げられます。
音声操作のため、半強制的かつ手軽に英語を話す/聞く環境下を構築できる
- 例えば目覚まし時計のアラームを止めるためにも、英語を話す必要が生じます
- 朝には身支度をしながら「Tell me 'MyDay'」と言うだけで、今日の天気・最新のニュースを英語で流してくれます
- "How can I get to the office"と聞くと、何時の電車に乗れそうかを教えてくれます
- 何か調べたいときにも、わざわざスマホやPCを立ち上げることなく音声で処理しようとして英語を発するようになります
英会話教室や実際の留学と違って相手が「忖度」してくれない
- Google Homeさんは発音が悪いと全く相手にしてくれません
- 向こうから助け舟を出してくれることも、ほとんどありません
- 目的語が足りないなど一定の条件下で聞き返してくれることも
- 一方で生身の人間と違い、何回も話しかけても嫌な顔をしないという利点もあります
取りあえず一日稼働させただけですが、結構な量の英語を話す/聞くことができたので、今後も続けていきたいと思っています。
「Google Home」か「Google Home Mini」か
店頭で店員に確認したところ
機能的に「できること」の違いはない
マイクとスピーカーの性能が違う
- Miniはマイクが1個で、通常版は2個。通常版は高さがある分、聞き取る可能性が高くなる
- スピーカーとしての音質/音域が違う
とのことでした。
スピーカーについては想定用途にも依りますが、店頭で確認すべきかと思います。個人的には結構違いました。
今回の用途はGoogle Homeとのやり取りが大切になるため、コミュニケーションの障害になりうる要素は極力排除したいと思い、倍の値段にはなりますが通常版を選択しました。
諸設定(参考までに)
- Google Homeのデフォルト初期設定
- マニュアルに沿って設定します。この初期設定の終了時点では言語設定が日本語になっています。もちろん英語で話しかけても理解してくれません。
- 言語設定の変更
- スマホのGoogle Homeアプリから、言語を"English"に変更します
- ニュースの設定
- スマホのGoogle Homeアプリから、英語のニュースを追加し、(必要に応じて日本語のニュースを外し)流す順番を整備します
- 音楽の設定
- Google Home - Spotifyのアカウントを作成しGoogle Homeと連携すると、洋楽を好きなだけ楽しめます
- spotifyのスマホアプリで歌詞を確認しながら聞くと、ヒアリングの勉強になるかなとも思います
PythonでRFM分析(任意のクラスタ数にK-meansクラスタリング)
やったこと
サンプル
想定データ構造
UserID | Recency | Frequency | Monetary | (K-meansResult) |
---|---|---|---|---|
000000 | 123 | 456 | 789 | 0 |
000001 | 378 | 764 | 924 | 0 |
000002 | 578 | 267 | 532 | 1 |
Pythonコード
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import pandas as pd df = pd.read_csv('df.csv') import numpy as np from sklearn.cluster import KMeans import matplotlib.pyplot as plt from matplotlib import cm from mpl_toolkits.mplot3d import Axes3D df.iloc[:,2] = np.log10(df.iloc[:,2]+1) df.iloc[:,3] = np.log10(df.iloc[:,3]+1) CLUSTERS_NUM = 5 pred = KMeans(n_clusters=CLUSTERS_NUM).fit_predict(df.iloc[:,1:4]) df = pd.concat([df, pd.DataFrame(pred)], axis=1) fig = plt.figure() ax = Axes3D(fig) ax.set_xlabel("Recency") ax.set_ylabel("Log10(Frequency)") ax.set_zlabel("Log10(Monetary)") d = [] for cluster_i in range(CLUSTERS_NUM): d.append(df[df.iloc[:,4]==cluster_i]) c = cm.hot(float(cluster_i) / CLUSTERS_NUM) ax.plot(d[cluster_i].iloc[:,1], d[cluster_i].iloc[:,2], d[cluster_i].iloc[:,3], "o", color=c, ms=2, mew=0.5) plt.show()
有料課金しているWebサービス一覧 (Aug, 2018)
自分の家計簿管理のために列挙してみる。
Service Name | Price(tax included) | Unit |
---|---|---|
日経Wプラン(宅配 + 電子版) | 5,900円 | 月 |
Amazonプライム | 3,900円 | 年 |
Github for Developer | $84.00 | 年 |
Google Drive 100G | 2700円 | 年 |
DAZN | 1,890円 | 月 |
もっとあるかと思ったけど、意外と少なかった。
「スタバなう」ツイートの画像は本当にスタバか、CNNで判定してみた
はじめに
Twitterで1日に一度くらいは「スタバなう」という投稿を目にする気がします。ただし大抵はキラキラ女子大生などを揶揄しており、ラーメンなどの画像とともに投稿されることが多いです。
今回は、画像分類に秀でたConvolutional Neural Network (CNN)を用いて、「スタバなう」という語句を含むツイートの添付画像が本当にスタバの画像か否か判定してみようと思います。
データセットの構築
下記の記事でも触れたウェブサービスを用いて「スタバなう」という語句を含むツイートの添付画像を収集しました。
手動でスタバの画像(正例)とそうでないもの(負例)に分類しました。枚数が中途半端なのは、ここで飽きたからです。
- 正例:168枚
- 負例:259枚
この段階で、検証用のデータセットとして以下の枚数分を取り出しました(当然、訓練用のデータセットとしては使いません)。
- 正例:40枚
- 負例:60枚
CNNの構築と学習
CNNの構築と学習には、下記の記事のPythonコードを再利用しました。もちろんパス名など細かい部分は修正しています(Github)。
CNNの構造
学習
327枚の訓練用のデータセットを学習させた結果は、下記の画像のようになりました。40ステップ辺りで収束していると分かります。
分類結果
予想\正解 | 正 | 負 |
---|---|---|
正 | 54 | 21 |
負 | 6 | 19 |
Precision = 0.72
Recall = 0.90
F-measure = 0.7999
指標についての説明はこちら。
F値 - 機械学習の「朱鷺の杜Wiki」
正と予想したのに正解は負だった画像(表の21)を調べてみると、スタバ以外のコーヒーチェーンの画像などが含まれていました。コーヒーカップは写っているのでロゴで判定するしかなく、これは間違えても仕方ないかなと思います。
【Twitter】特定キーワード&アカウントの画像を一括ダウンロードできるウェブサービス"timg"が便利
べき分布の対数を取る(ヒストグラムで可視化)
Jupyter Notebook
# 参考:https://qiita.com/tibigame/items/fa746573fbaf4666bc33 import numpy as np import scipy import matplotlib.pyplot as plt %matplotlib inline import seaborn as sns sns.set(style="whitegrid")
# 指数分布 # 平均して10分に1度起こる現象の発生間隔 rand_exp_scale = 10.0 rand_exp_size = 10000 rand_exp = np.random.exponential(scale=rand_exp_scale, size=rand_exp_size) fig = plt.figure() ax = fig.add_subplot(1,1,1) plt.title('Histgram of np.random.exponential') ax.set_ylabel('Frequency') sns.distplot(rand_exp, kde=False, rug=False, bins=50)
log_rand_exp = np.log(rand_exp ) fig = plt.figure() ax = fig.add_subplot(1,1,1) plt.title('Histgram of Log(np.random.exponential)') ax.set_ylabel('Frequency') sns.distplot(log_rand_exp, kde=False, rug=False, bins=50)
pareto = np.random.pareto(a=2.718281828, size=10000) fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.set_ylabel('freq') sns.distplot(pareto, kde=False, rug=False, bins=50)
# パレート分布 log_pareto = np.log(pareto) fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.set_ylabel('freq') sns.distplot(log_pareto, kde=False, rug=False, bins=50)