ファセットと相互作用項を使用した TensorFlow 線形回帰

⚡ スマートサマリー

ボストンの住宅データに対する線形回帰分析は、適切な交互作用項を最初に見つけることで精度が向上する。 Google Facetsはこれらの関係性を視覚的に明らかにし、2つの交差する特徴量によってTensorFlowのテスト損失が1650から1515に減少しました。

  • 🔘 データ優先: 分布と外れ値を理解することは、あらゆるモデル構築に先行する。なぜなら、モデルは既に特定されたパターンを一般化したものに過ぎないからだ。
  • ☑️ ファセットの概要: 特徴量ごとの統計情報により、欠損値、ゼロ値が多い列、および訓練データとテストデータの分布のずれが1つの表にまとめて表示されます。
  • ✅ ファセットの詳細分析: X軸とY軸によるファセット化によって、3者間の関係が価格四分位ごとに色分けされた、読みやすい2次元グラフに変換されます。
  • 🧪 相関関係の読み取り: ヒートマップとペアグリッドは、INDUSとNOX、およびDISとNOXの両方を相互作用候補として示している。
  • 🛠️ 標準化: preprocessing.scale は、推定器が参照する前に 12 個の連続列を中央揃えにしますが、CHAS と PRICE は変更されません。
  • 📈 測定されたゲイン: INDUS_NOSとINDUS_NOS_DISを追加すると、テスト分割における平均損失は86.89361から79.78876に減少します。

TensorFlowにおけるファセットと相互作用項を用いた線形回帰

TensorFlow 線形回帰

このチュートリアルでは、データを確認し、単純な線形回帰タスクを作成するための準備方法を学習します。

このチュートリアルは XNUMX つの部分に分かれています。

  • インタラクションを探す
  • モデルをテストする

前のチュートリアルでは、ボストンのデータセットを使用して、住宅の平均価格を推定しました。ボストンのデータセットはサイズが小さく、観測値は 506 個しかありません。このデータセットは、新しい線形回帰アルゴリズムを試すためのベンチマークとして考えられています。

データセットは次のもので構成されます。

変数 詳細説明
zn 25,000 平方フィートを超える敷地に区画された住宅地の割合は、
インダス 町ごとの非小売業の面積の割合。
noxの 一酸化窒素濃度
rm 住居ごとの平均部屋数
年齢 1940 年以前に建てられた所有者居住ユニットの割合
DIS ボストンの XNUMX つの雇用センターまでの加重距離
税金 10,000 ドルあたりの全額固定資産税の税率
プトラティオ 町ごとの生徒と教師の比率
メドゥ 持ち家住宅の中央値(千ドル)
クリム 町ごとの一人当たりの犯罪率
CHAS チャールズ川ダミー変数(川の境界にある場合は 1、そうでない場合は 0)
B 町ごとの黒人の割合

このチュートリアルでは、線形回帰変数を使用して中央価格を推定しますが、焦点は XNUMX つの特定のプロセスにあります。 機械学習:「データ準備」

モデルはデータ内のパターンを一般化します。 このようなパターンを捉えるには、まずそれを見つける必要があります。 機械学習アルゴリズムを実行する前にデータ分析を実行することをお勧めします。

適切な機能を選択することで、モデルの成功に大きな違いが生じます。 ある人々の賃金を推定しようとしていると想像してください。共変量として性別を含めないと、精度の低い推定値が得られます。

モデルを改善するもう XNUMX つの方法は、独立変数間の相関関係を調べることです。 例に戻ると、教育は賃金だけでなく職業も予測するための優れた候補であると考えることができます。 職業は教育レベルに依存する、つまり高等教育を受ければより良い職業に就くことが多いと言っても過言ではありません。 この考えを一般化すると、従属変数と説明変数の間の相関関係は、さらに別の説明変数で拡大できると言えます。

職業に対する教育の限定的な影響を捉えるために、交互作用項を使用できます。

賃金曲線上に示された教育と職業の相互作用項

賃金等式を見ると、次のようになります。

賃金方程式に教育と職業の交互作用項を追加

If 相互作用項のベータ係数記号 が正の場合、職業レベルが高い場合、教育レベルを追加すると住宅の中央値がより大きく増加することを意味します。 言い換えれば、教育と職業の間には相互作用効果があるということです。

同じ推定器ファミリーは、 線形分類器 ラベルが価格ではなくクラスである場合。このチュートリアルでは、どの変数が交互作用項の候補として適しているかを検討します。このような情報を追加することで、価格予測の精度が向上するかどうかを検証します。

要約統計

モデル構築に進む前に、いくつか手順を踏む必要があります。前述のとおり、モデルはデータの一般化です。最善の方法は、まずデータを理解し、それから予測を行うことです。データを理解していなければ、モデルを改善できる可能性は低いでしょう。

最初のステップとして、データを pandas データフレームとしてロードし、トレーニング セットとテスト セットを作成します。

ヒント: このチュートリアルでは、matplotlib と seaborn がインストールされている必要があります。 Pythonインストールできます Python パッケージを即座に Jupyter。 あなた いけない これを行う

!conda install -- yes matplotlib

焙煎が極度に未発達や過発達のコーヒーにて、クロロゲン酸の味わいへの影響は強くなり、金属を思わせる味わいと乾いたマウスフィールを感じさせます。

import sys
!{sys.executable} -m pip install matplotlib # Already installed
!{sys.executable} -m pip install seaborn 

matplotlib と seaborn がインストールされている場合、この手順は必要ないことに注意してください。

Matplotlibはグラフを作成するためのライブラリです。 PythonSeabornはmatplotlibをベースにした統計可視化ライブラリです。trac魅力的で美しいプロット。

以下のコードは、必要なライブラリをインポートします。

import pandas as pd
from sklearn import datasets
import tensorflow as tf
from sklearn.datasets import load_boston
import numpy as np

ライブラリ sklearn には、ボストン データセットが含まれています。 その API を呼び出してデータをインポートできます。

バージョンノート: load_boston scikit-learn 1.0 で非推奨となり、 scikit-learn 1.2で削除されました データセットに人種的な特徴がエンコードされているためです。現在のインストールでは、 カリフォルニア州の住宅情報を取得する 代わりに、生ファイルを自分で読み込むこともできます。以下に示すワークフローは変更されていません。異なるのはローダーのみです。

boston = load_boston()
df = pd.DataFrame(boston.data)

機能名は、オブジェクト feature_names に配列として格納されます。

boston.feature_names

出力

array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')

列の名前を変更できます。

df.columns = boston.feature_names
df['PRICE'] = boston.target
df.head(2)

列名を変更した後のボストンデータフレームの最初の2行

変数 CHAS を文字列変数として変換し、CHAS = 1 の場合は「yes」、CHAS = 0 の場合は「no」というラベルを付けます。

df['CHAS'] = df['CHAS'].map({1:'yes', 0:'no'})
df['CHAS'].head(5)
0    no
1    no
2    no
3    no
4    no
Name: CHAS, dtype: object

pandas を使用すると、データセットを簡単に分割できます。 データセットを 80% のトレーニング セットと 20% のテスト セットにランダムに分割します。 パンダ データフレームを分割するための組み込みのサンプリング機能があります。

最初のパラメータ frac は 0 ~ 1 の値です。データ フレームの 0.8% をランダムに選択するには、これを 80 に設定します。

random_stateはシャッフルを修正し、全員に同じ行が返されるようにします。

### Create train/test set
df_train=df.sample(frac=0.8,random_state=200)
df_test=df.drop(df_train.index)

データの形状を取得できます。 そのはず:

  • 列車セット: 506*0.8 = 405
  • テストセット: 506*0.2 = 101
print(df_train.shape, df_test.shape)

出力

(405, 14) (101, 14)
df_test.head(5)

出力

クリム ZN インダス チャス NOX RM 年齢 DIS RAD 税金 プトラティオ B LSTAT 料金
0 0.00632 18.0 2.31 いいえ 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98 24.0
1 0.02731 0.0 7.07 いいえ 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14 21.6
3 0.03237 0.0 2.18 いいえ 0.458 6.998 45.8 6.0622 3.0 222.0 18.7 394.63 2.94 33.4
6 0.08829 12.5 7.87 いいえ 0.524 6.012 66.6 5.5605 5.0 311.0 15.2 395.60 12.43 22.9
7 0.14455 12.5 7.87 いいえ 0.524 6.172 96.1 5.9505 5.0 311.0 15.2 396.90 19.15 27.1

データは乱雑です。 多くの場合、バランスが崩れており、分析や機械学習のトレーニングを混乱させる異常値が散りばめられています。

データセットをクリーンアップするための最初のステップは、クリーンアップが必要な場所を理解することです。 データセットのクリーンアップは、特に一般化可能な方法で行う場合、難しい場合があります。

その Google 研究チームはこの仕事のためにツールを開発しました。 ファセット これは、データを視覚化し、さまざまな方法で分析するのに役立ちます。データセットの構造を理解するための良い出発点となります。

ファセット機能を使うと、データが想定どおりに見えない箇所を見つけることができます。

ウェブアプリを除いて、 Google ツールキットを簡単に組み込むことができます Jupyter ノート。

ファセットには XNUMX つの部分があります。

  • ファセットの概要
  • ファセットの詳細

ファセットの概要

ファセット概要はデータセットの概要を示します。ファセット概要はデータの列を重要な情報の行に分割し、

  1. 欠落している観測値の割合
  2. 最小値と最大値
  3. 平均、中央値、標準偏差などの統計。
  4. また、ゼロである値の割合を示す列も追加されます。これは、ほとんどの値がゼロである場合に役立ちます。
  5. これらの分布は、各機能のトレーニング セットだけでなくテスト データセットでも確認できます。つまり、テストがトレーニング データと同様の分布を持っていることを再確認できます。

これは、機械学習タスクの前に少なくとも行うべき最低限の作業です。 このツールを使用すると、この重要なステップを見逃さず、いくつかの異常を強調表示します。

ファセットの詳細

Facets Deep Diveは優れたツールです。データセットをより深く理解し、個々のデータまで詳細に分析することができます。つまり、データセットのあらゆる特徴に基づいて、行と列ごとにデータをファセット化できるということです。

これら XNUMX つのツールを Boston データセットで使用します。

お願い: ファセットの概要とファセットの詳細を同時に使用することはできません。 ツールを変更するには、まずノートブックをクリアする必要があります。

どちらのツールを使用するにも、まずFacetsをノートブック環境にインストールする必要があります。

ファセットのインストール

ほとんどの分析には Facet Web アプリを使用できます。このチュートリアルでは、それを内部で使用する方法を説明します。 Jupyter ノート。

まず、nbextensions をインストールする必要があります。これは、このコードで実行されます。次のコードをコピーして、マシンのターミナルに貼り付けます。

pip install jupyter_contrib_nbextensions

その直後に、コンピュータ内のリポジトリのクローンを作成する必要があります。 選択肢は XNUMX つあります。

オプション1) このコードをコピーしてターミナルに貼り付けます (推奨)

お使いのマシンにGitがインストールされていない場合は、こちらにアクセスしてください。 URL Git 用 Windows ダウンロードのページ そして指示に従ってください。完了したら、Mac ユーザーのターミナルまたは Anaconda プロンプトで git コマンドを使用できます。 Windows user

git clone https://github.com/PAIR-code/facets

オプション2) に行く PAIRコード/ファセットリポジトリ そしてリポジトリをダウンロードします。

PAIR-codeファセットのGitHubリポジトリページ

上記のリポジトリページには、オプション2で使用するダウンロードボタンがあります。最初のオプションを選択した場合、ファイルはダウンロードフォルダに保存されます。ダウンロードしたファイルをそのままにしておくことも、別の場所にドラッグすることもできます。

次のコマンドラインを使用して、ファセットが保存されている場所を確認できます。

echo `pwd`/`ls facets`

ファセットを見つけたので、それをインストールする必要があります。 Jupyter ノート。作業ディレクトリをファセットが配置されているパスに設定する必要があります。

現在の作業ディレクトリと Facets zip の場所は同じである必要があります。

現在の作業ディレクトリにfacetsフォルダが表示されているターミナル画面

上記のターミナル出力から、facetsが現在の作業ディレクトリに存在することが確認できます。作業ディレクトリをFacetのディレクトリに設定する必要があります。

cd facets

ファセットをインストールするには Jupyter、XNUMXつの選択肢があります。インストールした場合 Jupyter すべてのユーザーの Conda を使用するには、次のコードをコピーします。

jupyter nbextension install facets-dist/

それ以外の場合は、以下を使用します。

jupyter nbextension install facets-dist/ --user

準備は完了です。 ファセットの概要を開いてみましょう。

ファセットの概要を実行する Jupyter

概要は Python 統計を計算するスクリプト。generic_feature_statistics_generatorというスクリプトをインポートする必要があります。 Jupyter。心配しないで;スクリプトはファセット ファイルにあります。

そのパスを見つける必要があります。 簡単にできます。 ファセットを開き、ファイル facets_overview を開き、次に Python を開きます。 パスをコピーする

facets_overview python フォルダのファイルパス

その後、に戻ります Jupyter、次のコードを記述します。パス '/Users/Thomas/facets/facets_overview/python' を自分のパスに変更します。

# Add the facets overview python code to the python path# Add t 
import sys
sys.path.append('/Users/Thomas/facets/facets_overview/python')

以下のコードを使用してスクリプトをインポートできます。

from generic_feature_statistics_generator import 
GenericFeatureStatisticsGenerator

Windowsでは、同じコードが

import sys
sys.path.append(r"C:\Users\Admin\Anaconda3\facets-master\facets_overview\python")

from generic_feature_statistics_generator import GenericFeatureStatisticsGenerator

機能統計を計算するには、関数 GenericFeatureStatistics を使用する必要があります。Generator() では、オブジェクト ProtoFromDataFrames を使用します。 データ フレームをディクショナリに渡すことができます。 たとえば、列車セットの概要統計を作成したい場合、その情報を辞書に保存し、オブジェクト「ProtoFromDataFrames」で使用できます。

'name': 'train', 'table': df_train

Name は表示されるテーブルの名前で、要約を計算するテーブルの名前を使用します。 あなたの例では、データを含むテーブルは df_train です。

# Calculate the feature statistics proto from the datasets and stringify it for use in facets overview
import base64

gfsg = GenericFeatureStatisticsGenerator()

proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train},
                                  {'name': 'test', 'table': df_test}])

#proto = gfsg.ProtoFromDataFrames([{'name': 'train', 'table': df_train}])
protostr = base64.b64encode(proto.SerializeToString()).decode("utf-8")

最後に、以下のコードをコピーして貼り付けるだけです。 コードは GitHub から直接取得します。 これを見ることができるはずです:

ファセット概要表(機能ごとの要約統計情報)

# Display the facets overview visualization for this data# Displ 
from IPython.core.display import display, HTML

HTML_TEMPLATE = """<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html" >
        <facets-overview id="elem"></facets-overview>
        <script>
          document.querySelector("#elem").protoInput = "{protostr}";
        </script>"""
html = HTML_TEMPLATE.format(protostr=protostr)
display(HTML(html))

相関グラフとペアグリッド

データとその分布を確認した後、相関行列を作成できます。相関行列はピアソン相関係数を計算します。この係数は-1から1の範囲にあり、正の値は正の相関、負の値は負の相関を示します。

どの変数が交互作用項の適切な候補となり得るかを知りたいと考えています。

バージョンノート: 下のマスクが呼びかける np.boolNumPy 1.20 で非推奨となったエイリアスであり、 NumPy 1.24で削除されました最近の NumPy では同じ行で AttributeError: module 'numpy' has no attribute 'bool'; 内蔵 bool そのまま交換できる代替品です。

## Choose important feature and further check with Dive
%matplotlib inline  
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="ticks")
# Compute the correlation matrix
corr = df.corr('pearson')
# Generate a mask for the upper triangle
mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))

# Generate a custom diverging colormap
cmap = sns.diverging_palette(220, 10, as_cmap=True)

# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,annot=True,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})

出力

<matplotlib.axes._subplots.AxesSubplot at 0x1a184d6518>

ボストン変数のSeaborn相関ヒートマップ

上記のヒートマップでは、濃い色の四角形は相関関係が強いことを示しています。マトリックスからは、次のことがわかります。

  • LSTAT
  • RM

PRICEと強い相関関係があります。もう一つ注目すべき点は、NOXとINDUSの間に強い正の相関関係があることです。これは、これら2つの変数が同じ方向に動くことを意味します。どちらもPRICEと相関関係があります。DISもINDUSとNOXと高い相関関係があります。

INDUSとNOXが相互作用項の有力な候補となり得るという最初の兆候が得られました。また、DISも注目する価値があるかもしれません。

ペアグリッドをプロットすると、もう少し深く調べることができます。 以前にプロットした相関マップをより詳細に示します。

ペアグリッドは以下のように構成されます。

  • 上部: 近似直線を含む散布図
  • 対角線: カーネル密度プロット
  • 下部: 多変量カーネル密度プロット

あなたは4つの独立変数に注目します。選択は、価格と強い相関関係にある変数に対応します。

  • インダス
  • NOX
  • RM
  • LSTAT

さらに、PRICE。

お願い 標準誤差がデフォルトで散布図に追加されることを確認します。

attributes = ["PRICE", "INDUS", "NOX", "RM", "LSTAT"]

g = sns.PairGrid(df[attributes])
g = g.map_upper(sns.regplot, color="g")
g = g.map_lower(sns.kdeplot,cmap="Reds", shade=True, shade_lowest=False)
g = g.map_diag(sns.kdeplot)

出力

SeabornのPRICE、INDUS、NOX、RM、LSTATのペアグリッド

上部から始めましょう。

  • 価格はINDUS、NOX、LSTATと負の相関があります。 RMと正の相関がありました。
  • LSTATとPRICEの間にはわずかな非線形性がある。
  • 価格が 50 に等しい場合、直線のようなものになります。データセットの説明から、PRICE は値 50 で切り捨てられています。

対角線: NOX には 0.5 つのクラスターがあるようです。0.85 つは XNUMX 付近、もう XNUMX つは XNUMX 付近です。

さらに詳しく確認するには、下部をご覧ください。多変量カーネル密度は、ポイントがほとんどある場所に色を付けるという点で興味深いものです。散布図との違いは、特定の座標のデータセットにポイントがなくても、確率密度を描画することです。色が濃いほど、このエリアの周囲にポイントが集中していることを示します。

INDUS と NOX の多変量密度を確認すると、正の相関関係と 18 つのクラスターが確認できます。産業のシェアが 0.6 を超えると、一酸化窒素濃度は XNUMX を超えます。

INDUS と NOX の間に線形関係の相互作用を追加することを考えることができます。

最後に、2番目のツールとして、 Googleファセットの詳細分析。インターフェースは主に4つのセクションに分かれています。中央のエリアは、データのズーム可能な表示です。パネルの上部には、データの配置を変更してファセット、位置、色を制御できるドロップダウンメニューがあります。右側には、特定のデータ行の詳細ビューがあります。つまり、中央の視覚化でデータのドットをクリックすると、その特定のデータポイントの詳細が表示されます。

データの視覚化のステップでは、住宅価格の独立変数間のペアワイズ相関関係を調べることに関心があります。ただし、これには少なくとも 3 つの変数が関係しており、XNUMXD プロットの扱いは複雑です。

この問題を解決する一つの方法は、カテゴリ変数を作成することです。つまり、2Dプロットを作成して点に色を付けることができます。変数PRICEを4つのカテゴリに分割し、各カテゴリを四分位数(0.25、0.5、0.75)とします。この新しい変数をQ_PRICEと呼びます。

## Check non linearity with important features
df['Q_PRICE'] =  pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"])
## Show non linearity between RM and LSTAT
ax = sns.lmplot(x="DIS", y="INDUS", hue="Q_PRICE", data=df, fit_reg = False,palette="Set3")

DISとINDUSの散布図(価格四分位で色分け)

ファセットの詳細解説

Deep Diveを開くには、データをJSON形式に変換する必要があります。Pandasにはそのためのメソッドがあります。DataFrameに対してto_jsonメソッドを呼び出してください。

最初のコード行は、データセットに含まれる行数に応じてスプライトのサイズを設定します。

df['Q_PRICE'] =  pd.qcut(df['PRICE'], 4, labels=["Lowest", "Low", "Upper", "upper_plus"])
sprite_size = 32 if len(df.index)>50000 else 64
jsonstr = df.to_json(orient='records')

以下のコードは Google GitHub。コードを実行すると、以下のような表示になるはずです。

ファセットの詳細分析:ボストンデータセットのファセット散布図

# Display thde Dive visualization for this data
from IPython.core.display import display, HTML

# Create Facets template  
HTML_TEMPLATE = """<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html">
        <facets-dive sprite-image-width="{sprite_size}" sprite-image-height="{sprite_size}" id="elem" height="600"></facets-dive>
        <script>
          document.querySelector("#elem").data = {jsonstr};
        </script>"""

# Load the json dataset and the sprite_size into the template
html = HTML_TEMPLATE.format(jsonstr=jsonstr, sprite_size=sprite_size)

# Display the template
display(HTML(html))

あなたは、業界のレート、酸化物濃度、ジョブセンターまでの距離、そして住宅の価格の間に関係があるかどうかを知りたいと考えています。

そのためには、まずデータを業界範囲ごとに分割し、価格の四分位で色分けします。

  • ファセット X を選択し、INDUS を選択します。
  • 「ディスプレイ」を選択し、「DIS」を選択します。 住宅価格の四分位に応じてドットに色が付けられます

ここでは、色が濃いほど、最初の職業安定所までの距離が長いことを意味します。

これまでのところ、業界のレートが低く、価格が高いことがわかっていることが再び表示されます。 INDUX 別、NOX 別の内訳を見ることができます。

ファセット Y を選択し、NOX を選択します。

これで、最初のジョブ センターから遠い家は業界シェアが最も低く、したがって酸化物濃度も最も低いことがわかります。Q_PRICE を使用してタイプを表示し、左下隅をズームすると、価格のタイプを確認できます。

IND、NOX、DIS 間の相互作用がモデルを改善するための有力な候補となる可能性があるというもう XNUMX つのヒントがあります。

今回の探索で2つの候補となる相互作用が明らかになったので、次のステップはそれらを実際のモデルでテストすることだ。

TensorFlow を使用した線形回帰

このセクションでは、線形回帰モデルを推定します。 TensorFlow Estimator API。以下の手順に従ってください。

  • データを準備する
  • ベンチマーク モデルの推定: 相互作用なし
  • 相互作用のあるモデルを推定する

バージョンノート:   tf-estimator パッケージは TensorFlow 2.15 で最終リリースされ、TensorFlow 2.16 以降では存在しないため、 tf.estimator.LinearRegressor Keras線形モデルに移行しない限り、TensorFlow 1.xでのみ動作します。

機械学習の目標は誤差を最小限に抑えることであることを覚えておいてください。この場合、平均二乗誤差が最も低いモデルが勝者となります。TensorFlowのエスティメータはこの指標を自動的に計算します。

準備データ

ほとんどの場合、データの変換が必要になります。だからこそ、ファセット概要は非常に興味深いのです。要約統計量から、外れ値が存在することが分かりました。これらの値は、分析対象の母集団とは異なるため、推定値に影響を与えます。外れ値は通常、結果に偏りをもたらします。例えば、正の外れ値は係数を過大評価する傾向があります。

この問題を解決する良い方法は、変数を標準化することです。標準化とは、標準偏差が1、平均が0になることを意味します。標準化のプロセスは2つのステップから成ります。まず、tractsは変数の平均値です。次に、標準偏差で割ることで、分布の標準偏差が1になるようにします。

図書館 scikit-学ぶ 変数を標準化することは有効です。そのためには、オブジェクトスケールを指定した前処理モジュールを使用できます。

以下の関数を使用して、データセットをスケーリングできます。 ラベル列とカテゴリ変数はスケーリングしないことに注意してください。

from sklearn import preprocessing
def standardize_data(df): 
    X_scaled = preprocessing.scale(df[['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT']])
    X_scaled_df = pd.DataFrame(X_scaled, columns = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT'])
    df_scale = pd.concat([X_scaled_df,
                       df['CHAS'],
                       df['PRICE']],axis=1, join='inner')
    return df_scale

この関数を使用して、スケーリングされたトレーニング/テスト セットを構築できます。

df_train_scale = standardize_data(df_train)
df_test_scale = standardize_data(df_test)

基本回帰:ベンチマーク

まず、対話なしでモデルをトレーニングしてテストします。 目的は、モデルのパフォーマンス メトリックを確認することです。

モデルのトレーニング方法は、チュートリアルに記載されているとおりです。 高レベルAPI。 TensorFlow 推定器 LinearRegressor を使用します。

注意として、次のものを選択する必要があります。

  • モデルに入れる特徴
  • 特徴を変える
  • 線形回帰変数を構築する
  • input_fn 関数を構築する
  • モデルを訓練する
  • モデルをテストする

データセット内のすべての変数を使用してモデルをトレーニングします。合計で、連続変数が12個、カテゴリ変数が1個あります。

## Add features to the bucket: 
### Define continuous list
CONTI_FEATURES  = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT']
CATE_FEATURES = ['CHAS']

特徴を数値列またはカテゴリ列に変換します。

continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
#categorical_features = tf.feature_column.categorical_column_with_hash_bucket(CATE_FEATURES, hash_bucket_size=1000)
categorical_features = [tf.feature_column.categorical_column_with_vocabulary_list('CHAS', ['yes','no'])]

モデルは、linearRegressor を使用して作成します。 モデルを train_Boston フォルダーに保存します。

model = tf.estimator.LinearRegressor(    
	model_dir="train_Boston",     
    feature_columns=categorical_features + continuous_features)

出力

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train_Boston', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a19e76ac8>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

トレーニングデータまたはテストデータの各列は、get_input_fn 関数を使用してテンソルに変換されます。

FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT', 'CHAS']
LABEL= 'PRICE'
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)

列車データ上でモデルを推定します。

model.train(input_fn=get_input_fn(df_train_scale, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

出力

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train_Boston/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 144.457
INFO:tensorflow:loss = 76982.734, step = 101 (0.697 sec)
INFO:tensorflow:global_step/sec: 258.392
INFO:tensorflow:loss = 21246.334, step = 201 (0.383 sec)
INFO:tensorflow:global_step/sec: 227.998
INFO:tensorflow:loss = 30534.78, step = 301 (0.439 sec)
INFO:tensorflow:global_step/sec: 210.739
INFO:tensorflow:loss = 36794.5, step = 401 (0.477 sec)
INFO:tensorflow:global_step/sec: 234.237
INFO:tensorflow:loss = 8562.981, step = 501 (0.425 sec)
INFO:tensorflow:global_step/sec: 238.1
INFO:tensorflow:loss = 34465.08, step = 601 (0.420 sec)
INFO:tensorflow:global_step/sec: 237.934
INFO:tensorflow:loss = 12241.709, step = 701 (0.420 sec)
INFO:tensorflow:global_step/sec: 220.687
INFO:tensorflow:loss = 11019.228, step = 801 (0.453 sec)
INFO:tensorflow:global_step/sec: 232.702
INFO:tensorflow:loss = 24049.678, step = 901 (0.432 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston/model.ckpt.
INFO:tensorflow:Loss for final step: 23228.568.


<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a19e76320>

最後に、テスト セットでのモデルのパフォーマンスを推定します。

model.evaluate(input_fn=get_input_fn(df_test_scale, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

出力

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-29-02:40:43
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train_Boston/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-29-02:40:43
INFO:tensorflow:Saving dict for global step 1000: average_loss = 86.89361, global_step = 1000, loss = 1650.9785


{'average_loss': 86.89361, 'global_step': 1000, 'loss': 1650.9785}

モデルの損失は 1650.9785 です。これは次のセクションで克服するメトリックです

モデルの改善: 相互作用項

チュートリアルの最初の部分では、変数間の興味深い関係性について説明しました。さまざまな視覚化手法によって、INDUSとNOXが相互に関連し、価格に対する互いの影響を増幅させていることが明らかになりました。IND​​USとNOXの相互作用は価格に影響を与えるだけでなく、DISと相互作用するとその影響はさらに強まります。

この考え方を一般化して、モデルの予測精度を向上させることができるかどうかを検証してみましょう。

各データセットに「train」と「test」という2つの新しい列を追加する必要があります。そのためには、相互作用項を計算する関数と、3つの相互作用項を計算する関数をそれぞれ作成します。各関数は1つの列を生成します。新しい変数が作成されたら、それらをトレーニングデータセットとテストデータセットに連結できます。

まず最初に、INDUS と NOX の間の相互作用のための新しい変数を作成する必要があります。

以下の関数は、var_1 と var_2 (この場合は INDUS と NOX) の間の相互作用を含む XNUMX つのデータフレーム、train と test を返します。

def interaction_term(var_1, var_2, name):
    t_train = df_train_scale[var_1]*df_train_scale[var_2]
    train = t_train.rename(name)
    t_test = df_test_scale[var_1]*df_test_scale[var_2]
    test = t_test.rename(name)
    return train, test

XNUMX つの新しい列を保存します

interation_ind_ns_train, interation_ind_ns_test= interaction_term('INDUS', 'NOX', 'INDUS_NOS')
interation_ind_ns_train.shape
(325,)

次に、三重交互作用項を計算する XNUMX 番目の関数を作成します。

def triple_interaction_term(var_1, var_2,var_3, name):
    t_train = df_train_scale[var_1]*df_train_scale[var_2]*df_train_scale[var_3]
    train = t_train.rename(name)
    t_test = df_test_scale[var_1]*df_test_scale[var_2]*df_test_scale[var_3]
    test = t_test.rename(name)
    return train, test
interation_ind_ns_dis_train, interation_ind_ns_dis_test= triple_interaction_term('INDUS', 'NOX', 'DIS','INDUS_NOS_DIS')

必要な列がすべて揃ったので、それらをデータセットのトレーニングとテストに追加できます。 これら XNUMX つの新しいデータフレームに次の名前を付けます。

  • df_train_new
  • df_test_new
df_train_new = pd.concat([df_train_scale,
                          interation_ind_ns_train,
                          interation_ind_ns_dis_train],
                         axis=1, join='inner')
df_test_new = pd.concat([df_test_scale,
                         interation_ind_ns_test,
                         interation_ind_ns_dis_test],
                         axis=1, join='inner')
df_train_new.head(5)

出力

INDUS_NOS列とINDUS_NOS_DIS列が追加されたトレーニング用データフレーム

以上です。相互作用項を含む新しいモデルを推定し、パフォーマンス指標がどのように変化するかを確認できます。

CONTI_FEATURES_NEW  = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT',
                       'INDUS_NOS', 'INDUS_NOS_DIS']
### Define categorical list
continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW]
model = tf.estimator.LinearRegressor(
    model_dir="train_Boston_1", 
    feature_columns= categorical_features + continuous_features_new)

出力

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'train_Boston_1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1a1a5d5860>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

Code

FEATURES = ['CRIM', 'ZN', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD','TAX', 'PTRATIO', 'B', 'LSTAT','INDUS_NOS', 'INDUS_NOS_DIS','CHAS']
LABEL= 'PRICE'
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)
model.train(input_fn=get_input_fn(df_train_new, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

出力

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into train_Boston_1/model.ckpt.
INFO:tensorflow:loss = 56417.703, step = 1
INFO:tensorflow:global_step/sec: 124.844
INFO:tensorflow:loss = 65522.3, step = 101 (0.803 sec)
INFO:tensorflow:global_step/sec: 182.704
INFO:tensorflow:loss = 15384.148, step = 201 (0.549 sec)
INFO:tensorflow:global_step/sec: 208.189
INFO:tensorflow:loss = 22020.305, step = 301 (0.482 sec)
INFO:tensorflow:global_step/sec: 213.855
INFO:tensorflow:loss = 28208.812, step = 401 (0.468 sec)
INFO:tensorflow:global_step/sec: 209.758
INFO:tensorflow:loss = 7606.877, step = 501 (0.473 sec)
INFO:tensorflow:global_step/sec: 196.618
INFO:tensorflow:loss = 26679.76, step = 601 (0.514 sec)
INFO:tensorflow:global_step/sec: 196.472
INFO:tensorflow:loss = 11377.163, step = 701 (0.504 sec)
INFO:tensorflow:global_step/sec: 172.82
INFO:tensorflow:loss = 8592.07, step = 801 (0.578 sec)
INFO:tensorflow:global_step/sec: 168.916
INFO:tensorflow:loss = 19878.56, step = 901 (0.592 sec)
INFO:tensorflow:Saving checkpoints for 1000 into train_Boston_1/model.ckpt.
INFO:tensorflow:Loss for final step: 19598.387.


<tensorflow.python.estimator.canned.linear.LinearRegressor at 0x1a1a5d5e10>
model.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

出力

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-05-29-02:41:14
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train_Boston_1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-05-29-02:41:14
INFO:tensorflow:Saving dict for global step 1000: average_loss = 79.78876, global_step = 1000, loss = 1515.9863


{'average_loss': 79.78876, 'global_step': 1000, 'loss': 1515.9863}

新しい損失は 1515.9863 です。XNUMX つの新しい変数を追加するだけで、損失を減らすことができました。 これは、ベンチマーク モデルよりも優れた予測を行うことができることを意味します。

モデル フィーチャセット モデルディレクトリ 平均損失 損失
ベンチマーク 12の標準化された連続カラムとCHAS ボストン行き列車 86.89361 1650.9785
相互作用を伴う ベンチマークプラスINDUS_NOSおよびINDUS_NOS_DIS train_Boston_1 79.78876 1515.9863

どちらの数値も同じ101行のテスト分割から得られたものであるため、平均損失が約8%減少したのは、2つの相互作用列のみに起因する。

よくあるご質問

この機能については、scikit-learn 1.0 で非推奨となり、1.2 で削除されました。このデータセットには、人種的自己隔離と住宅価格に関する仮定に基づいた特徴量が含まれており、元の研究では大気質に関する前提が検証されていませんでした。代替として、カリフォルニア州またはエイムズの住宅データが一般的に用いられます。

多項式項は、ある変数を二乗または三乗して、その変数の曲線を変化させます。相互作用項は、2つの異なる変数を乗算するため、一方の変数の傾きは他方の変数の値に依存します。このチュートリアルでは、後者の相互作用項であるINDUS×NOXを構築します。

互いに相関があり、かつターゲットとも相関のあるペアを探します。ピアソンヒートマップとペアグリッドはこれを視覚的に行います。ここではINDUSとNOXが一緒にクラスターを形成し、両方ともターゲットとも相関があります。 track PRICEは、それらを交差させることを正当化するシグナルです。

自動化された特徴量エンジニアリングライブラリは、候補となる変換と交差を生成し、それぞれをホールドアウトと比較してスコアリングし、エラーを削減するものだけを残します。これは、ここに示した手動のヒートマップ読み取りに取って代わるものですが、生成された列の意味を人間が確認する必要は依然としてあります。

Copilotは、ペアグリッド、マスク付きヒートマップ、ファセット用のHTMLテンプレートなど、繰り返し行うプロットの定型処理をうまく処理します。ただし、Seabornがいくつかの引数の名前を変更したため、Copilotが提案する引数を確認してください。Copilotは古いシグネチャと新しいシグネチャを混在させてしまうことがあります。

いいえ。損失は、ここで示されているように、同じホールドアウト分割で比較する必要があります。トレーニングデータのみで損失が発生する場合は、過学習の兆候です。また、列を追加すると、実際の情報が含まれているかどうかに関わらず、トレーニングの適合度がほぼ確実に向上します。

このマスクは、NumPy 1.20 で非推奨となり、1.24 で削除されたエイリアス np.bool を使用しています。最近のインストールでは AttributeError が発生します。組み込みの bool に置き換えても動作は同じです。NumPy のスカラー型が必要な場合は、np.bool_ も使用できます。

CHASはカテゴリカルなイエス・ノーのフラグであり、PRICEはラベルです。ダミー変数を中央揃えやスケーリングを行うと、適合度を変えずに係数が読みにくくなります。また、ラベルをスケーリングしても、報告される損失が再スケーリングされるだけです。標準化されるのは、12個の連続予測変数のみです。