<jupyter_start><jupyter_text>課題3 データの前処理と可視化配点- Q1, 1P- Q2, 4P- Q3, 1P- Q4, 1P- Q5, 3P<jupyter_code># 必要なモジュールの読み込み
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Q1 欠損値の処理 欠損値の検出pandasのシリーズやデータフレームではデータに欠損値（例えば数値データ内の空値）が含まれる場合、欠損値が`NaN`となります。以下では欠損値（空値）を含む得点データのcsvファイル, 'score_missing.csv', を読み込み、データフレーム`score`を作成します。<jupyter_code># Colaboratoryでは以下を実行して必要なファイルをダウンロード
!wget https://raw.githubusercontent.com/UTDataMining/2020A/master/ex3/score_missing.csv
score = pd.read_csv('score_missing.csv')
score<jupyter_output><empty_output><jupyter_text>データフレームに欠損値が含まれるかどうかはpandasの`isnull()`メソッドを使うと調べることができます。`isnull()`メソッドはデータフレームの各要素の値について、欠損値であれば`True`、欠損値でなければ`False`を要素としたデータフレームを返します。`isnull()`メソッドの詳細は以下を参照してください。[isnull()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.isnull.htmlpandas.isnull)<jupyter_code>score.isnull()<jupyter_output><empty_output><jupyter_text>`isnull()`メソッドで返された上記のデータフレームの`any()`メソッド使うと、データフレームにおいて欠損値を含む行または列を調べることができます。以下では、列ごとに欠損値を含むかどうかを示すシリーズオブジェクトを返します。<jupyter_code># 列ごとに欠損値があるか調べる
score.isnull().any()<jupyter_output><empty_output><jupyter_text>上記で`any()メソッド`の引数`axix`を1とすると、行ごとに欠損値を含むかどうかを示すシリーズオブジェクトを返します。<jupyter_code># 行ごとに欠損値があるか調べる
score.isnull().any(axis=1)<jupyter_output><empty_output><jupyter_text>上記のシリーズオブジェクトを以下のようデータフレーム抽出の条件として用いると、元のデータフレームから欠損値を含む行または列からなるデータフレームを抽出できます。<jupyter_code># データフレームから欠損値を含む行を抽出
score[score.isnull().any(axis=1)]
# データフレームから欠損値を含む列を抽出
score.loc[:, score.isnull().any()]<jupyter_output><empty_output><jupyter_text>欠損値の削除pandasの`dropna()`メソッドを使うと欠損値を含む行を削除することができます。`dropna()`メソッドでは、この他にもさまざまな方法で欠損値を削除することができます。詳細は以下を参照してください。[dropna()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html)<jupyter_code>score.dropna()<jupyter_output><empty_output><jupyter_text>欠損値の補完pandasの`fillna()`メソッドを使うと欠損値を補完することができます。以下では、欠損値が含まれる列の欠損がない要素の値の平均値でその列にある欠損値を補完しています。`fillna()`メソッドでは、この他にもさまざまな方法で欠損値を補完することができます。詳細は以下を参照してください。[fillna()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html)<jupyter_code>score = pd.read_csv('score_missing.csv')
score.fillna(score.mean())<jupyter_output><empty_output><jupyter_text>Q1欠損値（空値）を含む得点データのcsvファイル, 'score_missing.csv', を読み込み作成したデータフレームを受け取り、各列の欠損値をその列の欠損がない要素の値の中央値で補完したデータフレームを返す`fill_median()`関数を完成させてください。<jupyter_code>score = pd.read_csv('score_missing.csv') # csvファイル読み込み
def fill_median(df):
    return ### データフレームの各列の欠損値をその列の中央値で補完するコード ###
fill_median(score) # 関数呼び出して補完されたデータフレームを表示<jupyter_output><empty_output><jupyter_text>`fill_median()`関数が完成したら、以下のセルを実行してデータフレームのすべての要素の和を求めることで動作を確認してください。すべての要素の和は`2013`となります。<jupyter_code>fill_median(score).sum().sum()
assert 2013 == fill_median(score).sum().sum()<jupyter_output><empty_output><jupyter_text>Q2 外れ値の処理 NumPyでの記述統計以下では、次のような形式の"exam_score.csv"ファイルを読み込み、NumPyの配列を作成し、NumPyの関数または`ndarray`オブジェクトのメソッドを用いて、配列の記述統計を求めています。```Python exam_score.csvファイルkokugo, shakai, sugaku, rika30, 43, 51, 6339, 21, 49, 56...```<jupyter_code># Colaboratoryでは以下を実行して必要なファイルをダウンロード
!wget https://raw.githubusercontent.com/UTDataMining/2020A/master/ex3/exam_score.csv
# csvファイルからNumPy配列の作成
score = np.loadtxt("exam_score.csv", delimiter=",", skiprows=1)
# NumPyの関数で配列の各列の平均、分散、中央値、最大、最小を求める
print(np.mean(score, axis=0)) # 平均
print(np.var(score, axis=0)) # 分散
print(np.median(score, axis=0)) # 中央値
print(np.amax(score, axis=0)) # 最大値
print(np.amin(score, axis=0)) # 最小値
# ndarrayのメソッドで配列の各列の平均、分散、最大、最小を求める
print(score.mean(axis=0)) # 平均
print(score.var(axis=0)) # 分散
print(score.max(axis=0)) # 最大値
print(score.min(axis=0)) # 最小値<jupyter_output><empty_output><jupyter_text>Q2.1整数を要素とする任意の長さの1次元配列を入力として受け取り、配列の要素の値の中で、以下の外れ値の基準にあてはまる要素からなる1次元配列を返す`find_outliers()`関数を完成させてください。なお、IQRは四分位範囲であり、第3四分位から第1四分位を引いた値です。- （第1四分位-1.5IQR）を値の下限としてそれより小さい値は外れ値とする- （第3四分位+1.5IQR）を値の上限としてそれより大きい値は外れ値とする配列の第1四分位と第3四分位は、NumPyの`percentile()`関数を用いて以下のように求められる。```Python第1四分位, 第3四分位=np.percentile(配列, [25, 75])```<jupyter_code>def find_outliers(input_array):
    q1, q3 = ### 入力の第1四分位q1, 第3四分位q3を求めるコード ###
    iqr = ### 四分位範囲を求めるコード ###
    lower = ### 下限値を求めるコード ###
    upper = ### 上限値を求めるコード ###
    return  ### 下限より小さい値と上限より大きい値を外れ値としてそれらを要素する配列を抽出するコード ###<jupyter_output><empty_output><jupyter_text>`find_outliers()`関数が完成したら、以下のセルを実行して動作を確認してください。`[-100, 200, 1000]`が外れ値の配列です。<jupyter_code>find_outliers(np.array([30,39,-100,29,95,70,67,200,29,1000,56,45,68]))
assert set([-100,200,1000]) == set(find_outliers(np.array([30,39,-100,29,95,70,67,200,29,1000,56,45,68])))<jupyter_output><empty_output><jupyter_text>Q2.2以下のような形式の"score_outlier.csv"ファイルを読み込み、データフレーム`score`を作成します。```Python score_outlier.csvファイルkokugo, shakai, sugaku, rika30, 43, 51, 6339, 21, 49, 56...````score`を受け取り、各列ごとに、Q2.1と同様に四分位範囲, 第3四分位, 第1四分位を用いて外れ値を検出し、外れ値を含む行を除いたデータフレームを返す関数`drop_outliers()`を完成させてください。データフレームの各列の第1四分位と第3四分位は、pandasの`quantile()`メソッドを用いて以下のように求められる。```Python第1四分位 = データフレーム[列名].quantile(0.25)第3四分位 = データフレーム[列名].quantile(0.75)```<jupyter_code># Colaboratoryでは以下を実行して必要なファイルをダウンロード
!wget https://raw.githubusercontent.com/UTDataMining/2020A/master/ex3/score_outlier.csv
score = pd.read_csv('score_outlier.csv') # csvファイル読み込み
def drop_outliers(df):
    ...
    return ### 各列がその列の下限値以上かつ上限以内の値であるデータフレーム ###

drop_outliers(score).head(10)  # 関数呼び出して外れた値を含む行を除いたデータフレームを表示<jupyter_output><empty_output><jupyter_text>`drop_outliers()`関数が完成したら、以下のセルを実行して外れ値を含む行を除いたデータフレームの行数を求めることで動作を確認してください。行数は`155`となります。<jupyter_code>len(drop_outliers(score).index)
assert 155 == len(drop_outliers(score).index)<jupyter_output><empty_output><jupyter_text>Q2.3`matplotlib`では、以下のようにして複数の1次配列を入力として、それぞれを箱ひげ図として同時に可視化することができます。```Pythonplt.boxplot([配列1, 配列2, 配列3, ....], showmeans=True);```"score_outlier.csv"ファイルを読み込み、NumPyの配列を作成し、各教科の点数の箱ひげ図を可視化してください。<jupyter_code># csvファイルからNumPy配列の作成
score = np.loadtxt("score_outlier.csv", delimiter=",", skiprows=1)
plt.boxplot([### 各教科の点数の配列を指定するコード ###], showmeans=True);<jupyter_output><empty_output><jupyter_text>Q3 標準化以下のような形式の"exam_score.csv"ファイルを読み込み、作成したNumPyの配列を受け取り、各教科の点数をその教科の平均値と分散を用いて標準化した配列を返す`normalize_score()`関数を完成させてください。平均値と分散の計算には、NumPyの関数またはndarrayオブジェクトのメソッド、どちらを使ってもよいです。また、分散は標本分散としてください。```Python exam_score.csvファイルkokugo, shakai, sugaku, rika30, 43, 51, 6339, 21, 49, 56...```配列の列ごとに関数やメソッドを適用するには以下のように`axis`引数を0とする。```Pythonnp.mean(配列, axis=0)配列.mean(axis=0)```また、配列の元の次元を保持したい場合は`keepdims`引数をTrueとする。```Pythonnp.mean(配列, axis=0, keepdims=True)配列.mean(axis=0, keepdims=True)```<jupyter_code># csvファイルからNumPy配列の作成
score = np.loadtxt("exam_score.csv", delimiter=",", skiprows=1)
def normalize_score(a):
    return ### 配列aの各列をその列の平均値と分散を用いて標準化した配列を求めるコード ###
normalize_score(score) # 関数呼び出して標準化された配列を表示<jupyter_output><empty_output><jupyter_text>`normalize_score()`関数が完成したら、以下のセルを実行して標準化された`score`配列のすべての要素の整数値の和を求めることで動作を確認してください。すべての要素の整数値の和は`27`となります。（コードによってはそうならない場合もあります）<jupyter_code>normalize_score(score).astype(np.int64).sum()
assert normalize_score(score).astype(np.int64).sum() == 27<jupyter_output><empty_output><jupyter_text>参考pandasでは以下のようにしてデータフレームの各列をその列の平均値と分散を用いて標準化できます。<jupyter_code>score_df = pd.read_csv('exam_score.csv')
((score_df - score_df.mean()) / score_df.std(ddof=0)).head(5)<jupyter_output><empty_output><jupyter_text>Q4 ヒストグラム`matplotlib`では、以下のように1次配列を入力として、ヒストグラムを可視化することができます。```Pythonplt.hist(配列, bins=階級数);```"exam_score.csv"ファイルを読み込み、NumPyの配列を作成し、数学（3列目）の点数のヒストグラムを可視化してください。その際、階級数は任意に設定してください。<jupyter_code># csvファイルからNumPy配列の作成
score = np.loadtxt("exam_score.csv", delimiter=",", skiprows=1)
plt.hist(### 数学の点数の配列, bins=階級数 ###);<jupyter_output><empty_output><jupyter_text>参考平均=muと標準偏差=stdの時の正規分布に従うランダムな値からなる配列を入力とするヒストグラム<jupyter_code>mu, std = 0, 1
nor = np.random.normal(mu, std,200)
plt.hist(nor, bins=20);<jupyter_output><empty_output><jupyter_text>Q5 相関 Q5.1整数を要素とする同じ長さの2つの1次元配列を入力として受け取り、それらの配列の要素の相関係数を返す`correlation()`関数を完成させてください。2つの配列は先頭から順にそれぞれの要素が対応するものとします。それぞれの配列の対応する要素の値を$x_{i}, y_{i}$とすると、相関係数は以下のように求められます。$\frac{1}{n}\Sigma^{n}_{i=1}(\frac{x_{i}-\overline{x}}{s_{x}})(\frac{y_{i}-\overline{y}}{s_{y}})$$\overline{x}, \overline{y}$は平均、$s_{x}, s_{y}$は標準偏差です。<jupyter_code>def correlation(x, y):
    return ### 配列xと配列yの相関係数を計算するコード ###<jupyter_output><empty_output><jupyter_text>`correlation()`関数が完成したら、以下のセルを実行して動作を確認してください。それぞれ相関係数は`1`,`-1`となります<jupyter_code>correlation(np.array([-1,1]),np.array([ -1, 1]))
assert correlation(np.array([-1,1]),np.array([ -1, 1])) == 1
correlation(np.array([1,-1]),np.array([-1, 1]))
assert correlation(np.array([1,-1]),np.array([-1, 1])) == -1<jupyter_output><empty_output><jupyter_text>Q5.2以下のような形式の"exam_score.csv"ファイルを読み込み、数学と理科の点数の関係を散布図として可視化してください。```Python exam_score.csvファイルkokugo, shakai, sugaku, rika30, 43, 51, 6339, 21, 49, 56...````matplotlib`では、以下のように2つの1次配列を入力として、散布図を可視化することができます。```Pythonplt.plot(配列1, 配列2, 'o');```<jupyter_code># csvファイルからNumPy配列の作成
score = np.loadtxt("exam_score.csv", delimiter=",", skiprows=1)
plt.plot(### 数学の点数の配列, 理科の点数の配列 ###, 'o');<jupyter_output><empty_output><jupyter_text>参考NumPyの`corrcoef()`関数を使うと2つの配列の共分散行列を以下のように求めることができます。<jupyter_code>score = np.loadtxt("exam_score.csv", delimiter=",", skiprows=1)
np.corrcoef(score[:,0], score[:,1])<jupyter_output><empty_output><jupyter_text>pandasのcorrメソッドを使うとデータフレームの列間の相関係数を以下のように求めることができます。<jupyter_code>score = pd.read_csv("exam_score.csv", sep=",")
score.corr(method='pearson')<jupyter_output><empty_output><jupyter_text>これらの相関係数の大小に基づいて以下のように列間の相関の大小をヒートマップとして可視化することができます。<jupyter_code>plt.colorbar(plt.imshow(score.corr(method='pearson')));<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15806988352745424, 'fraction_numerical': 0.03306988352745424, 'mean_word_length': 14.56148867313916, 'pattern_counts': {'":': 0, '<': 109, '<?xml version=': 0, '>': 109, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '27', 'dir': 'jupyter-structured-clean-dedup', 'id': '310080', 'license': 'MIT', 'n_tokens_mistral': 6358, 'n_tokens_neox': 6059, 'n_words': 274, 'path': 'ex3/ex3.ipynb', 'repo_name': 'UTDataMining/2020A', 'size': '9616'}