DatawhaleAI サマーキャンプ 第 3 フェーズ 機械学習ユーザー 新しい予測チャレンジ ベースライン 初心者チュートリアル

このチュートリアルでは、プロジェクトベースの学習を浅いものから深いものへと段階的に進めていきます。コンテストの一般的なプロセスと最も単純なベースラインの実行から、各コンテストのリンクの詳細な読み取り、ベースラインの集中的な読み取り、および高度な実践的スキルの学習まで。
千マイルの旅も一歩から AI 学習の旅をここから始めましょう!
——Datawhale 貢献者チーム

ユーザー追加予測チャレンジ:
https://challenge.xfyun.cn/topic/info?type=subscriber-addition-prediction&ch=ymfk4uU
主催者: iFlytek
データのダウンロード
結果を送信する

クリックして環境を開始します
ここに画像の説明を挿入します
クリックして環境に入ります
ワンクリックですべてのコードを実行
答えを得た
ファイルを右クリックしてダウンロードし、iFlytek プラットフォームに送信します。

# 导入库
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier#决策树模型

# 读取训练集和测试集文件
train_data = pd.read_csv('用户新增预测挑战赛公开数据/train.csv')
test_data = pd.read_csv('用户新增预测挑战赛公开数据/test.csv')

# 提取udmap特征,人工进行onehot
#定义udmap_onethot()函数:该函数用于对udmap特征进行人工的one-hot编码。首先创建一个长度为9的全零向量v,然后根据输入的d的值进行判断,如果值为'unknown',则直接返回全零向量。如果值不为'unknown',则通过eval()函数将字符串转换成字典对象d,然后遍历数字1到9,检查字典中是否包含键名为'key1'、'key2'、...、'key9'的元素,如果存在,则将对应的值赋给向量v的相应位置(索引为i-1),最后返回得到的向量v。
def udmap_onethot(d):
    v = np.zeros(9)
    if d == 'unknown':
        return v
    d = eval(d)
    for i in range(1, 10):
        if 'key' + str(i) in d:
            v[i-1] = d['key' + str(i)]
            
    return v
#对udmap特征进行one-hot编码:通过apply()方法将udmap_onethot()函数应用到train_data['udmap']和test_data['udmap']上,将返回的数组垂直堆叠成DataFrame对象train_udmap_df和test_udmap_df,然后为这两个DataFrame设置列名。
train_udmap_df = pd.DataFrame(np.vstack(train_data['udmap'].apply(udmap_onethot)))
test_udmap_df = pd.DataFrame(np.vstack(test_data['udmap'].apply(udmap_onethot)))
train_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]
test_udmap_df.columns = ['key' + str(i) for i in range(1, 10)]

# 编码udmap是否为空
train_data['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)

# udmap特征和原始数据拼接
#通过使用.concat()函数将train_udmap_df和test_udmap_df与原始数据集train_data和test_data进行列拼接。
train_data = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)

# 提取eid的频次特征
# 使用value_counts()函数统计train_data['eid']中每个元素的出现次数,并通过map()函数将结果映射到对应的train_data['eid_freq']和test_data['eid_freq']中。
train_data['eid_freq'] = train_data['eid'].map(train_data['eid'].value_counts())
test_data['eid_freq'] = test_data['eid'].map(train_data['eid'].value_counts())

# 提取eid的标签特征
# 使用groupby()函数根据eid对train_data进行分组,然后计算每个分组中target列的均值,并通过map()函数将结果映射到对应的train_data['eid_mean']和test_data['eid_mean']中。
train_data['eid_mean'] = train_data['eid'].map(train_data.groupby('eid')['target'].mean())
test_data['eid_mean'] = test_data['eid'].map(train_data.groupby('eid')['target'].mean())

# 提取时间戳
# 将train_data['common_ts']和test_data['common_ts']的数值类型转换为时间戳类型,指定时间单位为毫秒。然后使用.dt.hour将时间戳转换为小时数,并将结果存储在train_data['common_ts_hour']和test_data['common_ts_hour']中。
train_data['common_ts'] = pd.to_datetime(train_data['common_ts'], unit='ms')
test_data['common_ts'] = pd.to_datetime(test_data['common_ts'], unit='ms')
train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
test_data['common_ts_hour'] = test_data['common_ts'].dt.hour

# 加载决策树模型进行训练
# 创建一个DecisionTreeClassifier分类器对象clf,使用fit()方法将训练集的特征列(去除不需要的列)与目标列作为输入进行模型训练。
clf = DecisionTreeClassifier()
clf.fit(
    train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),
    train_data['target']
)

# 对测试集进行预测,将submit.csv在比赛页面提交
# 使用已训练好的分类器clf对测试集的特征列(去除不需要的列)进行预测,并生成包含预测结果的DataFrame对象。最后将预测结果保存为CSV文件submit.csv,并包括uuid和target两列。
pd.DataFrame({
    
    
    'uuid': test_data['uuid'],
    'target': clf.predict(test_data.drop(['udmap', 'common_ts', 'uuid'], axis=1))
}).to_csv('submit.csv', index=None)

使用されるFit メソッドは、 scikit-learn ライブラリでモデルをトレーニングするためのメソッドです。最初にモデルが必要です。ここでは、デシジョン ツリー モデルを使用します。フィッティング手法は線形回帰フィッティングであり、モデリング誤差の二乗和、つまり損失関数を最小化できるモデルパラメータを選択することが目標です。

ワンホット エンコーディングの分析を解決する前に、まずワンホット エンコーディングが使用される理由の問題を解決します。明らかに、ここでのデータの離散特徴の値には意味がなく、ワンホット エンコーディングは使用できます。離散特徴の値は、サイズの意味については、連続値の 1 対 1 マッピングを使用できます。
ワンホット エンコーディングは、ワンホット エンコーディングであり、1 ビット効果エンコーディングとも呼ばれます。その方法は、N ビットのステータス レジスタを使用して N 状態をエンコードすることです。各状態には独自の独立したレジスタ ビットがあり、いつでも1 つは有効です。
各特徴量が m 個の可能な値を持つ場合、ワンホット エンコード後、m 個のバイナリ特徴量になることがわかります (たとえば、成績の特徴量は、良、中、低を持ち、ワンホットになります 100)。 、010、001)。また、これらの機能は相互に排他的であり、一度にアクティブになるのは 1 つだけです。したがって、データはまばらになります。
これの主な利点は、
分類器が属性データを処理できない問題を解決すること
と、機能をある程度拡張する役割を果たすことです。

Q&A

  • submit.csv を iFlytek コンペティション ページに提出した場合、何ポイント獲得できますか?
  • 私が提出したスコアは 0.62686 でした
  • コード内で udmp で手動 onehot を実行するにはどうすればよいですか?
  • コードでは、udmap は、カスタマイズされた udmap_onethot() 関数を通じて手動でワンホット エンコードされます。udmap_onethot() 関数の具体的な実装手順は次のとおりです。

1. エンコードされた結果を保存するために、長さ 9 のすべてゼロのベクトル v を作成します。
2. 入力 d の値が「不明」であるかどうかを判断し、そうである場合は、すべてゼロのベクトル v を直接返します。
3. d の値が「不明」でない場合は、eval() 関数を使用して、文字列形式の辞書オブジェクトを実際の辞書オブジェクトに変換します。
4. 1 から 9 までの数字 (ワンホット エンコーディングの 9 つのカテゴリを表す) を調べて、辞書オブジェクト d にキー名「key1」、「key2」、...、「key9」の要素が含まれているかどうかを確認します。
5. 各数値 i について、辞書オブジェクト d にキー名 'key'+str(i) を持つ要素がある場合、その要素の値をベクトル v (インデックス) の i-1 番目の位置に代入します。はi-1)です。
6. 最後に、エンコード後に得られたベクトル v を返します。
udmap_onethot() 関数を呼び出し、トレーニング セットとテスト セットの udmap 列に適用することで、手動ワンホット エンコーディング後の特徴行列を取得できます。

datawhale の偉人によるベースラインの説明をチェックしてください。
ベースラインのビデオ説明

デシジョン ツリーの概要

デシジョンツリーモデルとは何ですか?
デシジョン ツリーは、オブジェクトの属性とオブジェクトの値の間のマッピング関係を表す予測モデルです。ツリー内の各ノードはオブジェクトを表し、各分岐パスは可能な属性値を表し、各リーフ ノードはルート ノードからリーフ ノードまでのパスによって表されるオブジェクトの値に対応します。

デシジョンツリービュー
意思決定木の構成 ルート
ノード:最初の選択点
非リーフノードと枝:中間プロセス
リーフノード:最終的な意思決定結果


ここに画像の説明を挿入します
決定木アルゴリズムには、情報エントロピーと情報ゲインの 3 種類があります。
情報エントロピー
条件付きエントロピー
いわゆる情報ゲインとは、学習データセット D に対する特徴 A の情報ゲイン g (D, A) を指します。情報エントロピー H( D) 集合 D と特徴 A の情報条件付きエントロピー H(D|A) の差、つまり式は次のとおりです。 したがって、決定木の生成は主に次の 2 つに分けられます
ここに画像の説明を挿入します
。これら 2 つのステップは、通常、分類結果がすでにわかっているサンプルを学習することによって達成されます。

  1. ノードの分割:一般に、ノードが表す属性を判断できない場合、そのノードは2つの子
    ノードに分割されます(二分木でない場合はn個の子ノードに分割されます)。
  2. しきい値の決定: 分類エラー率 (トレーニング エラー) を最小限に抑えるために、適切なしきい値を選択します。

データ例:
ここに画像の説明を挿入します

二分木と仮定すると、決定木の一般的な決定結果は次のようになります。
ここに画像の説明を挿入します
ここで、なぜ自分の家を先頭に置く必要があるのでしょうか。情報利得の大きさがわかりますので、上記の情報利得の公式に従って、
ここに画像の説明を挿入します年齢、職業、持ち家、信用状況の 4 つの特徴を A1、A2、A3、A4 として、それを当てはめてみましょう。年齢の情報利得は次のとおりです:
ここに画像の説明を挿入します
同様に、g(D,A2)=0.324、g(D,A3)=0.420、g(D,A4)=0.363 を計算できます。比較すると、特徴 A3 の情報利得が最も大きくなります。 . なので、前に置きます。

デシジョン ツリーの長所と短所:

  • 利点:
    デシジョン ツリーは理解しやすく説明しやすく、視覚化して分析でき、ルールを簡単に抽出できます。
    名目データと数値データの両方を処理できます。属性が欠落しているサンプルの処理により
    適しています。
    無関係な特徴を処理できます。
    データ セット、実行 比較的高速であり、
    比較的短期間で大規模なデータ ソースに対して実行可能な良好な結果を生成できます。
  • 短所:
    過学習が発生しやすい (ランダム フォレストは過学習を大幅に軽減できます)、
    データ セット内の属性の相関関係を無視しやすい、
    意思決定で属性を分割するときに、各カテゴリのサンプル数が一貫していないデータの場合ツリー、異なる 判断基準によって異なる属性選択傾向がもたらされます。情報獲得基準では、より多くの望ましい属性 (通常は ID3 アルゴリズムを代表) を持つ属性が優先されますが、ゲイン率基準 (CART) では、より少数の望ましい属性を持つ属性が優先されます。ただし、CART が属性分類を実行するとき、単にゲイン レートを使用して分割するのではなく、ヒューリスティック ルールを使用します) (RF など、情報ゲインが使用される限り、この欠点は存在します)。
    ID3 アルゴリズムが情報ゲインを計算すると、結果はより多くの数値を持つ特徴に偏ります。

なぜ剪定するのですか?
デシジョン ツリー モデルでの過剰適合のリスクは非常に高く、理論的にはデータを完全に分離できます。ノードが多すぎると、各サンプルがリーフに分割される可能性があるためです。トレーニング セットでは良好な結果が得られますが、テスト セットでは効果が良くありません。したがって、デシジョン ツリー モデルを構築した後、分類基準をより強力にし、ツリーをより簡潔にし、操作効率を向上させ、モデルの適用性を向上させるために、枝刈り戦略を採用する必要があります。

剪定の考え方:
剪定前:特定の枝の成長をあらかじめ止めておく
剪定後:完全な木を生成し、戻って下から上に向かって剪定を行う 剪定前の
例:
分割 精度が低くなってから剪定分割は行わずに実行されます 分割後も精度は変わりません オッカムのカミソリの原理に従って分割は行われません 事後枝刈りの例: 下から上に向かって、各ノードが枝刈りするかどうかを検討します 枝刈りの場合、枝刈りが
ここに画像の説明を挿入します
ある
場合切っても変化がないので切らないでください。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します
枝刈り前 VS 枝刈り後
(1) 時間コスト
枝刈り前: テスト時間のコストが削減され、トレーニング時間のコストが削減 枝
刈り後: テスト時間のコストが削減され、トレーニング時間のコストが増加
(2) オーバーフィッティング/アンダーフィッティングリスク:
枝刈り前: 過適合のリスクが減少し、過小適合のリスクが増加 枝刈り後: 過適合のリスクが減少し、
過小適合のリスクは基本的に変化しません
( 3) 一般化パフォーマンス: 通常、剪定後の方が剪定前よりも優れています。

おすすめ

転載: blog.csdn.net/m0_68165821/article/details/132248848