データのロード

CSVファイルのロード

1
2
import pandas as pd
pd.read_csv('./data.csv')

BigQueryクエリ結果のロード

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pydata_google_auth
import pydata_google_auth.cache
from google.cloud.bigquery import Client
credentials = pydata_google_auth.get_user_credentials(
    scopes = ['https://www.googleapis.com/auth/bigquery'],
)
client = Client(project="myprojectname", credentials=credentials)

job = client.query("SELECT * FROM mytable;")
df = job.to_dataframe()

データ仕様の把握

データの中身を見る

1
2
df.head() # 先頭
df.tail() # 末端

スキーマ情報を見る

1
df.info()
1
2
3
4
5
6
7
8
9
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
Name           891 non-null object
Sex            891 non-null object
Age            714 non-null float64
...
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB

数値型の列の統計を見る

1
df.describe()
PassengerIdSurvivedPclassAgeSibSpParchFare
count891.000000891.000000891.000000714.000000891.000000891.000000891.000000
mean446.0000000.3838382.30864229.6991180.5230080.38159432.204208
std257.3538420.4865920.83607114.5264971.1027430.80605749.693429
min1.0000000.0000001.0000000.4200000.0000000.0000000.000000
25%223.5000000.0000002.00000020.1250000.0000000.0000007.910400
50%446.0000000.0000003.00000028.0000000.0000000.00000014.454200
75%668.5000001.0000003.00000038.0000001.0000000.00000031.000000
max891.0000001.0000003.00000080.0000008.0000006.000000512.329200
  • count non-nullな行数
  • mean 平均
  • std 標準偏差
  • max,min 最大値、最小値
  • 25%,50%,75% 25,50,75パーセンタイル

カテゴリ変数が含まれる列の統計を見る

1
df.describe(include=['O'])
NameSexTicketCabinEmbarked
count891891891204
unique8912681147
topPanula, Master. Juha Niilomale1601C23 C25 C27
freq157774
  • count non-nullな行数
  • unique 含まれる値の種類
  • top 最頻値
  • freq 最頻値が登場する回数

カラムに含まれる値のリストを見る

1
df.unique()

データ加工

転置

1
df.T

ソート

1
df[["hoge", "fuga"]].sort_values(by='hoge', ascending=False)

行・列の削除

列の削除

1
df.drop(columns=['hoge'])

inplace=True オプションを指定すると元のデータフレームを書き換える

行を条件で抽出

1
df[df['Name'].isin(['Alice','Bob'])]
1
df.query('name == "Alice" or name == "Bob"', engine='python')

リネーム

行のリネーム

1
df.rename(columns={'A': 'Col_1'})

集約

1
df[["hoge", "fuga"]].groupby(['hoge'], as_index=False).mean()

以下のSQLと同じ意味

1
SELECT hoge, AVG(fuga) AS fuga FROM df GROUP BY hoge;

結合

1
pd.merge(df_a, df_b, on='column1', how='inner')

howは inner, left, right, outer を指定する

以下のSQLと同じ意味

1
SELECT * FROM df_a INNER JOIN df_b ON df_a.column1 = df_b.column1;

値の変換

map

1
df['Flag'] = df['Flag'].map({'True': 1, 'False': 0}).astype(int)

apply

1
df['Diff'] = df[['X','Y'].apply(lambda a: a['X'] - a['Y'], axis=1)

欠損値を埋める

1
df=df.fillna("None")

クロス集計

1
pd.crosstab(df['Job'],df['Sex'])

Before:

JobSex
1studentmale
2engineerfemale
3

After:

femalemale
engineer1949
student7095

標準化

平均が0、分散が1になるようにデータのスケールを変換する

StandardScaler

1
2
3
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(df)

RobustScaler

外れ値を除外した上でStandardScalerの処理を行う

1
2
3
from sklearn.preprocessing import RobustScaler
scaler = RobustScaler(quantile_range(25.0,75.0))
scaler.fit(df)

正規化

最大値と最小値が揃うようにデータのスケールを変換する

1
2
3
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range(0,1))
scaler.fit(df)

カテゴリ変数の数値化

1
2
3
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df = le.fit_transform(df)

Before:

AgeSex
124female
242male
3

After

AgeSex
1240
2421
3

ダミー変数化

1
df=pd.get_dummies(df, columns=['sex'])

Before:

nameagesex
Alice24female
Bob42male

After:

nameagesex_malesex_female
Alice2401
Bob4210

drop_first=True オプションを指定すると自由度の数だけダミー変数が用意される

1
df=pd.get_dummies(df, drop_first=True)

After:

nameagesex_male
Alice240
Bob421

データ可視化

数値変数間の相関を見る

1
2
3
import seaborn as sns
import japanize_matplotlib # 文字化け対応
sns.pairplot(df)

ref: seaborn.pairplot

カテゴリ変数ごとの傾向を見る

1
sns.FacetGrid(df, col="time", row="sex").map(sns.scatterplot, "total_bill", "tip")

ref: seaborn.FacetGrid

散布図

1
df.plot.scatter(x='length',y='width')

ヒストグラム

1
sns.histplot(data=df, x='Length', stat='percent')

経験的累積分布関数

1
sns.distplot(data=df, x='Length', kind="ecdf")

二変量プロット

1
sns.distplot(data=df, x='Width', y='Length')

ヒートマップ

1
sns.heatmap(df)

統計的仮説検定

二項検定

2つのカテゴリに分類されたデータの比率が偏っているかどうかを検定する

A/BテストにおいてCVRに有意差があるかどうかなど

1
2
3
4
5
6
from scipy import stats
x=500 #事象の発生回数
n=1000 #試行回数
a=0.5 #発生確率の帰無仮説
p = stats.binom_test(x, n, a)
print(p)

マンホイットニーのU検定

2組の数値の集合が独立分布といえるかどうかを検定する

2つのクラスのテスト成績に有意差があるかどうかなど

1
2
3
from scipy import stats
result = stats.mannwhitneyu(df['A'],df['B'],alternative='two-sided')
print(result.pvalue)

χ二乗検定(独立性検定)

2つのカテゴリ変数が互いに独立であるかどうかを検定する

性別によって職業が左右されるかなど

1
2
3
4
from scipy import stats
df=pd.crosstab(df['Job'],df['Sex'])
x2, p, dof, expected = stats.chi2_contingency(df)
print(p)

ref: クロス集計

分析モデル

Cox比例ハザードモデル

生存期間を予測する

1
2
3
4
5
6
7
from lifelines import CoxPHFitter

cph = CoxPHFitter()
cph.fit(rossi, duration_col='lifetime', event_col='is_dead')

cph.print_summary()
cph.plot()

機械学習

学習データの用意

テストデータと教師データの分割

1
2
3
4
5
from sklearn.model_selection import train_test_split
X=df.drop(index='Target')
y=df['Target']

train_X, test_X, train_y, test_y = train_test_split(X,y)

クロスバリデーション

1
2
3
4
5
6
7
8
from sklearn.model_selection import cross_validate

clf = RandomForestClassifier()
X=df.drop(index='Target')
y=df['Target']

scores = cross_validate(clf, X, y, scoring=['accuracy','precision','recall','f1'], cv=5)
print(scores)

特徴量選択

ロジスティック回帰の決定関数における特徴量の係数を表示する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from sklearn.linear_model import LogisticRegression

logreg = LogisticRegression()
logreg.fit(X_train, y_train)

y_pred = logreg.predict(X_test)
print(logreg.score(X_train, y_train))

coeff_df = pd.DataFrame(train_df.columns.delete(0))
coeff_df.columns = ['Feature']
coeff_df["Correlation"] = pd.Series(logreg.coef_[0])

coeff_df.sort_values(by='Correlation', ascending=False)
FeatureCorrelation
1Sex2.201527
5Title0.398234
2Age0.287163
4Embarked0.261762
6IsAlone0.129140
3Fare-0.085150
7Age*Class-0.311200
0Pclass-0.749007

決定木モデルを可視化する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from sklearn.tree import DecisionTreeClassifier,plot_tree
import matplotlib.pyplot as plt

clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(clf.score(X_train, y_train))

plot_tree(clf,max_depth=2)
plt.show()

モデル選択