中古車取引価格予測コードの本格解析(2)データ解析と特徴量エンジニアリング

失敗に直面しても躊躇しないでください、選択に直面しても躊躇しないでください、困難に直面しても恐れないでください。

欠損値と重複値を表示する

ここで欠損値とは何かについて話しましょう。たとえば、特定の列には明らかに数字があるはずですが、数字がまったくありません。これにより、プログラムの実行中にエラーが報告され、変換を実行できないNaN(数値ではない) というメッセージが表示されます。

Tianchi が提供するデータセットには欠損値が多数あり、最初にプログラムを実行し始めたとき、いたるところで NaN エラーが報告されました。したがって、欠損値を確認する必要があるため、次のコードを使用して欠損値と重複値を確認します

missing=data_all.isnull().sum()
missing=missing[missing>0]
print(missing)
print(data_all['bodyType'].value_counts())
print(data_all['fuelType'].value_counts())
print(data_all['gearbox'].value_counts())

ここでは isnull().sum() と value_counts() について説明します。: この関数は、元の行列の対応する位置が NaN 欠損値であるかどうかを示すブール型(つまり、 または) 行列
isnull()を返します。TrueFalse

isnull().sum():sum() は、isnull() によって返されたブール行列に基づいて累積します。私たちは皆、言語の基礎となる実装に , があることを知っていますTrue=1したがって、isnull().sum() は行列の各列に欠損値がいくつあるかを出力します (欠損値が 1 つある限り True であるため、ある行列に Q 個の欠損値があるとします)列の場合、sum によって出力されるこの列の値は)です各列の欠損値の数が直接わかります。False=0
Q*1=Q

value_counts():この関数は、テーブルの列に異なる値がいくつあるかを確認し、列内の異なる値ごとに重複する値がいくつあるかを計算するために使用されます。返されるコンテンツはリストと同等です。

数値的特徴のデータ分析

数値特徴とは、特徴の表現が分類特徴に対応する特定の数値である必要があることを意味します (つまり、分類特徴の値はカテゴリを表します。たとえば、0 は高品質を意味し、1 は低品質を意味します)。さらに、特徴エンジニアリングには、時間特徴、テキスト特徴なども含まれます。

次のコードでは、num_features電力 (power)、価格 (price)、およびいくつかの匿名の数値特徴を含む数値特徴を選択しました。これに対応して、categorical_features名前、ブランドなどを含む分類機能があります。

このコードの機能は、各列の異なる値や一意の値の数などの情報を出力することで、元のデータセットの観察を実現し、Excel を 1 行ずつ開く時間を節約し、作業を容易にします。私たちのフォローアップ業務:

num_features=[ 'kilometer','power','price', 'v_0',
       'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6', 'v_7', 'v_8', 'v_9', 'v_10',
       'v_11', 'v_12', 'v_13', 'v_14']

for num in num_features:
    print('{}特征有{}个不同值'.format(num,data_all[num].nunique()))
    temp=data_all[num].value_counts()
    print(temp)
    print(pd.DataFrame(data_all[num]).describe())

上記のコードでは、describe()関数はデータ列のさまざまなデータ統計を計算します。これは、行列の基本的な内容を簡単に観察すると理解できます。description() のパラメータの詳細については、以下を参照してください。

https://blog.csdn.net/m0_45210226/article/details/108942526

さらに、コードのこの部分では新しい関数が使用されていますnunique()

英語で unique とは「単独」「唯一」という意味です。したがって、ここでの nunique は n unique、つまり「n 個の固有の値が存在する」という意味です。

パンダについての知識を加えてみましょう。pandas には2 つのメソッドunique()がありますnunique():
(1)unique()選択した列のすべての一意の値 (特徴量のすべての一意の値) を配列 (numpy.ndarray) の形式で返します。
(2)nunique()返されるのは一意の値の数です。

分類特徴のデータ分析

数値的特徴について話した後は、もちろん次のステップは分類特徴です。

categorical_features名称(名称)、商標(ブランド)などの分類特徴をご紹介します

このコードは、上記の数値特徴部分のコードと似ていますが、その目的は、分類特徴データの基本的な状況を観察することです。

categorical_features=['model','name', 'brand', 'notRepairedDamage','bodyType', 'fuelType', 'gearbox','regionCode']
for cat in categorical_features:
    print('{}特征有{}个不同值'.format(cat,data_all[cat].nunique()))
    temp=data_all[cat].value_counts()
    print(temp)
    print(pd.DataFrame(data_all[cat]).describe())

外れ値をクリーンアップする

Tianchi が提供するデータセットは本当にひどいもので、NaN だけでなく「-」などの特殊文字も含まれています。良い数値行列ですが、「-」を付けると文字列行列になってしまい、非常に面倒でデータを解析できません。

クラスメートの Q と私が一緒にコードを実行したとき、私たちは長い間この問題について理解していませんでした。この間、Excelを使って「-」記号を激しくクリーンアップしたりもしましたが、Excelの置換効率が遅すぎましたorz

ここでは、まずデータ型をチェックするコードを入力します。

print(data_all.info())

出力結果は次のとおりです。このデータ列がいかに混乱しているかが
ここに画像の説明を挿入します
わかります。notRepairedDamage他のものは all型floatまたはint数値型ですが、これだけがオブジェクト型です。

機械学習モデルは数値行列で動作するため、オブジェクト タイプを解析できず、置き換える必要があります。

ここでのアプローチは、まずすべての「-」を NaN に置き換えてから、NaN を入力してすべての値を入力することです。

したがって、‘-’異常値をクリーンアップするコードは次のようになります。

data_all['notRepairedDamage'].replace('-', np.nan, inplace=True)

replace(): オブジェクトの最初のパラメータを 2 番目のパラメータに置き換えます。ここでは、「-」を NaN に置き換えます。この関数にはパラメータが 1 つありますinplace。これは英語で「その場で変更」を意味します。false に設定すると、置換時に元のオブジェクトは変更されませんが、変更された新しいオブジェクトが返されます。True に設定すると、元のオブジェクトに直接変更されるため、True に設定する必要があります。

データ内で明らかではない特徴を除去する

Tianchi Datawhale のチュートリアルによると、これら 2 つの列のカテゴリ特徴は大きく偏っており、一般に予測に役立たないため、これら 2 つの列は削除できますsellerofferType

drop()このメソッドは、最初のパラメータに削除する列名をリストすることによって、DataFrame オブジェクトから指定された行と列を削除できます。また、axis=1列が削除されると行axis=0も削除されます。
具体的なデータ削除コードは以下の通りです。

#删掉没用的两列
data_all=data_all.drop(['seller','offerType'],axis=1)

for cat in categorical_features:
    data_all[(data_all['type']=='train')][cat].value_counts().plot(kind='box')
    plt.show()

for num in num_features:
   sns.distplot(data_train[num],kde=False,fit=stats.norm)
   plt.show()

matplotlibコードのこの部分では、2 つの描画ループが記述されています。その機能は、数値特徴またはカテゴリ特徴の各列に対して箱ひげ図を作成し、データ分布を観察することです。

sns.distplot()matplotlib の機能を統合したものでhist()sns.kdeplot()ヒストグラム+カーネル密度曲線を描画する機能を持っていますが、ここではその応用を理解するだけです。
詳細は以下でご覧いただけます。

https://blog.csdn.net/pythonxiaopeng/article/details/109642444

描いた画像2枚を掲載:
ここに画像の説明を挿入します
上の図はbrand商標のデータ分布図ですが、かなり差が大きいようです。下の写真は先ほどクリーニングしたデータですnotRepairedDamage。とても親しみやすいですね。
ここに画像の説明を挿入します

機能の分布を表示する

この部分は、sns.kdeplot主要な機能の配布を呼び出して確認することです。
sns.kdeplot()この関数は、2 つの変数間の関係を比較して線形回帰に準拠しているかどうかを確認するグラフを描画するために使用されます。通常、特徴変数とラベル変数を比較するために使用されます。彼の専門用語にカーネル密度推定(Kerneldensity estimaton)というものがあります。

いわゆるsns、実際には私たちのimport seaborn as sns結果です。絵を描くのにも使われるPythonに似たPythonグラフィックライブラリseabornです。matplotlibこれは実際にはmatplotlib、 に基づいたより高度な API カプセル化であり、描画を容易にします。
特徴分布をプロットするコードは次のとおりです。

feature=[ 'name',  'model', 'brand', 'bodyType', 'fuelType',
       'gearbox', 'power', 'kilometer', 'notRepairedDamage', 'regionCode',
        'v_0', 'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6','v_7', 'v_8', 'v_9',
        'v_10', 'v_11', 'v_12', 'v_13', 'v_14']
for i in feature:
    g=sns.kdeplot(data=data_all[i][(data_all['type']=='train')],color='Red',shade=True)
    g = sns.kdeplot(data=data_all[i][(data_all['type'] == 'test')],ax=g, color='Blue', shade=True)
    g.set_xlabel(i)
    g.set_ylabel("Frequency")  #纵轴即特征变量,具体数值与核密度估计数学实现有关
    g = g.legend(["train", "test"])
    plt.show()

ここでは、私が実際に描いた結果を示します。これは、一見すると明確に見える、トレーニング セットとテスト セットのデータの基本的な分布を実際に描くことです。
ここに画像の説明を挿入します
上が名前(名称)の特徴分布、下がブランド(商標)の特徴分布です。この画像は補助的な観察として使用されますので、ご覧ください。
ここに画像の説明を挿入します

特徴の相関を分析し、相関の低い特徴を除外します。

コードのこの部分は特徴スクリーニングに対応し、相関関係の計算に使用されます。
corr()この関数は 2 つの変数間の変化傾向の方向と程度を確認するために使用され、値の範囲は -1 ~ +1 です。0 は 2 つの変数に関連がないことを意味し、正の値は正の相関を意味し、負の値は正の相関を意味しますは負の相関を意味し、値が大きいほど相関が強いことを意味します。

methodパラメーターには、pearson、spearman、kendall、pointbiserialr、およびその他の相関係数を使用できます。ここでは、Spearman 相関係数が使用されます。最適化したい場合、どれを選択するかについては、数学的に考慮する必要があります。まずは申請をしてみましょう。
相関計算コードは以下のとおりです。

feature=['price','name',  'model', 'brand', 'bodyType', 'fuelType',
       'gearbox', 'power', 'kilometer', 'notRepairedDamage', 'regionCode',
        'v_0', 'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6','v_7', 'v_8', 'v_9',
        'v_10', 'v_11', 'v_12', 'v_13', 'v_14']
corr=data_all[feature].corr(method='spearman')
corr=pd.DataFrame(corr)   #用pandas的DataFrame封装一下相关性矩阵
#这是因为seaborn库是基于pandas的,所以必须用pandas的数据类型嘛

sns.heatmap(corr,fmt='0.2f')  #fmt就是数据格式format,代表输出的数据类型
plt.show()
# 删掉相关性比较低的特征
data_all=data_all.drop(['regionCode'],axis=1)

このプログラムはheatmapSNSを利用して(ヒートマップ)を描画します。
それが何かというとheatmap、誰でも理解できるように描画結果を載せておきます。(市外局番)と他の要素との相関が十分に高くない(すべての相関がほぼ0である)ことが一目でわかるので、このコードで
ここに画像の説明を挿入します
regionCode,dropこの列を削除するには、次を使用します。

時間機能を表示する

時間特性も非常に重要な特徴です。後で 2 つの時間特性変数の減算を使用して車の耐用年数を計算するためです。ここで を呼び出しますpd.to_datetime()。この関数は Str と Unicode を時刻形式に変換できます。これは、元のデータ セットの時刻がすべて文字列 (たとえば、2021-03-30 など) であり、必要な 2021-03-30 ではないためです。pd.to_datetime()これは、文字から日付への自動変換を実現するのに役立ちます。

具体的な日付変換コードは次のとおりです。

data_all['regDate']= pd.to_datetime(data_all['regDate'], format='%Y%m%d', errors='coerce')
data_all['creatDate']=pd.to_datetime(data_all['creatDate'], format='%Y%m%d', errors='coerce')
print(data_all['regDate'].isnull().sum()) 
# 在regDate里,有一些数据的格式出错,如20070009,可是我们没有0月
#所以我们需要 errors='coerce'。errors遇到错误会将该值设置为NaN,方便我们后续补全空值
print(data_all['creatDate'].isnull().sum())  #查看有多少空行

次に、より重要なステップが続きます。これは、特徴エンジニアリング データ処理における典型的なアプローチでもあります。

data_all['used_time']=(data_all['creatDate']-data_all['regDate']).dt.days
data_all=data_all.drop(['SaleID','regDate','creatDate','type'],axis=1)#删掉不需要的列
# 使用时间:data['creatDate'] - data['regDate'],反应汽车使用时间,一般来说价格与使用时间成反比
# 不过要注意,数据里有时间出错的格式,

ここでは新しいused_time列を構築しましたが、その名前が示すように、車の使用期間を表しており、元のcreatDate(オンライン時間) とregDate(登録時間) の情報を抽出することに相当します。

ブランドと価格の特徴を見る

コードのこの部分は Tianchi Datawhale で書かれたものよりも単純で、ブランドとモデルの 2 つの列をクラスター化し、それらを平均します。コードの意味を説明します。

groupby()この関数は、指定された列内の同じ値を持つ要素をグループに結合するため、返される結果はグループによって割り当てられた行列になります。このコードは、同じブランドの車の価格を平均し、同じモデルの車の平均価格と中央値を計算することと同等です。

mean()この関数は平均を計算するために使用されます。デフォルトでは、平均は垂直列によって計算されます。行の平均を計算する場合は、これを使用しますmean(1)

median()求められるのは中央値であり、使い方はmean()似ています。

brand_and_price_mean=data_all.groupby('brand')['price'].mean()
model_and_price_mean=data_all.groupby('model')['price'].mean()
brand_and_price_median=data_all.groupby('brand')['price'].median()
model_and_price_median=data_all.groupby('model')['price'].median()
data_all['brand_and_price_mean']=data_all.loc[:,'brand'].map(brand_and_price_mean)
data_all['model_and_price_mean']=data_all.loc[:,'model'].map(model_and_price_mean).fillna(model_and_price_mean.mean())
data_all['brand_and_price_median']=data_all.loc[:,'brand'].map(brand_and_price_mean)
data_all['model_and_price_median']=data_all.loc[:,'model'].map(model_and_price_mean).fillna(model_and_price_median.mean())

コードの最後の 4 行では、pandas の賢い関数 map() を使用しています。その機能は、マップ内のキーと値のペア (キー:値の形式のキーと値のペア) に従って呼び出し元オブジェクトの値を再割り当てすることです。 、辞書に似ています) (専門的にはマッピングと呼ばれます)。マップの基本的なアプリケーションに関しては、画像を借用して表現することができます。
ここに画像の説明を挿入します
マップが実際に辞書を提供していることがわかり、呼び出し元は自分の内部データに基づいて画像を検索することで、対応する新しい値を取得できます。

したがって、このコードでは、同じ車の 、 、およびこれらの新たに追加された属性列に、車のブランド価格に応じて同じ値が割り当てられるbrand_and_price_meanことを理解するのは難しくありません。model_and_price_meanbrand_and_price_medianmodel_and_price_median

個人的には、これは機能の統合といくつかの新しい機能の構築に似ていると思います。これは、特徴エンジニアリングにおける特徴構築のいくつかの構築方向とも一致しています。

  • 統計的特徴を構築して、数、合計、割合、標準偏差などをレポートします。
  • 相対時間と絶対時間、休日、週末などの時間特性。
  • ビニング、配信コーディング、その他の方法を含む地理情報。
  • 対数/二乗/ルートなどを含む非線形変換。
  • 特徴の組み合わせ、特徴の交差。
  • 仁者は仁を見、賢者は知恵を見て、現実の状況に応じて構造が構築されます。

おすすめ

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