IoTデータ学習して chainerで時系列予測を出力する。
index:
概要
機械学習の関連となります。
ディープラーニングも対応できそうなchainer を使って、IoTデータの数値予測してみました。
前は、LSTMのKeras+ tensorFlow 版でしたが、
Ubuntu以外のLinux で、tensorFlow最新インストールが困難でしたので、
別のライブラリを探し、chainer 同等の機能が追加できるか検討してみました。
参考のページさま
chainerでsin関数を学習させてみた
https://qiita.com/hikobotch/items/018808ef795061176824
Chainerで始めるニューラルネットワーク
https://qiita.com/icoxfog417/items/96ecaff323434c8d677b
結果
件数的には、やや少なめですが
最近の、IoT温度値を程読ませて
matplotlib のグラフ表示
一次元配列を読ませています。
predict: 予測
temp : 温度/実測値
前半は、やや曲線の波形でしたが
後半は、ほぼ直線的でした。
まだ調整が必要かもしれません。
実行ログ:
code
Github
python3.5, cha_iot_rand.py
デモ用で、乱数を読ませていますが。
使用時は、IoT実測値を読ませて学習させています。
https://gist.github.com/kuc-arc-f/fd5d3981a9ce05087f74fdaa908841b2#file-cha_iot_rand-py
update
=== Update:2018/02/19===
csv から、温度データを読み込み処理を追加しました。 (pandas )
https://github.com/kuc-arc-f/cha_iot_pd
まとめ
その他の、使えそうな機械学習ライブラリ
があれば、調査していと思います。
確率
index:
必要なimport
import numpy as np import numpy.random as random import scipy as sp import pandas as pd from pandas import Series, DataFrame import matplotlib.pyplot as plt import matplotlib as mpl
データの準備
# dice_data = np.array([1, 2, 3, 4, 5, 6])
抽出します
# from numpy import random random.seed(0) # 抽出します print( random.choice(dice_data, 1))
結果
[5]
この試行結果を根元事象(基本事象)といいます
統計的確率
抽出した、各値の出現する確率を求める。
# 試行、1000回行う。 calc_steps = 1000 # seedの固定 random.seed(0) # 1〜6のデータの中から、抽出を実施 count_all_dice = random.choice(dice_data, calc_steps) count_all_dice # # 計算結果を入れる prob_data = np.array([]) # prob_data = np.array([]) for i in range(1, 7): n= float(len(count_all_dice[count_all_dice==i]) ) / float(calc_steps ) print(i, "ritu=", n ) prob_data = np.append(prob_data ,n) print(prob_data)
結果
(1, 'ritu=', 0.171) (2, 'ritu=', 0.157) (3, 'ritu=', 0.157) (4, 'ritu=', 0.183) (5, 'ritu=', 0.161) (6, 'ritu=', 0.171) [0.171 0.157 0.157 0.183 0.161 0.171]
ほぼ1/6に近いのがわかります。これは
統計的確率
という。
確立変数
ある変数の値をとる確率が存在する変数のことです。例えば、
さいころを投げて出る目は{1, 2, 3, 4, 5, 6}のいずれかであり、
それぞれの目が出る確率はであることから、さいころを投げて出る目は確率変数であると言えます。
確率分布:
確率変数がとる値とその値をとる確率の対応の様子を「確率分布」と言います。
https://bellcurve.jp/statistics/course/6596.html
ベルヌーイ分布:
結果が2種類しかない試行をベルヌーイ試行といいます。
1回のベルヌーイ試行において各事象が生じる確率の分布
prob_be_data = np.array([]) coin_data = np.array([0, 0, 0, 0, 0, 1, 1, 1]) # for i in np.unique(coin_data): n= (float(len(coin_data[coin_data==i]) ) / float(len(coin_data) )) print(i, " = ", n) prob_be_data = np.append(prob_be_data, n )
結果
(0, ' = ', 0.625) (1, ' = ', 0.375)
二項分布:
独立なベルヌーイ試行をn回繰り返します。
パラメータは順に、試行回数(n)、確率(p)、サンプル数
を示しています。
https://ja.wikipedia.org/wiki/%E4%BA%8C%E9%A0%85%E5%88%86%E5%B8%83
# 二項分布 random.seed(0) x = random.binomial(30, 0.5, 1000) plt.hist(x) plt.grid(True) plt.show()
ポアソン分布:
稀な事象が起きる確率の時、使われます。
https://bellcurve.jp/statistics/course/6984.html
# ポアソン分布 x = random.poisson(7, 1000) plt.hist(x) plt.grid(True)
分散、標準偏差、要約統計量
index:
必要なimport
# import numpy as np import numpy.random as random import scipy as sp import pandas as pd from pandas import Series, DataFrame import matplotlib.pyplot as plt import matplotlib as mpl
サンプルのデータ: 特定に抽出した人物のサンプル。データ。
=>アンケート値でなく、適当なランダム値
height :身長 150 -180 ,random
weight :体重 50 - 80 , random
coffee :週にcoffeeを飲む回数
tea : 週に お茶を飲む回数
分散
ばらつきを示す。
https://bellcurve.jp/statistics/course/5919.html
データを読み込みます。
# person = pd.read_csv("dat_person.csv") person.head()
結果:
cofee heiht tea weight 0 13 169 19 58 1 11 158 14 59 2 6 160 10 70 3 15 150 1 77 4 3 150 17 62
分散の表示
#
person.coffee.var()
結果
26.819871794871798
標準偏差
ばらつきを示す。分散の平方根とる。
https://bellcurve.jp/statistics/course/5924.html
coffee の標準偏差
#
person.coffee.std()
結果
5.178790572602043
平均値
print( person.coffee.mean())
結果
10.275
中央値
print( person.coffee.median())
結果
11.0
最頻値
最も頻度が多い値
print( person.coffee.mode())
結果
0 12 dtype: int64
要約統計量
https://ja.wikipedia.org/wiki/%E8%A6%81%E7%B4%84%E7%B5%B1%E8%A8%88%E9%87%8F
標本の分布の特徴を代表的に(要約して)表す統計学上の値であり、
統計量の一種。記述統計量(英: descriptive statistics value)、
基本統計量、代表値(英: representative value)ともいう
正規分布の場合は、平均と、分散または標準偏差で分布を記述できる。
正規分布からのずれを知るためには、尖度や歪度などの高次モーメントから求められる統計量を用いる。
正規分布から著しく外れた場合には、
より頑健な中央値、四分位点、最大値・最小値や最頻値が用いられる。
「頑健」とは分布の非対称性や外れ値などの影響を受けにくいことを意味する統計用語である
#
person.coffee.describe()
結果:上から
データ数
平均値
標準偏差
最小値
第一四分位数
第二四分位数
第三四分位数
最大値
count 40.000000 mean 10.275000 std 5.178791 min 0.000000 25% 6.000000 50% 11.000000 75% 13.500000 max 19.000000 Name: coffee, dtype: float64
四分位範囲
=> 散らばりの程度を表す尺度の一つ。
「75パーセンタイル(第三四分位数)-25パーセンタイル(第一四分位数)」として求められる。
# desc= person.coffee.describe() (desc[6] -desc[4] )
結果
7.5
pandas info()
index:
.info()
dataFrame についての、情報が表示できます。
importしておきます
# import numpy as np import numpy.random as random import scipy as sp import pandas as pd from pandas import Series, DataFrame
データの定義
# # a1 = { 'ID':['11','12','13', '14' ] ,'num1':[ 101 ,102,103 , 101] ,'num2':[ 201 ,202,203 ,204 ] ,'num3':[ 301 ,302,303 ,304 ] } frame1 = DataFrame(a1 ) print(frame1 )
結果:
ID num1 num2 num3 0 11 101 201 301 1 12 102 202 302 2 13 103 203 303 3 14 101 204 304
info() 実行
frame1.info()
結果:
null 判定, 型の表示ができます。
# <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 4 columns): ID 4 non-null object num1 4 non-null int64 num2 4 non-null int64 num3 4 non-null int64 dtypes: int64(3), object(1) memory usage: 148.0+ bytes
mean
平均値、 num1 の平均を出力します。
# # 平均値 print( frame1.num1.mean())
結果:
# 101.75
median()
中央値
# 中央値 print( frame1.num1.median())
結果:
101.5
mode()
最頻値:出現する頻度が多い値
print(frame1.num1.mode())
結果:
0 101 dtype: int64
describe()
要約統計量 の表示
# a1 =frame1.describe() print(a1 )
結果:
num1 num2 num3 count 4.000000 4.000000 4.000000 mean 101.750000 202.500000 302.500000 std 0.957427 1.290994 1.290994 min 101.000000 201.000000 301.000000 25% 101.000000 201.750000 301.750000 50% 101.500000 202.500000 302.500000 75% 102.250000 203.250000 303.250000 max 103.000000 204.000000 304.000000
出力内容:
データ数
平均値
標準偏差
最小値
第一四分位数
第二四分位数
第三四分位数
最大値
pandas sort_values()
ソート
指定列で、ソートする。
a2 = {'ID':['11','12','13' ] ,'birth':[1980,1973,1970 ] ,'type1':['a','b','c' ]} frame2 = DataFrame( a2) #frame2 a3 = frame2.sort_values(by='birth' ) print(a3 )
結果:
ID birth type1 2 13 1970 c 1 12 1973 b 0 11 1980 a
欠損値
値を検索し、論理値を返す
# 値があるかどうかの確認 a1 = {'ID':['11','12','13' ] ,'city':['Tokyo','Osaka','Kyoto' ] ,'num1':[ 101 ,102,103 ] } frame1 = DataFrame(a1 ) print(frame1 ) print(frame1.isin(["Tokyo"]) )
結果:
ID city num1 0 11 Tokyo 101 1 12 Osaka 102 2 13 Kyoto 103 ID city num1 0 False True False 1 False False False 2 False False False
欠損値の取り扱い
nullを判定
a1 = {'ID':['11','12','13' ] ,'city':['Tokyo','Osaka', np.nan ] ,'num1':[ 101 ,102,103 ] } frame1 = DataFrame(a1 ) print(frame1 ) print(frame1.isnull() ) #nullを判定し、合計する frame1.isnull().sum()
結果:
ID city num1 0 11 Tokyo 101 1 12 Osaka 102 2 13 NaN 103 ID city num1 0 False False False 1 False False False 2 False True False ID 0 city 1 num1 0 dtype: int64
pandas merge()
merge()
dataFrame マージ
結合用のデータを準備しておきます。
# a1 = {'ID':['11','12','13' ] ,'city':['Tokyo','Osaka','Kyoto' ] ,'num1':[ 101 ,102,103 ] } frame1 = DataFrame(a1 ) print(frame1 ) a2 = {'ID':['11','12','13' ] ,'birth':[1980,1981,1982 ] ,'type1':['a','b','c' ]} frame2 = DataFrame( a2) print(frame2 )
結果:
ID city num1 0 11 Tokyo 101 1 12 Osaka 102 2 13 Kyoto 103 ID birth type1 0 11 1980 a 1 12 1981 b 2 13 1982 c
マージ
# データのマージ m1= pd.merge( frame1, frame2) print(m1)
結果:
ID city num1 birth type1 0 11 Tokyo 101 1980 a 1 12 Osaka 102 1981 b 2 13 Kyoto 103 1982 c
index をキーにして、結合されているようです。
pandas DataFrame
作成
a1 = {'ID':['11','12','13' ] ,'city':['Tokyo','Osaka','Kyoto' ] ,'num1':[ 101 ,102,103 ] } frame1 = DataFrame(a1 ) print(frame1 )
結果:
ID city num1 0 11 Tokyo 101 1 12 Osaka 102 2 13 Kyoto 103
T
置き換え、行列の転置が可能です。
a2= frame1.T
print(a2)
結果:
0 1 2 ID 11 12 13 city Tokyo Osaka Kyoto num1 101 102 103
列名の指定
# 列名の指定
frame1.num1
結果:
0 101 1 102 2 103 Name: num1, dtype: int64
条件フィルター
条件の指定を行い、特定のレコードを抽出できる
# 条件(フィルター) a2= frame1[frame1['city']=='Tokyo'] print(a2 )
結果:
ID city num1 0 11 Tokyo 101