0.机器学习-数据预处理

一.标准化

二.归一化

三.二值化

四.独热编码与标签编码

一.标准化

1.什么是标准化?

标准化指的是将数据按比例缩放,使之落入一个小的特定区间。在大多数情况下,这个区间是[0, 1],但有时也可以是[-1, 1]。标准化后的数据的平均值为0,标准差为1。

标准化通常使用以下公式进行:

z=(x−μ)/σ

其中,x是原始数据,μ是数据的均值,σ是数据的标准差,z是标准化后的数据。

目的:使不同特征具有相同的尺度,便于算法处理

在机器学习中,标准化数据时应使用训练集的统计信息来处理所有数据集(包括验证集和测试集),以避免数据泄漏并保持一致性。

2.案例

案例1:(方法一:手搓)将"[[1,2,3,4],[9,8,7,6],[11,12,11,44]]"该组数据标准化

import pandas as pd
data=pd.DataFrame([[1,2,3,4],[9,8,7,6],[11,12,11,44]])
column=["特征1","特征2","特征3","特征4"]
index=["数据1","数据2","数据3"]
data.columns=column
data.index=index
print(data)
data_mean=data.mean()  #每一列特征的平均值
data_std=data.std()    #每一列特征的标准差
data1=data-data_mean
data2=data1/data_std   #标准化后的数据
print(data2.round(2))
     特征1  特征2  特征3  特征4
数据1    1    2    3    4
数据2    9    8    7    6
数据3   11   12   11   44
      特征1   特征2  特征3   特征4
数据1 -1.13 -1.06 -1.0 -0.62
数据2  0.38  0.13  0.0 -0.53
数据3  0.76  0.93  1.0  1.15

案例1:(方法二:调用sklearn库)将"[[1,2,3,4],[9,8,7,6],[11,12,11,44],[10,10,10,10]]"该组数据标准化

import pandas as pd
from sklearn.preprocessing import StandardScaler
#数据导入
data=pd.DataFrame([[1,2,3,4],[9,8,7,6],[11,12,11,44],[10,10,10,10]])
column=["特征1","特征2","特征3","特征4"]
index=["数据1","数据2","数据3","数据4"]
data.columns=column
data.index=index
print(data)

#创建标准化实例,训练集与测试集的划分
scaler=StandardScaler()
x_train=data[:3]
x_test=data[3:4]

#计算x_train的均值与标准差,并保存统计信息
scaler.fit(x_train)

#使用保存的统计信息,来标准化x_train,x_text,data
order_train=scaler.transform(x_train)
order_test=scaler.transform(x_test)
order_data=scaler.transform(data)

#输出标准化后的order_train,order_test,order_data
print("标准化后的训练集:\n",order_train.round(2))
print("标准化后的测试集:\n",order_test.round(2))
print("标准化后的原数据:\n",order_data.round(2))

#打印出原数据的均值与标准差,既在调用fit方法时存储下来的
print("标准化前原数据的均值:",scaler.mean_.round(2))   #均值
print("标准化前原数据的标准差:",scaler.scale_.round(2))  #标准差
print("标准化后数据的均值:",order_data.mean(axis=0).round(2))
print("标准化后数据的标准差:",order_data.std(axis=0).round(2))
     特征1  特征2  特征3  特征4
数据1    1    2    3    4
数据2    9    8    7    6
数据3   11   12   11   44
数据4   10   10   10   10
标准化后的训练集:
 [[-1.39 -1.3  -1.22 -0.76]
 [ 0.46  0.16  0.   -0.65]
 [ 0.93  1.14  1.22  1.41]]
标准化后的测试集:
 [[ 0.69  0.65  0.92 -0.43]]
标准化后的原数据:
 [[-1.39 -1.3  -1.22 -0.76]
 [ 0.46  0.16  0.   -0.65]
 [ 0.93  1.14  1.22  1.41]
 [ 0.69  0.65  0.92 -0.43]]
标准化前原数据的均值: [ 7.    7.33  7.   18.  ]
标准化前原数据的标准差: [ 4.32  4.11  3.27 18.4 ]
标准化后数据的均值: [ 0.17  0.16  0.23 -0.11]
标准化后数据的标准差: [0.92 0.91 0.95 0.89]

二.归一化

1.什么是归一化?

归一化是将数据按比例缩放,以使其落入一个指定的最小到最大值的范围内。最常见的归一化范围是 [0, 1]。

归一化通常使用以下公式进行:

x′=(x−x_min)/(x_max−x_min)​​

其中,x是原始数据,x_min是数据的最小值,x_max是数据的最大值,x′是归一化后的数据。

目的:防止不同量纲的特征对模型结果产生过大影响

2.案例

案例1:(调用sklearn库)

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
data=pd.DataFrame([
    [25,175,79,0],
    [21,169,75,1],
    [22,155,72,0]])
print(data)
#创建归一化实例
mms=MinMaxScaler((0,1))#括号里的参数改为取值范围
#计算最大值最小值,并进行归一化处理
new_data=pd.DataFrame(mms.fit_transform(data))
print(new_data)

#预测
text_data=np.array([21,122,73,1]).reshape(1,-1)
print(mms.transform(text_data))
#反推
try_data=np.array([1,1,1,1]).reshape(1,-1)
print(mms.inverse_transform(try_data))
    0    1   2  3
0  25  175  79  0
1  21  169  75  1
2  22  155  72  0
      0    1         2    3
0  1.00  1.0  1.000000  0.0
1  0.00  0.7  0.428571  1.0
2  0.25  0.0  0.000000  0.0
[[ 0.         -1.65        0.14285714  1.        ]]
[[ 25. 175.  79.   1.]]

三.二值化

1.什么是二值化?

二值化(Binarization)是数据预处理中的一种技术,它将数据转换为仅包含两个值的数据,通常是0和1。这种转换通常基于一个阈值,数据点根据是否超过这个阈值被分类为0或1。二值化在各种应用中都很有用,特别是在特征工程中,当需要将连续变量转换为分类变量时。

公式:

x是原始数据,t是阈值,x′是二值化后的数据。 

目的:简化数据,将连续变量转换为离散变量。

2.案例

案例1(方法1:手搓)

import numpy as np
data=np.array([
    [20,30,40,50],
    [10,29,405,60],
    [30,406,406,30]
    ],dtype="float32")
#法一
new_data=data.copy()
new_data=np.where(new_data>=45,1,0)
print(new_data)
"""
法二:
new_data[new_data>=45]=1
new_data[new_data<=45]=0
"""
[[0 0 0 1]
 [0 0 1 1]
 [0 1 1 0]]

案例1(方法2:调用sklearn库)

from sklearn.preprocessing import Binarizer
import numpy as np
data=np.array([
    [20,30,40,50],
    [10,29,405,60],
    [30,406,406,30]
    ],dtype="float32")
#创建二值化实例,并设置阈值为50
bin=Binarizer(threshold=50)#大于阈值
#进行二值化
new_data=bin.fit_transform(data)
print(new_data)
[[0. 0. 0. 0.]
 [0. 0. 1. 1.]
 [0. 1. 1. 0.]]

四.编码类别特征

1.独热编码

1.什么是独热编码?

独热编码(One-Hot Encoding)是一种处理分类数据的常用技术,特别是在机器学习中。它将分类变量的不同类别转换为二进制(0或1)的形式,每个类别对应一个唯一的二进制向量。这种编码方式使得机器学习算法能够更好地理解和处理分类数据,尤其是那些处理数值数据的算法.

设有数据为:

3        4        5

3        2        5

1        3        4

独热编码:每一列特征用不同的二进制表示,数位的个数为每一列的不同值数量

3:10        4:100        5:10

1:01        2:010        4:01

               3:001

编码后

10         100         10
10         010         10
01         001         01

2.案例

案例1:(方法1:手搓)

import numpy as np
data=np.array([1,2,3,4,5,8,7,5,3,1,3,3]).reshape(-1,3)
print(data)
c_data=data.copy()
list=[]
for col in data.T:
    dict={}
    for val in col:
        dict[val]=None
    list.append(dict)#利用字典的去重性
print(list)
for dict in list:
    size=len(dict)
    for index,key in enumerate(sorted(dict.keys())):
        dict[key]=np.zeros(shape=size,dtype=int)
        dict[key][index]=1
print(list)
list1=[]
for d in c_data:
    new_list=np.array([],dtype=int)
    for index,key in enumerate(d):
        new_list=np.hstack((new_list,list[index][key]))
    list1.append(new_list)
list1=np.array(list1)
print(list1)
[[1 2 3]
 [4 5 8]
 [7 5 3]
 [1 3 3]]
[{1: None, 4: None, 7: None}, {2: None, 5: None, 3: None}, {3: None, 8: None}]
[{1: array([1, 0, 0]), 4: array([0, 1, 0]), 7: array([0, 0, 1])}, {2: array([1, 0, 0]), 5: array([0, 0, 1]), 3: array([0, 1, 0])}, {3: array([1, 0]), 8: array([0, 1])}]
[[1 0 0 1 0 0 1 0]
 [0 1 0 0 0 1 0 1]
 [0 0 1 0 0 1 1 0]
 [1 0 0 0 1 0 1 0]]

案例1:(方法2:调用sklearn库)

from sklearn.preprocessing import OneHotEncoder
import numpy as np
data=np.array([1,2,3,4,5,8,7,5,3,1,3,3]).reshape(-1,3)
print(data)
#创建独热编码器
ohe=OneHotEncoder(sparse_output=False,dtype=int)
#计算独热编码
new_data=ohe.fit_transform(data)#先拟合后转换
print(new_data)
#反向解码
test_array=np.array([0,1,0,0,0,1,1,0]).reshape(1,-1)
try_=ohe.inverse_transform(test_array)
print(try_)
[[1 2 3]
 [4 5 8]
 [7 5 3]
 [1 3 3]]
[[1 0 0 1 0 0 1 0]
 [0 1 0 0 0 1 0 1]
 [0 0 1 0 0 1 1 0]
 [1 0 0 0 1 0 1 0]]
[[4 5 3]]

2.标签编码

1.什么是标签编码?

标签编码(Label Encoding)是一种将分类变量转换为整数的方法,通常用于将类别标签转换为从0开始的整数序列。这种方法在处理不平衡数据集时特别有用,因为它可以确保每个类别的权重相等。标签编码适用于有序特征,其中类别之间存在一定的顺序关系,但没有明确的意义

2.案例

案例1(方法1:调用sklearn库)

import numpy as np
from sklearn.preprocessing import LabelEncoder

data=np.array(["wo","we","w","ew","r","wo"])
#创建标签编码实例
lbe=LabelEncoder()
#计算,将每个标签用,从0开始的整数代替
data_=lbe.fit_transform(data)
print(data_)

#反向编码
da=[2,0,1]
da_=lbe.inverse_transform(da)
print(da_)
#使用原训练集的结果,进行编码,前提是所要编码的标签已被创建成功,不然会找不到数字进行代替,而出现保存
st="w we"
st_=st.split(" ")
print(st_)
st__=lbe.transform(st_)
print(st__)
[4 3 2 0 1 4]
['w' 'ew' 'r']
['w', 'we']
[2 3]

 五.特征工程-1逐步回归

#1.导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler

#2.设置显示选项
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
pd.set_option('display.max_rows', None)    #显示最大行数
pd.set_option('display.max_columns', None)  #显示最大列数
pd.set_option('display.max_colwidth', None)  #显示的最大列宽
pd.set_option('display.width', None)  #显示的最宽度

#3.导入数据
data=pd.read_excel("客户价值数据表.xlsx")
x=data.drop(["客户价值"],axis=1)  #去掉"客户价值这一列"
y=data["客户价值"]

#4.数据预处理
#4.1标准化
scaler = StandardScaler()
x=scaler.fit_transform(x)
x=pd.DataFrame(x,columns=["历史贷款金额","贷款次数","学历","月收入","性别"])
#4.2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

#5.建立模型
def stepwise_selection(X, y, initial_list=[], threshold_in=0.01, threshold_out=0.05, verbose=True):
    """
    逐步回归特征选择
    :param X: 特征数据(DataFrame)
    :param y: 目标变量(Series)
    :param initial_list: 初始特征列表
    :param threshold_in: 添加特征的显著性阈值
    :param threshold_out: 删除特征的显著性阈值
    :param verbose: 是否打印过程
    :return: 最终选择的特征列表
    """
    included = list(initial_list)
    while True:
        changed = False
        # 前向选择
        excluded = list(set(X.columns) - set(included))
        new_pval = pd.Series(index=excluded, dtype=float)
        for new_column in excluded:
            model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included + [new_column]]))).fit()
            new_pval[new_column] = model.pvalues[new_column]
        best_pval = new_pval.min()
        if best_pval < threshold_in:
            best_feature = new_pval.idxmin()
            included.append(best_feature)
            changed = True
            if verbose:
                print(f"Add {best_feature} with p-value {best_pval:.6f}")

        # 后向消除
        model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included]))).fit()
        pvalues = model.pvalues.iloc[1:]  # 忽略截距
        worst_pval = pvalues.max()
        if worst_pval > threshold_out:
            changed = True
            worst_feature = pvalues.idxmax()
            included.remove(worst_feature)
            if verbose:
                print(f"Remove {worst_feature} with p-value {worst_pval:.6f}")

        if not changed:
            break
    return included

# 运行逐步回归
selected_features = stepwise_selection(X_train, y_train)
# 输出最终选择的特征
print("最终选择的特征:", selected_features)

六.特征工程-2PCA主成分分析

主成分分析(Principal Component Analysis, PCA) 是一种常用的降维技术,通过线性变换将高维数据映射到低维空间,同时保留数据的主要信息。PCA 的目标是找到数据中方差最大的方向(主成分),并用这些方向来表示数据。

from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import numpy as np

# 1. 标准化数据
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# 2. 使用 PCA 降维
pca = PCA(n_components=2)  # 降维到 2 维
data_reduced = pca.fit_transform(data_scaled)

# 3. 输出结果
print("降维后的数据:\n", data_reduced)
print("解释方差比:\n", pca.explained_variance_ratio_)

七.特征工程-3随机森林特征重要性

#1.导入必备的库
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from scipy import stats
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score, KFold
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler
#2.设置显示选项
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
pd.set_option('display.max_rows', None)    #显示最大行数
pd.set_option('display.max_columns', None)  #显示最大列数
pd.set_option('display.max_colwidth', None)  #显示的最大列宽
pd.set_option('display.width', None)  #显示的最宽度
#3.导入数据
data=pd.read_excel("信用评分卡模型.xlsx")
#4.数据预处理
#4.1使用均值填写缺失值
print("缺失值统计:\n",data.isnull().sum())
data=data.apply(lambda col:col.fillna(col.mean()),axis=0)
#4.2处理异常值
numeric_data = data.select_dtypes(include=[np.number])
z_scores = np.abs(stats.zscore(data.select_dtypes(include=[np.number])))  # 仅对数值型数据计算 Z-score
threshold = 3  # Z-score 阈值 3个标准差
outliers = (z_scores > threshold).any(axis=1)  # 检测异常值
print("检测到的异常值行索引:\n", data[outliers].index.tolist())  # 输出异常值的行索引
print(data[outliers])
data = data[~outliers]  # 移除异常值
X=data.drop("信用评分",axis=1)
y=data["信用评分"]
#4.3将数据划分为训练集与测试集
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3,random_state=0)
#4.4创建标准化训练测试集与训练集
scaler=StandardScaler()
X_train=scaler.fit_transform(X_train)
X_test=scaler.transform(X_test)
#5.建立模型
Model = RandomForestRegressor(
    criterion='squared_error',  # 分裂标准(MSE)
    min_samples_leaf=2,         # 叶节点所需的最小样本数
    bootstrap=True,             # 使用 Bootstrap 采样
    oob_score=True,             # 使用袋外样本评估模型性能
    random_state=42,              # 固定随机种子
    n_jobs=-1,                  # 使用所有 CPU 核心
    # verbose=1                   # 输出训练进度
)
#5.1参数调优:网格搜索(数据量大时使用随机搜索)
cv = KFold(n_splits=5, shuffle=True, random_state=42)
param_grid = {
    'n_estimators': [50, 100, 200],     # 树的数量
    'max_depth': [None, 5, 10],         # 树的最大深度
    'min_samples_split': [2, 5],        # 分裂内部节点所需的最小样本数
    'max_features': ['sqrt', 'log2']    # 每棵树分裂时考虑的特征数
}
grid_search = GridSearchCV(
    estimator=Model,
    param_grid=param_grid,
    cv = cv,  # 5折交叉验证
    scoring='neg_mean_squared_error',  # 负均方误差(越大越好)
    n_jobs=-1,  # 使用所有CPU核心
)
grid_search.fit(X_train, y_train)
print("最佳参数组合:", grid_search.best_params_)
best_model = grid_search.best_estimator_
#5.2模型评估
cv_scores = cross_val_score(best_model, X_train, y_train,cv=cv, scoring='neg_mean_squared_error')
print(f"交叉验证 MSE: {-np.mean(cv_scores):.4f} (±{np.std(cv_scores):.4f})")
y_pred = best_model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"测试集 MSE: {mse:.4f}")
print(f"测试集 R²: {r2:.4f}")
#5.3模型特征重要性
feature_importances = pd.DataFrame(best_model.feature_importances_, index=X.columns)
feature_importances = feature_importances.sort_values(by=0,ascending=False)
print("\n特征重要性:")
print(feature_importances)
#6.可视化
plt.figure()
feature_importances.plot(kind='barh')
plt.title("Feature Importances")
plt.show()

八.模型选择

#1.导入必备的库
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from statsmodels.stats.outliers_influence import variance_inflation_factor
from sklearn.feature_selection import mutual_info_regression
#2.显示选项
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

"""
1.皮尔逊相关系数:用于衡量两个连续变量之间的线性关系,值范围在 -1 到 1 之间。
值接近 1 表示强正相关,接近 -1 表示强负相关,接近 0 表示无相关性。   
2.斯皮尔曼等级相关系数:用于衡量两个变量之间的单调关系,适用于非正态分布的数据。
3.肯德尔相关系数:另一种用于衡量两个变量之间的相关性的方法,适用于小样本数据。
"""
df=pd.read_excel("客户价值数据表.xlsx")
pearson = df.corr(method='pearson')  # 计算皮尔逊相关系数
spearman =df.corr(method='spearman') # 计算斯皮尔曼等级相关系数
kendall = df.corr(method='kendall')  # 计算肯德尔相关系数
correlation_matrices = [pearson, spearman, kendall]
names = ["pearson", "spearman", "kendall"]
# 遍历列表并绘制热力图
for matrix, name in zip(correlation_matrices, names):
    plt.figure(figsize=(10, 8))
    sns.heatmap(matrix, annot=True, fmt=".2f", cmap='coolwarm')
    plt.title(f"{name}相关性矩阵")
    plt.show()


#2.VIF 用于检测多重共线性,计算每个特征与其他特征的相关性。VIF 值越高,表示该特征与其他特征的相关性越强,通常 VIF > 10 被认为存在严重的多重共线性
# 计算 VIF
X = df.drop('客户价值', axis=1)  # 特征
vif = pd.DataFrame()
vif['特征'] = X.columns
vif['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print(vif)


# 互信息用于衡量两个变量之间的信息共享程度,适用于分类和连续变量。值越高,表示两个变量之间的相关性越强。
y=df["客户价值"]
mi = mutual_info_regression(X, y)
mi_scores = pd.Series(mi, index=X.columns)
print(mi_scores.sort_values(ascending=False))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恸流失

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值