有哪些網(wǎng)站建設(shè)工作本周新聞熱點(diǎn)
數(shù)據(jù)清洗
數(shù)據(jù)清洗是數(shù)據(jù)預(yù)處理的核心步驟,旨在修正或移除數(shù)據(jù)集中的錯(cuò)誤、不完整、重復(fù)或不一致的部分,為后續(xù)分析和建模提供可靠基礎(chǔ)。以下是數(shù)據(jù)清洗的詳細(xì)流程、方法和實(shí)戰(zhàn)示例:
一、數(shù)據(jù)清洗的核心任務(wù)
問題類型 | 表現(xiàn)示例 | 影響 |
---|---|---|
缺失值 | 數(shù)值型字段為空(NaN) | 模型無法處理缺失值,導(dǎo)致訓(xùn)練中斷或偏差 |
異常值 | 年齡=200歲,房?jī)r(jià)=-100萬 | 扭曲統(tǒng)計(jì)指標(biāo)(如均值),降低模型泛化性 |
重復(fù)數(shù)據(jù) | 兩行記錄完全相同 | 導(dǎo)致模型過擬合,降低數(shù)據(jù)代表性 |
不一致數(shù)據(jù) | 日期格式混亂(2023-09-01 vs 01/09/23) | 解析錯(cuò)誤,特征提取失敗 |
二、數(shù)據(jù)清洗流程與工具
1. 缺失值處理
-
檢測(cè)缺失值:
# 統(tǒng)計(jì)每列缺失比例 missing_ratio = data.isnull().mean() * 100 print(missing_ratio.sort_values(ascending=False))
-
處理方法:
方法 適用場(chǎng)景 代碼示例 直接刪除 缺失比例高(>80%)或無關(guān)字段 data.dropna(axis=1, thresh=len(data)*0.2)
均值/中位數(shù)填充 數(shù)值型字段,缺失隨機(jī)分布 data['age'].fillna(data['age'].median(), inplace=True)
眾數(shù)填充 類別型字段 data['gender'].fillna(data['gender'].mode()[0], inplace=True)
插值法 時(shí)間序列數(shù)據(jù)(如溫度記錄) data['temperature'].interpolate(method='time', inplace=True)
模型預(yù)測(cè)填充 復(fù)雜場(chǎng)景(如多變量關(guān)聯(lián)缺失) 使用KNN或隨機(jī)森林預(yù)測(cè)缺失值(見下方代碼) KNN填充示例:
from sklearn.impute import KNNImputer imputer = KNNImputer(n_neighbors=5) data_filled = pd.DataFrame(imputer.fit_transform(data), columns=data.columns)
2. 異常值處理
-
檢測(cè)方法:
- 描述性統(tǒng)計(jì):檢查最小/最大值是否合理
print(data.describe())
- 箱線圖(Boxplot):
plt.figure(figsize=(8,4)) sns.boxplot(x=data['income']) plt.title("Income Distribution") plt.show()
- Z-Score法(正態(tài)分布數(shù)據(jù)):
z_scores = (data['value'] - data['value'].mean()) / data['value'].std() outliers = data[abs(z_scores) > 3] # Z>3為異常
- IQR法(非正態(tài)分布數(shù)據(jù)):
Q1 = data['age'].quantile(0.25) Q3 = data['age'].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR
- 描述性統(tǒng)計(jì):檢查最小/最大值是否合理
-
處理方法:
方法 代碼示例 刪除異常值 data = data[(data['age'] >= 0) & (data['age'] <= 100)]
截?cái)?#xff08;Winsorize) from scipy.stats.mstats import winsorize<br>data['income'] = winsorize(data['income'], limits=[0.05, 0.05])
分箱(Binning) data['age_bin'] = pd.cut(data['age'], bins=[0,18,35,60,100])
3. 重復(fù)數(shù)據(jù)處理
-
檢測(cè)與刪除:
# 檢測(cè)完全重復(fù)的行 duplicates = data.duplicated() print(f"重復(fù)行數(shù)量: {duplicates.sum()}")# 刪除重復(fù)行(保留第一個(gè)出現(xiàn)值) data.drop_duplicates(keep='first', inplace=True)
-
部分重復(fù)處理(如用戶ID重復(fù)但信息不同):
# 按關(guān)鍵字段去重(如用戶ID) data.drop_duplicates(subset=['user_id'], keep='last', inplace=True)
4. 不一致數(shù)據(jù)修正
-
格式統(tǒng)一:
# 日期格式標(biāo)準(zhǔn)化 data['date'] = pd.to_datetime(data['date'], format='mixed')# 文本大小寫統(tǒng)一 data['category'] = data['category'].str.lower()# 單位統(tǒng)一(如貨幣轉(zhuǎn)換) data['price'] = data['price'].apply(lambda x: x * 6.5 if 'USD' in x else x )
-
邏輯校驗(yàn):
# 檢查年齡與出生日期是否一致 current_year = pd.Timestamp.now().year data['calculated_age'] = current_year - data['birth_year'] invalid_age = data[abs(data['age'] - data['calculated_age']) > 1]
三、實(shí)戰(zhàn)案例:電商訂單數(shù)據(jù)清洗
原始數(shù)據(jù)問題
import pandas as pd
data = pd.DataFrame({'order_id': [101, 102, 103, 104, 105, 106],'user_id': [1, 2, 2, 3, 4, None],'price': [29.9, 199.0, 199.0, -50.0, 89.9, 120.0],'order_date': ['2023-09-01', '01/09/2023', '2023-09-01', '2023-10-32', None, '2023-09-05']
})
清洗步驟
-
處理缺失值:
# 填充user_id缺失值(假設(shè)新用戶ID為999) data['user_id'].fillna(999, inplace=True)# 刪除order_date缺失的行 data.dropna(subset=['order_date'], inplace=True)
-
修正異常價(jià)格:
# 刪除價(jià)格為負(fù)的訂單 data = data[data['price'] > 0]# 截?cái)鄡r(jià)格超過200的訂單(假設(shè)業(yè)務(wù)上限為200) data['price'] = data['price'].clip(upper=200)
-
標(biāo)準(zhǔn)化日期格式:
# 轉(zhuǎn)換日期并過濾無效日期(如2023-10-32) data['order_date'] = pd.to_datetime(data['order_date'], errors='coerce') data.dropna(subset=['order_date'], inplace=True)
-
去重:
# 按user_id和order_date去重(保留最后一條) data.drop_duplicates(subset=['user_id', 'order_date'], keep='last', inplace=True)
清洗后數(shù)據(jù)
order_id | user_id | price | order_date |
---|---|---|---|
101 | 1 | 29.9 | 2023-09-01 |
102 | 2 | 199.0 | 2023-09-01 |
105 | 4 | 89.9 | NaT(已刪除) |
106 | 999 | 120.0 | 2023-09-05 |
四、注意事項(xiàng)
- 避免過度清洗:保留合理的數(shù)據(jù)多樣性(如正常的價(jià)格波動(dòng))。
- 記錄清洗日志:跟蹤每一步操作的影響(如刪除了多少行數(shù)據(jù))。
- 業(yè)務(wù)規(guī)則優(yōu)先:與領(lǐng)域?qū)<掖_認(rèn)異常定義(如“用戶年齡>100是否合理”)。
- 自動(dòng)化流水線:對(duì)持續(xù)更新的數(shù)據(jù),使用Pipeline封裝清洗步驟:
from sklearn.pipeline import Pipelineclean_pipeline = Pipeline([('fill_na', SimpleImputer(strategy='constant', fill_value=999)),('remove_duplicates', DropDuplicates(subset=['user_id'])),('clip_outliers', ColumnTransformer([('clip', FunctionTransformer(lambda x: x.clip(0, 200)), ['price'])])), ])
數(shù)據(jù)變換
以下是對(duì)數(shù)據(jù)變換的更緊湊、更細(xì)節(jié)化的總結(jié),突出核心要點(diǎn)與實(shí)用技巧:
一、標(biāo)準(zhǔn)化/歸一化:核心差異
方法 | 公式 | 適用場(chǎng)景 | 異常值敏感度 | Scikit-learn工具 |
---|---|---|---|---|
Z-score | z = x ? μ σ z = \frac{x - \mu}{\sigma} z=σx?μ? | 數(shù)據(jù)近似正態(tài)分布,線性模型(SVM、回歸) | 高 | StandardScaler |
Min-Max | x ′ = x ? x min ? x max ? ? x min ? x' = \frac{x - x_{\min}}{x_{\max} - x_{\min}} x′=xmax??xmin?x?xmin?? | 圖像像素、神經(jīng)網(wǎng)絡(luò)輸入層 | 高 | MinMaxScaler |
Robust | x ′ = x ? median I Q R x' = \frac{x - \text{median}}{IQR} x′=IQRx?median? | 存在異常值,非正態(tài)分布 | 低 | RobustScaler |
關(guān)鍵技巧:
- 樹模型(如隨機(jī)森林、XGBoost)無需標(biāo)準(zhǔn)化,但對(duì)特征組合敏感的模型(FM、NN)需要。
- 歸一化到[-1,1]可能對(duì)某些激活函數(shù)(如tanh)更友好。
二、非線性變換:快速選擇
- 對(duì)數(shù)變換:右偏數(shù)據(jù)(如收入),用
np.log1p
避免零值。 - Box-Cox變換:需數(shù)據(jù)嚴(yán)格為正,自動(dòng)優(yōu)化λ值(
scipy.stats.boxcox
)。 - 分位數(shù)變換:強(qiáng)制數(shù)據(jù)服從均勻/正態(tài)分布(
QuantileTransformer
)。
示例代碼:
from sklearn.preprocessing import PowerTransformer
pt = PowerTransformer(method='yeo-johnson') # 兼容零/負(fù)值
X_transformed = pt.fit_transform(X)
三、分類變量編碼:場(chǎng)景化方案
方法 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用模型 |
---|---|---|---|
One-Hot | 無順序假設(shè),兼容所有模型 | 高維稀疏,需處理共線性 | 線性模型、神經(jīng)網(wǎng)絡(luò) |
Target編碼 | 保留類別與目標(biāo)的關(guān)系 | 需防過擬合(如交叉驗(yàn)證) | 樹模型、高基數(shù)類別 |
Embedding | 低維稠密,捕捉語(yǔ)義相似性 | 需預(yù)訓(xùn)練或端到端學(xué)習(xí) | 深度學(xué)習(xí)(NLP/推薦系統(tǒng)) |
關(guān)鍵點(diǎn):
- 高基數(shù)類別優(yōu)先用
Target Encoding
或CatBoost
內(nèi)置處理。 - 樹模型可嘗試
Label Encoding
,但需驗(yàn)證類別順序是否合理。
四、特征工程:高效操作
- 數(shù)值特征:
- 交叉特征:加減乘除(如電商中“單價(jià)×購(gòu)買量=總金額”)。
- 分箱:等頻分箱(
pd.qcut
)或等寬分箱(pd.cut
),捕捉非線性。
- 時(shí)間特征:
- 提取周期性(星期、月份),滑動(dòng)窗口統(tǒng)計(jì)(均值、標(biāo)準(zhǔn)差)。
- 文本特征:
- 短文本用
TF-IDF
,長(zhǎng)文本用BERT
嵌入,高維稀疏時(shí)用TruncatedSVD
降維。
- 短文本用
代碼示例:
# 時(shí)間特征處理
df['hour'] = df['timestamp'].dt.hour
df['is_weekend'] = df['timestamp'].dt.weekday >= 5
五、降維:選擇策略
方法 | 核心思想 | 適用場(chǎng)景 | 注意事項(xiàng) |
---|---|---|---|
PCA | 線性投影最大化方差 | 高維數(shù)據(jù)可視化/去噪 | 需先標(biāo)準(zhǔn)化,可能丟失非線性信息 |
t-SNE | 非線性保留局部結(jié)構(gòu) | 可視化高維聚類 | 計(jì)算代價(jià)高,不用于特征輸入 |
UMAP | 平衡速度與局部/全局結(jié)構(gòu) | 大規(guī)模數(shù)據(jù)可視化/預(yù)處理 | 參數(shù)敏感,需調(diào)參 |
經(jīng)驗(yàn):
- 輸入特征>50時(shí)優(yōu)先用PCA,保留95%方差(
n_components=0.95
)。 - 避免對(duì)樹模型使用降維,可能破壞特征重要性。
六、避坑指南
- 數(shù)據(jù)泄露:
- 所有變換必須僅用訓(xùn)練集統(tǒng)計(jì)量!用
Pipeline
確保流程:from sklearn.pipeline import make_pipeline pipe = make_pipeline(StandardScaler(), SVM()) pipe.fit(X_train, y_train)
- 所有變換必須僅用訓(xùn)練集統(tǒng)計(jì)量!用
- 異常值處理:
- 縮尾處理(
np.clip
)或中位數(shù)填充,避免破壞分布。
- 縮尾處理(
- 評(píng)估驗(yàn)證:
- 對(duì)KNN、SVM等敏感模型,對(duì)比不同縮放方法的分類邊界(如決策邊界圖)。
七、端到端流程
- 輸入檢查:分布(直方圖/Q-Q圖)、缺失值、異常值。
- 數(shù)值特征:縮放→非線性變換→分箱。
- 分類特征:編碼→嵌入(可選)。
- 特征構(gòu)造:領(lǐng)域知識(shí)驅(qū)動(dòng)交叉/聚合。
- 輸出驗(yàn)證:模型在驗(yàn)證集的表現(xiàn)波動(dòng)是否<5%。
總結(jié):數(shù)據(jù)變換需與模型特性深度耦合,通過實(shí)驗(yàn)迭代優(yōu)化。記住:“Garbage in, garbage out”——寧可花80%時(shí)間在數(shù)據(jù)準(zhǔn)備,而非調(diào)參!
特征工程
特征工程:從原始數(shù)據(jù)到模型燃料的核心技術(shù)
特征工程是機(jī)器學(xué)習(xí)的“煉金術(shù)”,旨在將原始數(shù)據(jù)轉(zhuǎn)化為模型可理解的強(qiáng)特征,直接影響模型性能上限。以下是結(jié)構(gòu)化拆解:
一、核心目標(biāo)與價(jià)值
- 目標(biāo):構(gòu)造高信息量、低冗余、適配模型的特征。
- 價(jià)值:
- 提升模型準(zhǔn)確率(如添加用戶歷史行為統(tǒng)計(jì)特征)
- 降低計(jì)算成本(通過降維/特征選擇)
- 增強(qiáng)可解釋性(如分箱后的年齡組代替原始值)
二、特征構(gòu)造:從原始數(shù)據(jù)中“挖掘金子”
-
時(shí)間特征
- 基礎(chǔ)字段:年、月、日、小時(shí)、星期幾、是否節(jié)假日
- 衍生特征:時(shí)間間隔(如上次購(gòu)買距今的天數(shù))、滑動(dòng)窗口統(tǒng)計(jì)(過去7天均值)
df['purchase_hour'] = df['timestamp'].dt.hour df['days_since_last_purchase'] = (current_date - df['last_purchase_date']).dt.days
-
交互特征(組合特征)
- 數(shù)值交互:加減乘除(如“單價(jià)×數(shù)量=總價(jià)”)
- 類別交叉:笛卡爾積(如“地區(qū)×產(chǎn)品類型”生成組合標(biāo)簽)
df['price_per_sqmeter'] = df['total_price'] / df['area']
-
統(tǒng)計(jì)聚合特征
- 單維度統(tǒng)計(jì):用戶歷史購(gòu)買金額的均值、最大值、方差
- 跨表關(guān)聯(lián):訂單表按用戶ID聚合的訂單數(shù)、退貨率
user_stats = orders.groupby('user_id')['amount'].agg(['mean', 'max'])
-
文本/圖像特征
- 文本:TF-IDF關(guān)鍵詞權(quán)重、BERT句向量、情感分析得分
- 圖像:邊緣特征、顏色直方圖、預(yù)訓(xùn)練CNN提取的特征圖
三、特征變換:提升模型適配性
-
分箱(Binning)
- 等寬分箱:固定區(qū)間寬度(如年齡每10年一檔)
- 等頻分箱:保證每箱樣本量均衡
- 模型分箱:使用決策樹尋找最優(yōu)分割點(diǎn)
df['age_bin'] = pd.cut(df['age'], bins=[0,18,35,60,100], labels=['child', 'young', 'adult', 'senior'])
-
非線性變換
- 對(duì)數(shù)變換:處理右偏分布(
np.log1p
避免零值) - Box-Cox變換:自動(dòng)優(yōu)化正態(tài)性(僅適用于正值)
- 分位數(shù)變換:強(qiáng)制服從指定分布(如正態(tài)、均勻)
- 對(duì)數(shù)變換:處理右偏分布(
-
高基數(shù)類別處理
- 目標(biāo)編碼(Target Encoding):用目標(biāo)變量的統(tǒng)計(jì)量(如均值)代替類別
- 頻率編碼:使用類別出現(xiàn)頻率作為特征值
- 嵌入編碼(Embedding):通過神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)低維表示(如Word2Vec)
四、特征選擇:剔除噪聲與冗余
方法 | 原理 | 適用場(chǎng)景 |
---|---|---|
過濾法 | 基于統(tǒng)計(jì)指標(biāo)(如方差、卡方檢驗(yàn)) | 快速初篩,計(jì)算成本低 |
包裹法 | 通過模型性能迭代選擇特征子集 | 精確但計(jì)算代價(jià)高(遞歸特征消除) |
嵌入法 | 模型訓(xùn)練中自動(dòng)選擇(如L1正則化) | 與模型耦合,高效 |
實(shí)用技巧:
- 對(duì)樹模型,直接使用
feature_importances_
篩選重要性>閾值特征 - 對(duì)線性模型,結(jié)合Lasso回歸的系數(shù)稀疏性做特征剔除
五、自動(dòng)化特征工程工具
- FeatureTools:自動(dòng)生成跨表聚合特征(如“用戶最近3次登錄時(shí)間標(biāo)準(zhǔn)差”)
- TSFresh:針對(duì)時(shí)間序列自動(dòng)提取數(shù)百種統(tǒng)計(jì)特征(如自相關(guān)性、傅里葉變換系數(shù))
- AutoFeat:自動(dòng)構(gòu)造多項(xiàng)式特征并進(jìn)行顯著性篩選
# FeatureTools示例
import featuretools as ft
es = ft.EntitySet()
es = es.entity_from_dataframe(entity_id='users', dataframe=users_df, index='user_id')
features, feature_defs = ft.dfs(entityset=es, target_entity='users')
六、避坑指南與最佳實(shí)踐
-
避免數(shù)據(jù)泄露:
- 所有統(tǒng)計(jì)量(如Target Encoding的均值)必須僅從訓(xùn)練集計(jì)算!
- 使用
Pipeline
封裝預(yù)處理與模型訓(xùn)練:from sklearn.pipeline import Pipeline pipe = Pipeline([('encoder', TargetEncoder()), ('model', RandomForest())])
-
領(lǐng)域知識(shí)驅(qū)動(dòng):
- 在電商場(chǎng)景中,構(gòu)造“商品價(jià)格與類目平均價(jià)格的比值”可能比單純價(jià)格更有效
- 在風(fēng)控場(chǎng)景中,組合“申請(qǐng)時(shí)間與工作時(shí)段的重疊度”作為特征
-
迭代驗(yàn)證:
- 通過AB測(cè)試對(duì)比不同特征組合的模型性能
- 監(jiān)控特征穩(wěn)定性(如PSI指標(biāo))防止線上數(shù)據(jù)分布偏移
七、終極心法
- “Less is More”:優(yōu)先構(gòu)造10個(gè)強(qiáng)特征,而非100個(gè)弱特征。
- “Think Like a Model”:理解模型如何利用特征(如線性模型依賴線性可分性,NN偏好稠密低維輸入)。
- “Data First, Algorithm Second”:特征工程提升的上限遠(yuǎn)高于調(diào)參!
總結(jié):特征工程是融合領(lǐng)域知識(shí)、數(shù)據(jù)直覺與工程技巧的藝術(shù)。掌握核心方法后,需在業(yè)務(wù)場(chǎng)景中反復(fù)迭代,才能煉出“模型友好”的金牌特征。