您的位置:首页 > Web前端

特征探索性分析Exploring_features

2019-06-24 07:11 2006 查看

特征探索性分析
数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。那特征工程到底是什么呢?顾名思义,其本质是一项工程活动,目的是最大限度地从原始数据中提取特征以供算法和模型使用。通过总结和归纳,人们认为特征工程包括以下方面

  1. 加载数据
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split

dataset=pd.read_csv('heart.csv')
dataset.head(5)#查看前5个

X=dataset.iloc[:,0:-1]
Y=dataset.iloc[:,-1]
#对数据划分
X_train, X_test, y_train, y_test =train_test_split(X,Y,test_size=0.2,random_state=2019)
  1. 数据的描述性统计量分析
#观测0,1样本量,看样本量是否均衡
df=pd.DataFrame(y_train.value_counts())
df['percentage']=100*df['target']/y_train.shape[0]
df

输出结果如下:

由此可以看出样本基本平衡,如果说样本不平衡,则可以采用如下措施:
1 扩大数据集 :增加小样本
2 利用不是很敏感的指标评价分类器的优劣:如AUC,F1,ROC等;
3 对数据集进行重采样 :小类样本重复采样,大类样本少采样,欠采样
4 尝试不同的分类器:决策树有关的如随机森林对样本的平衡不是很敏感
5尝试对模型进行惩罚:增大小样本的惩罚,减小大样本的惩罚,如penalized-SVM和penalized-LDA算法。

#得到特征变量名
X_train.columns
#观测X_train里年龄的数量排前十的年龄
X_train.age.value_counts()[:10]

#看年龄的缺失情况
X_train.loc[X_train.age==-999999].shape

#将缺失值用0填充
X_train.replace(-999999,0)

#统计各个特征的缺失情况
col_total = X_train.isnull().sum().sort_values(ascending=False)#从大到小按顺序排每个特征缺失的个数
col_percent =(X_train.isnull().sum()/X_train.isnull().count()).sort_values(ascending=False)#从大到小按顺序排每个特征缺失率
#将X_train中每行为0的个数和作为一个新变量
X_train['n0']=(X_train==0).sum(axis=1)

#利用describe对trestbps连续变量描述性统计量分析
X_train.trestbps.describe()

#看target=1的trestbps描述统计量
train.loc[train['target']==1,'trestbps'].describe()
  1. 可视化数据
#借助seaborn包做可视化
import warnings # 一般seaborn中会出现warning,可以忽略
warnings.filterwarnings("ignore")
import seaborn as sns#seaborn 是python的一个可视化工具包
import matplotlib.pyplot as plt
sns.set(style="white", color_codes=True)
#直方图
X_train.age.hist(bins=100)
plt.xlabel('age')
plt.ylabel('number of heart patients')
plt.title('')
plt.show()

#画出年龄-是否心脏病患者直方图
train = pd.concat([X_train, y_train],axis=1)
sns.FacetGrid(train, hue="target", size=4).map(plt.hist, "age") \
.add_legend()
plt.title('relation between heart patients and age')
plt.show()

#密度图
sns.FacetGrid(train, hue="target", size=6).map(sns.kdeplot, "trestbps").add_legend()
plt.title('relation between heart patients and trestbps');
plt.show()

#双变量图
sns.pairplot(pd.concat([X_train,y_train],axis=1),hue='target',size=2,diag_kind='kde')
plt.show()

#箱图
pd.concat([X_train,y_train],axis=1).boxplot(by="target");
plt.show()

分别计算每个单变量的统计指标,删除未达标的变量
分类变量:卡方检验,f_classif, mutual_info_classif,互信息
连续变量:皮尔森相关系数,f_regression, mutual_info_regression,最大信息系数

#画散点图探究trestbps与chol的关系
sns.FacetGrid(train, hue="target", size=4).map(plt.scatter, 'chol',"trestbps").add_legend()
plt.title('interaction between heart chol and trestbps');
plt.show()

  1. **特征的筛选
    主要可以利用以下几种方式:
#方差法
from sklearn.feature_selection import VarianceThreshold

selector=VarianceThreshold(threshold=0.8*(1-0.8))
selector.fit(X)
print("Variances is %s"%selector.variances_)
print("After transform is %s"%selector.transform(X))
print("The surport is %s"%selector.get_support(True))

variance_selected_features = [ f for i,f in enumerate(X.columns) if  i in selector.get_support(True)]
X_V=X[variance_selected_features]
#发现fbs被移除

Variances is [8.22123321e+01 2.16449368e-01 1.06161705e+00 3.06571317e+02
2.67756065e+03 1.26458190e-01 2.75615680e-01 5.22914899e+02
2.19978433e-01 1.34364605e+00 3.78481412e-01 1.04227254e+00
3.73645285e-01]
After transform is [[63. 1. 3. … 0. 0. 1.]
[37. 1. 2. … 0. 0. 2.]
[41. 0. 1. … 2. 0. 2.]

[68. 1. 0. … 1. 2. 3.]
[57. 1. 0. … 1. 1. 3.]
[57. 0. 1. … 1. 1. 2.]]
The surport is [ True True True True True False True True True True True True True]

class_feat=['sex','cp','restecg','exang','slope','ca','thal']
X_class=X_V[class_feat]
X_regress=X_V.drop(class_feat,axis=1)
#利用sklearn中的feature_selection选择重要的特征变量

#离散变量采用卡方或F_classif
from sklearn.feature_selection import SelectPercentile ,SelectKBest
#SelectKBest 移除得分前 k 名以外的所有特征(取top k)
#SelectPercentile 移除得分在用户指定百分比以后的特征(取top k%)
from sklearn.feature_selection import f_classif,chi2
from sklearn.preprocessing import Binarizer, scale
k=5
selectChi2 = SelectKBest(chi2, k=k).fit(X_class, Y)
selectF_classif = SelectKBest(f_classif, k=k).fit(X_class, Y)
chi2_selected = selectChi2.get_support()
F_classif_selected=selectF_classif.get_support()
#chi2选择的特征
chi2_selected_features = [ f for i,f in enumerate(X_class.columns) if chi2_selected[i]]
print('Chi2 selected {} features {}.'.format(chi2_selected.sum(), chi2_selected_features))
#F_classif 选择的 特征
F_classif_selected_features=[f for i,f in enumerate(X_class.columns) if F_classif_selected[i]]
print('F_classif_selected {} features {}.'.format(F_classif_selected.sum(),F_classif_selected_features))

#选出chi2与F_classif的公共集
selected_features=set(chi2_selected_features)&set(F_classif_selected_features)
print('Chi2 & F_classif selected {} features{}'.format(len(selected_features),selected_features))

Chi2 selected 5 features [‘sex’, ‘cp’, ‘exang’, ‘slope’, ‘ca’].
F_classif_selected 5 features [‘cp’, ‘exang’, ‘slope’, ‘ca’, ‘thal’].
Chi2 & F_classif selected 4 features{‘ca’, ‘cp’, ‘slope’, ‘exang’}

#对于连续变量可以采用pearson相关系数或最大系数
from scipy.stats import pearsonr
pearsonr_df=pd.DataFrame([pearsonr(X_regress[feat],Y) for feat in X_regress.columns])
pearsonr_df.columns=['coeff','p_value']
pearsonr_df.index=X_regress.columns
#利用树选择模型
rf=RandomForestRegressor(max_depth=4,n_estimators=20)

scores=[]
for i in range(X.shape[1]):
score = cross_val_score(rf, X.iloc[:, i:i+1], Y,  # 注意X[:, i]和X[:, i:i+1]的区别
cv=ShuffleSplit(len(X),test_size=.3))
scores.append((format(np.mean(score), '.3f'), X.columns[i]))
print(sorted(scores, reverse=True))

[(‘0.252’, ‘thal’), (‘0.247’, ‘cp’), (‘0.211’, ‘ca’), (‘0.170’, ‘exang’), (‘0.124’, ‘slope’), (‘0.119’, ‘oldpeak’), (‘0.072’, ‘thalach’), (‘0.057’, ‘sex’), (’-0.066’, ‘trestbps’), (’-0.057’, ‘chol’), (’-0.043’, ‘age’), (’-0.024’, ‘fbs’), (’-0.001’, ‘restecg’)]
参考特征选择

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: