knaka Tech-Blog

AI, IoT, DIYエレクトロニクス, データサイエンスについて投稿予定です。

IoTデータから scikit-learnで線形回帰。

概要

前回続き、機械学習の関連となります。
IoT温度データから
scikit-learnを使用して線形回帰モデルでグラフ描画までテストしてみました。
比較的カンタンなデモですが、ライブラリの読み込みも速めで、
使いやすく見えました。

今回は、データ分析、特徴の抽出等できれば良いかな程度の目的でしたが、
scikit-learnは、他の機能も多いようで、調査したいと思います。

環境

win7

python 3.5
scikit-learn
numpy
matplotlib

結果

件数的には、やや少なめですが
最近の、IoT温度値を程読ませて
matplotlib のグラフ表示
一次元配列を読ませています。

predict: 予測
temp : 温度/ IoT実測値

f:id:knaka0209:20180518174036p:plain

Log:


f:id:knaka0209:20180513172430p:plain

code

python3.5
IoT実測値を読ませて学習させています。

https://github.com/kuc-arc-f/sklearn_linear_model

github.com

update 2018/05/18

sk_iot_2b.py
pandas の時系列データ(日付)を、グラフのx軸に表示
できるように修正しました。

注) sklearn / linear_model
はpandas/日付型(timeStamp)が処理できなかったので、
数値で学習/予測し、グラフは日付型を設定しています。

IoTデータ学習して chainerで時系列予測を出力する。

index:

概要

機械学習の関連となります。
ディープラーニングも対応できそうなchainer を使って、IoTデータの数値予測してみました。

前は、LSTMのKeras+ tensorFlow 版でしたが、
Ubuntu以外のLinux で、tensorFlow最新インストールが困難でしたので、
別のライブラリを探し、chainer 同等の機能が追加できるか検討してみました。

環境

win7
python 3.5
chainer 3.3.0
numpy
matplotlib

結果

件数的には、やや少なめですが
最近の、IoT温度値を程読ませて
matplotlib のグラフ表示
一次元配列を読ませています。

predict: 予測
temp : 温度/実測値

前半は、やや曲線の波形でしたが
後半は、ほぼ直線的でした。
まだ調整が必要かもしれません。


f:id:knaka0209:20180513170823p:plain

実行ログ:

f:id:knaka0209:20180513170845p:plain

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()


f:id:knaka0209:20180512181313p:plain

ポアソン分布:

稀な事象が起きる確率の時、使われます。
https://bellcurve.jp/statistics/course/6984.html

# ポアソン分布
x = random.poisson(7, 1000)
plt.hist(x)
plt.grid(True)

f:id:knaka0209:20180512181622p:plain

分散、標準偏差、要約統計量

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 をキーにして、結合されているようです。