기계 학습 모델 및 결과 해석 (Feature Importance)
9672 단어 파이썬MachineLearning기계 학습Kaggle
Abstract: 기계 학습 모델과 결과를 해석하는 방법
1. 어떤 특징량이 중요한가: 모델이 중요시하고 있는 요인을 알 수 있다
2. 각 특징량이 예측에 어떻게 영향을 미치는지: 특징량을 변화시켰을 때의 예측으로부터 경향을 잡는다
3. 예측 결과가 나왔을 때의 특징량의 기여: 근사한 모델을 만들어, 각 특징의 기여를 산출
Introduction : 기계 학습의 해석성의 중요성이 증가하고 있습니다.
현재, 고정밀도를 두드린 기계 학습은, 블랙 박스가 되기 쉽고 근거의 설명을 인간에게 제시하지 않는다
예를 들어, 가까운 장래에 의사가 기계 학습 모델에서 유도 한 모델에서 진단 할 시대가되었을 때
お医者さん「あなたは糖尿病に今後5年以内になりますよ。」
患者さん「どうしてわかったんですか? 何が原因なんですか!?」
お医者さん「...。 AIがそう判断したからですよ...。」
患者さん「納得できません!」
라고 되어 버린다.
기계 학습 모델이 예측 결과에 대해 왜 그 예측을 한지에 대한 설명이 필요하다.
Environment:
실험 환경
Python==3.6.8
matplotlib==3.0.3
jupyter notebook
import re
import sklearn
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
%reload_ext autoreload
%autoreload 2
데이터
Kaggle titanic를 사용.
적당한 데이터수, 카디널리티의 적음, 해석의 용이성, 모두에게 인식되고 있는 3점으로부터 채용.
Titanic: Machine Learning from Disaster
이 대회는 타이타닉호에 승선한 각 승객이 구입한 티켓의 클래스(Pclass1, 2, 3의 순서로 높은 클래스)나 요금(Fare), 연령(Age), 성별(Sex), 출항지( Embarked), 방 번호(Cabin), 티켓 번호(Tichket), 승선하고 있던 형제 또는 배우자의 수(SibSp), 승선하고 있던 부모 또는 아이의 수(Parch) 등 정보가 있으며, 거기에서 타이타닉호 빙산에 충돌하여 침몰했을 때 생존했는지(Survived)를 예측한다.
PassengerId – 乗客識別ユニークID
Survived – 生存フラグ(0=死亡、1=生存)
Pclass – チケットクラス
Name – 乗客の名前
Sex – 性別(male=男性、female=女性)
Age – 年齢
SibSp – タイタニックに同乗している兄弟/配偶者の数
parch – タイタニックに同乗している親/子供の数
ticket – チケット番号
fare – 料金
cabin – 客室番号
Embarked – 出港地(タイタニックへ乗った港)
train.head()
전처리
Python에서 앙상블 (스태킹) 학습 & 기계 학습 자습서 in Kaggle
↑전처리가 간결하고, 데이터를별로 괴롭히지 않으므로 참고로 했습니다. 감사합니다.
기본적으로는 전처리에 의해 이하의 용으로 빈 분할하였다. (빈 분할한 이유는 결과를 인간이 해석하기 쉬워지기 때문)
Value
Age(나이)
0
16세 이하
1
32세 이하
2
48세 이하
3
64세 이하
4
그 이상
Value
Fare(요금)
0
굉장히 낮은
1
낮은
2
높은
3
굉장히 높은
Value
Embarked(출항지)
0
S 사람이 많다.
1
C 부자가 많다.
2
Q 빈곤이 많다
Value
Title(경칭)
0
Mr
1
Miss
2
Mrs
3
마스터
4
Rare
Value
Sex(성별)
0
female 여자
1
male 남성
Value
Pclass(티켓 클래스)
0
럭셔리
1
중급
2
하급
Value
IsAlone (가족 유무)
0
가족 없음
1
가족 있음
full_data = [train, test]
# 客室番号データがあるなら1を、欠損値なら0
train['Has_Cabin'] = train["Cabin"].apply(lambda x: 0 if type(x) == float else 1)
test['Has_Cabin'] = test["Cabin"].apply(lambda x: 0 if type(x) == float else 1)
# 家族の大きさを"タイタニックに同乗している兄弟/配偶者の数"と
# "タイタニックに同乗している親/子供の数"から定義
for dataset in full_data:
dataset['FamilySize'] = dataset['SibSp'] + dataset['Parch'] + 1
# 家族の有無 0なら家族なし、1なら家族あり
for dataset in full_data:
dataset['IsAlone'] = 0
dataset.loc[dataset['FamilySize'] == 1, 'IsAlone'] = 1
# 出港地の欠損値を一番多い"S"としておく
for dataset in full_data:
dataset['Embarked'] = dataset['Embarked'].fillna('S')
# 料金の欠損値を中央値としておく
# 料金の4グループに分ける
for dataset in full_data:
dataset['Fare'] = dataset['Fare'].fillna(train['Fare'].median())
train['CategoricalFare'] = pd.qcut(train['Fare'], 4)
# 年齢を5グループに分ける
for dataset in full_data:
age_avg = dataset['Age'].mean()
age_std = dataset['Age'].std()
age_null_count = dataset['Age'].isnull().sum()
age_null_random_list = np.random.randint(age_avg - age_std, age_avg + age_std, size=age_null_count)
dataset['Age'][np.isnan(dataset['Age'])] = age_null_random_list
dataset['Age'] = dataset['Age'].astype(int)
train['CategoricalAge'] = pd.cut(train['Age'], 5)
# 正規表現で姓名を取り出す
def get_title(name):
title_search = re.search(' ([A-Za-z]+)\.', name)
if title_search:
return title_search.group(1)
return ""
for dataset in full_data:
dataset['Title'] = dataset['Name'].apply(get_title)
# 誤字修正
dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')
for dataset in full_data:
# 性別を2種類にラベル付 女なら0、男なら1
dataset['Sex'] = dataset['Sex'].map( {'female': 0, 'male': 1} ).astype(int)
# 敬称を5種類にラベル付
title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
dataset['Title'] = dataset['Title'].map(title_mapping)
dataset['Title'] = dataset['Title'].fillna(0)
# 出港地の3種類にラベル付
dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int)
# 料金を4グループに分ける
dataset.loc[ dataset['Fare'] <= 7.91, 'Fare'] = 0
dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare'] = 2
dataset.loc[ dataset['Fare'] > 31, 'Fare'] = 3
dataset['Fare'] = dataset['Fare'].astype(int)
# 年齢を5グループに分ける
dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0
dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
dataset.loc[ dataset['Age'] > 64, 'Age'] = 4 ;
# 必要ない特徴を削除
drop_elements = ['PassengerId', 'Name', 'Ticket', 'Cabin', 'SibSp']
train = train.drop(drop_elements, axis = 1)
train = train.drop(['CategoricalAge', 'CategoricalFare'], axis = 1)
test = test.drop(drop_elements, axis = 1)
데이터를 읽고 학습하고 싶은 데이터와 정답 라벨로 나누기
y_train = train['Survived'].ravel()
x_train = train.drop(['Survived'], axis=1)
x_test = test.values
모델링
Gradient Boosting Decision Tree의 LightGBM에서 모델을 만듭니다.
import lightgbm as lgbm
model = lgbm.LGBMClassifier()
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
prediction = np.round(y_pred).astype(int)
Method: Feature Importance
x축이 중요도를 나타내고 y축이 위에서부터 순서대로 중요한 특징을 표시합니다.
plot_importance(booster, ax=None, height=0.2,
xlim=None, ylim=None, title='Feature importance',
xlabel='Feature importance', ylabel='Features',
importance_type='split', max_num_features=None,
ignore_zero=True, figsize=None, grid=True,
precision=None, **kwargs):
Result:
lgbm.plot_importance(model, figsize=(12, 6))
plt.show()
Discussion:
교사가있는 학습 모델을 사용하여 개별 기능의 중요성을 계산합니다. 모델이 학습시 자동으로 산출해 주므로 손쉽게 사용할 수 있다.
References:
htps // gghtgbm. Red d. cs. 이오 / 엔 / ㅁ st / _ 모즈 ぇ s / ぃghtgbm / p ぉ チン g. HTML
htps : // 코 m / 호쿠토 _ 히라 노 / ms / 2c35 아 81fbc95f0에 4b7c1 # 세콘 d ぇょPut
Reference
이 문제에 관하여(기계 학습 모델 및 결과 해석 (Feature Importance)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/r2en/items/1d839a428b6080983218
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
お医者さん「あなたは糖尿病に今後5年以内になりますよ。」
患者さん「どうしてわかったんですか? 何が原因なんですか!?」
お医者さん「...。 AIがそう判断したからですよ...。」
患者さん「納得できません!」
실험 환경
Python==3.6.8
matplotlib==3.0.3
jupyter notebook
import re
import sklearn
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
%reload_ext autoreload
%autoreload 2
데이터
Kaggle titanic를 사용.
적당한 데이터수, 카디널리티의 적음, 해석의 용이성, 모두에게 인식되고 있는 3점으로부터 채용.
Titanic: Machine Learning from Disaster
이 대회는 타이타닉호에 승선한 각 승객이 구입한 티켓의 클래스(Pclass1, 2, 3의 순서로 높은 클래스)나 요금(Fare), 연령(Age), 성별(Sex), 출항지( Embarked), 방 번호(Cabin), 티켓 번호(Tichket), 승선하고 있던 형제 또는 배우자의 수(SibSp), 승선하고 있던 부모 또는 아이의 수(Parch) 등 정보가 있으며, 거기에서 타이타닉호 빙산에 충돌하여 침몰했을 때 생존했는지(Survived)를 예측한다.
PassengerId – 乗客識別ユニークID
Survived – 生存フラグ(0=死亡、1=生存)
Pclass – チケットクラス
Name – 乗客の名前
Sex – 性別(male=男性、female=女性)
Age – 年齢
SibSp – タイタニックに同乗している兄弟/配偶者の数
parch – タイタニックに同乗している親/子供の数
ticket – チケット番号
fare – 料金
cabin – 客室番号
Embarked – 出港地(タイタニックへ乗った港)
train.head()
전처리
Python에서 앙상블 (스태킹) 학습 & 기계 학습 자습서 in Kaggle
↑전처리가 간결하고, 데이터를별로 괴롭히지 않으므로 참고로 했습니다. 감사합니다.
기본적으로는 전처리에 의해 이하의 용으로 빈 분할하였다. (빈 분할한 이유는 결과를 인간이 해석하기 쉬워지기 때문)
Value
Age(나이)
0
16세 이하
1
32세 이하
2
48세 이하
3
64세 이하
4
그 이상
Value
Fare(요금)
0
굉장히 낮은
1
낮은
2
높은
3
굉장히 높은
Value
Embarked(출항지)
0
S 사람이 많다.
1
C 부자가 많다.
2
Q 빈곤이 많다
Value
Title(경칭)
0
Mr
1
Miss
2
Mrs
3
마스터
4
Rare
Value
Sex(성별)
0
female 여자
1
male 남성
Value
Pclass(티켓 클래스)
0
럭셔리
1
중급
2
하급
Value
IsAlone (가족 유무)
0
가족 없음
1
가족 있음
full_data = [train, test]
# 客室番号データがあるなら1を、欠損値なら0
train['Has_Cabin'] = train["Cabin"].apply(lambda x: 0 if type(x) == float else 1)
test['Has_Cabin'] = test["Cabin"].apply(lambda x: 0 if type(x) == float else 1)
# 家族の大きさを"タイタニックに同乗している兄弟/配偶者の数"と
# "タイタニックに同乗している親/子供の数"から定義
for dataset in full_data:
dataset['FamilySize'] = dataset['SibSp'] + dataset['Parch'] + 1
# 家族の有無 0なら家族なし、1なら家族あり
for dataset in full_data:
dataset['IsAlone'] = 0
dataset.loc[dataset['FamilySize'] == 1, 'IsAlone'] = 1
# 出港地の欠損値を一番多い"S"としておく
for dataset in full_data:
dataset['Embarked'] = dataset['Embarked'].fillna('S')
# 料金の欠損値を中央値としておく
# 料金の4グループに分ける
for dataset in full_data:
dataset['Fare'] = dataset['Fare'].fillna(train['Fare'].median())
train['CategoricalFare'] = pd.qcut(train['Fare'], 4)
# 年齢を5グループに分ける
for dataset in full_data:
age_avg = dataset['Age'].mean()
age_std = dataset['Age'].std()
age_null_count = dataset['Age'].isnull().sum()
age_null_random_list = np.random.randint(age_avg - age_std, age_avg + age_std, size=age_null_count)
dataset['Age'][np.isnan(dataset['Age'])] = age_null_random_list
dataset['Age'] = dataset['Age'].astype(int)
train['CategoricalAge'] = pd.cut(train['Age'], 5)
# 正規表現で姓名を取り出す
def get_title(name):
title_search = re.search(' ([A-Za-z]+)\.', name)
if title_search:
return title_search.group(1)
return ""
for dataset in full_data:
dataset['Title'] = dataset['Name'].apply(get_title)
# 誤字修正
dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')
for dataset in full_data:
# 性別を2種類にラベル付 女なら0、男なら1
dataset['Sex'] = dataset['Sex'].map( {'female': 0, 'male': 1} ).astype(int)
# 敬称を5種類にラベル付
title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
dataset['Title'] = dataset['Title'].map(title_mapping)
dataset['Title'] = dataset['Title'].fillna(0)
# 出港地の3種類にラベル付
dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int)
# 料金を4グループに分ける
dataset.loc[ dataset['Fare'] <= 7.91, 'Fare'] = 0
dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare'] = 2
dataset.loc[ dataset['Fare'] > 31, 'Fare'] = 3
dataset['Fare'] = dataset['Fare'].astype(int)
# 年齢を5グループに分ける
dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0
dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
dataset.loc[ dataset['Age'] > 64, 'Age'] = 4 ;
# 必要ない特徴を削除
drop_elements = ['PassengerId', 'Name', 'Ticket', 'Cabin', 'SibSp']
train = train.drop(drop_elements, axis = 1)
train = train.drop(['CategoricalAge', 'CategoricalFare'], axis = 1)
test = test.drop(drop_elements, axis = 1)
데이터를 읽고 학습하고 싶은 데이터와 정답 라벨로 나누기
y_train = train['Survived'].ravel()
x_train = train.drop(['Survived'], axis=1)
x_test = test.values
모델링
Gradient Boosting Decision Tree의 LightGBM에서 모델을 만듭니다.
import lightgbm as lgbm
model = lgbm.LGBMClassifier()
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
prediction = np.round(y_pred).astype(int)
Method: Feature Importance
x축이 중요도를 나타내고 y축이 위에서부터 순서대로 중요한 특징을 표시합니다.
plot_importance(booster, ax=None, height=0.2,
xlim=None, ylim=None, title='Feature importance',
xlabel='Feature importance', ylabel='Features',
importance_type='split', max_num_features=None,
ignore_zero=True, figsize=None, grid=True,
precision=None, **kwargs):
Result:
lgbm.plot_importance(model, figsize=(12, 6))
plt.show()
Discussion:
교사가있는 학습 모델을 사용하여 개별 기능의 중요성을 계산합니다. 모델이 학습시 자동으로 산출해 주므로 손쉽게 사용할 수 있다.
References:
htps // gghtgbm. Red d. cs. 이오 / 엔 / ㅁ st / _ 모즈 ぇ s / ぃghtgbm / p ぉ チン g. HTML
htps : // 코 m / 호쿠토 _ 히라 노 / ms / 2c35 아 81fbc95f0에 4b7c1 # 세콘 d ぇょPut
Reference
이 문제에 관하여(기계 학습 모델 및 결과 해석 (Feature Importance)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/r2en/items/1d839a428b6080983218
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
plot_importance(booster, ax=None, height=0.2,
xlim=None, ylim=None, title='Feature importance',
xlabel='Feature importance', ylabel='Features',
importance_type='split', max_num_features=None,
ignore_zero=True, figsize=None, grid=True,
precision=None, **kwargs):
lgbm.plot_importance(model, figsize=(12, 6))
plt.show()
Discussion:
교사가있는 학습 모델을 사용하여 개별 기능의 중요성을 계산합니다. 모델이 학습시 자동으로 산출해 주므로 손쉽게 사용할 수 있다.
References:
htps // gghtgbm. Red d. cs. 이오 / 엔 / ㅁ st / _ 모즈 ぇ s / ぃghtgbm / p ぉ チン g. HTML
htps : // 코 m / 호쿠토 _ 히라 노 / ms / 2c35 아 81fbc95f0에 4b7c1 # 세콘 d ぇょPut
Reference
이 문제에 관하여(기계 학습 모델 및 결과 해석 (Feature Importance)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/r2en/items/1d839a428b6080983218
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
htps // gghtgbm. Red d. cs. 이오 / 엔 / ㅁ st / _ 모즈 ぇ s / ぃghtgbm / p ぉ チン g. HTML
htps : // 코 m / 호쿠토 _ 히라 노 / ms / 2c35 아 81fbc95f0에 4b7c1 # 세콘 d ぇょPut
Reference
이 문제에 관하여(기계 학습 모델 및 결과 해석 (Feature Importance)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/r2en/items/1d839a428b6080983218텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)