kaggle工业蒸汽

数据信息

工业蒸馏数据

import库函数

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline

数据读取

# 数据集路径
test_data_file = "./zhengqi_test.txt"
train_data_file = "./zhengqi_train.txt"

# 读取数据
train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8')
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8')

# 得到没有NAN值,并且数据有三十八个特征,一个标签
# 因为数据标签没有显示,所以无法主观判断数据之间的关系
train_data.info()#38个特征一个标签
train_data.describe()

箱线图

def box_map(Data):
    """画出Data的所有的特征标签对应的箱线图"""
    #指定画布大小:
    plt.figure(figsize=(18, 10))
    #确定数据和画的标签列表
    plt.boxplot(Data.values, labels=Data.columns)
    #设置一些直线参数
    plt.hlines([-7.5, 7.5], 0, 40, "red")
"""
箱线图另一种画法:
#取出每个特征的标签,以便画图
column = Data.columns.tolist()[:39]
# 指定绘图对象宽度和高度
fig = plt.figure(figsize=(20, 40))  
for i in range(38):
    # 一张画布画13行3列
    plt.subplot(13, 3, i + 1)
    sns.boxplot(Data[column[i]]# 数据
                , orient="v"# “v”|“h” 用于控制图像使水平还是竖直显示
                , width=0.5)  # 箱式图
    # 添加标签名称
    plt.ylabel(column[i], fontsize=8)
"""
# 画出箱线图
box_map(train_data)
# 我们发现还是有很多在误差上下界外的数据(异常点),所以说我们要将这些数据删除掉

请添加图片描述

箱线图解释连接

在这里插入图片描述

获取并删除异常值

from sklearn.metrics import mean_squared_error

# model使用那个模型寻找异常值。train_data,sigma为阈值
# 就是用残差的分布转化成标准正态分布,残差在正态分布sigma外的数据为异常数据
def find_outliers(model, train_data, sigma=3):
    ALLX = train_data.iloc[:, 0:-1]
    ALLY = train_data.iloc[:, -1]
    """使用model来见到的预测每一个标签值,若差距过大,就删除该条数据"""
    plt.figure(figsize=(15, 3 * 38))# 38个标签特征
    # 对于每一个特征值都进行删除异常值操作
    for i, eachName in enumerate(ALLX.columns):
        print("this is "+str(eachName)+" situation:")
        _y = ALLX.loc[:, eachName]# 被预测的特征数据
        _X = ALLX.drop(eachName, axis=1)# 用于模型训练的数据
        model.fit(_X, _y)
        y_pred = pd.Series(model.predict(_X), index=_y.index)
        from sklearn.metrics import r2_score
        
        #捕捉的信息量比例(不能反了)
        R2=r2_score(model.predict(_X),_y)
        print("均方误差MSE:{}, R^2:{}".format(round(mean_squared_error(_y, y_pred), 4), round(R2, 4)))
        
        # 残差值
        resid = _y - y_pred
        # 残差值均值
        resid_mean = resid.mean()
        # 计算标准差啊
        resid_std = resid.std()
        
       
        print("残差均值resid_mean:{}, 残差标准差resid_std:{}".format(round(resid_mean, 4), round(resid_std, 4)))

        # 残差标准化成正态分布,就是公式: F(x)=Φ[(x-μ)/σ]
        z = (resid - resid_mean) / resid_std

        # 异常值位置(真实值和预测值偏离程度较大,大于sigma倍标准差)
        outliers = z[abs(z) > sigma].index # 取横向坐标索引便于删除异常值数据
        print("异常值索引outlier index:", outliers.tolist())
        
        # *******************可视化异常值(呈现正相关性越好)*****************

        # ---------------真实和预测数据之间的关系----------------
        # 创建ax_1子图
        ax_1 = plt.subplot(38, 3, i * 3 + 1)
        # 画出真实值和预测值,用“.”代表样本,颜色默认
        plt.plot(_y, y_pred, ".", label="Accepted")
        # 将异常值数据进行单独标出,用红色标出,有外轮廓
        plt.plot(_y.loc[outliers], y_pred[outliers], "ro", label="Outlier")
        # y轴为预测值
        plt.ylabel("y_pred")
        # x轴为真实值
        plt.xlabel("true_y of " + eachName)
        plt.legend()

        # ---------------残差 越靠近零值越好----------------
        ax_2 = plt.subplot(38, 3, i * 3 + 2)
        # 画出残差点
        plt.plot(_y, _y - y_pred, ".", label="Accepted")
        # 画出异常值数据的残差点
        plt.plot(_y.loc[outliers], _y.loc[outliers] - y_pred.loc[outliers], "ro", label="Outlier")
        plt.ylabel("residual")
        plt.xlabel("true_y of " + eachName)
        plt.legend()

         # ---------------绘制直方图,样本分布----------------
        ax_3 = plt.subplot(38, 3, i * 3 + 3)
        # 样本分箱50,颜色蓝色
        ax_3.hist(z, bins=50, facecolor="blue")
        # 异常值搞成红色
        ax_3.hist(z.loc[outliers], bins=50, facecolor="red")
        plt.legend(["Accepted", "Outlier"])
        plt.xlabel("distribution of " + eachName)
        if R2 > 0.7:
            # 根据异常值将样本数据异常值点删除
            ALLX = ALLX.drop(outliers)
            ALLY = ALLY.drop(outliers)

    # 自动进行子图缩进
    plt.tight_layout()
       # 返回删除异常值的train_data
    data=pd.concat([ALLX,ALLY],axis=1)
    data.index=list(range(data.shape[0]))
    return data


from sklearn.linear_model import Ridge
train_data=find_outliers(Ridge(),train_data, sigma=3)

那么得到的数据在正态分布上就是一下两个图的组合,sigma就是图中的z
在这里插入图片描述
在这里插入图片描述
样本删除可视化后:
请添加图片描述
删除后的箱线图:虽然还有很多
在这里插入图片描述

是否符合正态分布

def prob_kde(train_data):
    """画出样本分布,和Q-Q图"""
    train_cols = 6 # 一行三个特征
    train_rows = len(train_data.columns)# 特征个数
    # 4个单位一个图,纵:4 * train_cols 横:需要train_rows / 3行
    plt.figure(figsize=(4 * train_cols, 4 * train_rows / 3))

    i = 0
    for col in train_data.columns[:-1]:
        dat =  train_data[[col, "target"]].dropna()
        i += 1
        ax = plt.subplot(train_rows / 3, train_cols, i)
        # seaborn中的函数distplot画出分布密度函数以及核密度函数,默认参数直方图hist=True 核函数kde=True
        sns.distplot(dat[col], fit=stats.norm)# 拟合stats.norm正态分布
        plt.title("skew=" + "{:.4f}".format(stats.skew(dat[col])))#计算偏态问题质数
        """ skewness = 0 : normally distributed.
            skewness > 0 : more weight in the left tail of the distribution.
            skewness < 0 : more weight in the right tail of the distribution. """
        
        i += 1
        ax = plt.subplot(train_rows / 3, train_cols, i)
        # scipy.stats中的函数 能Q-Q图,越靠近直线越服从正态分布
        res = stats.probplot(dat[col], plot=plt)
        # 计算相关系数
        plt.title("corr=" + "{:.2f}".format(np.corrcoef(dat[col], dat["target"])[0][1]))
    plt.tight_layout()

训练数据和测试数据的分布关系

def train_test_kde(train_data, test_data, columns):
    # 一行六张图,六个特征
    dist_cols = 6
    dist_rows = len(test_data.columns)
    # 创建7行空间,一个字图为正方形,4个单位像素
    plt.figure(figsize=(4 * dist_cols, 4 * 7))
    i = 1
    for col in columns:
        ax = plt.subplot(7, dist_cols, i)
        # 训练数据核密度函数
        sns.kdeplot(train_data[col], color="red", shade=True,label="train")
        # 测试数据核密度函数
        sns.kdeplot(test_data[col], color="blue", shade=True,label="test")
        # 添加特征名称
        plt.xlabel(col)
        # 纵坐标
        plt.ylabel("Frequence")
        plt.legend()
        i += 1
    plt.tight_layout()
    
#看train_data和test_data中标签对应的数据是否分布相似,
# 若不相似会导致模型非泛化能力变差,需要删除此类特征。
train_test_kde(train_data,test_data,X_train.columns)

请添加图片描述

#特征变量V5,V9,V11,V17,V22,V28在训练集和测试集中的数据分布不一致,所以要删除特征数据
drop_columns=["V5","V9","V11","V17","V22","V28"]
# 指定删除columns特征,覆盖原数据
train_data.drop(columns = drop_columns, inplace=True)
test_data.drop(columns = drop_columns, inplace=True)

训练和测试数据归一化正态化

数据分布情况:

def prob_kde(train_data):
    """画出样本分布,和Q-Q图"""
    train_cols = 6 # 一行三个特征
    train_rows = len(train_data.columns)# 特征个数
    # 4个单位一个图,纵:4 * train_cols 横:需要train_rows / 3行
    plt.figure(figsize=(4 * train_cols, 4 * train_rows / 3))

    i = 0
    for col in train_data.columns[:-1]:
        dat =  train_data[[col, "target"]].dropna()
        i += 1
        ax = plt.subplot(train_rows / 3, train_cols, i)
        # seaborn中的函数distplot画出分布密度函数以及核密度函数,默认参数直方图hist=True 核函数kde=True
        sns.distplot(dat[col], fit=stats.norm)# 拟合stats.norm正态分布
        plt.title("skew=" + "{:.4f}".format(stats.skew(dat[col])))#计算偏态问题质数
        """ skewness = 0 : normally distributed.
            skewness > 0 : more weight in the left tail of the distribution.
            skewness < 0 : more weight in the right tail of the distribution. """
        
        i += 1
        ax = plt.subplot(train_rows / 3, train_cols, i)
        # scipy.stats中的函数 能Q-Q图,越靠近直线越服从正态分布
        res = stats.probplot(dat[col], plot=plt)
        # 计算相关系数
        plt.title("corr=" + "{:.2f}".format(np.corrcoef(dat[col], dat["target"])[0][1]))
    plt.tight_layout()
 
# 然后看每个特征数据是否符合标准正态分布
prob_kde(train_data)
# 从图中可以看出:
# 基本所有数据存在偏态问题,其中特征V9 V18 V23 V24 存在较为严重的偏态问题

请添加图片描述

# 未解决数据偏态问题,我们对于每个特征数据进行标准化,可视化:
# 预先进行归一化操作(全部数据,建议在数据量比较大的时候进行处理)
from sklearn.preprocessing import MinMaxScaler
def func_mms(train,test):
    # 取出需要归一化的特征
    cols_numeric = test.columns
    # 创建归一化方法
    # 对train,test进行数据训练
    train_data_process = pd.DataFrame(MinMaxScaler().fit_transform(train[cols_numeric]), columns=cols_numeric)
    test_data_process = pd.DataFrame(MinMaxScaler().fit_transform(test[cols_numeric]), columns=cols_numeric)
    return  pd.concat([train_data_process, train_data["target"]], axis=1),test_data_process


#调用归一化函数
train_data,test_data=func_mms(train_data,test_data)

stats.boxcox正态化:

for var in test_data.columns:
    train_data[var], lambda_var = stats.boxcox(train_data[var].dropna() + 1)  # 数值只能是正值
    test_data[var], lambda_var = stats.boxcox(test_data[var].dropna() + 1)  # 数值只能是正值
prob_kde(train_data)

请添加图片描述

多重共线性

通过热力图查看

train_corr = train_data.corr()# 生成关系矩阵
plt.figure(figsize=(20, 16))
sns.heatmap(train_corr, vmax=0.8, square=True, annot=True)#热力图

颜色越浅共线性越强:
请添加图片描述

#我们取出和便签["target"]相关系数最高的十个特征
#columns参数就是和标签target相关系数最高的十个特征,组成(10,train_corr.shape[0])矩阵
#然后取出最大值特征相对于taregt的数据组成pandas.Series数据nlargest_f
nlargest_f = train_corr.nlargest(10, columns="target")["target"]
cols = nlargest_f.index
plt.figure(figsize=(10, 10))
sns.heatmap(train_data[cols].corr(), annot=True, square=True)
#除了主对角线之外,其他的部分颜色越浅,代表相关性系数越高,多重共线性更加明显。

在这里插入图片描述

通过多重共线性方差膨胀因子查看

from statsmodels.stats.outliers_influence import variance_inflation_factor #多重共线性方差膨胀因子
cols=train_data.columns
X=np.matrix(train_data[cols])
VIF_list=[variance_inflation_factor(X, i) for i in range(X.shape[1])]
#VIF_list就是膨胀因子

方差膨胀因子的解释
请添加图片描述
PCA解决多重线性问题:
不过这里效果不好,没使用

# from sklearn.decomposition import PCA   #主成分分析
# #PCA方法降维处理多重共线性
# #保持90%的信息
# pca = PCA(n_components=0.95)
# new_train_data = pca.fit_transform(train_data.iloc[:,0:-1])
# new_test_data = pca.transform(test_data)
# new_train_data = pd.DataFrame(new_train_data)
# new_test_data = pd.DataFrame(new_test_data)
# new_train_data['target'] = train_data['target']
# new_train_data.describe()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

「 25' h 」

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

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

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

打赏作者

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

抵扣说明:

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

余额充值