質問編集履歴
3
参考資料追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -272,8 +272,12 @@
|
|
272
272
|
|
273
273
|
使用ライブラリ
|
274
274
|
|
275
|
-
sklearn
|
276
|
-
|
277
|
-
matplotlib
|
275
|
+
sklearn, matplotlib, pandas
|
278
|
-
|
276
|
+
|
277
|
+
|
278
|
+
|
279
|
-
|
279
|
+
参考
|
280
|
+
|
281
|
+
ロジスティック回帰分析で特徴量の重要度を知る方法
|
282
|
+
|
283
|
+
(https://teratail.com/questions/263204)
|
2
使用ライブラリ追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -275,3 +275,5 @@
|
|
275
275
|
sklearn
|
276
276
|
|
277
277
|
matplotlib
|
278
|
+
|
279
|
+
pandas
|
1
誤字修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -12,260 +12,254 @@
|
|
12
12
|
|
13
13
|
|
14
14
|
|
15
|
-
### 発生している問題
|
15
|
+
### 発生している問題
|
16
|
+
|
17
|
+
グラフが赤の時故障、青の時正常と凡例に追加したいが、うまくいっていない
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
### 該当のソースコード
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
```python3
|
26
|
+
|
27
|
+
print("*** LogisticRegression.pyの実行 ***")
|
28
|
+
|
29
|
+
print("Step1. ライブラリのインポート")
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
# ***** ライブラリのインポート *****
|
34
|
+
|
35
|
+
import warnings
|
36
|
+
|
37
|
+
# 余分なワーニングを非表示にする
|
38
|
+
|
39
|
+
warnings.filterwarnings('ignore')
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
import pickle
|
44
|
+
|
45
|
+
import os
|
46
|
+
|
47
|
+
import japanize_matplotlib
|
48
|
+
|
49
|
+
import matplotlib.pyplot as plt
|
50
|
+
|
51
|
+
from sklearn.linear_model import LogisticRegression
|
52
|
+
|
53
|
+
from sklearn.preprocessing import StandardScaler
|
54
|
+
|
55
|
+
from sklearn.metrics import roc_auc_score
|
56
|
+
|
57
|
+
from sklearn.model_selection import train_test_split
|
58
|
+
|
59
|
+
import csv
|
60
|
+
|
61
|
+
import pandas as pd
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
# ***** 入力ファイルの読み込み *****
|
68
|
+
|
69
|
+
print("Step2. 入力ファイルの読み込み")
|
70
|
+
|
71
|
+
INPUT_FILE = os.path.join(os.getcwd(), "input_file")
|
72
|
+
|
73
|
+
OUTPUT_FILE = os.path.join(os.getcwd(), "output_file")
|
74
|
+
|
75
|
+
os.makedirs(OUTPUT_FILE, exist_ok=True)
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
THRESH = 0.3 # 故障確率をいくつ以上を故障と判定するか指定
|
80
|
+
|
81
|
+
df = pd.read_csv(os.path.join(INPUT_FILE, 'train.csv'))
|
82
|
+
|
83
|
+
df.head() #図1
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
print("Step3. 入力データ前処理")
|
88
|
+
|
89
|
+
# 製品故障
|
90
|
+
|
91
|
+
df['状態(予測対象)'] = df['状態(予測対象)'].map({'故障': 0, '正常': 1})
|
92
|
+
|
93
|
+
# 購入の経過月数 131.0month -> 131.0
|
94
|
+
|
95
|
+
df['購入からの経過月数'] = df['購入からの経過月数'].str.replace('month', '').astype(float)
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
# 機器タイプ
|
100
|
+
|
101
|
+
m_type = pd.get_dummies(df['機器タイプ'], drop_first=True, prefix='機器')
|
102
|
+
|
103
|
+
# 保守担当チーム
|
104
|
+
|
105
|
+
team=pd.get_dummies(df['保守担当チーム'],drop_first=True,prefix='チーム')
|
106
|
+
|
107
|
+
# 表の統合
|
108
|
+
|
109
|
+
df_tmp=df.drop(['機器タイプ','保守担当チーム'],axis=1)
|
110
|
+
|
111
|
+
df_merge=pd.concat([df_tmp,m_type,team],axis=1)
|
112
|
+
|
113
|
+
df_merge.head() #図2
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
col = ['機器_B','機器_C','チーム_Team1-2','チーム_Team2-1','チーム_Team2-2','購入からの経過月数', '稼働時平均温度',
|
118
|
+
|
119
|
+
'稼働時平均湿度', '油圧メーター値']
|
120
|
+
|
121
|
+
x = df_merge[col]
|
122
|
+
|
123
|
+
t = df_merge['状態(予測対象)']
|
124
|
+
|
125
|
+
#訓練データ標準化
|
126
|
+
|
127
|
+
sc=StandardScaler()
|
128
|
+
|
129
|
+
new=sc.fit_transform(x)
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
# ***** 学習 *****
|
134
|
+
|
135
|
+
print("Step4. モデル学習")
|
136
|
+
|
137
|
+
x_train, x_test, y_train, y_test = train_test_split(new, t,
|
138
|
+
|
139
|
+
test_size=0.2, random_state=0)
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
#学習
|
144
|
+
|
145
|
+
model = LogisticRegression(random_state=0, C=0.1,
|
146
|
+
|
147
|
+
multi_class="auto", solver="lbfgs")
|
148
|
+
|
149
|
+
model.fit(x_train, y_train)
|
150
|
+
|
151
|
+
print(f'訓練データ件数{len(y_train)} 検証データ件数{len(y_test)}')
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
# ***** 精度評価 *****
|
156
|
+
|
157
|
+
print("Step5. 精度評価")
|
158
|
+
|
159
|
+
#正解率
|
160
|
+
|
161
|
+
score = model.score(x_train, y_train)
|
162
|
+
|
163
|
+
score2 = model.score(x_test, y_test)
|
164
|
+
|
165
|
+
print(f"Train {score:.2%}")
|
166
|
+
|
167
|
+
print(f"Test {score2:.2%}")
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
#影響度を知る
|
172
|
+
|
173
|
+
feature=pd.DataFrame(model.coef_[0],col)
|
174
|
+
|
175
|
+
feature.to_csv(os.path.join(OUTPUT_FILE,"feature.csv"),header=False,index=True,encoding="shift-jis")
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
#影響度をグラフ化する
|
180
|
+
|
181
|
+
plt.figure(figsize=(15,5))
|
182
|
+
|
183
|
+
plt.title("故障の影響度")
|
184
|
+
|
185
|
+
plt.xlabel("要因")
|
186
|
+
|
187
|
+
plt.ylabel('故障/正常の影響度')
|
188
|
+
|
189
|
+
#影響度が正の時青,影響度が負の時赤にする
|
190
|
+
|
191
|
+
color=[('r' if model.coef_[0][i]<0 else 'b') for i in range(len(model.coef_[0]))]
|
192
|
+
|
193
|
+
#影響度を絶対値にして表示
|
194
|
+
|
195
|
+
plt.bar(col,np.abs(model.coef_[0]),width=0.5,color=color) 図3
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
'''
|
202
|
+
|
203
|
+
影響度が正の時正常、負の時故障と凡例に表示させたい
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
'''
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
#plt.legend(loc='upper center')
|
214
|
+
|
215
|
+
plt.show()
|
16
216
|
|
17
217
|
|
18
218
|
|
19
219
|
```
|
20
220
|
|
221
|
+
![図1](aa3514f265d59b1fa2a00190c425c883.png)
|
222
|
+
|
21
|
-
|
223
|
+
図1 入力ファイル
|
224
|
+
|
225
|
+
![図2](b22a86acdae8de3775c0a46ddc3366d5.png)
|
226
|
+
|
227
|
+
図2 カテゴリ変数をダミー変数化した
|
228
|
+
|
229
|
+
![イメージ説明](15d4236c905184b9624a5c360cebbe0d.png)
|
230
|
+
|
231
|
+
図3 影響度をグラフ出力したもの
|
232
|
+
|
233
|
+
ここから凡例を追加したい
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
### 試したこと
|
238
|
+
|
239
|
+
以下のコードで場合分けしてみたが、凡例が期待通りの動作にならなかった。
|
240
|
+
|
241
|
+
図4では、凡例が9個も出てしまっているが、凡例を赤と青の2つだけにしたい。
|
242
|
+
|
243
|
+
```python3
|
244
|
+
|
245
|
+
plt.figure(figsize=(15,5))
|
246
|
+
|
247
|
+
for i in range(len(model.coef_[0])):
|
248
|
+
|
249
|
+
if model.coef_[0][i]<0:
|
250
|
+
|
251
|
+
plt.bar(col[i],model.coef_[0][i],width=0.5,color="r",label="故障")
|
252
|
+
|
253
|
+
else:
|
254
|
+
|
255
|
+
plt.bar(col[i],model.coef_[0][i],width=0.5,color="b",label="正常")
|
256
|
+
|
257
|
+
plt.legend(loc='upper left')
|
258
|
+
|
259
|
+
plt.show() #図4
|
22
260
|
|
23
261
|
```
|
24
262
|
|
25
|
-
|
26
|
-
|
27
|
-
### 該当のソースコード
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
```python3
|
32
|
-
|
33
|
-
print("*** LogisticRegression.pyの実行 ***")
|
34
|
-
|
35
|
-
print("Step1. ライブラリのインポート")
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# ***** ライブラリのインポート *****
|
40
|
-
|
41
|
-
import warnings
|
42
|
-
|
43
|
-
# 余分なワーニングを非表示にする
|
44
|
-
|
45
|
-
warnings.filterwarnings('ignore')
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
import pickle
|
50
|
-
|
51
|
-
import os
|
52
|
-
|
53
|
-
import japanize_matplotlib
|
54
|
-
|
55
|
-
import matplotlib.pyplot as plt
|
56
|
-
|
57
|
-
from sklearn.linear_model import LogisticRegression
|
58
|
-
|
59
|
-
from sklearn.preprocessing import StandardScaler
|
60
|
-
|
61
|
-
from sklearn.metrics import roc_auc_score
|
62
|
-
|
63
|
-
from sklearn.model_selection import train_test_split
|
64
|
-
|
65
|
-
import csv
|
66
|
-
|
67
|
-
import pandas as pd
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# ***** 入力ファイルの読み込み *****
|
74
|
-
|
75
|
-
print("Step2. 入力ファイルの読み込み")
|
76
|
-
|
77
|
-
INPUT_FILE = os.path.join(os.getcwd(), "input_file")
|
78
|
-
|
79
|
-
OUTPUT_FILE = os.path.join(os.getcwd(), "output_file")
|
80
|
-
|
81
|
-
os.makedirs(OUTPUT_FILE, exist_ok=True)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
THRESH = 0.3 # 故障確率をいくつ以上を故障と判定するか指定
|
86
|
-
|
87
|
-
df = pd.read_csv(os.path.join(INPUT_FILE, 'train.csv'))
|
88
|
-
|
89
|
-
df.head() #図1
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
print("Step3. 入力データ前処理")
|
94
|
-
|
95
|
-
# 製品故障
|
96
|
-
|
97
|
-
df['状態(予測対象)'] = df['状態(予測対象)'].map({'故障': 0, '正常': 1})
|
98
|
-
|
99
|
-
# 購入の経過月数 131.0month -> 131.0
|
100
|
-
|
101
|
-
df['購入からの経過月数'] = df['購入からの経過月数'].str.replace('month', '').astype(float)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
# 機器タイプ
|
106
|
-
|
107
|
-
m_type = pd.get_dummies(df['機器タイプ'], drop_first=True, prefix='機器')
|
108
|
-
|
109
|
-
# 保守担当チーム
|
110
|
-
|
111
|
-
team=pd.get_dummies(df['保守担当チーム'],drop_first=True,prefix='チーム')
|
112
|
-
|
113
|
-
# 表の統合
|
114
|
-
|
115
|
-
df_tmp=df.drop(['機器タイプ','保守担当チーム'],axis=1)
|
116
|
-
|
117
|
-
df_merge=pd.concat([df_tmp,m_type,team],axis=1)
|
118
|
-
|
119
|
-
df_merge.head() #図2
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
col = ['機器_B','機器_C','チーム_Team1-2','チーム_Team2-1','チーム_Team2-2','購入からの経過月数', '稼働時平均温度',
|
124
|
-
|
125
|
-
'稼働時平均湿度', '油圧メーター値']
|
126
|
-
|
127
|
-
x = df_merge[col]
|
128
|
-
|
129
|
-
t = df_merge['状態(予測対象)']
|
130
|
-
|
131
|
-
#訓練データ標準化
|
132
|
-
|
133
|
-
sc=StandardScaler()
|
134
|
-
|
135
|
-
new=sc.fit_transform(x)
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
# ***** 学習 *****
|
140
|
-
|
141
|
-
print("Step4. モデル学習")
|
142
|
-
|
143
|
-
x_train, x_test, y_train, y_test = train_test_split(new, t,
|
144
|
-
|
145
|
-
test_size=0.2, random_state=0)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
#学習
|
150
|
-
|
151
|
-
model = LogisticRegression(random_state=0, C=0.1,
|
152
|
-
|
153
|
-
multi_class="auto", solver="lbfgs")
|
154
|
-
|
155
|
-
model.fit(x_train, y_train)
|
156
|
-
|
157
|
-
print(f'訓練データ件数{len(y_train)} 検証データ件数{len(y_test)}')
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
# ***** 精度評価 *****
|
162
|
-
|
163
|
-
print("Step5. 精度評価")
|
164
|
-
|
165
|
-
#正解率
|
166
|
-
|
167
|
-
score = model.score(x_train, y_train)
|
168
|
-
|
169
|
-
score2 = model.score(x_test, y_test)
|
170
|
-
|
171
|
-
print(f"Train {score:.2%}")
|
172
|
-
|
173
|
-
print(f"Test {score2:.2%}")
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
#影響度を知る
|
178
|
-
|
179
|
-
feature=pd.DataFrame(model.coef_[0],col)
|
180
|
-
|
181
|
-
feature.to_csv(os.path.join(OUTPUT_FILE,"feature.csv"),header=False,index=True,encoding="shift-jis")
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
#影響度をグラフ化する
|
186
|
-
|
187
|
-
plt.figure(figsize=(15,5))
|
188
|
-
|
189
|
-
plt.title("故障の影響度")
|
190
|
-
|
191
|
-
plt.xlabel("要因")
|
192
|
-
|
193
|
-
plt.ylabel('故障/正常の影響度')
|
194
|
-
|
195
|
-
#影響度が正の時青,影響度が負の時赤にする
|
196
|
-
|
197
|
-
color=[('r' if model.coef_[0][i]<0 else 'b') for i in range(len(model.coef_[0]))]
|
198
|
-
|
199
|
-
#影響度を絶対値にして表示
|
200
|
-
|
201
|
-
plt.bar(col,np.abs(model.coef_[0]),width=0.5,color=color) 図3
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
'''
|
208
|
-
|
209
|
-
影響度が正の時正常、負の時故障と凡例に表示させたい
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
'''
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
#plt.legend(loc='upper center')
|
220
|
-
|
221
|
-
plt.show()
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
```
|
226
|
-
|
227
|
-
![図1](aa3514f265d59b1fa2a00190c425c883.png)
|
228
|
-
|
229
|
-
図1 入力ファイル
|
230
|
-
|
231
|
-
![図2](b22a86acdae8de3775c0a46ddc3366d5.png)
|
232
|
-
|
233
|
-
図2 カテゴリ変数をダミー変数化した
|
234
|
-
|
235
|
-
![イメージ説明](15d4236c905184b9624a5c360cebbe0d.png)
|
236
|
-
|
237
|
-
図3 影響度をグラフ出力したもの
|
238
|
-
|
239
|
-
ここから凡例を追加したい
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
### 試したこと
|
244
|
-
|
245
|
-
以下のコードで場合分けしてみたが、凡例が期待通りの動作にならなかった。
|
246
|
-
|
247
|
-
図4では、凡例が9個も出てしまっているが、凡例を赤と青の2つだけにしたい。
|
248
|
-
|
249
|
-
```python3
|
250
|
-
|
251
|
-
plt.figure(figsize=(15,5))
|
252
|
-
|
253
|
-
for i in range(len(model.coef_[0])):
|
254
|
-
|
255
|
-
if model.coef_[0][i]<0:
|
256
|
-
|
257
|
-
plt.bar(col[i],model.coef_[0][i],width=0.5,color="r",label="故障")
|
258
|
-
|
259
|
-
else:
|
260
|
-
|
261
|
-
plt.bar(col[i],model.coef_[0][i],width=0.5,color="b",label="正常")
|
262
|
-
|
263
|
-
plt.legend(loc='upper left')
|
264
|
-
|
265
|
-
plt.show() #図4
|
266
|
-
|
267
|
-
```
|
268
|
-
|
269
263
|
![イメージ説明](5ed797c011effa9eb970a8f5bb1f0f5b.png)
|
270
264
|
|
271
265
|
図4 凡例失敗図
|