用戶新增預測——baseline學習筆記

一、賽題理解

1. 賽題名稱

? ? ? ? 用戶新增預測挑戰賽

2. 賽題數據集

? ? ? ? 賽題數據由約62萬條訓練集、20萬條測試集數據組成,共包含13個字段。其中uuid為樣本唯一標識,eid為訪問行為ID,udmap為行為屬性,其中的key1到key9表示不同的行為屬性,如項目名、項目id等相關字段,common_ts為應用訪問記錄發生時間(毫秒時間戳),其余字段x1至x8為用戶相關的屬性,為匿名處理字段。target字段為預測目標,即是否為新增用戶。

3. 賽題鏈接?

2023 iFLYTEK A.I.開發者大賽-訊飛開放平臺 (xfyun.cn)


4. 評估指標

? ? ? ? F1 score,具體公式如下:?

Precision_i = \frac{TP_i}{TP_i + FP_i} Recall_i = \frac{TP_i}{TP_i + FN_i}

F1_i = \frac{2 \cdot Precision_i \cdot Recall_i}{Precision_i + Recall_i}

二、數據競賽開發步驟

1. 問題分析

? ? ? ? 問題分析是競賽的第一步,它涉及對問題進行定義、目標明確化和數據需求的識別。

2. ?數據清洗

????????在采集數據完后,對數據進行數據清洗,即把采集到的、不適合用來做機器學習訓練的數據進行預處理,從而轉化為適合機器學習的數據。

3. 數據探索

? ? ? ? 對清洗后的數據進行可視化和統計分析的過程。通過數據探索,可以深入了解數據的特征、分布、相關性等情況,發現數據之間的模式和趨勢,為特征工程和特征篩選提供指導。常見的數據探索方法包括繪制直方圖、散點圖、箱線圖等圖形,計算統計指標如均值、方差、相關系數等。

4. 特征工程

? ? ? ? 根據數據的領域知識和探索結果,對原始數據進行變換、組合、衍生等操作,以創建更有意義、更能表達問題特征的新特征。好的特征工程可以提高模型的性能和泛化能力。常見的特征工程包括特征縮放、編碼分類變量、處理時間序列數據、創建多項式特征等。

5. 特征篩選?

? ? ? ? 通過一定的評估方法選擇對模型訓練最有用的特征,去除冗余或不相關的特征。這樣可以降低模型復雜度,加快訓練速度,減少過擬合的可能性,并提高模型的解釋性。常見的特征篩選方法包括基于統計的方法、基于模型的方法和基于特征重要性的方法。

6. 模型訓練

? ? ? ? 使用清洗、探索和篩選后的數據來訓練機器學習模型的過程。根據問題的類型和數據的特點,可以選擇合適的機器學習算法和模型架構進行訓練。訓練過程涉及優化模型參數,使其能夠最好地擬合訓練數據,并能在未見過的數據上泛化。

7. 模型保存?

? ? ? ? 模型訓練完成后,需要將訓練得到的模型保存起來,以便在后續部署和使用中使用。模型保存可以包括保存模型權重、參數和架構,以及相關的輔助信息。在實際應用中,保存的模型可以用于預測新數據的結果或作為其他任務的基礎。

? ? ? ? 當然,對于上面的特征工程不是一步到位的,而是不斷的通過模型訓練的結果進行不斷的優化調整,直到最優的特征組合。

三、 baseline詳細解讀

1. 數據讀取

# 1. 導入需要用到的相關庫
# 導入 pandas 庫,用于數據處理和分析
import pandas as pd
# 導入 numpy 庫,用于科學計算和多維數組操作
import numpy as np
# 從 sklearn.tree 模塊中導入 DecisionTreeClassifier 類
# DecisionTreeClassifier 用于構建決策樹分類模型
from sklearn.tree import DecisionTreeClassifier# 2. 讀取訓練集和測試集
# 使用 read_csv() 函數從文件中讀取訓練集數據,文件名為 'train.csv'
train_data = pd.read_csv('用戶新增預測挑戰賽公開數據/train.csv')
# 使用 read_csv() 函數從文件中讀取測試集數據,文件名為 'test.csv'
test_data = pd.read_csv('用戶新增預測挑戰賽公開數據/test.csv')

2. 特征構造

(1)對'udmap' 列進行 One-Hot 編碼?

# 數據樣例:
#                    udmap  key1  key2  key3  key4  key5  key6  key7  key8  key9
# 0           {'key1': 2}     2     0     0     0     0     0     0     0     0
# 1           {'key2': 1}     0     1     0     0     0     0     0     0     0
# 2  {'key1': 3, 'key2': 2}   3     2     0     0     0     0     0     0     0
# 具體實現代碼:
# 定義函數 udmap_onethot,用于將 'udmap' 列進行 One-Hot 編碼
def udmap_onethot(d):v = np.zeros(9)  # 創建一個長度為 9 的零數組if d == 'unknown':  # 如果 'udmap' 的值是 'unknown'return v  # 返回零數組d = eval(d)  # 將 'udmap' 的值解析為一個字典for i in range(1, 10):  # 遍歷 'key1' 到 'key9'if 'key' + str(i) in d:  # 如果當前鍵存在于字典中v[i-1] = d['key' + str(i)]  # 將字典中的值存儲在對應的索引位置上return v  # 返回 One-Hot 編碼后的數組# 使用 apply() 方法將 udmap_onethot 函數應用于每個樣本的 'udmap' 列
# np.vstack() 用于將結果堆疊成一個數組
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)))
# 為新的特征 DataFrame 命名列名
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 = pd.concat([train_data, train_udmap_df], axis=1)
test_data = pd.concat([test_data, test_udmap_df], axis=1)

(2)?編碼 udmap 是否為空

# 使用比較運算符將每個樣本的 'udmap' 列與字符串 'unknown' 進行比較,返回一個布爾值的 Series
# 使用 astype(int) 將布爾值轉換為整數(0 或 1),以便進行后續的數值計算和分析
train_data['udmap_isunknown'] = (train_data['udmap'] == 'unknown').astype(int)
test_data['udmap_isunknown'] = (test_data['udmap'] == 'unknown').astype(int)

?(3)提取 eid 的頻次特征和標簽特征

# 使用 map() 方法將每個樣本的 eid 映射到訓練數據中 eid 的頻次計數
# train_data['eid'].value_counts() 返回每個 eid 出現的頻次計數
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())# 使用 groupby() 方法按照 eid 進行分組,然后計算每個 eid 分組的目標值均值
# train_data.groupby('eid')['target'].mean() 返回每個 eid 分組的目標值均值
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())

?(4)提取時間戳

# 使用 pd.to_datetime() 函數將時間戳列轉換為 datetime 類型
# 樣例:1678932546000->2023-03-15 15:14:16
# 具體實現代碼:
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')# 使用 dt.hour 屬性從 datetime 列中提取小時信息,并將提取的小時信息存儲在新的列 'common_ts_hour'
train_data['common_ts_hour'] = train_data['common_ts'].dt.hour
test_data['common_ts_hour'] = test_data['common_ts'].dt.hour


3. 模型訓練

????????加載決策樹模型進行訓練(直接使用sklearn中導入的包進行模型建立);

????????對測試集進行預測,并保存結果到result_df中;

????????保存結果文件到本地

clf = DecisionTreeClassifier()
# 使用 fit 方法訓練模型
# train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1) 從訓練數據集中移除列 'udmap', 'common_ts', 'uuid', 'target'
# 這些列可能是特征或標簽,取決于數據集的設置
# train_data['target'] 是訓練數據集中的標簽列,它包含了每個樣本的目標值
clf.fit(train_data.drop(['udmap', 'common_ts', 'uuid', 'target'], axis=1),  # 特征數據:移除指定的列作為特征train_data['target']  # 目標數據:將 'target' 列作為模型的目標進行訓練
)# 9. 對測試集進行預測,并保存結果到result_df中
# 創建一個DataFrame來存儲預測結果,其中包括兩列:'uuid' 和 'target'
# 'uuid' 列來自測試數據集中的 'uuid' 列,'target' 列將用來存儲模型的預測結果
result_df = pd.DataFrame({'uuid': test_data['uuid'],  # 使用測試數據集中的 'uuid' 列作為 'uuid' 列的值'target': clf.predict(test_data.drop(['udmap', 'common_ts', 'uuid'], axis=1))  # 使用模型 clf 對測試數據集進行預測,并將預測結果存儲在 'target' 列中
})# 10. 保存結果文件到本地
# 將結果DataFrame保存為一個CSV文件,文件名為 'submit.csv'
# 參數 index=None 表示不將DataFrame的索引寫入文件中
result_df.to_csv('submit.csv', index=None)

?四、后續提升方案

1. 構建交叉訓練框架

def cv_model(clf, train_x, train_y, test_x, clf_name, seed = 23):folds = 5kf = KFold(n_splits=folds, shuffle=True, random_state=seed)oof = np.zeros(train_x.shape[0])test_predict = np.zeros(test_x.shape[0])cv_scores = []for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):print('************************************ {} ************************************'.format(str(i+1)))trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]if clf_name == "cat":params = {'learning_rate': 0.03, 'depth': 6, 'bootstrap_type':'Bernoulli','random_seed':2023,'od_type': 'Iter', 'od_wait': 100, 'random_seed': 23, 'allow_writing_files': False, 'task_type' : 'GPU'}model = clf(iterations=20000, **params, eval_metric='F1')model.fit(trn_x, trn_y, eval_set=(val_x, val_y),metric_period=100,use_best_model=True, cat_features=[],verbose=1)val_pred  = model.predict_proba(val_x)[:,1]test_pred = model.predict_proba(test_x)[:,1]oof[valid_index] = val_predtest_predict += test_pred / kf.n_splitsF1_score = f1_score(val_y, [1 if prob >= 0.5 else 0 for prob in val_pred])cv_scores.append(F1_score)print(cv_scores)return oof, test_predict

2. 特征篩選

(1)相關性

? ? ? ? 通過統計單個特征與目標變量之間的相關性,選取相關性較高的特征。

(2)遞歸特征消除

? ? ? ? 通過遞歸地擬合模型并去除對模型性能貢獻較小的特征,直到達到所需的特征數量

(3)特征重要性

? ? ? ? 通過查看模型內部的特征重要性指標

(4)具有空重要性的特征選擇

? ? ? ? 使用目標排列的特征選擇過程測試與噪聲(混洗目標)擬合時特征重要性分布的實際重要性顯著性。

Feature Selection with Null Importances | Kaggle

強烈推薦此方案?

3. 特征交叉

? ? ? ? 選取特征重要性排名靠前進行特征交叉,可以選擇排名靠前的特征組合來構建新的特征,從而增強模型的表現。

4. 模型調參

? ? ? ? 機器學習和深度學習中,通過調整模型的超參數來優化模型性能。超參數是在模型訓練之前設置的參數,它們不會在訓練過程中自動學習,而需要手動選擇。

? ? ? ? 一般常用的調參方法:

? ? ? ? a. 網格搜索(Grid Search):遍歷所有超參數的組合,逐一嘗試。雖然它是全面搜索,但在超參數空間較大時計算代價較高。

? ? ? ? ?b. 隨機搜索(Random Search):隨機從超參數空間中抽取組合進行嘗試。相比網格搜索,它的計算代價較低,但可能需要更多的嘗試次數。

? ? ? ? ?c. 貝葉斯優化(Bayesian Optimization):通過構建超參數組合的概率模型,根據模型對性能的估計來選擇最有可能改善性能的組合。

? ? ? ? ?d. 遺傳算法(Genetic Algorithms):借鑒自然進化的原理,通過基因交叉和變異等方式逐漸優化超參數組合。

? ? ? ? 網格搜索一般在數據量很大時不建議使用,會導致迭代的次數很多,而無法跑出最優的參數組合。強烈建議使用貝葉斯優化進行模型調參

5. 特征構造

? ? ? ? (1)eid存在多個數據樣本,可以進行mean,max,min,std,skew等數據的統計。

? ? ? ? (2)補充完整頻次特征和標簽特征;

? ? ? ? (3)提取更多的時間信息;

? ? ? ? (4)對label進行閾值調整

?6. stacking集成

? ? ? ? stacking是一種分層模型集成框架。以兩層為例,第一層由多個基學習器組成,其輸入為原始訓練集,第二層的模型則是以第一層基學習器的輸出作為特征加入訓練集進行再訓練,從而得到完整的stacking模型。

五、降低內存方法

????????比賽按照上面的baseline會讀取較大的數據內存,因此在此處放入一個降低內存的方法:

? ? ? ? 通過減少數字列的數據類型并將對象列轉換為分類類型來優化 DataFrame 'train_df' 的內存使用量,從而減少內存使用量。

predictor_columns = [col for col in test_df.columns if col not in ['uuid','time','file']]
def reduce_mem_usage(df):start_mem = df.memory_usage().sum() / 1024**2print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))for col in tqdm.tqdm(predictor_columns):col_type = df[col].dtypeif col_type != object:c_min = df[col].min()c_max = df[col].max()if str(col_type)[:3] == 'int':if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:df[col] = df[col].astype(np.int8)elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:df[col] = df[col].astype(np.int16)elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:df[col] = df[col].astype(np.int32)elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:df[col] = df[col].astype(np.int64)else:if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:df[col] = df[col].astype(np.float16)elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:df[col] = df[col].astype(np.float32)else:df[col] = df[col].astype(np.float64)else:df[col] = df[col].astype('category')end_mem = df.memory_usage().sum() / 1024**2print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))return dftrain_df = reduce_mem_usage(train_df)

?https://datawhaler.feishu.cn/docx/HBIHd7ugzoOsMqx0LEncR1lJnCf

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42501.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42501.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42501.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

S-Video端口接口芯片ESD保護方案圖

在音/視頻領域&#xff0c;除了常見的HDMI、DVI接口等&#xff0c;還有一些冷門的接口&#xff0c;比如S-Video端口&#xff0c;相信很多人可能都沒有聽說過。S-Video視頻端口同樣擁有較好的數據傳輸功能。S-Video二分量視頻端口&#xff0c;英文全稱Separate Video&#xff0c…

Macbook 終端 git 命令補全和提示

Mac OS自帶的終端&#xff0c;用起來雖然有些不太方便&#xff0c;界面也不夠友好&#xff0c;關鍵是在windows上用習慣了自動補全功能&#xff0c;在Mac上一個個的拼寫單詞是真的難受&#xff0c;逼著我記英文單詞。 經過一天的磨合&#xff0c;我實在忍不了&#xff0c;在網上…

復習vue3,簡簡單單記錄

這里的知識是結合視頻以及其他文章一起學習&#xff0c;僅用于個人復習記錄 ref 和reactive ref 用于基本類型 reactive 用于引用類型 如果使用ref 傳遞對象&#xff0c;修改值時候需要寫為obj.value.attr 方式修改屬性值 如果使用reactive 處理對象&#xff0c;直接obj.att…

Lua學習記錄

Lua基礎了解 Lua的注釋通過 (-- 單行注釋&#xff0c;--[[ ]] 多行注釋)可以不加&#xff1b; 多個變量賦值&#xff0c;按順序賦值&#xff0c;沒有則為nil&#xff1b; function的簡單用法&#xff0c;多個返回值配合多重賦值&#xff0c;以end為結束標志 Lua下標從1開始&…

JSP-學習筆記

文章目錄 1.JSP介紹2 JSP快速入門3 JSP 腳本3.1 JSP腳本案例3.2 JSP缺點 4 EL表達式4.1 快速入門案例 5. JSTL標簽6. MVC模式和三層架構6.1 MVC6.2 三層架構 7. 案例-基于MVC和三層架構實現商品表的增刪改查 1.JSP介紹 概念 JSP&#xff08;JavaServer Pages&#xff09;是一種…

Azure存儲賬戶

存儲賬戶的概念 Azure存儲賬戶是Azure提供的一種云存儲解決方案&#xff0c;用于存儲和訪問各種類型的數據&#xff0c;包括文件、磁盤、隊列、表格和Blob&#xff08;二進制大對象&#xff09;數據。存儲賬戶可以基于訪問模式和冗余需求來選擇不同的類型&#xff0c;以滿足應…

【MySQL--->表的操作】

文章目錄 [TOC](文章目錄) 一、創建表二、查看表三、修改表四、刪除表drop table 表名; ![在這里插入圖片描述](https://img-blog.csdnimg.cn/15227b8335364d41bd01b4b4dd83ee55.png) 一、創建表 語句格式:create table 表名(列名 類型,…)字符集 校驗規則 存儲引擎;字符集和校…

我還不知道?Android組件化插件化模塊化

Android組件化、插件化和模塊化是針對Android應用程序開發的一種架構設計思想和開發方式。 組件化&#xff08;Componentization&#xff09;&#xff1a; 組件化是將一個大型的Android應用程序拆分成多個獨立的組件&#xff08;Module&#xff09;&#xff0c;每個組件可以獨…

python使用裝飾器記錄方法耗時

思路 python使用修飾器記錄方法耗時&#xff0c;目的是每當方法執行完后&#xff0c;可以記錄該方法耗時&#xff0c;而不需要在每個方法的執行前后&#xff0c;去創建一個臨時變量&#xff0c;來記錄耗時。 方式一&#xff08;不推薦&#xff09;&#xff1a; 在每個方法的…

source insight 添加宏-文件頭加注釋

source insight 3.5 自帶的一些宏&#xff0c;在安裝目錄下的 utils.em 文件中&#xff0c;用戶也可以自己寫文件&#xff0c;命令為xxx.em &#xff0c;然后把這個文件添加到項目中即可&#xff0c;添加后在菜單欄 Options -> Key Assignments 里輸入macro 就能顯示新添加的…

第一個ArkTS項目實踐-鴻蒙ArkTS

第一個ArkTS項目實踐-ArkTS 第一個ArkTS項目實踐-ArkTS自定義組件的組成配置屬性與布局配置屬性布局 改變組件狀態循環渲染列表數據代碼ToDoItem組件ToDoList頁面 效果參考資料 第一個ArkTS項目實踐-ArkTS 本篇文章是官網上視頻對ArkTS開發實踐的第一個視頻&#xff0c;主要是引…

Matplotlib數據可視化(三)

目錄 1.繪圖的填充 1.1 曲線下方區域的填充 1.2 填充部分區域 1.3 兩條曲線之間的區域填充 1.4 直接使用fill進行填充 1.繪圖的填充 繪圖的填充可以調用fill_between()或fill()進行填充。 1.1 曲線下方區域的填充 x np.linspace(0,1,500) y np.sin(3*np.pi*x)*np.exp…

【C語言】每日一題(找到所有數組中消失的數字)

找到所有數組中消失的數字&#xff0c;鏈接奉上。 這里簡單說一下&#xff0c;因為還沒有接觸到動態內存&#xff0c;數據結構&#xff0c;所以知識有限&#xff0c;也是盡力而為&#xff0c;結合題庫的評論區找到了適合我的解法&#xff0c;以后有機會&#xff0c;會補上各種…

如何在HTML中使用React

突發奇想 查了查真的可以,官方文檔: 在網站中添加 React – React 開始 引入js <!-- 開發環境使用 --><script src"https://unpkg.com/react18/umd/react.development.js"></script><script src"https://unpkg.com/react-dom18/umd/reac…

穿越數字奇境:探尋元宇宙中的科技奇跡

隨著科技的迅速發展&#xff0c;元宇宙正逐漸成為一個備受關注的話題&#xff0c;它不僅是虛擬現實的延伸&#xff0c;更是將現實世界與數字世界融合的未來典范。在這個神秘而充滿活力的數字奇境中&#xff0c;涉及了眾多領域和技術&#xff0c;為我們呈現出了一個無限的創新和…

創建Azure資源鎖

鎖的介紹 在Azure中&#xff0c;資源鎖是一種用于保護訂閱、資源組或者單個資源的機制。它可以防止對受鎖定的資源進行刪除或修改操作&#xff0c;幫助確保資源的連續可用性和安全性。 Azure中的資源鎖可以分為兩種類型&#xff1a; 刪除鎖&#xff08;CanNotDelete&#xf…

elementUI遇到的問題記錄

一、 組件&#xff1a;el-table 問題&#xff1a;使用動態數據創建多級表頭后&#xff0c;刷新頁面時&#xff0c;table行會串行&#xff0c;某些列丟失&#xff0c;圖片列未顯示圖片 解決方案&#xff1a;給el-table增加key <el-table :key"${Matn.random()}${ite…

javaScript:模板字符串讓你忘記字符串拼接

目錄 一.前言 二.模板字符串的使用 1.介紹 2.模板字符串 支持換行 模板字符串更適合元素寫入 innerHTML模板字符串寫法 3.模板字符串中&#xff0c;可以運行表達式 4.模板字符串中可以運行函數 三.總結 語法&#xff1a; 多行字符串&#xff1a; 變量插值&#xff1a; …

μCOS-Ⅲ_簡介

μCOS-Ⅲ簡介 文章目錄 μCOS-Ⅲ簡介前言一、什么是 C/OS-III&#xff1f;二、C/OS-III的特點三、C/OS-III的版本和參考資料1、C/OS-III版本2、C/OS-III源碼獲取3、C/OS-III參考資料 四、C/OS-III源碼簡介總結 前言 μcos-III是一個可以基于ROM運行的、可裁剪的、搶占式、實時…

uniapp Vue 使用 sip.js進行語音通話視頻通話

下載或者安裝 sip.js 到 uniapp 項目&#xff0c;APP 端在 menifest.json 中配置麥克風權限 menifest.json 中 app 權限配置選中&#xff1a; android.permission.RECORD_AUDIO android.permission.MODIFY_AUDIO_SETTINGS sip.js 低版本 如 V0.13.0 版本的寫法 <template&…