LoginSignup
2
2

More than 3 years have passed since last update.

SIGNATE Quest④

Posted at

可視化

ヒストグラムの使いどころ

数量変数の可視化にはヒストグラムが適している。
"性別"にデータが数値以外になっている場合、ヒストグラムだとデータの数値変換が必要となる。
棒グラフは数値変換が不要である為、この場合は棒グラフの方が適していると言える。

データの内容を数値項目とカテゴリ項目に分けている場合、数値項目の変数をヒストグラムにすると、それぞれの列ごとにヒストグラムを作成してくれる。(10列ある場合、一度に10個のヒストグラムを作ってくれる)

#ライブラリのimport
import pandas as pd
import matplotlib.pyplot as plt

#前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)

#データフレームの分離
col_categoric = ["Gender", "disease"]
df_numeric = df.drop(col_categoric, axis=1)
df_categoric = df[col_categoric]

#数量変数のヒストグラムを表示(※figsizeオプションはグラフのサイズを指定)
df_numeric.hist(figsize=(8, 6))

# グラフのラベルが重ならないようにレイアウトを自動調整
plt.tight_layout()
plt.show()

結果

2020-09-06_10h25_22.png

ヒストグラムを重ねて表示する

# ライブラリのimport
import pandas as pd
import matplotlib.pyplot as plt

# seabornライブラリをsnsという省略名でインポート
import seaborn as sns

# 前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)
col_categoric = ["Gender", "disease"]
df_numeric = df.drop(col_categoric, axis=1)
df_categoric = df[col_categoric]

# disease列とdf_numericを結合
df_tmp = pd.concat([df_categoric["disease"], df_numeric], axis=1)

# diseaseの値に応じた"Age"データの抽出
df_Age_non=df_tmp.query("disease==0")["Age"]
df_Age_diseased=df_tmp.query("disease==1")["Age"]

# 2つのデータフレームのヒストグラムを同時に表示
sns.distplot(df_Age_non)
sns.distplot(df_Age_diseased)
# 凡例の表示
plt.legend(labels=["non", "diseased"], loc='upper right')
plt.show()

2020-09-06_10h47_26.png

データの抽出

データの抽出方法は主に2種類ある。

#データフレームの再帰代入
df_tmp[df_tmp["disease"] == 0]
#query関数を使う
df_tmp.query("disease == 0")

↓ 重要:queryを使ったデータ抽出方法。複数条件の場合はqueryを推奨 ↓

# diseaseの値に応じた"Age"データの抽出
df_Age_non=df_tmp.query("disease==0")["Age"]
df_Age_diseased=df_tmp.query("disease==1")["Age"]

2020-09-06_10h47_26.png
2020-09-06_10h47_26.png

corr()の結果をヒートマップで表示する

# ライブラリのimport
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)

# heatmapの表示
plt.figure(figsize=(10,8))
sns.heatmap(df.corr(), vmin=-1.0, vmax=1.0, annot=True, cmap='coolwarm', linewidths=0.1)
plt.show()

2020-09-07_22h13_19.png

ロジスティック回帰を使った疾患の予測

# ライブラリのimport
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, roc_curve

# 前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)
df["Gender"] = df["Gender"].apply(lambda x: 1 if x=="Male" else 0)

# 説明変数・目的変数の作成と分割
X = df.drop(["disease"], axis=1)
y = df["disease"]
X_train, X_test, y_train, y_test = train_test_split(X, y ,test_size=0.3, random_state=0)

# モデルの学習
lr = LogisticRegression()
lr.fit(X_train, y_train)

# モデルの予測(疾患あり(=1)に属する確率の算出)
y_pred_prob = lr.predict_proba(X_test)[:, 1]

# AUCスコアの算出
auc_score = ____(y_true=____, y_score=____)
print(auc_score)

# ROC曲線の要素(偽陽性率、真陽性率、閾値)の算出
fpr, tpr, thresholds = ____(y_true=____, y_score=____)

# ROC曲線の描画
plt.plot(fpr, tpr, label='roc curve (area = %0.3f)' % auc_score)
plt.plot([0, 1], [0, 1], linestyle=':', label='random')
plt.plot([0, 0, 1], [0, 1, 1], linestyle=':', label='ideal')
plt.legend()
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.show()

ビニングした列の作成、ダミー変数化して元データに横連結。生成した特徴量を使って再度モデリング。

# ライブラリのインポート
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, roc_curve
import pandas as pd
import matplotlib.pyplot as plt

# 前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)
df["Gender"] = df["Gender"].apply(lambda x: 1 if x=="Male" else 0)
X = df.drop(["disease"], axis=1)
y = df["disease"]

# binの境界値を指定
bins_T_Bil = [0, 0.5, 1.0, 100]

# T_Bil列を分割し、0始まりの連番でラベル化した結果を、X_cutに格納する
X_cut, bin_indice = pd.cut(X["T_Bil"], bins=bins_T_Bil, retbins=True, labels=False)

# bin分割した結果をダミー変数化 (prefix=X_Cut.nameは、列名の接頭語を指定している)
X_dummies = pd.get_dummies(X_cut, prefix=X_cut.name)

# 元の説明変数のデータフレーム(X)と、ダミー変数化の結果(X_dummies)を横連結
X_binned = pd.concat([X, X_dummies], axis=1)

# 学習用・評価用データの分割(元の説明変数Xの代わりに、bin分割したX_binnedを使う)
X_train, X_test, y_train, y_test = train_test_split(X_binned, y, test_size=0.3, random_state=0)

# モデルの学習・予測
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict_proba(X_test)[:, 1]

# ROC曲線の描画(偽陽性率、真陽性率、閾値の算出)
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=y_pred)
plt.plot(fpr, tpr, label='roc curve')
plt.plot([0, 1], [0, 1], linestyle=':', label='random')
plt.plot([0, 0, 1], [0, 1, 1], linestyle=':', label='ideal')
plt.legend()
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.show()

# AUCスコアの算出
auc_score = roc_auc_score(y_true=y_test, y_score=y_pred)
print("AUC:", auc_score)

多項式・交互作用特徴量の生成

# ライブラリのimport
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_curve, auc, roc_auc_score
from sklearn.preprocessing import PolynomialFeatures

# 前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)
df["Gender"] = df["Gender"].apply(lambda x: 1 if x=="Male" else 0)
X = df.drop(["disease"], axis=1)
y = df["disease"]

# Gender列を除外(数量変数のデータに絞る)
X_target = X.drop(["Gender"], axis=1)

# 多項式・交互作用特徴量の生成
polynomial = PolynomialFeatures(degree=2, include_bias=False)
polynomial_arr = polynomial.fit_transform(X_target)

# polynomial_arrのデータフレーム化 (※カラムはshape[1]でpolynomial_arrの列数分だけ出力)
X_polynomial = pd.DataFrame(polynomial_arr, columns=["poly" + str(x) for x in range(polynomial_arr.shape[1])])

# 生成した多項式・交互作用特徴量の表示
print(X_polynomial.shape)
print(X_polynomial.head())

特徴量選択

# ライブラリのimport
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.feature_selection import SelectFromModel

# 前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)
df["Gender"] = df["Gender"].apply(lambda x: 1 if x=="Male" else 0)
X = df.drop(["disease"], axis=1)
y = df["disease"]
X_target = X.drop(["Gender"], axis=1)

# 多項式・交互作用特徴量の生成
polynomial = PolynomialFeatures(degree=2, include_bias=False)
polynomial_arr = polynomial.fit_transform(X_target)
X_polynomial = pd.DataFrame(polynomial_arr, columns=["poly" + str(x) for x in range(polynomial_arr.shape[1])])

# 組み込み法のモデル、閾値の指定
fs_model = LogisticRegression(penalty='l1', random_state=0)
# 閾値の指定
fs_threshold = "mean"
# 組み込み法モデルの初期化
selector = SelectFromModel(fs_model, threshold=fs_threshold)

# 特徴量選択の実行
selector.fit(X_polynomial, y)
mask = selector.get_support()

# 選択された特徴量だけのサンプル取得
X_polynomial_masked = X_polynomial.loc[:, mask]

print("選択された特徴量の表示(最初の5行)")
print(X_polynomial_masked.head())
print("選択された特徴量の数の確認")
print(X_polynomial_masked.shape)

まとめ

# ライブラリのimport
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, roc_curve
from sklearn.preprocessing import PolynomialFeatures
from sklearn.feature_selection import SelectFromModel

# 前処理
df = pd.read_csv('dataset.csv')
df["AG_ratio"].fillna(df["Alb"] / (df["TP"] - df["Alb"]), inplace=True)
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)
df["Gender"] = df["Gender"].apply(lambda x: 1 if x=="Male" else 0)
X = df.drop(["disease"], axis=1)
y = df["disease"]
X_target = X.drop(["Gender"], axis=1)

# 多項式・交互作用特徴量
polynomial = PolynomialFeatures(degree=2, include_bias=False)
polynomial_arr = polynomial.fit_transform(X_target)
X_polynomial = pd.DataFrame(polynomial_arr, columns=["poly" + str(x) for x in range(polynomial_arr.shape[1])])

# 組み込み法のモデル、閾値の指定
fs_model = LogisticRegression(penalty='l1', random_state=0)
fs_threshold = "mean"
# 組み込み法モデルの初期化
selector = SelectFromModel(fs_model, threshold=fs_threshold)

# 特徴量選択の実行
selector.fit(X_polynomial, y)
mask = selector.get_support()

# 選択された特徴量だけのサンプル取得
X_polynomial_masked = X_polynomial.loc[:, mask]

# 学習用・評価用データの分割(元の説明変数Xの代わりに、特徴量選択後のX_polynomial_maskedを使う)
X_train, X_test, y_train, y_test = train_test_split(X_polynomial_masked, y, test_size=0.3, random_state=0)

# モデルの学習・予測
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict_proba(X_test)[:, 1]

# ROC曲線の描画(偽陽性率、真陽性率、閾値の算出)
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=y_pred)
plt.plot(fpr, tpr, label='roc curve')
plt.plot([0, 1], [0, 1], linestyle=':', label='random')
plt.plot([0, 0, 1], [0, 1, 1], linestyle=':', label='ideal')
plt.legend()
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.show()

# AUCスコアの算出
auc_score = roc_auc_score(y_true=y_test, y_score=y_pred)
print("AUC:", auc_score)
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2