PythonからGraphvizを使う
環境はMacでPython3.5です。
Graphvizというdot言語を用いてグラフを作成するツールがあるので使ってみた。
インストール
# コマンドから使用するときは brew install graphviz # Pythonから呼び出したいときは pip install graphviz
コード
from graphviz import * G = Digraph(format="png") # 有向グラフ初期化 G.attr('node', shape='circle') # ノードの形 G.node("my","俺") # ノード作成 N = 1 # ノード数 for i in range(N): G.node("boss"+str(i),"ボス") G.edge("boss"+str(i), "my" ) # edge(元, 先) で線をつなぐ print(G) G.render('my') # 画像作成
pngファイルが生成される。
機械学習でのCSVファイルの読み込み
Kaggleのチュートリアルを参考にした。
コードはPython3.5。
ロジスティック回帰
import csv import numpy as np from sklearn.linear_model import LogisticRegression from sklearn import metrics def read_dataset(filename): csv_file_object = csv.reader(open(filename 'r')) # header = next(csv_file_object) x = [] y = [] for row in csv_file_object: x.append(row[:2]) y.append(row[2]) return (np.array(x), np.array(y)) # トレーニングデータ読み込み X, Y = read_dataset("train.csv") X = X.astype(np.float64) # テストデータ読み込み X_, Y_ = read_dataset("test.csv") X_ = X_.astype(np.float64) # ロジスティック回帰モデル 定義 lr = LogisticRegression() # 学習 lr.fit(X, Y) # 予測 score = metrics.accuracy_score(lr.predict(X_), Y) # 正解率 print(str(score*100)+"%")
サポートベクターマシン
import csv import numpy as np from sklearn import svm from sklearn import metrics def read_dataset(filename): csv_file_object = csv.reader(open(filename, 'r')) # header = next(csv_file_object) x = [] y = [] for row in csv_file_object: x.append(row[:2]) y.append(row[2]) return (np.array(x), np.array(y)) # トレーニングデータ読み込み X, Y = read_dataset("train.csv") # テストデータ読み込み X_, Y_ = read_dataset("test.csv") # 学習 for kernel in ('linear', 'poly', 'rbf'): # SVMでの学習 clf = svm.SVC(kernel=kernel, gamma=2) clf.fit(X, Y) # 正答率 score = metrics.accuracy_score(clf.predict(X), Y) print(kernel,str(score*100)+"%")
TensorFlowつかってみた
Python3.5で書いてみた。
TensorFlow
TensorFlowは Googleが作った機械学習ライブラリのこと。 深層学習以外にも使える。 書いたコードからニューラルネットワークの可視化できるも便利。
コード
from helper import * INPUT_SIZE = 2 CATEGORY_NUM = 1 # 出力ユニット数 LEARNING_RATE = 0.02 TRAINING_LOOP = 10000 # 学習回数 SUMMARY_DIR = 'test' # ログデータを保存するディレクトリ SUMMARY_INTERVAL = 1000 # 途中経過の出力 # データセットの準備 X = np.array([[1.,3.],[3., 1.],[5.,7.]]) Y = np.array([190., 330., 660.]).reshape(3,1) with tf.Graph().as_default(): # 入力 with tf.name_scope('input'): # 入力ベクトル x = tf.placeholder(tf.float32, [None, INPUT_SIZE], name='input_x') # 正解ラベル y_ = tf.placeholder(tf.float32, [None, CATEGORY_NUM], name='labels') # 出力 with tf.name_scope('readout'): # 重みベクトル W = weight_variable([INPUT_SIZE, CATEGORY_NUM], name='weight') # バイアスベクトル b = bias_variable([CATEGORY_NUM], name='bias') # 出力ベクトル y = tf.matmul(x, W) + b # 誤差関数と更新するアルゴリズムの定義 with tf.name_scope('optimize'): # 二乗誤差 loss = tf.reduce_mean(tf.square(y_ - y)) # パラメータ更新のためのアルゴリズム train_step = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(loss) loss_summary = tf.scalar_summary('loss', loss) # 学習 with tf.Session() as sess: # ログデータを入れるファイルを開く train_writer = tf.train.SummaryWriter(SUMMARY_DIR + '/train', sess.graph) test_writer = tf.train.SummaryWriter(SUMMARY_DIR + '/test', sess.graph) # 正解率の計算 correct_prediction = tf.equal(tf.sign(y), tf.sign(y_)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) train_accuracy_summary = tf.scalar_summary('accuracy', accuracy) test_accuracy_summary = tf.scalar_summary('accuracy', accuracy) # パラメータの更新 sess.run(tf.initialize_all_variables()) for i in range(TRAINING_LOOP + 1): sess.run([train_step], {x: X, y_: Y}) # 途中経過の出力 if i % SUMMARY_INTERVAL == 0: print('step %d' % i) summary = sess.run(tf.merge_summary([loss_summary, train_accuracy_summary]), {x: X, y_: Y}) train_writer.add_summary(summary, i) summary = sess.run(tf.merge_summary([test_accuracy_summary]), {x: X, y_: Y}) test_writer.add_summary(summary, i) # テストデータを入れてみる new_x = np.array([2., 4.]).reshape(1,2) new_y = sess.run(y, {x: new_x}) print(new_y)
可視化
可視化するためのコマンドでtensorboardっていうものがあるんですが、引数にログデータの絶対パスを入れる必要がある。 いちいち打つのめんどくさいから、greadlink を使って絶対パスを取得した。
$ tensorboard --logdir=`greadlink -f test` Starting TensorBoard b'16' on port 6006 (You can navigate to http://0.0.0.0:6006)
って出てくる。
そして、http://localhost:6006 にアクセスすると
と、出てくる。
今回は回帰問題を扱ってみた。
参考URL
簡単な推薦システムを作ってみた
ある人の使用しているプログラミング言語から、次に学習すべきプログラミング言語の推薦システムを簡単に作った。
Python3.5でかいた。 参考書籍はこれ。
データサイエンティスト養成読本 機械学習入門編 (Software Design plus)
- 作者: 比戸将平,馬場雪乃,里洋平,戸嶋龍哉,得居誠也,福島真太朗,加藤公一,関喜史,阿部厳,熊崎宏樹
- 出版社/メーカー: 技術評論社
- 発売日: 2015/09/10
- メディア: 大型本
- この商品を含むブログ (7件) を見る
データ
データはこれ。
Ruby,Python,HTML/CSS/JS,C,C++,Java,PHP,C# 0,5,2,0,3,4,1,0 4,0,0,0,0,0,5,0 0,0,0,5,4,0,0,0 0,3,2,0,5,4,0,0 0,5,4,0,0,2,0,0 3,0,2,0,5,4,0,0 0,0,0,0,4,3,0,5 0,1,2,5,4,0,0,3 0,4,0,5,0,0,0,0 0,4,0,0,5,0,0,0 0,0,0,0,4,5,0,0 3,4,1,0,0,5,2,0 5,4,2,0,0,0,0,3 4,5,0,0,0,0,0,0 3,0,4,0,0,5,0,0 5,0,4,0,3,0,0,0 3,0,0,0,0,5,4,0 0,0,3,5,4,0,0,0 0,0,0,5,4,0,0,3 0,4,0,5,0,3,0,0 4,0,3,0,0,0,0,5 0,4,0,0,5,0,0,0
Twitterのフォロワーさんのプロフィールを元にデータを作りました。 プロフィールの一番左に書いてあるプログラミング言語を評価値を5として、右にいくにつれてデクリメント。
例えば、 C/C++/Ruby/JS なら Cの評価値を5、C++の評価値を4、Rubyの評価値を3、そしてJSの評価値を2みたいな感じで、最大5個まで評価値をつけていった。
書いていない言語は触ったことがないものとして、評価値を0にした。
コード
処理としては、推薦したい人が習得している言語と、似たような傾向を持った人が習得している言語を推薦している。
似てるか似てないかは、コサイン距離を用いて表現している。
# coding:utf-8 import numpy as np import scipy as sp from scipy.spatial.distance import cosine def calc_item_score(target_user_index, user_rating_matrix): """ 指定したアイテムの評価値を計算する :param target_user_index: int: ユーザのIndex :param user_rating_matrix: numpy.ndarray: ユーザアイテムの評価値行列 :return: float: 指定したアイテムの評価値 """ target_user_ratings = user_rating_matrix[target_user_index] item_similarity = np.zeros(len(target_user_ratings)) for compare_user_index in np.arange(len(user_rating_matrix)): compare_user_ratings = user_rating_matrix[compare_user_index] if compare_user_index == target_user_index: # 同一ユーザのときは類似度計算はしない continue # ユーザの類似度をコサイン距離から求める user_similarity = 1.0 - cosine(target_user_ratings, compare_user_ratings) # 求めたコサイン距離をそのユーザの評価値に乗じて足しあわせる item_similarity += user_similarity * compare_user_ratings return item_similarity # データ読み込み data = sp.loadtxt("data.csv",delimiter=",",skiprows=1) # 推薦計算 predict_ratings = calc_item_score(0,data) # 推薦したい言語の取得 header = ['Ruby','Python','HTML/CSS/JS','C','C++','Java','PHP','C\#'] zero_index = np.nonzero(data[0,:] != 0) for i in zero_index: predict_ratings[i] = 0.0 max_index = np.where(predict_ratings == predict_ratings.max()) print("次は ",end="") print(header[max_index[0][0]],end="") print(" をやるんやで")
実行結果
% python main.py 次は Ruby をやるんやで
となる。
サポートベクターマシンによる分類
Python3.5でやってみた
サポートベクターマシン
データと境界線との距離の最大化を戦略とする手法。
非線形変換により線形分離ができないものでも分類可能。
かなり精度が良く、いろんなところに使われている。
コード
# coding:utf-8 import numpy as np import matplotlib.pyplot as plt from sklearn import datasets from sklearn import svm from sklearn import cross_validation # データセット X = np.c_[ (1.3, .8), (1.2, .5), (1.3, 2.1), (-1.5, -1), (-1.4, -.9), (-1.3, -1.2), (-1.1, -.2), (-1.2, -.4), # -- (1, -1), (.2, -2), (.5, -2.4), (.2, -2.3), (0, -2.7), (.4, -.7), (-.5, 1.2), (-1.5, 2.1),].T # 正解ラベル Y = [0] * 8 + [1] * 8 # 画面の数 fignum = 1 # 学習と描画 for kernel in ('linear', 'poly', 'rbf'): # SVMでの学習 clf = svm.SVC(kernel=kernel, gamma=2) clf.fit(X, Y) # クリア plt.figure(fignum, figsize=(4, 3)) plt.clf() # データセットのプロット plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=80, facecolors='none', zorder=10) plt.scatter(X[:, 0], X[:, 1], c=Y, zorder=10, cmap=plt.cm.Paired,s=100) # maxとmin plt.axis('tight') x_min = -3 x_max = 3 y_min = -3 y_max = 3 # 等高線を書くための準備 XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j] Z = clf.decision_function(np.c_[XX.ravel(), YY.ravel()]) Z = Z.reshape(XX.shape) plt.figure(fignum, figsize=(4, 3)) plt.pcolormesh(XX, YY, Z > 0, cmap=plt.cm.Paired) # 描画画面の設定 plt.xlim(x_min, x_max) plt.ylim(y_min, y_max) plt.xticks(()) plt.yticks(()) fignum = fignum + 1 # plt.scatter(X[:8,0],X[:8,1],c="blue",s=100) # plt.scatter(X[8:,0],X[8:,1],c="red",s=100) plt.show()
こんな感じです
matplotlib 複数のグラフを表示
# coding: utf-8 import matplotlib.pyplot as plt import numpy as np # データ x = np.linspace(0, 2 * np.pi, 400) y = np.sin(x ** 2) # クリア plt.close('all') # どのように分割するかを行列で指定 f, ax = plt.subplots(2,2) # それぞれの要素に描画 ax[0,0].plot(x, y) ax[0,0].set_title('Simple plot') ax[0,1].plot(-x, -y) ax[0,1].set_title('Reverse Simple plot') ax[1,0].plot(x, y) ax[1,0].set_title('Simple plot') ax[1,1].plot(-x, -y) ax[1,1].set_title('Reverse Simple plot') # 表示 plt.show()
行列で指定できるの便利
参考URL
pylab_examples example code: subplots_demo.py — Matplotlib 1.5.1 documentation
回帰学習を簡単に実装してみた
Python3.5で教師あり学習の回帰の簡単な実装。
sinカーブを学習してみた。 パラメータの個数は1,3,5,7。
# coding: utf-8 import scipy as sp import matplotlib.pyplot as plt # 次元ごとに取得 x = sp.arange(0, 10, 0.1) y = [ sp.sin(i) for i in x] # NaNの除去 # x = x[~sp.isnan(y)] # y = y[~sp.isnan(y)] # グラフに散布 plt.scatter(x,y) # 学習(回帰) fx = sp.linspace(0, x[-1], 1000) f1 = sp.poly1d(sp.polyfit(x, y, 1)) f3 = sp.poly1d(sp.polyfit(x, y, 3)) f5 = sp.poly1d(sp.polyfit(x, y, 5)) f7 = sp.poly1d(sp.polyfit(x, y, 7)) # 描画 plt.plot(fx, f1(fx), c="red", linewidth=2) plt.plot(fx, f3(fx), c="green", linewidth=2) plt.plot(fx, f5(fx), c="blue", linewidth=2) plt.plot(fx, f7(fx), c="pink", linewidth=2) # グラフの設定と表示 plt.title("Title") plt.xlabel("x label") plt.ylabel("y label") plt.xticks([w*7*24 for w in range(10)], ['week %i'%w for w in range(10)]) plt.legend(["d=%i" % f1.order, "d=%i" % f3.order, "d=%i" % f5.order, "d=%i" % f7.order], loc="upper left") plt.autoscale(tight=True) plt.grid() plt.show()
こんな感じのグラフが出たらOK。