質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1942閲覧

Python 機械学習を用いて製造現場における2値分類モデル作成

python01

総合スコア11

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/11/19 03:34

編集2020/11/23 02:32

前提・実現したいこと

製造現場において、生産時のプロセス情報(生産設備の使用号機、生産中に製品が停止した時間)を基に
不良品が発生するかどうかの2値分類モデルを作りたいです。

発生している問題・エラーメッセージ

不良品が発生する確率は100個中2~3個程度です。

下記のアルゴリズムで試しました。
・ランダムフォレスト
・ロジスティック回帰
・決定木
・ニューラルネットワーク

不良品300個と良品300個のデータを用いて学習及びテストを行った結果は下記通りです。

学習データ:精度、適合率、再現率、F値は全て90%以上
テストデータ:精度、適合率、再現率、F値は全て80%以上

しかし、上記で学習させた後、1万個ほどのデータでテストすると、
下記のように低くなります。

精度60%、適合率5%、再現率98%、F値10%

エラーメッセージ

該当のソースコード

python

1import pandas as pd 2test_file = "data.csv" 3test_file2 = "test_N.csv" 4 5df_make = pd.read_csv(test_file,engine="python") 6df_make.describe() 7 8#■標準化■ 9from sklearn.preprocessing import StandardScaler 10stdsc = StandardScaler() 11df_make[['ラインの停止区間A',ラインの停止区間B']] = stdsc.fit_transform(df_make[['ラインの停止区間A','ラインの停止区間B']]) 12 13df_y = df_make["不良"] 14df_make = pd.get_dummies(df_make, columns=["製品の位置情報"]) 15df_make = pd.get_dummies(df_make, columns=["使用装置"]) 16df_x = df_make.drop(["不良"], axis=1) 17 18#■機械学習■ 19from sklearn.model_selection import train_test_split 20train_x, test_x, train_y, test_y = train_test_split(df_x, df_y,stratify = df_y, test_size = 0.9, random_state=0) 21 22#ここで不良あり/なしの個数を確認 23train_y.value_counts() 24 25 26#■アルゴリズム選択■ 27#ロジスティック回帰 (このコードではこのアルゴリズムを使用) 28from sklearn.linear_model import LogisticRegression 29model = LogisticRegression(C=10) 30 31#ランダムフォレスト 32from sklearn.ensemble import RandomForestClassifier 33model = RandomForestClassifier(random_state=random_seed) 34model = RandomForestClassifier(3) 35 36#決定木 37from sklearn.tree import DecisionTreeClassifier 38model = DecisionTreeClassifier(max_depth = 2) 39 40#XGBoost 41from xgboost import XGBClassifier 42model = XGBClassifier(3) 43 44#ニューラルネットワーク 45from sklearn.neural_network import MLPClassifier 46model = MLPClassifier(hidden_layer_sizes=(200,200), random_state=random_seed) 47 48 49 50model.fit(train_x,train_y) 51pred = model.predict(train_x) 52 53import matplotlib.pyplot as plt 54%matplotlib inline 55 56import numpy as np 57plt.plot(pred, color="red") #AIの予想 = 赤 58plt.plot(np.array(train_y), color="black", linestyle="dotted",linewidth="0.2") #答え = 黒 59 60 61#■学習データで精度確認■ 62from sklearn.metrics import precision_recall_fscore_support 63 64precision, recall, fscore, _ = precision_recall_fscore_support(train_y, pred, average='binary') 65score = model.score(train_x, train_y) 66 67print(f'精度: {score:.4f}') 68print(f'適合率: {precision:.4f}') 69print(f'再現率: {recall:.4f}') 70print(f'F値: {fscore:.4f}') 71 72pred2 = model.predict(test_x) 73 74plt.plot(pred2, color="red") #予測線 75plt.plot(np.array(test_y), color="black", linestyle="dotted",linewidth="0.2") #答え 76 77#■テストデータで精度確認■ 78precision, recall, fscore, _ = precision_recall_fscore_support(test_y, pred2, average='binary') 79score = model.score(test_x, test_y) #決定係数を確認する。1に近いほど精度が良い。 80 81print(f'精度: {score:.4f}') 82print(f'適合率: {precision:.4f}') 83print(f'再現率: {recall:.4f}') 84print(f'F値: {fscore:.4f}') 85 86 87#■他のデータ(1万個のデータ)の予測■ 88df_make2 = pd.read_csv(test_file2,engine="python") 89 90df_make2[['ラインの停止区間A',ラインの停止区間B']] = stdsc.fit_transform(df_make[['ラインの停止区間A','ラインの停止区間B']]) 91 92test_y2 = df_make2["不良"] 93df_make2 = pd.get_dummies(df_make2, columns=["製品の位置情報"]) 94df_make2 = pd.get_dummies(df_make2, columns=["使用装置"]) 95test_x2 = df_make2.drop(["不良"], axis=1) 96 97pred_test = model.predict(test_x2) 98 99plt.plot(pred_test, color="red") #予測線 100plt.plot(np.array(test_y2), color="black", linestyle="dotted",linewidth="0.2") #答え 101 102precision, recall, fscore, _ = precision_recall_fscore_support(test_y2, pred_test, average='binary') 103score = model.score(test_x2, test_y2) 104 105print(f'精度: {score:.4f}') 106print(f'適合率: {precision:.4f}') 107print(f'再現率: {recall:.4f}') 108print(f'F値: {fscore:.4f}') #←ここでF値が10%ほどしか出ない 109 110

試したこと

特徴量の増加:4個 → 7個

補足情報(FW/ツールのバージョンなど)

使用言語:Python
作業環境:jupyter notebook

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

コードやデータの提示が無いので、少し一般論として回答します。

まず、1万個のデータがあるにも関わらず600個だけでモデルを作っていることが問題であると思います。
1万個の教師データが存在するというのは、このような不良率発見において「恵まれた環境」であると思いますので、せっかくの教師データを存分に使いたいです。

現在は、1万個から明らかに現実の良品率と異なる恣意的な抽出をしているため、できたモデルも信頼がおけません。なお、画像などアナログデータを角度や光の具合を変えたシミュレーションにより「水増し」するのは正しく効果がある手法のようです。今回のように同一のデータで水増しした状態はよくないようです。

参考: 失敗から学ぶ機械学習応用
スライド7からの例「不良率の少ない中で普通に全データ学習させてしまったらうまく学習できないから、不良品と良品を等分で学習させたら成功したよ!ーあれ?成功したのかな?」

不良データを多く学習させると、その訓練データに過学習して、より不良に敏感になります。結果的に、再現率は高いが精度は低い、質問者様のような状況になります。

機械学習の評価指標として、単純な正解率ではなく、F値など「高めたい指標」を採用しましょう。それによって、「全データを学習させたら全て良品と判定してしまった」といったこのスライドの最初の失敗は防止できると思います。

その上で全データを使いましょう。
ランダムで抽出して7割〜8割を学習データ、残りをテストデータとするとよいでしょう。
また学習データを、訓練データと検証データに分割し、検証データを訓練にまぜないように注意ください。

さらに良い結果を得るには、現場の知見も入れて様々な特徴量を思いつくだけ追加しましょう。なお、現実の環境で取得できる特徴量である必要があります。例えば、1つ前が不良品だったら次も不良品率が高いから、1つ前が良品/不良品かどうかを特徴量として採用する!みたいに考えても、良品/不良品といった正解データがそんなにリアルタイムに得られているとは限りませんので、現実の環境では取得できない値になってしまいます。

モデルとして、GBDTのような決定木系のモデルだと、無関係な特徴量を増やしても結果に影響を与えにくいのと、特徴量の寄与度も把握できるため、特徴量をいろいろ試してみる時には最適です。

投稿2020/11/19 03:45

編集2020/11/19 23:07
toast-uz

総合スコア3266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

python01

2020/11/19 05:35

ご教授頂きありがとうございます。 600個データ抽出の経緯に関して、 最初全てのデータで学習をさせたところ、 良品データ数に対して 不良データ数が極端にすくなくなった為、不良データ数(300個)と同数の良品データをランダムで抽出しています。 また、コードは別途添付します。
toast-uz

2020/11/19 10:15

不具合発見モデルは、不具合事象が相対的に少ないというのがチャレンジャブルなところです。 実際の推論と、訓練で条件を変えてはダメです。不良データを余計に訓練させるのではなく、現場の詳しい方を交えて、可能性ある特徴量をもっと思いつくだけ加え、GBDTのような無関係な特徴量が増えても精度が落ちにくいモデルを使ってみましょう。
toast-uz

2020/11/19 23:14

いったん、考え方レベルで回答を大幅加筆しましたので、ご確認ください。 この考え方をコードとしてどう実装するのか、という質問がもしありましたら、元の質問とはかなり異なるため、質問として別にされたほうがよいかと思います。なお、元の質問を崩さずに、参考情報としてコードを記載いただくのは、ありがたいです。
python01

2020/11/20 03:37

ご丁寧な回答ありがとうございました。 頂いたスライドに関しても確認してみます。 また、参考でコードを入力しました。
python01

2020/11/20 12:19

ご丁寧にありがとうございます。 休日に勉強してみます。
python01

2020/11/23 02:35

toast-uz様 コードのご指摘ありがとうございました。 参考画像を基に修正してみました。
toast-uz

2020/11/23 03:17

ありがとうございます。コードが読めるようになりました。test_fileが600個抽出したもの、test_file2が1万個全件なのですね。「test_file2の全体をもとに訓練し、訓練時の評価方法として単純な正解率は使わないように注意しましょう」というのが私の回答骨子です。
python01

2020/11/24 03:13

テストファイルは上記認識で合っています。 ご教授頂いた内容を基に下記で試してみます。 ・良品、不良品が同等になるようなデータ抽出は行わず、全体のファイルで訓練させる ・追加できる特徴量を追加 ・評価指標にAUCも追加 ・アルゴリズムにGBDTも追加
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問