[python]データの可視化と相関関係の把握を同時に行う
はじめに
データ分析の際にはグラフを用いてデータを可視化すると思います。そのとき、2変数の相関を表す統計量も同時に表示できたら便利ですよね。そこで、変数の内容(カテゴリか数値か)に応じて適切なグラフに適切な統計量を表示できるようにしました。
これまでのおさらい
これまで記事にした、変数の内容別の適切なグラフ化メソッドと、相関を表す統計量についてまとめます。詳細は下記のリンクをご覧ください。
適切なグラフに適切な統計量を記載
各変数の組み合わせに対して、離散量か連続量かに応じて適切なグラフ、適切な統計量を選んで表示するメソッドを作りました。
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as st
def visualize_data(data, target_col, categorical_keys=None):
keys=data.keys()
if categorical_keys is None:
categorical_keys=keys[[is_categorical(data, key) for key in keys]]
for key in keys:
if key==target_col:
continue
length=10
subplot_size=(length, length/2)
if (key in categorical_keys) and (target_col in categorical_keys):
r=cramerV(key, target_col, data)
fig, axes=plt.subplots(1, 2, figsize=subplot_size)
sns.countplot(x=key, data=data, ax=axes[0])
sns.countplot(x=key, data=data, hue=target_col, ax=axes[1])
plt.title(r)
plt.tight_layout()
plt.show()
elif (key in categorical_keys) and not (target_col in categorical_keys):
r=correlation_ratio(cat_key=key, num_key=target_col, data=data)
fig, axes=plt.subplots(1, 2, figsize=subplot_size)
sns.countplot(x=key, data=data, ax=axes[0])
sns.violinplot(x=key, y=target_col, data=data, ax=axes[1])
plt.title(r)
plt.tight_layout()
plt.show()
elif not (key in categorical_keys) and (target_col in categorical_keys):
r=correlation_ratio(cat_key=target_col, num_key=key, data=data)
fig, axes=plt.subplots(1, 2, figsize=subplot_size)
sns.distplot(data[key], ax=axes[0], kde=False)
g=sns.FacetGrid(data, hue=target_col)
g.map(sns.distplot, key, ax=axes[1], kde=False)
axes[1].set_title(r)
axes[1].legend()
plt.tight_layout()
plt.close()
plt.show()
else:
r=data.corr().loc[key, target_col]
sg=sns.jointplot(x=key, y=target_col, data=data, height=length*2/3)
plt.title(r)
plt.show()
途中以下のメソッドを使っています。
def is_categorical(data, key): #カテゴリ変数かどうかを判定
col_type=data[key].dtype
if col_type=='int':
nunique=data[key].nunique()
return nunique<6
elif col_type=="float":
return False
else:
return True
def correlation_ratio(cat_key, num_key, data): #相関比を求める
categorical=data[cat_key]
numerical=data[num_key]
mean=numerical.dropna().mean()
all_var=((numerical-mean)**2).sum()
unique_cat=pd.Series(categorical.unique())
unique_cat=list(unique_cat.dropna())
categorical_num=[numerical[categorical==cat] for cat in unique_cat]
categorical_var=[len(x.dropna())*(x.dropna().mean()-mean)**2 for x in categorical_num]
r=sum(categorical_var)/all_var
return r
def cramerV(x, y, data): #連関係数を求める
table=pd.crosstab(data[x], data[y])
x2, p, dof, e=st.chi2_contingency(table, False)
n=table.sum().sum()
r=np.sqrt(x2/(n*(np.min(table.shape)-1)))
return r
titanicデータに適用してみます(結果は一部のみ表示)。
train_data=pd.read_csv("train.csv")
train_data=train_data.drop(["PassengerId", "Name", "Ticket", "Cabin"], axis=1)
categories=["Survived", "Pclass", "Sex", "Embarked"]
visualize_data(train_data, "Survived", categories)
最後に
今までのメソッドを1つにまとめてみました。データ分析の最初にこれを実行してデータの概観を把握するようにしています。
記事内で扱ったメソッドはgithubに上げてあります。
最新記事
すべて表示概要 pythonでデータ解析を行っている。解析自体はpandasを用いて行い、最終結果はpandas.DataFrameの形式で保持されている。 この結果を他のアプリケーションで利用するため、json形式でファイル出力したい。 やり方 1...
現象 raspberry piでfirestoreをimportしようとするとタイトルのエラーが発生。 from from firebase_admin import firestore ImportError: Failed to import the Cloud...
概要 フィッティングを行いたい場合、pythonならばscipy.optimize.leastsqなどでできます。 しかし、フィッティングを行う場合、フィッティングパラメータに条件を付けたい場合も多々あります。 例えば、下記のようにパラメータa、bは共に正の範囲で最適な値を...
Comments