旅行好きなソフトエンジニアの備忘録

プログラミングや技術関連のメモを始めました

【C#】 C#からDOSコマンドでPythonスクリプトを呼び出す

C#からPythonを呼び出す方法はいくつかあるようで、IronPythonを利用する方法がまずヒットしたのですが、IronPythonではサポートされていないライブラリを利用したスクリプトを呼び出したいと考えています。そのため、こちら(DOSコマンドを実行し出力データを取得する: .NET Tips: C#, VB.NET)の方法を利用してみることにしました。

// プロセスクラスのインスタンス化
var p = new Process();

// cmd.exeのパスを取得
p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec");
// 出力を読み取れるようにする
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = false;
// ウインドウを表示しないようにする
p.StartInfo.CreateNoWindow = true;
// hello.pyを実行する(ファイルにはprint('Hello')と書かれている)
p.StartInfo.Arguments = @"/c python hello.py";

// 起動
p.Start();

// 出力を読み取る
string result = p.StandardOutput.ReadToEnd();

// プロセス終了まで待機する
p.WaitForExit();
p.Close();

// コンソールにHelloと表示される
Console.WriteLine(result);

【OpenOffice】 作成したグラフを削除する

Excelが入っていないPCがあって、そこでOpenOffice Calcを使っているのですが、Excelとは勝手が違って面倒です。今日は作成したグラフを削除できず調べてみると解決策が書かれていました。

blog-orion110.at.webry.info

一旦グラフと異なる場所をクリックしてグラフを抜け出し、その後グラフをクリックしてDelキーで削除できました。

【料理】 ゴーヤチャンプルー

ここを元に作成。 www.sirogohan.com

材料(二人分)

  • ゴーヤ   1/2本

  • 木綿豆腐  300g

  • バラ肉  100g

  • 卵     1個

  • 塩コショウ 適量

  • サラダ油/ごま油

  • 醤油

作り方

1. 木綿豆腐をキッチンペーパーでくるんで水切りする
2. 卵1個をといておく
3. ゴーヤを縦半分に切る
4. スプーンを使って種を取り除く
5. 4~5mm幅に切る
6. 塩小さじ1/4をまぶし、軽く混ぜ合わせる
7. 豚バラ肉を3~4cm幅に切り、塩をうっすら、粗挽き胡椒を多めにふる
8. フライパンにサラダ油をひき、温まったら豆腐を入れる
9. 豆腐を取り出し、ごま油小さじ1を追加し、ゴーヤを炒める
10. 豚バラ肉を入れて炒める
11. 塩ひとつまみ強、胡椒少々で味付けし、溶き卵を流し入れる
12. 10秒待ってフライパンを振る。最後に醤油を小さじ2回しかける

【数学】 フィッシャーの線形判別を理解するのに有効なサイトのメモ

フィッシャーの線形判別について調べていたのですが、分かりやすく書いてくれているサイトを見つけたのでメモします。

理論についてはこちらが分かりやすいです。

s0sem0y.hatenablog.com

コードが必要であればこちらにコード付きで記事を書かれています。

aidiary.hatenablog.com

【Python】 LSTMによる時系列データの予測

前回SimpleRNNによる時系列データの予測を行いましたが、今回はLSTMを用いて時系列データの予測を行ってみます。

ni4muraano.hatenablog.com

LSTMはSimpleRNNと比較すると長期依存性の高いデータに有効とのことなので、50回に一回パルスが発生する信号に対する予測をSimpleRNNとLSTMで行ってみました。

import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.layers.recurrent import SimpleRNN, LSTM
from keras.optimizers import Adam
from keras.callbacks import EarlyStopping

np.random.seed(0)

def generate_periodic_data():
    pulse = []
    for i in range(1000):
        if i%25 == 0:
            pulse.append(1.0)
        else:
            pulse.append(0.0)

    return np.array(pulse)


def generate_data(pulse, length_per_unit, dimension):
    sequences = []
    target = []
    for i in range(0, pulse.size - length_per_unit):
        sequences.append(pulse[i:i + length_per_unit])
        target.append(pulse[i + length_per_unit])

    X = np.array(sequences).reshape(len(sequences), length_per_unit, dimension)
    Y = np.array(target).reshape(len(sequences), dimension)

    N_train = int(len(sequences)*0.8)
    X_train = X[:N_train]
    X_validation = X[N_train:]
    Y_train = Y[:N_train]
    Y_validation = Y[N_train:]

    return (X_train, X_validation, Y_train, Y_validation)


def build_model(input_shape, hidden_layer_count):
    model = Sequential()
    model.add(LSTM(hidden_layer_count, input_shape=input_shape))
    model.add(Dense(input_shape[1]))
    model.add(Activation('linear'))
    model.compile(loss='mse', optimizer=Adam())
    return model


# 一つの時系列データの長さ
LENGTH_PER_UNIT = 201
# 一次元データを扱う
DIMENSION = 1
# パルスの生成
pulse = generate_periodic_data()
# トレーニング、バリデーション用データの生成
X_train, X_validation, Y_train, Y_validation = generate_data(pulse, LENGTH_PER_UNIT, DIMENSION)

# LSTM隠れ層の数
HIDDEN_LAYER_COUNT = 25
# 入力の形状
input_shape=(LENGTH_PER_UNIT, DIMENSION)
# モデルの生成
model = build_model(input_shape, HIDDEN_LAYER_COUNT)

# モデルのトレーニング
epochs = 500
batch_size = 10
early_stopping = EarlyStopping(monitor='val_loss', patience=10, verbose=1)
model.fit(X_train, Y_train,
          batch_size=batch_size,
          epochs=epochs,
          validation_data=(X_validation, Y_validation),
          callbacks=[early_stopping])

# 予測を行う
part_of_sequence = np.array([pulse[i] for i in range(LENGTH_PER_UNIT)])
predicted = [None for i in range(LENGTH_PER_UNIT)]
Z = X_train[:1, :, :]
for i in range(pulse.size - LENGTH_PER_UNIT + 1):
    y_ = model.predict(Z)
    # 予測結果を入力として利用するため、第0項を削除し予測結果をひっつける
    Z = np.concatenate(
            (Z.reshape(LENGTH_PER_UNIT, DIMENSION)[1:], y_),
            axis=0).reshape(1, LENGTH_PER_UNIT, DIMENSION)
    predicted.append(y_.reshape(-1))
predicted = np.array(predicted)

# 予測結果の描画
plt.rc('font', family='serif')
plt.figure()
plt.ylim([0.0, 1.1])
plt.plot(pulse, linestyle='dotted', color='#aaaaaa')
plt.plot(part_of_sequence, linestyle='dashed', color='black')
plt.plot(predicted, color='black')
plt.show()

SimpleRNNの予測結果がこちらでf:id:ni4muraano:20170617162126p:plain

LSTMの予測結果がこうなりました。f:id:ni4muraano:20170617162147p:plain

LSTMはもう少し綺麗に予測できることを期待していたのですが、パラメータチューニングを行っていないので上図のような結果になったのかなと思います。とはいえ閾値決めてあげることで後処理でどうにでもなりそうなのでSimpleRNNよりは良い結果なのではと思います。

詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

【Python】 SimpleRNNで月平均気温を予測する

画像だけでなく時系列データにも手を出してみたい、ということで書籍「詳解ディープラーニング」を購入しました。書籍第5章から時系列データを扱っているのですが、そこで紹介されているSimpleRNNの例を写経します。書籍ではノイズの入ったサイン波の予測を行っているのですが、ここでは気象庁から取得した年別の月平均気温を使って予測を行います。

www.data.jma.go.jp


import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.layers.recurrent import SimpleRNN
from keras.optimizers import Adam
from keras.callbacks import EarlyStopping

np.random.seed(0)

def generate_temperatures():
    # 月平均気温
    temperatures = [[7.6, 6.0, 9.4, 14.5, 19.8, 22.5, 27.7, 28.3, 25.6, 18.8, 13.3, 8.8], #2000年
                    [4.9, 6.6, 9.8, 15.7, 19.5, 23.1, 28.5, 26.4, 23.2, 18.7, 13.1, 8.4], #2001年
                    [7.4, 7.9, 12.2, 16.1, 18.4, 21.6, 28.0, 28.0, 23.1, 19.0, 11.6, 7.2],#2002年
                    [5.5, 6.4, 8.7, 15.1, 18.8, 23.2, 22.8, 26.0, 24.2, 17.8, 14.4, 9.2], #2003年
                    [6.3, 8.5, 9.8, 16.4, 19.6, 23.7, 28.5, 27.2, 25.1, 17.5, 15.6, 9.9], #2004年
                    [6.1, 6.2, 9.0, 15.1, 17.7, 23.2, 25.6, 28.1, 24.7, 19.2, 13.3, 6.4],
                    [5.1, 6.7, 9.8, 13.6, 19.0, 22.5, 25.6, 27.5, 23.5, 19.5, 14.4, 9.5],
                    [7.6, 8.6, 10.8, 13.7, 19.8, 23.2, 24.4, 29.0, 25.2, 19.0, 13.3, 9.0],
                    [5.9, 5.5, 10.7, 14.7, 18.5, 21.3, 27.0, 26.8, 24.4, 19.4, 13.1, 9.8],
                    [6.8, 7.8, 10.0, 15.7, 20.1, 22.5, 26.3, 26.6, 23.0, 19.0, 13.5, 9.0],
                    [7.0, 6.5, 9.1, 12.4, 19.0, 23.6, 28.0, 29.6, 25.1, 18.9, 13.5, 9.9],
                    [5.1, 7.0, 8.1, 14.5, 18.5, 22.8, 27.3, 27.5, 25.1, 19.5, 14.9, 7.5],
                    [4.8, 5.4, 8.8, 14.5, 19.6, 21.4, 26.4, 29.1, 26.2, 19.4, 12.7, 7.3],
                    [5.5, 6.2, 12.1, 15.2, 19.8, 22.9, 27.3, 29.2, 25.2, 19.8, 13.5, 8.3],
                    [6.3, 5.9, 10.4, 15.0, 20.3, 23.4, 26.8, 27.7, 23.2, 19.1, 14.2, 6.7],
                    [5.8, 5.7, 10.3, 14.5, 21.1, 22.1, 26.2, 26.7, 22.6, 18.4, 13.9, 9.3],
                    [6.1, 7.2, 10.1, 15.4, 20.2, 22.4, 25.4, 27.1, 24.4, 18.7, 11.4, 8.9]]#2016年
    temperatures = np.array(temperatures)
    temperatures = np.reshape(temperatures, (temperatures.size))
    return temperatures


def generate_data(temperatures, length_per_unit, dimension):
    sequences = []
    target = []
    for i in range(0, temperatures.size - length_per_unit):
        sequences.append(temperatures[i:i + length_per_unit])
        target.append(temperatures[i + length_per_unit])

    X = np.array(sequences).reshape(len(sequences), length_per_unit, dimension)
    Y = np.array(target).reshape(len(sequences), dimension)

    N_train = int(len(sequences) * 0.9)
    X_train = X[:N_train]
    X_validation = X[N_train:]
    Y_train = Y[:N_train]
    Y_validation = Y[N_train:]

    return (X_train, X_validation, Y_train, Y_validation)


def build_model(input_shape, hidden_layer_count):
    model = Sequential()
    model.add(SimpleRNN(hidden_layer_count, input_shape=input_shape))
    model.add(Dense(input_shape[1]))
    model.add(Activation('linear'))
    model.compile(loss='mse', optimizer=Adam())
    return model


# 一つの時系列データの長さ
LENGTH_PER_UNIT = 24
# 一次元データを扱う
DIMENSION = 1
# 年別月平均気温の生成
temperatures = generate_temperatures()
# トレーニング、バリデーション用データの生成
X_train, X_validation, Y_train, Y_validation = generate_data(temperatures, LENGTH_PER_UNIT, DIMENSION)

# SimpleRNN隠れ層の数
HIDDEN_LAYER_COUNT = 25
# 入力の形状
input_shape=(LENGTH_PER_UNIT, DIMENSION)
# モデルの生成
model = build_model(input_shape, HIDDEN_LAYER_COUNT)

# モデルのトレーニング
epochs = 500
batch_size = 10
early_stopping = EarlyStopping(monitor='val_loss', patience=10, verbose=1)
model.fit(X_train, Y_train,
          batch_size=batch_size,
          epochs=epochs,
          validation_data=(X_validation, Y_validation),
          callbacks=[early_stopping])

# 予測を行う
part_of_sequence = np.array([temperatures[i] for i in range(LENGTH_PER_UNIT)])
predicted = [None for i in range(LENGTH_PER_UNIT)]
Z = X_train[:1, :, :]
for i in range(temperatures.size - LENGTH_PER_UNIT + 1):
    y_ = model.predict(Z)
    # 予測結果を入力として利用するため、第0項を削除し予測結果をひっつける
    Z = np.concatenate(
            (Z.reshape(LENGTH_PER_UNIT, DIMENSION)[1:], y_),
            axis=0).reshape(1, LENGTH_PER_UNIT, DIMENSION)
    predicted.append(y_.reshape(-1))
predicted = np.array(predicted)

# 予測結果の描画
plt.rc('font', family='serif')
plt.figure()
plt.ylim([0.0, 35.0])
plt.plot(temperatures, linestyle='dotted', color='#aaaaaa')
plt.plot(part_of_sequence, linestyle='dashed', color='black')
plt.plot(predicted, color='black')
plt.show()


割と無難な結果を得ることが出来ました。 f:id:ni4muraano:20170615213133p:plain

詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~

詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~