[color=rgba(0, 0, 0, 0.3)]数据准备此处数据获取可参见金融数据准备。df.info()<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 1260 entries, 2015-12-31 to 2020-12-31
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Open 1260 non-null float64
1 High 1260 non-null float64
2 Low 1260 non-null float64
3 Close 1260 non-null float64
4 Adj Close 1260 non-null float64
5 Volume 1260 non-null int64
dtypes: float64(5), int64(1)
memory usage: 68.9 KB
特征构造df['H-L'] = df['High'] - df['Low']
df['O-C'] = df['Adj Close'] - df['Open']
df['3day MA'] = df['Adj Close'].shift(1).rolling(window=3).mean()
df['10day MA'] = df['Adj Close'].shift(1).rolling(window=10).mean()
df['30day MA'] = df['Adj Close'].shift(1).rolling(window=30).mean()
df['Std_dev'] = df['Adj Close'].rolling(5).std()
df.dtypes
描述性统计df.describe().T
缺失值分析检查缺失值df.isnull().sum()
Open 0
High 0
Low 0
Close 0
Adj Close 0
Volume 0
H-L 0
O-C 0
3day MA 3
10day MA 10
30day MA 30
Std_dev 4
dtype: int64
缺失值可视化这里使用Series的属性plot直接绘制条形图。df_missing_count = df.isnull().sum()
# -1表示缺失数据
# 另一个不常见的设置画布的方法
plt.rcParams['figure.figsize'] = (15,8)
df_missing_count.plot.bar()
plt.show()
for column in df:
print("column nunique NaN")
print("{0:15} {1:6d} {2:6}".format(
column, df[column].nunique(),
(df[column] == -1).sum()))
column nunique NaN
Open 1082 0
High 1083 0
Low 1025 0
Close 1098 0
Adj Close 1173 0
Volume 1250 0
H-L 357 0
O-C 1237 2
3day MA 1240 0
10day MA 1244 0
30day MA 1230 0
Std_dev 1252 0
特征间相关性分析import seaborn as sns
# 一个设置色板的方法
# cmap = sns.diverging_palette(220, 10,
as_cmap=True)
sns.heatmap(df.iloc[:df.shape[0]].corr()
,annot = True, cmap = 'Blues')
特征值分布直方图columns_multi = [x for x in list(df.columns)]
df.hist(layout = (3,4), column = columns_multi)
# 一种不常用的调整画布大小的方法
fig=plt.gcf()
fig.set_size_inches(20,9)
密度图names = columns_multi
df.plot(kind='density', subplots=True,
layout=(3,4), sharex=False)
特征间的关系函数可视化探索数据特征间的关系sns.pairplot(df, size=3,
diag_kind="kde")
特征重要性通过多种方式对特征重要性进行评估,将每个特征的特征重要的得分取均值,最后以均值大小排序绘制特征重要性排序图,直观查看特征重要性。导入相关模块from sklearn.feature_selection import RFE,RFECV, f_regression
from sklearn.linear_model import (LinearRegression, Ridge, Lasso,LarsCV)
from stability_selection import StabilitySelection, RandomizedLasso
from sklearn.preprocessing import MinMaxScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVR
线性回归系数大小排序回归系数(regression coefficient)在回归方程中表示自变量 对因变量 影响大小的参数。回归系数越大表示 对 影响越大。创建排序函数df = df.dropna()
Y = df['Adj Close'].values
X = df.values
colnames = df.columns
# 定义字典来存储的排名
ranks = {}
# 创建函数,它将特征排名存储到rank字典中
def ranking(ranks, names, order=1):
minmax = MinMaxScaler()
ranks = minmax.fit_transform(
order*np.array([ranks]).T).T[0]
ranks = map(lambda x: round(x,2), ranks)
res = dict(zip(names, ranks))
return res
多个回归模型系数排序# 使用线性回归
lr = LinearRegression(normalize=True)
lr.fit(X,Y)
ranks["LinReg"] = ranking(np.abs(lr.coef_), colnames)
# 使用 Ridge
ridge = Ridge(alpha = 7)
ridge.fit(X,Y)
ranks['Ridge'] = ranking(np.abs(ridge.coef_), colnames)
# 使用 Lasso
lasso = Lasso(alpha=.05)
lasso.fit(X, Y)
ranks["Lasso"] = ranking(np.abs(lasso.coef_), colnames)
随机森林特征重要性排序随机森林得到的特征重要性的原理是我们平时用的较频繁的一种方法,无论是对分类型任务还是连续型任务,都有较好对效果。在随机森林中某个特征X的重要性的计算方法如下:
- 对于随机森林中的每一颗决策树, 使用相应的OOB(袋外数据)数据来计算它的袋外数据误差 ,记为.
- 随机地对袋外数据OOB所有样本的特征X加入噪声干扰 (就可以随机的改变样本在特征X处的值), 再次计算它的袋外数据误差 ,记为.
- 假设随机森林中有 棵树,那么对于特征X的重要性,之所以可以用这个表达式来作为相应特征的重要性的度量值是因为:若给某个特征随机加入噪声之后,袋外的准确率大幅度降低,则说明这个特征对于样本的分类结果影响很大,也就是说它的重要程度比较高。
'Increase_Decrease','Buy_Sell_on_Open',
'Buy_Sell', 'Returns']]
y_1 = dataset['Adj Close']
# 创建决策树分类器对象
clf = RandomForestRegressor(random_state=0, n_jobs=-1)
# 训练模型
model = clf.fit(X_1, y_1)
# 计算特征重要性
importances = model.feature_importances_
# 按降序排序特性的重要性
indices = np.argsort(importances)[::-1]
# 重新排列特性名称,使它们与已排序的特性重要性相匹配
names = [dataset.columns for i in indices]
# 创建画布
plt.figure(figsize=(10,6))
# 添加标题
plt.title("Feature Importance")
# 添加柱状图
plt.bar(range(X.shape[1]), importances[indices])
# 为x轴添加特征名
plt.xticks(range(X.shape[1]), names, rotation=90)
分类型特征重要性当该任务是分类型,需要用分类型模型时,可以使用RandomForestClassifier中的feature_importances_属性。X2 = dataset[['Open', 'High', 'Low','Adj Close',
'Volume', 'Buy_Sell_on_Open',
'Buy_Sell', 'Returns']]
y2 = dataset['Increase_Decrease']
clf = RandomForestClassifier(random_state=0, n_jobs=-1)
model = clf.fit(X2, y2)
importances = model.feature_importances_
indices = np.argsort(importances)[::-1]
names = [dataset.columns for i in indices]
plt.figure(figsize=(10,6))
plt.title("Feature Importance")
plt.bar(range(X2.shape[1]), importances[indices])
plt.xticks(range(X2.shape[1]), names, rotation=90)
plt.show()
本案例中使用回归模型rf = RandomForestRegressor(n_jobs=-1, n_estimators=50, verbose=3)
rf.fit(X,Y)
ranks["RF"] = ranking(rf.feature_importances_, colnames);
下面介绍两个顶层特征选择算法,之所以叫做顶层,是因为他们都是建立在基于模型的特征选择方法基础之上的,例如回归和SVM,在不同的子集上建立模型,然后汇总最终确定特征得分。RandomizedLassoRandomizedLasso的选择稳定性方法排序。稳定性选择是一种基于二次抽样和选择算法相结合较新的方法,选择算法可以是回归、SVM或其他类似的方法。它的主要思想是在不同的数据子集和特征子集上运行特征选择算法,不断的重复,最终汇总特征选择结果,比如可以统计某个特征被认为是重要特征的频率(被选为重要特征的次数除以它所在的子集被测试的次数)。理想情况下,重要特征的得分会接近100%。稍微弱一点的特征得分会是非0的数,而最无用的特征得分将会接近于0。lambda_grid = np.linspace(0.001, 0.5, num=100)
rlasso = RandomizedLasso(alpha=0.04)
selector = StabilitySelection(base_estimator=rlasso, lambda_name='alpha',
lambda_grid=lambda_grid, threshold=0.9, verbose=1)
selector.fit(X, Y)
# 运行随机Lasso的选择稳定性方法
ranks["rlasso/Stability"] = ranking(np.abs(selector.stability_scores_.max(axis=1)), colnames)
print('finished')
{'Open': 1.0, 'High': 1.0, 'Low': 0.76,
'Close': 1.0, 'Adj Close': 0.99, 'Volume': 0.0,
'H-L': 0.0, 'O-C': 1.0, '3day MA': 1.0,
'10day MA': 0.27, '30day MA': 0.75, 'Std_dev': 0.0}
finished
稳定性得分可视化fig, ax = plot_stability_path(selector)
fig.set_size_inches(15,6)
fig.show()
查看得分超过阈值的变量索引及其得分# 获取所选特征的掩码或整数索引
selected_variables = selector.get_support(indices=True)
selected_scores = selector.stability_scores_.max(axis=1)
print('Selected variables are:')
print('-----------------------')
for idx, (variable, score) in enumerate(
zip(selected_variables,
selected_scores[selected_variables])):
print('Variable %d: [%d],
score %.3f' % (idx + 1, variable, score))
Selected variables are:
-----------------------
Variable 1: [0], score 1.000
Variable 2: [1], score 1.000
Variable 3: [3], score 1.000
Variable 4: [4], score 0.990
Variable 5: [7], score 1.000
Variable 6: [8], score 1.000