中古車取引価格予測コードの完全解析(3)特徴量エンジニアリングと欠損値処理

道は長くて遠い、上へ下へ探してみる。

欠損値処理のアイデア

まず 2 番目のセクションの内容を確認してください。2 番目のセクションでは特徴の構築について説明し、特徴間の相関関係を分析し、無駄な特徴を削除するだけでなく、いくつかの新しい特徴を構築しました。used_time: (使用期間)、brand_and_price_mean(ブランドと価格) など。

新しい特徴を構築するとき、fillna()関数を使用して新しい特徴の欠損値を埋めます。ただし、元の特徴列にはまだ多くの欠損値があり、処理する必要があることにも注意する必要があります。ここでの考え方は次のとおりです。

(1) 欠落している数値は非常に小さいため、中央値または平均値に直接置き換えます。
(2) 欠損値の数が多い: 機械学習モデルを使用して欠損値を予測します。

また、欠損値に関しては、以下の問題も考慮する必要があります。
(1) トレーニング セットとテスト セットに欠損値が存在する可能性があるため、それを埋める必要があります。
(2) 既存の値を使用する必要があります。欠損値を予測するには値を使用する必要があります。結局のところ、NaN予測は使用できませんNaN

このステップでは、まず予測に関係のないいくつかの列を削除します。

data_all=data_all.drop(['SaleID','regDate','creatDate','type'],axis=1)

SaleIDはトランザクション ID であり、regDatecreatDateの新しい機能はused_time既に構築されていますtype。トレーニング セットとテスト セットを区別するためにコードの先頭で定義したラベルです。予測には明らかに役に立たないため、これらを削除してください最初に列。

次に、どの列に欠損値があるのか​​、またいくつ欠損値があるのか​​を確認してみましょう。

print(data_all.isnull().sum())   #检查每一列有多少缺失值

印刷結果は次のとおりです。
ここに画像の説明を挿入します

ここに画像の説明を挿入します
modelこの結果から、列には欠損値が 1 つだけあり、これらの列には多数の欠損値 ( 、 、 、 ) があり、その数は数万であるbodyTypeことfuelTypegearboxわかりますnotRepairedDamagepriceused_time

ごく少数の欠損値を埋める

したがって、欠損値が最も少ない列についてはmodel、中央値を直接埋めます。

data_all['model']=data_all['model'].fillna(data_all['model'].median())

特に多数の欠損値を持ついくつかの属性についてはbodyType、機械学習モデルを使用して欠損値を予測および補完する必要があります。これは、欠損値を含む各列を個別にモデル化して、その欠如を予測することと同等です。 bodyType 予測モデル、fuelType 予測モデル...

大量の欠損値: 機械学習モデルによる予測埋め込み

まず、bodyType予測モデル (トレーニング セットとテスト テスト セット) の構築に必要なデータを前処理し、欠損値が多数ある列を削除しましょう。NaN を使用して NaN を予測することはできず、NaN をトレーニング セットでのトレーニングに使用することもできないためです。前処理コードは次のとおりです。

# 处理bodyType
X_bT=data_all.loc[(data_all['bodyType'].notnull()),:]   
#先找出所有bodyType行,按True和False(空和不空)分类
X_bT=X_bT.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)#XbT删去了空值较多的列
ybT_train=data_all.loc[data_all['bodyType'].notnull()==True,'bodyType']   #只选择bodyType不为空的列
XbT_test=data_all.loc[data_all['bodyType'].isnull()==True,:]
XbT_test=XbT_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

上記のコードでは次のようになります。

notnull()==True記述方法は、空ではない行を選択することであり、isnull()==True空の行を選択することです。2 番目のセクションでも説明した理由は、notnull()sum関数がsumで構成される行列isnull()を返すためです。TrueFalse

X_bT: これは、bodyType 予測モデルをトレーニングするために使用するトレーニング セットです。つまり、欠損値を含まない他のいくつかの機能を使用して、bodyType列の値を予測します。したがって、コードの 2 行目では、欠損値が多く、予測にも熱心な特徴を削除します。

ybT_train: もちろん、それは予測したい目標値です。もちろん、予測値は NaN ではなく実数である必要があるため、ここでは元の列に欠損値を含まない行notnull()のみを取り出す関数を呼び出します。bodyType

XbT_test:これはわかりやすいですね、弊社が自社で扱っているテストセットです。ここでは、bodyType 内のすべての空の行データが XbT_test に入れられ、drop()予測対象となる他のいくつかの欠落列が削除され、予測に['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time']必要な特徴だけが残ります。bodyType

同様に、などの他のいくつかの機能のデータ前処理も同じ方法で行われます。コードは次のとおりですfuelTypegearbox

# 处理fuelType
X_fT=data_all.loc[(data_all['fuelType'].notnull()),:]
X_fT=X_fT.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
yfT_train=data_all.loc[data_all['fuelType'].notnull()==True,'fuelType']
XfT_test=data_all.loc[data_all['fuelType'].isnull()==True,:]
XfT_test=XfT_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

#处理gearbox
X_gb=data_all.loc[(data_all['gearbox'].notnull()),:]
X_gb=X_gb.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
ygb_train=data_all.loc[data_all['gearbox'].notnull()==True,'gearbox']
Xgb_test=data_all.loc[data_all['gearbox'].isnull()==True,:]
Xgb_test=Xgb_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

#处理notRepairedDamage
X_nRD=data_all.loc[(data_all['notRepairedDamage'].notnull()),:]
X_nRD=X_nRD.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
ynRD_train=pd.DataFrame(data_all.loc[data_all['notRepairedDamage'].notnull()==True,'notRepairedDamage']).astype('float64')
XnRD_test=data_all.loc[data_all['notRepairedDamage'].isnull()==True,:]
XnRD_test=XnRD_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

興味深いことに、used_time時間特徴のデータ処理は上記の特徴とは少し異なります。

#处理used_time
scaler=preprocessing.StandardScaler()
uesed_time=scaler.fit(np.array(data_all['used_time']).reshape(-1, 1))
data_all['used_time']=scaler.fit_transform(np.array(data_all['used_time']).reshape(-1, 1),uesed_time)

X_ut=data_all.loc[(data_all['used_time'].notnull()),:]
X_ut=X_ut.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
yut_train=data_all.loc[data_all['used_time'].notnull()==True,'used_time']
Xut_test=data_all.loc[data_all['used_time'].isnull()==True,:]
Xut_test=Xut_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

上記のコードでは、最初の 3 行は、used_timeこの時間タイプのデータに対して標準化および正規化操作を実行することを目的としています。その後の計算を容易にするため。

さらに、コードでは numpy 関数が使用されていますreshape()。reshape の最初のパラメータは -1 であり、これは行数が不確実であることを意味します (列数が固定されているため、具体的な行数はコンピュータ自体によって計算されます)。 )、2 番目のパラメーターは 1 です。これは、新しい行列には 1 つの列しかないことを意味します。そこで、正規化された時間データを列に変換します。

ここで使用されているscaler.fit()と はすべてライブラリにパッケージ化されている統計ツールでscaler.fit_transform()あり、具体的な説明は次のとおりです。sklearn

fit(): 簡単に言うと、トレーニング セットの平均、分散、最大値、最小値など、トレーニング セットの固有のプロパティを取得することです。

transform(): フィットに基づいて、標準化、次元削減、正規化、その他の操作を実行します (PCA、StandardScaler など、どのツールが使用されているかを確認してください)。

fit_transform():fit_transform は、fit と transform を組み合わせたものです。最初にデータを適合させて、平均、分散、最大値と最小値などのデータ全体の指標を見つけます。次に、データセットを変換して標準化と正規化を実現します。データの統合された操作。

transform()両方の機能fit_transform()は、データに対して何らかの統合処理 (標準化 ~N(0,1)、データの固定間隔へのスケーリング (マッピング)、正規化、正則化など) を実行することです。

Xgboostで欠損値を埋める

データを処理したら、もちろん機械学習予測モデルの構築を開始する必要があります。まず、ライブラリからインポートされた予測関数を定義しましょう。名前が示すように、回帰問題に xgb アルゴリズムを適用します
パラメータを追加するだけで直接利用できるので、とても便利ではないでしょうか?具体的な予測コードは以下の通りです。xgb.XGBRegressorxgboost

def RFmodel(X_train,y_train,X_test):
    model_xgb= xgb.XGBRegressor(max_depth=4, colsample_btree=0.1, learning_rate=0.1, n_estimators=32, min_child_weight=2)#模型定义
    model_xgb.fit(X_train,y_train)#拟合
    y_pre=model_xgb.predict(X_test)#预测
    return y_pre

XGBRegressor関数のコードの最初の行は、モデル オブジェクトが宣言されていることを意味します。2 行目は、処理されたトレーニング データをモデルに入力してフィッティングを行うことです。

このようにして、関数の戻り値 y_pre が欠損値を埋めるターゲットになります。

特徴ごとに欠損値を予測する

予測関数を定義すると、欠損値を実際に予測できます。ここに入力したデータは、各フィーチャに対して処理したばかりのデータです。次に、行列内の元の欠損値の位置に予測値を代入して、欠損値の補完を完了します。

y_pred=RFmodel(X_bT,ybT_train,XbT_test)
data_all.loc[data_all['bodyType'].isnull(),'bodyType']=y_pred

y_pred0=RFmodel(X_fT,yfT_train,XfT_test)
data_all.loc[data_all['fuelType'].isnull(),'fuelType']=y_pred0

y_pred1=RFmodel(X_gb,ygb_train,Xgb_test)
data_all.loc[data_all['gearbox'].isnull(),'gearbox']=y_pred1

y_pred2=RFmodel(X_nRD,ynRD_train,XnRD_test)
data_all.loc[data_all['notRepairedDamage'].isnull(),'notRepairedDamage']=y_pred2

y_pred3=RFmodel(X_ut,yut_train,Xut_test)
data_all.loc[data_all['used_time'].isnull(),'used_time']=y_pred3

特徴量エンジニアリングの部分はここで終了します。私たちのほとんどの初心者にとって、この部分のコード実装には、pandas や sklearn などのライブラリの高度な習熟が必要です。そのため、理解するのに長い時間がかかるコード部分や、状況の背後にある動作原理を理解してください。

優れた特徴量エンジニアリングは、モデルのパフォーマンスに非常に優れた補助効果をもたらします。現在の深層学習ではモデルの構造により注目が集まっていますが、おそらく特徴量エンジニアリングの最適化も深層学習に大きな可能性を秘めているのではないでしょうか?

おすすめ

転載: blog.csdn.net/zoubaihan/article/details/115342851
おすすめ