• Python数据分析案例04——超高维数据的降维(随机森林)、特征工程


    本次带来的案例是高维数据的处理,以及降维,使用随机森林降维和分类。

    本次数据长这个样子,没有特征名称。

     只有最后一列是0和1 ,代表响应变量y,这是一个二分类问题。其他前面都是x。

    需要这代码演示数据的同学可以参考:数据

    首先导入包,读取数据的时候给每个变量命个名称,从var1到var250:

    1. import numpy as np
    2. import pandas as pd
    3. import matplotlib.pyplot as plt
    4. import seaborn as sns

     读取数据,给训练集和测试集都命名

    1. names=['var'+str(i+1) for i in range(250)]
    2. data=pd.read_csv('train.csv',header=None,names=names)
    3. data2=pd.read_csv('test.csv',header=None,names=names)

    如果有一行全为空值就删除

    1. data.dropna(how='all',inplace=True)
    2. data2.dropna(how='all',inplace=True)

    查看训练集数据

    data

     可以看到数据有74900条,250维特征,算是高维数据了。


    继续清洗,降维

    首先取值唯一的变量都删除,就是这一列的特征全为一样的数值的话就删除,因为值都是一样的,这个特征对于分类就没帮助

    1. #取值唯一的变量都删除
    2. for col in data.columns:
    3. if len(data[col].value_counts())==1:
    4. print(col)
    5. data.drop(col,axis=1,inplace=True)

     打印了一下删除的变量的名称。

    然后将文本型的数据都删掉,平时对于文本类数据可以要处理一下,比如独热编码之类的,但是数据维度很高,直接扔了也没损失很多信息

    data=data.select_dtypes(include=['float64'])

    然后将缺失值过多的列删除,这里阈值是74000,就是说一个列特征的缺失值达到900条的特征就删除

    data=data.dropna(thresh=74000,axis=1)

    查看数据

    data

     从250维度降到146,继续


     观察缺失值

    1. #观察缺失值
    2. import missingno as msno
    3. %matplotlib inline
    4. msno.matrix(data)

    可以看到缺失值不算很多了,那就直接填充,取上一个值填充空值

    data.fillna(method='pad',axis=1,inplace=True)

     然后将上面挑选出来的特征给测试集也做一些同样的处理

    1. data2=data2[data.columns[:-1]]
    2. data2=data2.fillna(method='pad',axis=1)

    下面开始用机器学习的方法降维。


    开始机器学习

    划分X和y

    1. y=data.iloc[:,-1]
    2. X=data.iloc[:,:-1]
    3. X.shape,y.shape

    145个特征

     划分训练验证集

    1. from sklearn.model_selection import train_test_split
    2. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=0)

    数据归一化

    1. from sklearn.preprocessing import MinMaxScaler
    2. scaler =MinMaxScaler()
    3. scaler.fit(X_train)
    4. X_train_s = scaler.transform(X_train)
    5. X_test_s = scaler.transform(X_test)
    6. #x=scaler.transform(data2)
    1. #row_id2=data2.iloc[:,0]
    2. X2=data2.iloc[:,:]
    3. scaler =MinMaxScaler()
    4. X3=np.vstack((X,X2))
    5. scaler.fit(X3)
    6. X_s = scaler.transform(X)
    7. X2_s = scaler.transform(X2)

    先用逻辑回归试一试分类效果

    1. #逻辑回归
    2. from sklearn.linear_model import LogisticRegression
    3. model = LogisticRegression(C=1e10,max_iter=1e6)
    4. model.fit(X_train_s, y_train)
    5. model.score(X_test_s, y_test)

    准确率很高

    然后使用随机森林分类

    1. #随机森林
    2. from sklearn.ensemble import RandomForestClassifier
    3. model = RandomForestClassifier(n_estimators=1000, max_features='sqrt',random_state=123)
    4. model.fit(X_train_s, y_train)
    5. model.score(X_test_s, y_test)

     

     准确率直接100%了。。。

    然后对测试集集预测,然后保存

    1. pred = model.predict(X2_s)
    2. df = pd.DataFrame(columns=['target'])
    3. #df['row_id']=row_id2
    4. df['target']=pred
    5. df.to_csv('predict_result.csv',header=False,index=False)

    下面我们在不降低准确率的情况下对数据进行筛选,首先画出变量的重要性排序图

    1. model.feature_importances_
    2. sorted_index = model.feature_importances_.argsort()
    3. plt.barh(range(X_train.shape[1]), model.feature_importances_[sorted_index])
    4. plt.yticks(np.arange(X_train.shape[1]), X_train.columns[sorted_index])
    5. plt.xlabel('Feature Importance')
    6. plt.ylabel('Feature')
    7. plt.title('Random Forest')
    8. plt.tight_layout()

     由于特征太多了,直接密密麻麻看不清.....大体上我们看的出来是第一个特征对分类的帮助很大,其他特征的重要性则没那么高。

    我们查看一些排序后的变量名称和各种的重要性

    1. var_names=X_train.columns[sorted_index][::-1]
    2. var_weight=model.feature_importances_[sorted_index][::-1]
    3. #imf_weight[0]=1
    4. var_names,var_weight

     

     可以看到最重要的变量是var249.

    我们可以设置一个阈值,变量重要性小于这个阈值就不要这个变量

    1. 重要变量=var_names[var_weight>0.002]
    2. 重要变量的系数=var_weight[:len(重要变量)]

    然后筛选出来的变量应用到训练集和测试集上

    1. X_train=X_train.loc[:,重要变量]
    2. X_test=X_test.loc[:,重要变量]

    然后数据标准化,再进行随机森林分类

    1. scaler2 =MinMaxScaler()
    2. scaler2.fit(X_train)
    3. X_train_s = scaler2.transform(X_train)
    4. X_test_s = scaler2.transform(X_test)
    5. #随机森林
    6. from sklearn.ensemble import RandomForestClassifier
    7. model = RandomForestClassifier(n_estimators=1000, max_features='sqrt',random_state=123)
    8. model.fit(X_train_s, y_train)
    9. model.score(X_test_s, y_test)

     还是100%,说明我们筛选掉了一些变量,但是模型的准确率没有下降。

    然后将筛选出来的变量去保存

    1. model.feature_importances_
    2. sorted_index = model.feature_importances_.argsort()
    3. var_names=X_train.columns[sorted_index][::-1]
    4. var_weight=model.feature_importances_[sorted_index][::-1]
    5. var_names,var_weight
    6. var=pd.DataFrame()
    7. var['重要变量']=var_names
    8. var['重要变量的重要性程度']=var_weight
    9. var.to_csv('筛选变量.csv',index=False,encoding='gbk')
    1. df=data[var_names].to_csv('训练集筛选的X变量.csv',index=False)
    2. df2=data2[var_names].to_csv('测试集筛选的X变量.csv',index=False)

    这样就达到了降维的目的。


    当然也可以使用sklearn里面的SelectFromModel可以便捷一点。

    1. from sklearn.feature_selection import SelectFromModel
    2. model = RandomForestClassifier(n_estimators=5000, max_features=int(np.sqrt(X.shape[-1])), random_state=0)
    3. model.fit(X,y)
    4. selection =SelectFromModel(model,threshold=0.002,prefit=True)
    5. select_X=selection.transform(X)
    6. select_X.shape

    这样可以直接把筛选出来的X应用到训练集上,还可以运用到测试集上,也可以很方便的查看筛选出来的变量

    1. print(selection.get_support())
    2. print(selection.get_support(True))
    3. [columns[i] for i in selection.get_support(True)]

    创作不易,看官觉得写得还不错的话点个关注和赞吧,本人会持续更新python数据分析领域的代码文章~(需要定制代码可私信)

  • 相关阅读:
    爬虫与反爬虫技术简介
    【先楫HPM6750系列】移植轻量级AI推理框架——TinyMaix
    Python:每日一题之最少砝码
    搜维尔科技:Movella Xsens MVN LINK 实际应用,一镜到底!
    Web APIs:事件高级--DOM事件流及DOM事件流程代码验证
    新年学新语言Go之二
    eslint+stylelint+prettier全流程配置
    距平图(标签-AR)
    Verasity Tokenomics — 社区讨论总结与下一步计划
    C#实现根据字体名称获取字体文件名
  • 原文地址:https://blog.csdn.net/weixin_46277779/article/details/126402547