phm-algo-ias 1.1.1__cp311-cp311-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of phm-algo-ias might be problematic. Click here for more details.
- algo/HI/HI.cpython-311-aarch64-linux-musl.so +0 -0
- algo/HI/__init__.py +7 -0
- algo/RUL/RUL.cpython-311-aarch64-linux-musl.so +0 -0
- algo/RUL/__init__.py +7 -0
- algo/__init__.py +10 -0
- algo/_version.py +34 -0
- phm_algo_ias-1.1.1.dist-info/METADATA +19 -0
- phm_algo_ias-1.1.1.dist-info/RECORD +12 -0
- phm_algo_ias-1.1.1.dist-info/WHEEL +5 -0
- phm_algo_ias-1.1.1.dist-info/top_level.txt +3 -0
- test_code/HI_Verify.py +220 -0
- test_code/health_index_robot.py +178 -0
|
Binary file
|
algo/HI/__init__.py
ADDED
|
Binary file
|
algo/RUL/__init__.py
ADDED
algo/__init__.py
ADDED
algo/_version.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '1.1.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 1, 1)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'gbe7236c04'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phm-algo-ias
|
|
3
|
+
Version: 1.1.1
|
|
4
|
+
Summary: Example algo package with Cython-compiled submodules
|
|
5
|
+
Author: Your Name
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Programming Language :: Cython
|
|
8
|
+
Classifier: Programming Language :: C
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: passlib==1.7.4
|
|
12
|
+
Requires-Dist: pandas==2.2.3
|
|
13
|
+
Requires-Dist: numpy==2.0.1
|
|
14
|
+
Requires-Dist: scipy==1.14.0
|
|
15
|
+
Requires-Dist: scikit-learn==1.5.1
|
|
16
|
+
Requires-Dist: matplotlib==3.9.2
|
|
17
|
+
Requires-Dist: seaborn==0.13.2
|
|
18
|
+
Requires-Dist: openpyxl==3.1.5
|
|
19
|
+
Requires-Dist: statsmodels==0.14.4
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
algo/__init__.py,sha256=39U0vAwYJyChXgyxKTVca-mYS5g6wp0axllwilFCx9g,228
|
|
2
|
+
algo/_version.py,sha256=fXellVhWRA4cMOkEBuKmFjLLro0rVyAOEKs6CbgrYtc,712
|
|
3
|
+
algo/HI/HI.cpython-311-aarch64-linux-musl.so,sha256=LYjkz-Ca1ra29LCLQfYH9w-BX72-ug71Cev2BTSZrBg,605592
|
|
4
|
+
algo/HI/__init__.py,sha256=qHY2ACOtfIznQYvMFLJBpoB0xjUdd0rY2FUVunk2kEk,127
|
|
5
|
+
algo/RUL/RUL.cpython-311-aarch64-linux-musl.so,sha256=I_2XmT0HnOmdnRQWM2P82zANDfV1hBkyHQxr7-tWxYY,157776
|
|
6
|
+
algo/RUL/__init__.py,sha256=VoJ0tZAIEh6TI8pJSo6hBAjEUYb2n2KiQ9dpXnrGF5g,131
|
|
7
|
+
test_code/HI_Verify.py,sha256=WgYlEpbqdUpe5XNjSE__D_1hqCWWlykkeNfX9u2pWrw,8636
|
|
8
|
+
test_code/health_index_robot.py,sha256=qOQwfu8HOpfjEg7u804HZJq2D4PbzpsEVgT6PRtJ5-c,4424
|
|
9
|
+
phm_algo_ias-1.1.1.dist-info/METADATA,sha256=NjtQDqSdRhodwFbtndtmzcNmvtmeU9ZgB0f8uOgJDSI,610
|
|
10
|
+
phm_algo_ias-1.1.1.dist-info/WHEEL,sha256=LNZuceeFd58B9QVekwESAWqB09LEv_tgGDcYQrpkG9U,113
|
|
11
|
+
phm_algo_ias-1.1.1.dist-info/top_level.txt,sha256=G1rxqg36Dwkx3w8o50708_IOrZelxPOJVB_KPOLlJM0,26
|
|
12
|
+
phm_algo_ias-1.1.1.dist-info/RECORD,,
|
test_code/HI_Verify.py
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Mon Jul 3 14:19:40 2023
|
|
4
|
+
|
|
5
|
+
@author: yunghua.chang
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pandas as pd
|
|
11
|
+
#import scipy.stats as st
|
|
12
|
+
import datetime
|
|
13
|
+
#from glob import glob
|
|
14
|
+
#from matplotlib import pyplot as plt
|
|
15
|
+
#from sklearn.preprocessing import StandardScaler
|
|
16
|
+
#from sklearn.decomposition import PCA
|
|
17
|
+
#from scipy.stats import f, skew
|
|
18
|
+
#import matplotlib.ticker as ticker
|
|
19
|
+
#import pickle
|
|
20
|
+
import sys
|
|
21
|
+
#from types import SimpleNamespace
|
|
22
|
+
|
|
23
|
+
sys.path.append(os.getcwd())
|
|
24
|
+
from algo.HI import HI
|
|
25
|
+
from algo.RUL import RUL
|
|
26
|
+
from datetime import timedelta
|
|
27
|
+
|
|
28
|
+
import matplotlib.pyplot as plt
|
|
29
|
+
import pickle
|
|
30
|
+
|
|
31
|
+
def plot(health, target):
|
|
32
|
+
|
|
33
|
+
health = health.copy()
|
|
34
|
+
health = health.sort_index()
|
|
35
|
+
|
|
36
|
+
# 用 datetime index 轉為字串來當作 x 軸標籤
|
|
37
|
+
health["TimeLabel"] = health.index.strftime("%Y-%m-%d %H:%M")
|
|
38
|
+
|
|
39
|
+
fig, ax = plt.subplots(figsize=(14, 5))
|
|
40
|
+
ax.plot(health["TimeLabel"], health["Score"], marker="o", color="#3A8FB7", label="Score")
|
|
41
|
+
ax.axhline(0.9 * 100, linestyle="--", color="#F26D5A", label="Threshold")
|
|
42
|
+
|
|
43
|
+
ax.set_title("Health Index - " + target, fontsize=20)
|
|
44
|
+
ax.set_ylabel("Score", fontsize=15)
|
|
45
|
+
ax.set_ylim(0, 100)
|
|
46
|
+
|
|
47
|
+
# 控制 x 軸顯示密度
|
|
48
|
+
step = max(len(health) // 12, 1) # 至少每 12 個點顯示一次
|
|
49
|
+
ax.set_xticks(health["TimeLabel"][::step])
|
|
50
|
+
ax.set_xticklabels(health["TimeLabel"][::step], rotation=15, fontsize=10)
|
|
51
|
+
|
|
52
|
+
plt.yticks(fontsize=12)
|
|
53
|
+
plt.subplots_adjust(bottom=0.25)
|
|
54
|
+
plt.legend()
|
|
55
|
+
|
|
56
|
+
plt.show()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def drop_time_ranges(df, time_col="_time", ranges=None, fmt=None):
|
|
60
|
+
"""
|
|
61
|
+
將 df 中 time_col 落在 ranges 內的列刪除(含起訖)。
|
|
62
|
+
ranges: [("YYYY/MM/DD HH:MM:SS", "YYYY/MM/DD HH:MM:SS"), ...]
|
|
63
|
+
fmt: 若你的時間字串有固定格式可填,否則留 None 讓 pandas 自動判斷
|
|
64
|
+
"""
|
|
65
|
+
if ranges is None or len(ranges) == 0:
|
|
66
|
+
return df
|
|
67
|
+
|
|
68
|
+
out = df.copy()
|
|
69
|
+
# 轉成 datetime
|
|
70
|
+
out[time_col] = pd.to_datetime(out[time_col], format=fmt, errors="coerce")
|
|
71
|
+
|
|
72
|
+
for start, end in ranges:
|
|
73
|
+
start_dt = pd.to_datetime(start, format=fmt, errors="coerce")
|
|
74
|
+
end_dt = pd.to_datetime(end, format=fmt, errors="coerce")
|
|
75
|
+
mask = (out[time_col] >= start_dt) & (out[time_col] <= end_dt)
|
|
76
|
+
out = out.loc[~mask]
|
|
77
|
+
|
|
78
|
+
# 如果你後續還要把 Time 當 index 用:
|
|
79
|
+
# out = out.set_index(time_col).sort_index()
|
|
80
|
+
|
|
81
|
+
return out
|
|
82
|
+
|
|
83
|
+
#----------------------------------- 改欄位名稱 -------------------------------------------------------------
|
|
84
|
+
def rename_columns(df: pd.DataFrame) -> pd.DataFrame:
|
|
85
|
+
"""
|
|
86
|
+
將輸入的 DataFrame 欄位依照對應表改名
|
|
87
|
+
Input: df (pandas.DataFrame)
|
|
88
|
+
Output: df (pandas.DataFrame, 欄位已改名)
|
|
89
|
+
"""
|
|
90
|
+
# 先去掉欄位名稱前後空白
|
|
91
|
+
df.columns = df.columns.str.strip()
|
|
92
|
+
|
|
93
|
+
mapping_dict = {
|
|
94
|
+
"Time": "_time",
|
|
95
|
+
"RPM": "RPM",
|
|
96
|
+
"X-Overall": "X_Overall",
|
|
97
|
+
"Y-Overall": "Y_Overall",
|
|
98
|
+
"Z-Overall": "Z_Overall",
|
|
99
|
+
"X-Peak": "X_Peak",
|
|
100
|
+
"Y-Peak": "Y_Peak",
|
|
101
|
+
"Z-Peak": "Z_Peak",
|
|
102
|
+
"X-Peak to Peak": "X_Peak_to_Peak",
|
|
103
|
+
"Y-Peak to Peak": "Y_Peak_to_Peak",
|
|
104
|
+
"Z-Peak to Peak": "Z_Peak_to_Peak",
|
|
105
|
+
"X-Crest Factor": "X_Crest_Factor",
|
|
106
|
+
"Y-Crest Factor": "Y_Crest_Factor",
|
|
107
|
+
"Z-Crest Factor": "Z_Crest_Factor",
|
|
108
|
+
|
|
109
|
+
"X-Power in Band 01": "X_Power_in_Band_01",
|
|
110
|
+
"X-Power in Band 02": "X_Power_in_Band_02",
|
|
111
|
+
"X-Power in Band 03": "X_Power_in_Band_03",
|
|
112
|
+
"X-Power in Band 04": "X_Power_in_Band_04",
|
|
113
|
+
"X-Power in Band 05": "X_Power_in_Band_05",
|
|
114
|
+
"X-Power in Band 06": "X_Power_in_Band_06",
|
|
115
|
+
"X-Power in Band 07": "X_Power_in_Band_07",
|
|
116
|
+
"X-Power in Band 08": "X_Power_in_Band_08",
|
|
117
|
+
"X-Power in Band 09": "X_Power_in_Band_09",
|
|
118
|
+
"X-Power in Band 10": "X_Power_in_Band_10",
|
|
119
|
+
|
|
120
|
+
"Y-Power in Band 01": "Y_Power_in_Band_01",
|
|
121
|
+
"Y-Power in Band 02": "Y_Power_in_Band_02",
|
|
122
|
+
"Y-Power in Band 03": "Y_Power_in_Band_03",
|
|
123
|
+
"Y-Power in Band 04": "Y_Power_in_Band_04",
|
|
124
|
+
"Y-Power in Band 05": "Y_Power_in_Band_05",
|
|
125
|
+
"Y-Power in Band 06": "Y_Power_in_Band_06",
|
|
126
|
+
"Y-Power in Band 07": "Y_Power_in_Band_07",
|
|
127
|
+
"Y-Power in Band 08": "Y_Power_in_Band_08",
|
|
128
|
+
"Y-Power in Band 09": "Y_Power_in_Band_09",
|
|
129
|
+
"Y-Power in Band 10": "Y_Power_in_Band_10",
|
|
130
|
+
|
|
131
|
+
"Z-Power in Band 01": "Z_Power_in_Band_01",
|
|
132
|
+
"Z-Power in Band 02": "Z_Power_in_Band_02",
|
|
133
|
+
"Z-Power in Band 03": "Z_Power_in_Band_03",
|
|
134
|
+
"Z-Power in Band 04": "Z_Power_in_Band_04",
|
|
135
|
+
"Z-Power in Band 05": "Z_Power_in_Band_05",
|
|
136
|
+
"Z-Power in Band 06": "Z_Power_in_Band_06",
|
|
137
|
+
"Z-Power in Band 07": "Z_Power_in_Band_07",
|
|
138
|
+
"Z-Power in Band 08": "Z_Power_in_Band_08",
|
|
139
|
+
"Z-Power in Band 09": "Z_Power_in_Band_09",
|
|
140
|
+
"Z-Power in Band 10": "Z_Power_in_Band_10",
|
|
141
|
+
|
|
142
|
+
"Bearing": "Bearing",
|
|
143
|
+
"Looseness": "Looseness",
|
|
144
|
+
"Misalignment": "Misalignment",
|
|
145
|
+
"Imbalance": "Imbalance",
|
|
146
|
+
"Gear_mesh": "Gear_mesh",
|
|
147
|
+
"Van_Pass": "Van_Pass",
|
|
148
|
+
|
|
149
|
+
"Bearing %": "Bearing_percentage",
|
|
150
|
+
"Looseness %": "Looseness_percentage",
|
|
151
|
+
"Misalignment %": "Misalignment_percentage",
|
|
152
|
+
"Imbalance %": "Imbalance_percentage",
|
|
153
|
+
"Gear_mesh %": "Gear_mesh_percentage",
|
|
154
|
+
"Van_Pass %": "Van_Pass_percentage",
|
|
155
|
+
|
|
156
|
+
"Temperature": "Temperature",
|
|
157
|
+
"X-Overall QC": "X_Overall_QC",
|
|
158
|
+
"Y-Overall QC": "Y_Overall_QC",
|
|
159
|
+
"Z-Overall QC": "Z_Overall_QC",
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
df = df.rename(columns=mapping_dict, errors="ignore")
|
|
163
|
+
return df
|
|
164
|
+
|
|
165
|
+
if __name__ == "__main__":
|
|
166
|
+
#------------------------------- << Training Model >> ---------------------------------------------------------
|
|
167
|
+
#time_scale = "h" # 輸入時間維度 : "每小時"("h"), "每分鐘"("min")
|
|
168
|
+
file_path = os.path.join(os.getcwd(), "data", "410_good_1_all_feature.csv")
|
|
169
|
+
df = pd.read_csv(file_path)
|
|
170
|
+
|
|
171
|
+
#df = df[["Time"] + df.select_dtypes(include="number").columns.tolist()]
|
|
172
|
+
df = rename_columns(df) # 更改欄位名稱 (.CSV檔欄位名稱->系統欄位名稱)
|
|
173
|
+
|
|
174
|
+
algo_config = "1, 0, 1, 1, 2, 1, 1" # [時長維度, testing資料離處理, 低解析度特徵刪除, 特徵選擇, 資料正規化, 模型, rul_deadline]
|
|
175
|
+
|
|
176
|
+
result = HI.training_model(df, algo_config) # Training Model : "training_model_robust_index"(訓練模型指標分數), "training_model_robust_status"(verify:綠燈,warning:紅燈)
|
|
177
|
+
print(result)
|
|
178
|
+
|
|
179
|
+
# result_clean = HI.outlier_clean(df, result) # 測試資料清洗後的model
|
|
180
|
+
# print(result_clean)
|
|
181
|
+
|
|
182
|
+
#Health_train = plot(result['HI_Score'], target="train") # 繪出HI圖
|
|
183
|
+
|
|
184
|
+
#展覽pickle檔案輸出
|
|
185
|
+
# pick_path = os.path.join(os.getcwd(), "uploaded_files", "model", "model.pkl")
|
|
186
|
+
# to_save = dict(result)
|
|
187
|
+
# #to_save["for_demo"] = "for_demo" # 展覽pickle輸出,給系統辨識
|
|
188
|
+
# with open(pick_path, "wb") as f:
|
|
189
|
+
# pickle.dump(to_save, f)
|
|
190
|
+
|
|
191
|
+
#----------------------------------------<<測試一好一壞算法>>---------------------------------------------------------
|
|
192
|
+
# file_path_1 = os.path.join(os.getcwd(), "data", "410_good_1_all_feature.csv")
|
|
193
|
+
# df_1 = pd.read_csv(file_path_1)
|
|
194
|
+
# df_1 = rename_columns(df_1)
|
|
195
|
+
# file_path_2 = os.path.join(os.getcwd(), "data", "Robust_Bad.csv")
|
|
196
|
+
# df_2 = pd.read_csv(file_path_2)
|
|
197
|
+
# df_2 = rename_columns(df_2)
|
|
198
|
+
# good_bad_result = HI.training_model_GB_compare(df_1, df_2, time_scale)
|
|
199
|
+
|
|
200
|
+
#------------------------------- << Inference_HI & 嫌疑度變量 >> ---------------------------------------------------------
|
|
201
|
+
file_path_test = os.path.join(os.getcwd(), "data", "410_good_1_all_feature.csv")
|
|
202
|
+
test_df = pd.read_csv(file_path_test)
|
|
203
|
+
test_df = rename_columns(test_df) # 更改欄位名稱 (.CSV檔欄位名稱->系統欄位名稱)
|
|
204
|
+
test_result = HI.testing_model(test_df,result) # Inference : 輸出 "HI_Score"(HI分數), "suspicious_variable"(變量嫌疑度)
|
|
205
|
+
print(test_result)
|
|
206
|
+
|
|
207
|
+
#test_cleaned = HI.testing_model(test_df,result_clean) # 測試資料清洗後的model
|
|
208
|
+
#Health_test = plot(test_result['HI_Score'], target="test")
|
|
209
|
+
|
|
210
|
+
#------------------------------------- << RUL >> ------------------------------------------------------------------------
|
|
211
|
+
RUL_result = RUL.rul_calculation_h(test_result["HI_Score"], result) # Inference : 輸出 RUL
|
|
212
|
+
print(RUL_result)
|
|
213
|
+
|
|
214
|
+
#------------------------------- << HI_Score 異常時間區段 >> --------------------------------------------------------------
|
|
215
|
+
fail_time = HI.detect_bad_HI_zone(test_result["HI_Score"],threshold=90)
|
|
216
|
+
print(fail_time)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Mon Jul 3 14:19:40 2023
|
|
4
|
+
|
|
5
|
+
@author: yunghua.chang
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pandas as pd
|
|
11
|
+
import scipy.stats as st
|
|
12
|
+
import datetime
|
|
13
|
+
from glob import glob
|
|
14
|
+
from matplotlib import pyplot as plt
|
|
15
|
+
from sklearn.preprocessing import StandardScaler
|
|
16
|
+
from sklearn.decomposition import PCA
|
|
17
|
+
from scipy.stats import f, skew
|
|
18
|
+
import matplotlib.ticker as ticker
|
|
19
|
+
|
|
20
|
+
#%% Health Index計算
|
|
21
|
+
def health_modeling(df, score, alpha=0.05):
|
|
22
|
+
# 標準化
|
|
23
|
+
scaler = StandardScaler()
|
|
24
|
+
scaler.fit(df)
|
|
25
|
+
df_scaled = scaler.transform(df)
|
|
26
|
+
|
|
27
|
+
# 進行主成份分析降維
|
|
28
|
+
pca = PCA(n_components=0.9)
|
|
29
|
+
pca.fit(df_scaled)
|
|
30
|
+
df_pca = pca.transform(df_scaled)
|
|
31
|
+
|
|
32
|
+
# 計算模型的 mu & sigma
|
|
33
|
+
model_mu = df_pca.mean(axis=0)
|
|
34
|
+
model_cov = np.cov(df_pca.T)
|
|
35
|
+
|
|
36
|
+
# 計算模型的UCL
|
|
37
|
+
m = df_pca.shape[0]
|
|
38
|
+
p = df_pca.shape[1]
|
|
39
|
+
fscore = f.ppf(1 - alpha, p, m - p)
|
|
40
|
+
ucl = (p * (m - 1)) / (m - p) * fscore
|
|
41
|
+
|
|
42
|
+
## 計算分數
|
|
43
|
+
df_health = Health_Index(df_pca, model_mu, model_cov, ucl, df.index, score)
|
|
44
|
+
|
|
45
|
+
return df_health, model_mu, model_cov, ucl, scaler, pca
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def health_testing(df, model_mu, model_cov, ucl, scaler, pca):
|
|
49
|
+
|
|
50
|
+
# 以模型平均&標準差進行標準
|
|
51
|
+
df_scaled = scaler.transform(df)
|
|
52
|
+
# 進行主成份分析降維
|
|
53
|
+
df_pca = pca.transform(df_scaled)
|
|
54
|
+
## 計算分數
|
|
55
|
+
df_health = Health_Index(df_pca, model_mu, model_cov, ucl, df.index, score)
|
|
56
|
+
|
|
57
|
+
return df_health
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def score_ewma(df_health, score):
|
|
61
|
+
## EWMA部分
|
|
62
|
+
grade_rolling = df_health["Score"].ewm(span=3, adjust=False).mean()
|
|
63
|
+
index = grade_rolling[df_health["Score"] < score * 100].index
|
|
64
|
+
df_health.loc[index, "Score"] = grade_rolling[
|
|
65
|
+
df_health["Score"] < score * 100
|
|
66
|
+
]
|
|
67
|
+
return df_health
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def CalTSquare(data_pca, i, mu, sigma):
|
|
71
|
+
x = data_pca[i]
|
|
72
|
+
bias = x - mu
|
|
73
|
+
tsquare = bias.dot(np.linalg.pinv(sigma)).dot(np.transpose(bias))
|
|
74
|
+
return tsquare
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def CalScore(tsquare, ucl, score):
|
|
78
|
+
|
|
79
|
+
score_ = np.exp(np.log(score) * ((tsquare) / ucl)) * 100
|
|
80
|
+
|
|
81
|
+
return score_
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def Health_Index(data_pca, model_mu, model_cov, ucl, index, score):
|
|
85
|
+
|
|
86
|
+
df = pd.DataFrame(index=index)
|
|
87
|
+
df["Tsquare"] = list(
|
|
88
|
+
map(
|
|
89
|
+
lambda x: CalTSquare(data_pca, x, model_mu, model_cov),
|
|
90
|
+
np.arange(len(data_pca)),
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
df["Score"] = df["Tsquare"].apply(lambda x: CalScore(x, ucl, score))
|
|
94
|
+
|
|
95
|
+
return df
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def plot(health, target):
|
|
99
|
+
|
|
100
|
+
tick_spacing = 15
|
|
101
|
+
fig, ax = plt.subplots(figsize=(20, 5))
|
|
102
|
+
ax.plot(health.index, health["Score"], marker="o")
|
|
103
|
+
ax.axhline(score * 100, color="r")
|
|
104
|
+
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
|
|
105
|
+
plt.title(" Health Index ," + target, fontsize=25)
|
|
106
|
+
plt.yticks(fontsize=20)
|
|
107
|
+
plt.xticks(rotation=15, fontsize=20)
|
|
108
|
+
plt.ylim(0, 100)
|
|
109
|
+
plt.show()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
#%% 參數設定
|
|
114
|
+
score = 0.9
|
|
115
|
+
modeling_start_time = "2024-09-30 16:00:00"
|
|
116
|
+
modeling_end_time = "2024-10-21 23:59:59"
|
|
117
|
+
|
|
118
|
+
file_path = r"C:\Users\chiyu.hong\Desktop\T7_TLRB0100_00_00001_____9_2_edc_raw_data.csv"
|
|
119
|
+
|
|
120
|
+
df = pd.read_csv(file_path)
|
|
121
|
+
|
|
122
|
+
df["txn_dttm"] = pd.to_datetime(df["txn_dttm"], errors="coerce")
|
|
123
|
+
df = df.set_index("txn_dttm")
|
|
124
|
+
|
|
125
|
+
indicator_name = [
|
|
126
|
+
"X-OA_MAX~_X",
|
|
127
|
+
"Y-OA_MAX~_X",
|
|
128
|
+
"Z-B01_MAX~_X",
|
|
129
|
+
"Z-OA_MAX~_X",
|
|
130
|
+
"Y-B03_MAX~_X",
|
|
131
|
+
"X-B03_MAX~_X",
|
|
132
|
+
"TSquare~_X",
|
|
133
|
+
"Y-B01_MAX~_X",
|
|
134
|
+
"Z-B02_MAX~_X",
|
|
135
|
+
"X-B01_MAX~_X",
|
|
136
|
+
"Z-B03_MAX~_X",
|
|
137
|
+
"Y-B02_MAX~_X",
|
|
138
|
+
"X-B02_MAX~_X"
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
#%%
|
|
142
|
+
std_name = list(map(lambda x: x + "_std", indicator_name))
|
|
143
|
+
mean_name = list(map(lambda x: x + "_mean", indicator_name))
|
|
144
|
+
|
|
145
|
+
#%%
|
|
146
|
+
df_copy = df.copy()
|
|
147
|
+
df = df_copy[indicator_name].resample("H").max()
|
|
148
|
+
df = df.dropna(axis="index", how="any")
|
|
149
|
+
df[mean_name] = df_copy[indicator_name].resample("H").mean()
|
|
150
|
+
df[std_name] = df_copy[indicator_name].resample("H").std()
|
|
151
|
+
|
|
152
|
+
df = df.dropna(axis="index", how="any")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
if __name__ == "__main__":
|
|
157
|
+
target = "Train"
|
|
158
|
+
|
|
159
|
+
(df_health_train, mu, cov, ucl, scaler, pca) = health_modeling(
|
|
160
|
+
df.loc[modeling_start_time:modeling_end_time], score
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
df_health_train = df_health_train.rolling("3H").mean()
|
|
164
|
+
|
|
165
|
+
# Health_train = plot(df_health_train, target)
|
|
166
|
+
|
|
167
|
+
#%%
|
|
168
|
+
## Test
|
|
169
|
+
if __name__ == "__main__":
|
|
170
|
+
target = "Test"
|
|
171
|
+
df_health_test = health_testing(
|
|
172
|
+
df.loc[modeling_end_time:], mu, cov, ucl, scaler, pca
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
df_health_test = df_health_test.rolling("3H").mean()
|
|
176
|
+
|
|
177
|
+
Health_test = plot(df_health_test, target)
|
|
178
|
+
|