「入門 信頼性工学」第1章~第2章
福井泰好「入門 信頼性工学(第2版)」森北出版 の読後メモ。
設例について、Python [Google Colaboratory]による演算処理例を示す。
1章 信頼性工学の概要
p5 図1.4 部品数と部品の信頼度Rがアイテムの信頼度におよぼす影響
(作業手順)
- 部品数を 1~\(10^6\) 個まで設定(グラフ横軸)
- 部品の信頼度\(R\)を複数設定
- アイテム(直列システム全体)の信頼度を計算(グラフ縦軸)
- グラフ化
import numpy as np
import matplotlib.pyplot as plt
start = 0
end = 10**6
X_list = np.arange(start, end, 1) #部品数
R_list = [0.9, 0.99, 0.999, 0.9999, 0.99999] # 部品の信頼度
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.grid(color='gray')
for rel in range(len(R_list)):
Y_list = R_list[rel]**X_list # システム全体の信頼度
ax.plot(X_list, Y_list, label=fr'R={R_list[rel]}')
plt.xscale('log') #横軸を対数目盛り
plt.xlabel('Number of parts')
plt.ylabel('Overall system reliability')
plt.xlim(1,) # 部品点数は1以上
plt.ylim(0,)
plt.legend()
plt.show()
- 部品点数が増加するにつれて、直列システムの信頼度は減少する。
- 同減少度合いは、部品の信頼度が小さいほど、強い。
p11 例題1.1 信頼度R
(作業手順)
- 故障時刻と信頼度を求めたい時刻(運用時刻)のリストを設定
- 特定の運用時刻における残存数を計算する関数を設定
- 各残存数から各信頼度を計算
- 一覧表化
import pandas as pd
Num = 3 # アイテム数
f_time = [6,12,20] # 故障時刻
r_time = [5,10,25] # 運用時刻
# 関数 残存数
def residual(f_time,snap):
available = Num
for failure in f_time:
if failure <= snap:
available -= 1
return available
# 残存数と信頼度の計算
res_list = [] # 残存数のリスト
R_list = [] # 信頼度R のリスト
for snap in r_time:
res = residual(f_time,snap)
res_list.append(res)
R_list.append(res/Num*100)
# DF化
DF = pd.DataFrame([r_time, '', res_list, R_list]).T
DF.columns = ['hours','start','available','Reliability[%]']
DF['start'] = Num
pd.options.display.precision = 1
DF
hours start available Reliability[%] 0 5.0 3 3.0 100.0 1 10.0 3 2.0 66.7 2 25.0 3 0.0 0.0
- p14 演習問題1.1 も同様のプログラムで計算できる。
p12 例題1.2 保全度M
(作業手順)
- 保守時間のリストを設定
- 保守時間が基準値未満のものを抽出
- 基準値未満のものの個数と全体個数から保全度を計算
m_time = [30,39,42,44,46,47,50,53,56,58,61,63,64,65,66,67,69,73,76,80,82,85,88,93]
threshold = 70 # 基準指定
don_list = [item for item in m_time if item < threshold] # 基準値未満の抽出
Maintenance = len(don_list)/len(m_time) # 保全度の計算
print(f'保全度:{Maintenance:.2%}')
保全度:70.83%
- p14 演習問題1.2 も同様のプログラムで計算できる。
p13 例題1.3 故障率λ
(作業手順)
- 故障時刻(start)と故障率を求めたい時刻(運用時刻)のリストを設定
- 特定の運用時刻における残存数(available)を計算
- 残存数リストの要素差分を取得し新規故障数(failure)とする
- 新規故障数(failure)を運用時刻の残存数(available)で除して新規故障割合を求める
- 新規故障割合を運用時刻差(end - start)で除して故障率(\(\lambda\))を求める
- 一覧表化
import pandas as pd
Num = 4 # アイテム数
f_time = [3,6,9,13] # 故障時刻
r_time = [5,10,15,20] # 運用時刻
# 関数 残存数
def residual(f_time,snap):
available = Num
for failure in f_time:
if failure <= snap:
available -= 1
return available
# 残存数の計算
res_list = [] # 残存数のリスト
for snap in r_time:
res = residual(f_time,snap)
res_list.append(res)
# 新規故障リスト
res_list.insert(0,Num) # 冒頭に当初アイテム数を追加
dif = [i-j for i, j in zip(res_list[:-1], res_list[1:])]
# 開始時刻リスト
s_time = [rs-5 for rs in r_time]
# DF化
DF = pd.DataFrame([s_time, r_time, res_list[:-1], dif]).T
DF.columns = ['start','end', 'available', 'failure']
# 故障率λを計算
DF['λ[%/time]'] = (DF['failure']/DF['available'])/(DF['end']-DF['start'])*100
pd.options.display.precision = 1
DF
start end available failure λ[%/time] 0 0 5 4 1 5.0 1 5 10 3 2 13.3 2 10 15 1 1 20.0 3 15 20 0 0 NaN
- p14 演習問題1.3 も同様のプログラムで計算できる。
p14 演習問題1.4 アベイラビリティA
(作業手順)
- 稼働時間のリストを設定
- 非可動時間のリストを計算
- 稼働時間を全体時間(稼働+非可動)で除してアベイラビリティを求める
up_hours = [20,21,20,19,21,21,22] # アップ時間
down_hours = [24-time for time in up_hours]
available = sum(up_hours)/(sum(up_hours)+sum(down_hours))
print(f'{available:.2%}')
85.71%
- p14 例題1.4 も同様のプログラムで計算できる。
2章 確率と統計の基礎
p18 例題2.2 順列と組み合わせ
全m個中r個故障の集団から、n個を任意抽出したとき、s個故障の確率
\(\cfrac{{}_r C_s \times {}_{m-r} C_{n-s}}{{}_m C_n}\)
import math
all = 10
fail_p = 3
choice = 3
fail_c = 2
prob = math.comb(fail_p,fail_c)*math.comb(all-fail_p,choice-fail_c)/math.comb(all,choice)
print(f'確率:{prob*100}%')
確率:17.5%
p22 例題2.3 独立事象
(作業工程)
- A工場品である確率 ×A工場品の合格率 =A工場の合格品である確率 (1)の解
- B工場品である確率 ×B工場品の合格率 =B工場の合格品である確率
- A工場の合格品である確率 +B工場の合格品である確率 =合格品である確率 (2)の解
- 2個目がB工場品である確率 ×B工場品の合格率 =2個目がB工場の合格品である確率
- (1個目が)A工場の合格品である確率 +2個目がB工場の合格品である確率 (3)の解
import pandas as pd
# 個数と不良確率のデータ
a_factory = [100, 0.02]
b_factory = [150, 0.05]
DF = pd.DataFrame([a_factory, b_factory]
,index=['A_factory', 'B_factory']
, columns = ['個数','不良率'] )
# A工場の合格品である確率
prob_a = DF['個数']['A_factory']/DF['個数'].sum() # A工場品である確率
pass_a = 1-DF['不良率']['A_factory'] # A工場品の合格率
answer1 = prob_a * pass_a
print(f'(1)A工場の合格品である確率:{answer1*100}%')
# 合格品である確率
prob_b = DF['個数']['B_factory']/DF['個数'].sum() # B工場品である確率
pass_b = 1-DF['不良率']['B_factory'] # B工場品の合格率
answer2b = prob_b * pass_b # B工場の合格品である確率
answer2 = answer1 + answer2b
print(f'(2)合格品である確率:{answer2*100}%')
# A合格品 →B合格品である確率
prob_b_2 = DF['個数']['B_factory']/(DF['個数'].sum()-1) # 2個目がB工場品である確率
answer3b = prob_b_2 * pass_b # 2個目がB工場の合格品である確率
answer3 = answer1 * answer3b
print(f'(3)A合格品→B合格品である確率:{round(answer3*100,2)}%')
DF
(1)A工場の合格品である確率:39.2% (2)合格品である確率:96.2% (3)A合格品→B合格品である確率:22.43% 個数 不良率 A_factory 100 0.02 B_factory 150 0.05
p24 例題2.4(1) 反復試行の確率
(作業工程)
import math
# 分数を扱う
from decimal import Decimal
from fractions import Fraction
# 関数 x個中y個が不良品である確率
def prob_func(xn,yn,ratio):
nume, deno = Decimal(str(ratio)).as_integer_ratio() # 分子、分母に分解
fault = Fraction(nume,deno) **yn
normal = Fraction(deno-nume,deno)**(xn-yn)
prob = math.comb(xn,yn) *fault *normal
return float(prob)*100
# 例題2.4(1) の設定値
s_num = 5
def_num = 2
def_per = 0.1
# 関数を用いて確率を演算
probability = prob_func(s_num, def_num, def_per)
print(f'(1) 5個中2個が不良品である確率:{round(probability,2)}%')
(1) 5個中2個が不良品である確率:7.29%
p24 例題2.4(2) 反復試行の確率
(作業工程)
- 関数(x個中y個が不良品である確率)を設定
- y個の各個数について上記関数で確率を計算
- 上記確率を合計
# 例題2.4(2) 5個中3個以上が不良品である確率
over_dnum = 3
# 各個について確率を計算して集計
sum_prob = 0
for num in range(over_dnum, s_num+1):
sum_prob += prob_func(s_num, num, def_per)
# 表示
print(f'(2) 5個中3個以上が不良品である確率:{round(sum_prob,3)}%')
(2) 5個中3個以上が不良品である確率:0.856%
p26 表2.1 度数分布
(作業工程)
- 階級と度数を設定
- 累積度数を計算(1階級下の累積度数 +度数 =現階級の累積度数)
- 一覧表化
# 表2.1
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
bins_list = np.arange(0, 91, 10) # 階級
freq_list = [0,1,2,3,9,13,12,4,1,0] # 度数
cumu_list = [0] # 累積度数の空リスト
index_list = ['Class','Frequency','Cumulative_Freq']
DF = pd.DataFrame([bins_list, freq_list, cumu_list], index =index_list)
# 累積度数の行を生成
for freq in DF.loc['Frequency']: # 度数を取り出す
cumu = cumu_list[-1]+freq # 累積度数を計算
cumu_list.append(cumu)
cumu_list.pop(0) # 先頭要素を削除
cumu_series = pd.DataFrame(cumu_list).T
# 累積度数の行を結合
DF = pd.concat([DF,cumu_series],axis=0) # 結合
DF.drop('Cumulative_Freq', axis=0, inplace=True) # 不要行の削除
DF.index = index_list # インデックスの再付与
DF
p27 図2.7~2.8 ヒストグラム、累積度数多角形
# コードは上記の続き
plt.bar(DF.loc['Class'], DF.loc['Frequency'], width=9, align="edge", color="lightskyblue", edgecolor="black", label='Frequency')
plt.plot(DF.loc['Class'],DF.loc['Cumulative_Freq'],label='Cumulative_Frequency', color='orange', marker='o')
plt.xlim(0,)
plt.xticks(bins_list)
plt.xlabel('Inspection Time')
plt.ylabel('Frequency')
plt.legend()
plt.grid()
plt.show()
p28 例題2.5 平均、メジアン、モード
(作業工程)
- 平均:numpy.mean で演算
- メジアン:numpy.median で演算
- モード:度数分布表を作成 →最大値を持つ行の階級値
import numpy as np
import pandas as pd
# 設定値
scores = [7230,6560,10800,10990,3200,5520,8680,4650,7810,5320,10080,7260,3600,5640,7050,6650,7180,5840,7500,10310,4630,9020,7620,10040,8860,9200,7420,9350,10400,9530]
width = 1000 # 階級の幅
print(f'平均:{int(np.mean(scores))}')
print(f'メジアン:{int(np.median(scores))}')
# 関数 点数、階級幅 → 階級、度数
def FDDF(score_list, width):
data = np.asarray(score_list)
bins = np.arange(0, data.max()+width+1, width) # 最大値の上限を含む階級値まで階級値を作成
hist = np.histogram(data, bins)[0] # 度数を計算
return bins, hist
# 関数を使用
bins, hist = FDDF(scores,width)
# DF化
indexs = pd.Index([f'{bins[i]}~{bins[i+1]}' for i in range(hist.size)], # インデックス列を生成
name='階級(以上~未満)') # インデックス名称
DF = pd.DataFrame({'階級値': (bins[1:] + bins[:-1]) / 2, # ズレ数列の平均 →中間値
'度数': hist},
index = indexs)
# モード
max_row = DF.loc[DF['度数'].idxmax()] # 最大値を持つ行を取得
print(f'モード:{int(max_row[0])}') # 該当行の階級値
DF
平均:7598 メジアン:7460 モード:7500
p30 例題2.6 散布度(範囲、平均、分散、変動係数)
(作業工程)
- 範囲:最大値numpy.max-最小値numpy.min
- 平均:numpy.mean で演算
- 標準偏差:numpy.std で計算
- 変動係数:標準偏差/平均
import numpy as np
numbers = [38,61,52,14,69,84,55,62,65,27,52,53,76,45,71,56,60,40,46,74]
range = np.max(numbers)-np.min(numbers)
myu = np.mean(numbers)
sigma = np.std(numbers)
eta = sigma/myu
print(f'範囲:{range}\n平均:{myu}\n分散:{round(sigma,3)}\n変動係数:{round(eta,4)}')
範囲:70 平均:55.0 分散:16.565 変動係数:0.3012
p32 例題2.7 2つのデータを混合
(作業工程)
- 全データ →混合データの平均、標準偏差
- 2データのデータ数・平均・標準偏差 →混合データの平均、標準偏差
import pandas as pd
import numpy as np
# データ値
a_worker = [50.07, 49.96, 50.05, 49.88, 50.09, 50.07, 49.94, 50.03, 49.96, 50.05]
b_worker = [49.98, 50.06, 49.99, 50.01, 50.02, 50.04, 50.03, 49.98, 49.97, 50.02]
all_worker = a_worker + b_worker
# データ数
a_len = len(a_worker)
b_len = len(b_worker)
all_len = len(all_worker)
# 平均
a_mu = np.mean(a_worker)
b_mu = np.mean(b_worker)
all_mu = np.mean(all_worker)
# 標準偏差
a_std = np.std(a_worker)
b_std = np.std(b_worker)
all_std = np.std(all_worker)
# DF化
index_list = ['Num','Mean','Std']
DF = pd.DataFrame([[a_len,b_len,all_len],[a_mu,b_mu,all_mu],[a_std,b_std,all_std]]
,index = index_list
,columns = ['Worker_A','Worker_B','all(definition)'])
# 公式 全平均,全標準偏差
def myu_std(DataFrame):
mux = DF['Worker_A']['Mean']
muy = DF['Worker_B']['Mean']
sx = DF['Worker_A']['Std']
sy = DF['Worker_B']['Std']
m = DF['Worker_A']['Num']
n = DF['Worker_B']['Num']
N = DF['all(definition)']['Num']
mu_all = (m *mux + n* muy)/(m +n) # 全体の平均
s_all = np.sqrt((m *sx**2 +n *sy**2 + (m*n/N)*(mux-muy)**2)/N) # 全体の標準偏差
return N, mu_all, s_all
# 公式での演算
fcalc = pd.DataFrame([item for item in myu_std(DF)], index=index_list, columns= ['all (By_formula)'])
DF = pd.concat([DF,fcalc],axis=1)
DF
Worker_A Worker_B all(definition) all (By_formula) Num 10.000000 10.000000 20.000000 20.000000 Mean 50.010000 50.010000 50.010000 50.010000 Std 0.066332 0.027928 0.050892 0.050892
- 全データから定義に基づき計算した値 all(definition) と公式で求めた値 all (By_formula) は一致している。
p35 例題2.8(1) 2変数の和
(作業工程)
- 確率変数の和が指定値を満足するような確率変数を求める
- 当該確率変数が生起する確率を求める
(使用モジュール)
# 例題2.8(1)
import pandas as pd
# 設定値
x_list = [0,1,2,3]
x_prob = [0.2, 0.4, 0.2, 0.2]
y_list = [0,1,2,3,4]
y_prob = [0.4, 0.2, 0.1, 0.2, 0.1]
# 辞書化
x_dic = dict(zip(x_list, x_prob))
y_dic = dict(zip(y_list, y_prob))
# 関数 足し算
def addition(a_value,b_value):
return a_value + b_value
# 関数 掛け算
def multiple(a_value,b_value):
return a_value * b_value
# 関数 解を与える要素(X,Yの値リスト)を求める
def target(dic_a, dic_b, func, answer): # 引数:辞書2つ、関数、解
target_a = []
target_b = []
for a_ele in dic_a:
for b_ele in dic_b:
if func(a_ele,b_ele) == answer:
target_a.append(a_ele)
target_b.append(b_ele)
return target_a,target_b
# (1) X+Y=7 となる場合 のX,Yを求める
function = addition # 加法を指定
answer = 7 # 解を指定
x_answer = target(x_dic,y_dic,function, answer)[0]
y_answer = target(x_dic,y_dic,function, answer)[1]
# 表示
print(f'X+Y={answer} となる組合せは、{len(x_answer)}通り。')
total_p = 0
for answer in zip(x_answer,y_answer):
prob = round(x_dic[answer[0]]*y_dic[answer[1]],3)
print(f'(X,Y)={answer}の確率:{prob}')
total_p += prob
print(f'合計確率:{total_p}')
X+Y=7 となる組合せは、1通り。 (X,Y)=(3, 4)の確率:0.02 合計確率:0.02
p35 例題2.8(2) 2変数の積
(処理工程)
- 確率変数の積が指定値を満足するような確率変数を求める
- 当該確率変数が生起する確率を求める
# コードは上記の続き
# (2) X*Y=4 となる場合 のX,Yを求める
function = multiple # 乗法を指定
answer = 4 # 解を指定
x_answer = target(x_dic,y_dic,function, answer)[0]
y_answer = target(x_dic,y_dic,function, answer)[1]
# 表示
print(f'X*Y={answer} となる組合せは、{len(x_answer)}通り。')
total_p = 0
for answer in zip(x_answer,y_answer):
prob = round(x_dic[answer[0]]*y_dic[answer[1]],3)
print(f'(X,Y)={answer}の確率:{prob}')
total_p += prob
print(f'合計確率:{total_p}')
X*Y=4 となる組合せは、2通り。 (X,Y)=(1, 4)の確率:0.04 (X,Y)=(2, 2)の確率:0.02 合計確率:0.06
p35 例題2.8(3) 確率変数の平均と分散
(処理工程)
- 関数(確率変数の平均)で計算
- 関数(確率変数の分散)で計算
# コードは上記の続き
# 関数 確率変数の平均
def myu(dic):
myu_value = 0
for variable in dic:
myu_value += variable * dic[variable]
return myu_value
# 関数 確率変数の分散
def variance(dic,myu):
var_value = 0
for variable in dic:
var_value += (variable - myu)**2 * dic[variable]
return var_value
# 関数で演算
y_myu = myu(y_dic) # 平均
y_var = variance(y_dic, y_myu) # 分散
# 表示
print(f'Yの平均:{y_myu}\nYの分散:{y_var}')
Yの平均:1.4 Yの分散:2.04
p38 演習問題2.1 事象確率の積算
(作業工程)
- 特定の故障台数が生ずる確率を計算
- 故障台数を0~3台について合計
- 判定基準との大小比較に従い、結果を表示
import math
# 設定値
total =1000
max_failure = 3
prob = 1/100
rare = 1/100
# 故障台数0~3台の事象確率を積算
probability = 0
for failure in range(max_failure+1):
probability += math.comb(total,failure) *prob **failure *(1-prob)**(total-failure)
# 表示
print(f'生起確率:{round(probability,7)}')
if probability <= rare:
print(f'故障台数{max_failure}台以下との事象は、珍しい')
else:
print(f'故障台数{max_failure}台以下との事象は、珍しくはない')
生起確率:0.0100727 故障台数3台以下との事象は、珍しくはない
p38 演習問題2.2 生起確率
# 演習問題2.2
import math
# 設定値
A_factory = 4
B_factory = 3
select = 3
A_select = 2
# 計算
total = A_factory + B_factory
prob = (math.comb(A_factory,A_select)*math.comb(B_factory, select-A_select))/math.comb(total, select)
# 表示
print(f'確率:{round(prob *100,2)}%')
確率:51.43%
p38 演習問題2.4
import math
# 設定値
A_factory = 150
B_factory = 100
select = 2
at_least = 1
# A工場分が1~2個となる事象確率を積算
total = A_factory + B_factory
probability = 0
for a_num in range(at_least, select+1):
prob = (math.comb(A_factory,a_num)*math.comb(B_factory, select-a_num))/math.comb(total, select)
probability += prob
# 表示
print(f'確率:{round(probability *100,2)}%')
確率:84.1%
p38 演習問題2.5
import pandas as pd
import numpy as np
# データ数
a_len = 45
b_len = 50
# 平均
a_mu = 50.022
b_mu = 49.995
# 標準偏差
a_std = 0.121
b_std = 0.047
# DF化
all_len = a_len + b_len
index_list = ['Num','Mean','Std']
DF = pd.DataFrame([[a_len,b_len,all_len],[a_mu,b_mu,],[a_std,b_std,]]
,index = index_list
,columns = ['旋盤A','旋盤B','All'])
# 公式 全平均,全標準偏差
def myu_std(DataFrame):
mux = DF['旋盤A']['Mean']
muy = DF['旋盤B']['Mean']
sx = DF['旋盤A']['Std']
sy = DF['旋盤B']['Std']
m = DF['旋盤A']['Num']
n = DF['旋盤B']['Num']
N = DF['All']['Num']
mu_all = (m *mux + n* muy)/(m +n) # 全体の平均
s_all = np.sqrt((m *sx**2 +n *sy**2 + (m*n/N)*(mux-muy)**2)/N) # 全体の標準偏差
return N, mu_all, s_all
# 公式での演算
fcalc = pd.DataFrame([item for item in myu_std(DF)], index=index_list, columns= ['all(formula)'])
# 表示
DF = pd.concat([DF,fcalc],axis=1)
DFA = DF.drop('All', axis=1)
DFA.round({'旋盤A':3, '旋盤B':3, 'all(formula)':5})
p38 演習問題2.6(1) 2つのデータの混合
# 設定値
x_list = [0,1,2,3,4]
x_prob = [0.1, 0.2, 0.4, 0.2, 0.1]
y_list = [0,1,2,3]
y_prob = [0.6, 0.2, 0.1, 0.1]
# 辞書化
x_dic = dict(zip(x_list, x_prob))
y_dic = dict(zip(y_list, y_prob))
# 関数 足し算
def addition(a_value,b_value):
return a_value + b_value
# 関数 解を与える要素(X,Yの値リスト)を求める
def target(dic_a, dic_b, func, answer): # 引数:辞書2つ、関数、解
target_a = []
target_b = []
for a_ele in dic_a:
for b_ele in dic_b:
if func(a_ele,b_ele) == answer:
target_a.append(a_ele)
target_b.append(b_ele)
return target_a,target_b
# X+Y=4 となる場合 のX,Yを求める
function = addition # 加法を指定
answer = 4 # 解を指定
x_answer = target(x_dic,y_dic,function, answer)[0]
y_answer = target(x_dic,y_dic,function, answer)[1]
# 表示
print(f'X+Y={answer} となる組合せは、{len(x_answer)}通り。')
total_p = 0
for answer in zip(x_answer,y_answer):
prob = round(x_dic[answer[0]]*y_dic[answer[1]],3)
print(f'(X,Y)={answer}の確率:{prob}')
total_p += prob
print(f'合計確率:{total_p}')
X+Y=4 となる組合せは、4通り。 (X,Y)=(1, 3)の確率:0.02 (X,Y)=(2, 2)の確率:0.04 (X,Y)=(3, 1)の確率:0.04 (X,Y)=(4, 0)の確率:0.06 合計確率:0.16
p38 演習問題2.6(2) 2つのデータの混合(平均)
# コードは上記の続き
# 関数 確率変数の平均
def myu(dic):
myu_value = 0
for variable in dic:
myu_value += variable * dic[variable]
return myu_value
# 関数で各平均を演算
x_myu = myu(x_dic)
y_myu = myu(y_dic)
xy_myu = x_myu * y_myu
# 表示
print(f'Xの平均:{round(x_myu,2)}\nYの平均:{round(y_myu,2)}\nXYの平均:{round(xy_myu,2)}')
Xの平均:2.0 Yの平均:0.7 XYの平均:1.4
