『書籍のエラー対策』 Pythonのscikit-learnライブラリでモデル変数のメソッドpredict()を実行する際、「UserWarning: X does not have valid feature names, …」が表示される

インプレスの「スッキリわかる Pythonによる機械学習入門」のエラー対策記事です。

書籍に記述されているコードを間違いなく入力しても警告(Warning)が発生した箇所があったので対策方法を掲載します。

エラーではなく警告なので処理結果は得られるのですが、気持ちの良いものではありませんので、対策します。

警告内容

P.114 第Ⅰ部 第4章 「機械学習の体験」 – 4.4.3 モデルの準備と機械学習の実行 / 新しいデータでの予測のコード4-17 predictメソッドで、学習済みモデルでの予測

# taroがどちらに分類されるか予測
model.predict(taro)

を実行すると

UserWarning: X does not have valid feature names, but DecisionTreeClassifier was fitted
 with feature names warnings.warn(

と警告が表示され、その次の行に処理結果が表示されます。

実行環境

下記の環境で発生を確認しています。

  • Anaconda3-2023.09-0-Windows-x86_64
  • JupyterLab 3.6.3
  • Python 3.11.5
  • pandas 2.0.3

警告の原因

モデルの準備と学習の実行時、引数として与えている「特徴量のデータ」がデータフレーム型であるのに対して、予測対象のデータは2次元のリストを使用している為です。
関係するコードのみを並べると下記になります。

# KvsT.csvファイルを読み込んで、データフレームに変換
df = pd.read_csv('KvsT.csv')

# 特徴量の列を参照して xに代入
xcol = ['身長', '体重', '年代']
# dfはデータフレーム型
x = df[xcol]

# モデルの準備と学習の実行
model = tree.DecisionTreeClassifier(random_state = 0)
model.fit(x, t)

# 身長170cm、体重70kg、年齢20代のデータを2次元リストで作成
taro = [[170, 70, 20]]

# taroがどちらに分類されるか予測
model.predict(taro)

x がデータフレーム型、taroが2次元リストになっています。

解決方法

方法1 : 予測対象データを2次元のリストからデータフレーム型に変換すると共に、列名を指定します。

# 身長170cm、体重70kg、年齢20代のデータを2次元リストで作成
taro = [[170, 70, 20]]

# 2次元リストからデータフレーム型に変換し、列名を指定
taro = pd.DataFrame(taro, columns=['身長', '体重', '年代'])

# taroがどちらに分類されるか予測
model.predict(taro)

方法2 : 予測対象データをデータフレーム型で作成します。

# 身長170cm、体重70kg、年代20代のデータをデータフレーム型で作成
taro = pd.DataFrame( {'身長':[170], '体重':[70], '年代':[20]} )

# taroがどちらに分類されるか予測
model.predict(taro)

P.115 コード4-18においても同様の警告が発生するので、下記のように対策できます。

matsuda = [172, 65, 20]        # 松田のデータ
asagi = [158, 48, 20]          # 浅木のデータ
new_data = [matsuda, asagi]    # 2人のデータを二次元リスト化

# データフレーム型に変換
new_data = pd.DataFrame(new_data, columns=['身長', '体重', '年代'])

# 2人のデータを一括で予測
model.predict(new_data)

P.124 コード4-22も同様です。

コメント

タイトルとURLをコピーしました