製造業界のデータサイエンティスト奮闘記

製造業向けのビッグデータ分析やAIによるデータ解析、機械学習についてのブログ

とにかく簡単に、製品不良の原因分析をしてみる(PythonのRandom Forestを使って)

f:id:data_scientist:20181228132620j:plain
不良の原因を突き止めるにあたっては、MT法やT法、新QC七つ道具やらなぜなぜ分析やらいろんなものがありますが、製造業に関して言えば機械学習的なアプローチで進めることはまだ少ないのではないでしょうか。今では機械学習を売りにしたソフトウェアも随分と沢山作られており、「不良の要因分析をしたい」というニーズがあることをどこからか嗅ぎつけて来ては、どこぞの企業が営業をかけてくるという事も少なくないと思います。

とはいえ、設計であれ製造であれ、予算を使ってそれらのソフトウェアを導入すること自体はやぶさかでないにせよ、困っているのは”今”な訳で、何ヶ月もかかるようなPoCをやりたい人はあまりいないと思います。また、担当者がソフトウェアにドンピシャな回答を求めることも稀で、手当たり次第に原因を突き止めようとするのではなく、あくまでアタリをつけるために使いたいという場合が多いように思います。担当者自身はそれなりにノウハウを持っているものなので、ソフトウェアに頼らずともなんだかんだで原因を探り当ててくることがほとんどです。

そんなわけで今回は、予測精度や見つけ出した原因の確からしさといったことは優先順位を落として、とにかく「簡単」に「それっぽい」結果が出てくる方法を紹介したいと思います。使用するのはPythonで、scikit-learnのランダムフォレストというアルゴリズムを用います。流行りではXGBoostやLightGBMといったより高い精度がでやすいライブラリもありますが、今回はインストールも最小になるようランダムフォレストを使っています。また、簡単をモットーに紹介するので、結果の吟味を十分に行わないと、誤った判断をしてしまう可能性がある点については予めご了承ください。

手順

大まかに3つの作業があります。

  1. データを準備する
  2. Anacondaをインストールする
  3. Pythonコードをコピペして実行する。
1.データを準備する

分析に使用するデータは、下記の条件が必要です。以降、判定結果となる値を目的変数、原因となる項目を説明変数と呼びます。

  • 目的変数と説明変数は1行でまとまっている。
  • 行数は最低でも100行。(説明変数が多い場合はそれ以上)
  • 空白になっている場所(欠損値)が無い。
  • csvファイル。ファイル名は「data.csv
  • 目的変数のヘッダーを"Judge"にする、説明変数のヘッダーは日本語を使わない(文字化けします)
  • 説明変数にOK/NG等のカテゴリデータがある場合は、数値に置き換える

データを用意できない場合、今回ご紹介する方法は使えないので、上記の条件を十分確認してください。後に使用するプログラムで読み込めない可能性が出てくるので、空白になっている場所(欠損値)が無いことも確認が必要です。数値の置き換えや欠損値のある行の排除などは、Excelなどで行ってください。

例として、サクッと用意できるデータがタイタニックだったので、タイタニックで生存したか否かのデータを分析してみました。
Titanic: Machine Learning from Disaster | Kaggle

生存したか否かが製品の良/不良、生存できた理由が不良原因と読み替えて貰えればと思います。
データは下記のようなイメージです。
f:id:data_scientist:20181228121957p:plain

Judgeとなる項目はOK/NGでもTrue/Falseでも、0or1でもいいです。

2.Anacondaをインストールする

Anacondaとは、データサイエンス、機械学習などの開発で必要なツールがまとめられたものです。ライブラリのインストールも同時にやってくれるので、知識がない場合はこちらをインストールすることをお勧めします。

下記からダウンロードしてインストールしてください。
https://www.anaconda.com/download/

3.Pythonコードをコピペして実行する

下記手順でプログラムを実行します。

  1. 「スタートメニュー > Anaconda3 > Jupyter Notebook」を起動する。
  2. 「File > New Notebook > Python 3」でファイルを作成。
  3. 作成したファイルと同じ場所に、準備したデータを置く。
  4. 下記コードをコピーして、Runを実行。
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import train_test_split

pd_data = pd.read_csv("data.csv")
y = pd_data[["Judge"]]
X = pd_data.drop("Judge",axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)

RFR = RandomForestClassifier(max_depth = 20, random_state = 0, n_estimators = 10)
RFR.fit(X_train,y_train)

print ("Training score:",RFR.score(X_train,y_train),"Test Score:",RFR.score(X_test,y_test))

default_imp=pd.DataFrame(data={'importance':RFR.feature_importances_,'features':X_train.columns})
default_imp=default_imp.set_index('features')
default_imp=default_imp.sort_values('importance',ascending=False)
default_imp=default_imp[:30]
default_imp.plot(kind='bar',figsize=(15,5))
plt.show()

f:id:data_scientist:20181228121640p:plain
棒グラフが大きいものが原因となる項目です。当たり前といえば当たり前ですが、救命ボートに乗れたか否かが生存率に大きく影響しているようです。Test Scoreという値も表示されていますが、1に近いほど結果が正しいことを示しています。0.5といった値の場合は、精度に問題があるためあまり参考にはならないでしょう。

上記のコードだけで簡単に要因分析ができますが、もしエラーが起きた場合は読み込ませるデータがおかしなものでないか再度確認してください。欠損値、カテゴリデータの数値化の部分で躓きやすいので注意してください。