見出し画像

100日後にプロになるワシ22日目(Python)

昨日から「健康経営のための疾患リスク予測」が始まった。

この課題の目的は体のデータから疾患リスクを予想すること。

今日はデータの分析と分類をした。

統計データ

今回は統計量を1発で調べられる関数decribeを使う

df.decribe() # dfは今回のdataframe

               Age Gender       T_Bil       D_Bil          ALP      ALT_GPT  \
count   790.000000    790  790.000000  790.000000   790.000000   790.000000   
unique         NaN      2         NaN         NaN          NaN          NaN   
top            NaN   Male         NaN         NaN          NaN          NaN   
freq           NaN    600         NaN         NaN          NaN          NaN   
mean     43.710127    NaN    2.836709    1.226709   269.035443    66.174684   
std      16.290480    NaN    5.475744    2.483529   217.648811   155.959794   
min       4.000000    NaN    0.500000    0.100000    63.000000    10.000000   
25%      32.000000    NaN    0.800000    0.200000   171.250000    22.000000   
50%      45.000000    NaN    1.100000    0.300000   198.000000    31.000000   
75%      57.000000    NaN    2.100000    0.900000   282.000000    52.750000   
max      90.000000    NaN   75.300000   19.800000  2110.000000  2000.000000   

           AST_GOT          TP         Alb    AG_ratio     disease  
count    790.000000  790.000000  790.000000  790.000000  790.000000  
unique          NaN         NaN         NaN         NaN         NaN  
top             NaN         NaN         NaN         NaN         NaN  
freq            NaN         NaN         NaN         NaN         NaN  
mean      89.001266    6.518987    3.213924    0.991480    0.513924  
std      249.549767    1.032388    0.760867    0.288487    0.500123  
min       10.000000    2.700000    0.900000    0.270000    0.000000  
25%       23.000000    5.900000    2.700000    0.810000    0.000000  
50%       35.000000    6.600000    3.200000    0.980000    1.000000  
75%       67.000000    7.200000    3.800000    1.170000    1.000000  
max     4929.000000    9.600000    5.500000    2.840000    1.000000 

(T_Bilとか意味わかんないけど。どうやらタンパク質の一種らしい)

数量とユニーク数と最大頻度の値と平均と最小と・・・って!
このコマンドだけでできるんかい!!!

今まで、行ごとに計算して平均出してたわ!!

楽・・・

数量変数とカテゴリ変数の分離

同じ数値データでも。数量変数とカテゴリ変数というので違いがあるらしい。

例えば前回やった引っ越しでいうと

引っ越し回数のyはそのまま引っ越しの回数を表していて多いとか少ないとか判断できる

一方。法人が絡む引っ越しかどうか、を表す。0、1はオンオフのようなもので多いとか少ないとかという意味を持たない。

この二つを区別して扱う必要がある。

てか!区別してなかったね!!!!!!!!

これが前回の精度が低かった原因の一つか・・・

まあいい。取り合えず今回の疾患データをみる。

今回でいうと「disease(疾患の有無)」が0で疾患なし。1で疾患ありと分けられる。これがカテゴリ変数に当たる。

あとは男女を表す「Gender」これもMaleとFemaleで分けられている。

全データからこれら2つのカテゴリデータを取り除いた数量データと
カテゴリデータに分類する

# カテゴリ変数の列名をリストで指定
col_categoric = ["Gender", "disease"]

#数量変数のデータフレームを作成し、printで確認
df_numeric = df.drop(col_categoric, axis=1)
print(df_numeric)

#カテゴリ変数のデータフレームを作成し、printで確認
df_categoric = df[col_categoric]
print(df_categoric)

結果↓

# 数量変数
   Age  T_Bil  D_Bil  ALP  ALT_GPT  AST_GOT   TP  Alb  AG_ratio
0   65    1.0    0.2  187       16       18  6.8  3.3      0.92
1   62   11.2    5.6  699       64      100  7.5  3.2      0.73
2   62    7.6    4.2  490       60       68  7.0  3.3      0.87
3   58    1.3    0.5  182       14       20  6.8  3.4      0.98
4   72    4.2    2.1  195       27       59  7.3  2.4      0.48

# カテゴリ変数
  Gender  disease
0  Female        1
1    Male        1
2    Male        1
3    Male        1
4    Male        1

データの可視化

次はデータをわかりやすく俯瞰してみるために表にします

使うモジュールはmatplotlib.pyplot()

# 疾患の数をカウント
counts_disease = df_categoric["disease"].value_counts()
print(counts_disease)

# 棒グラフによる可視化
counts_disease.plot(kind='bar')
plt.show()

スクリーンショット 2020-09-03 13.15.30

↑疾患が1で疾患がない人が0。

だいたい半々でデータが揃っているのがわかる

データの結合

今回の目的は、状態によって疾患リスクを予測することなので
目的変数を疾患かどうか(disease)に設定して分析する必要がある。

つまりdiseaseとの関係性を調べたい。

なのでdiseaseを基準にデータを整形したいんですが、
先ほど行った数量変数とカテゴリ変数は同じに扱えないので別々にデータを作成する

その時、数量変数とdisease、カテゴリ変数とdiseaseという風に結合する

# df_categoric内の"disease"列と、df_numericの列を横結合する
df_tmp = pd.concat([df_categoric["disease"], df_numeric], axis=1)
# 結合したデータフレームの最初の5行を表示
print(df_tmp.head())

concatは結合メソッドでaxis=1は列を表す。
[df_categoric["disease"], df_numeric←この2つを列で結合した。ということになる

   disease  Age  T_Bil  D_Bil  ALP  ALT_GPT  AST_GOT   TP  Alb  AG_ratio
0        1   65    1.0    0.2  187       16       18  6.8  3.3      0.92
1        1   62   11.2    5.6  699       64      100  7.5  3.2      0.73
2        1   62    7.6    4.2  490       60       68  7.0  3.3      0.87
3        1   58    1.3    0.5  182       14       20  6.8  3.4      0.98
4        1   72    4.2    2.1  195       27       59  7.3  2.4      0.48

↑結果(一番左にdiseaseがきてる)

さらに分析

今はdiseaseが0のときと1の時両方同じデータ(データフレーム)で扱っていますが、本来0(疾患がない時)と1(疾患がある時)の差異を調べたいので別のデータフレームで扱う必要がある。

ので、これを分割する

# diseaseの値が0(疾患なし)のサンプルを表示(最初の5行を表示)
print(df_tmp.query("disease == 0").head())
# diseaseの値が1(疾患あり)のサンプルを表示(最初の5行を表示)
print(df_tmp.query("disease==1").head())

queryメソッドを使えばその中に条件がかけて、その条件に沿ったデータが抽出できる。

    disease  Age  T_Bil  D_Bil  ALP  ALT_GPT  AST_GOT   TP  Alb  AG_ratio
8         0   17    0.9    0.3  202       22       19  7.4  4.1      1.24
12        0   64    0.9    0.3  310       61       58  7.0  3.4      0.94
15        0   25    0.6    0.1  183       91       53  5.5  2.3      0.72
17        0   33    1.6    0.5  165       15       23  7.3  3.5      0.92
23        0   63    0.9    0.2  194       52       45  6.0  3.9      1.86

  disease  Age  T_Bil  D_Bil  ALP  ALT_GPT  AST_GOT   TP  Alb  AG_ratio
0        1   65    1.0    0.2  187       16       18  6.8  3.3      0.92
1        1   62   11.2    5.6  699       64      100  7.5  3.2      0.73
2        1   62    7.6    4.2  490       60       68  7.0  3.3      0.87
3        1   58    1.3    0.5  182       14       20  6.8  3.4      0.98
4        1   72    4.2    2.1  195       27       59  7.3  2.4      0.48

疾患ありとなしの表(データフレーム)ができた↑

目的変数との関係の可視化

データが疾患のありなしで分けることができたので、
今度はこれを使って分析していきます

(機械学習マダー????)

まず、年齢と疾患データとの関係を見ていきます

疾患有り無しのグラフを重ねて表示できれば比較が楽なので
seabornというライブラリを使います。

# diseaseの値に応じた"Age"データの抽出
df_Age_non=df_tmp.query("disease==0")["Age"] #疾患がないものと年齢の関係
df_Age_diseased=df_tmp.query("disease==1")["Age"] #疾患ありと年齢の関係

# 2つのデータフレームのヒストグラムを同時に表示
# snsというのがseabornライブラリの略語
sns.distplot(df_Age_non)
sns.distplot(df_Age_diseased)

# 凡例の表示
plt.legend(labels=["non", "diseased"], loc='upper right')
plt.show()

結果↓

スクリーンショット 2020-09-03 9.07.33

オレンジが疾患あり。青が疾患なし。

横軸が年齢なので、やはり年齢が高いほど疾患がかかっているっぽい

その他のデータの関係↓

スクリーンショット 2020-09-03 13.44.38

今日はここまで。

次回はこれらのデータと疾患との相関関係を調べる。

感想

機械学習まではとにかく分析が長い。

ただ、ちゃんと分析しないと全く関係ないデータで分析してもいい結果は得られないし、欠損データや、外れ値というおかしい値を見ていてもしょうがないので、機械学習は前処理が9割!らしい。

ただ、グラフが出てきて、機械学習というよりはデータサイエンティストっぽくていい。




































 

いつもサポートありがとうございます。 難しい方は感想をコメントでいただけると嬉しいです。