一些学习前的想法:
自己拿Kaggl上的金价数据做过简单的模型分析,发现SVM的表现效果非常不好,随机森林还行…想要重新把机器学习的部分再学习一遍,再学一学深度学习的部分。
如何确定用什么算法
没有任何的标签的时候,–clustering(无监督)
常用工具 sklearn
只需要造出XY后就可以自动fit
gensim
NumPy
pandas(数据清洗时频繁用到)
XGBoost
学习曲线
过拟合该怎么办?
增大样本量,增加正则化作用
经济金融实战案例
a.分类/回归器
1.Linear/nonLinear
y = α+β*Xi + 残差项
根据order norm 因子选取等等的不同产生各种变种:
LR LASSO…
b.决策树
类似于分治思想:
把数据集分成两组,通过entropy熵和informationGain信息增益来决定从哪个var开始搞分裂
不同数据点被完美区分开了吗?
不是:重复楼上两步
是的:打完收工
优势:
- 非黑盒
- 轻松去除无关attribute(gain = 0)
- test起来很块(O(depth))
量化交易目前还不能轻易使用深度学习(黑盒机制)
劣势:
- 只能线性分割数据
- 贪婪算法(可能找不到最好的树)(树枝中 谁在前谁在后的顺序改变会影响结果很大)
因此决策树是一个弱分类器。
把弱分类器ensemble集成为强分类器。
Bagging:类似于大多数人投票的方式
Random Forest:更加漂亮的bagging方式,多加了一层随机层
Boosting:把第一次学习时学的不好的地方多加一点权重,在下一次继续学习。
ensemble不是算法,只是一个算法框架。
房价预测案例
调用数据来自kaggle: house price 第一位
独热编码
当我们用numerical来表达categorical的时候,要注意,数字本身有大小的含义,所以乱用数字会给之后的模型学习带来麻烦。于是我们可以用one-hot的方法来表达category。
pandas自带的get_dummies方法,可以一键做到one-hot
标准化数据
这一步并不是必要。一般来说,regression分类器最好把源数据放在标准分布里,不要让数据间差距太大。
Ridge Regression
这里用Ridege Regression来跑的(对于多因子的数据集,这种模型可以方便的把所有的var都无脑放进去)
Stacking
把两种或多种模型的优点汲取
把最好的parameter拿出来,做成最终的model
一次正经的Ensemble是把几个model的预测结果作为新的input,再做一次预测,这里简单的直接平均化了。
模型进阶
Bagging
把很多的小分类器放在一起,每个train随机的一部分数据,然后把它们的最终结果综合起来(多数投票制)
Boosting
理论上稍微高级一些,也是揽来一把的分类器。但是把他们线性排列。下一个分类器把上一个分类器分类的不好的地方加上更高的权重,这样下一个分类器就能在这个部分学得更加“深刻”。
XGBoost
外号Kaggle神器。依旧是Boosting框架的模型,但是做了很多改进。
源代码:
import numpy as np
import pandas as pd
train_df = pd.read_csv('C:/documentstransfer/data analysis/house-prices-advanced-regression-techniques/train.csv',index_col=0)
test_df = pd.read_csv('C:/documentstransfer/data analysis/house-prices-advanced-regression-techniques/test.csv',index_col=0)
%matplotlib inline
prices = pd.DataFrame({"price":train_df["SalePrice"], "log(price + 1)":np.log1p(train_df["SalePrice"])})
prices.hist()
# 机器学习运用到了很多概率上的方法,数据集本身是偏着,所以结果也会偏,因此要对数据做一个标准化,使输出更符合正太分布
# 当然再现实中不能把测试集和训练集放在一起处理数据
# log(+1) 是为了防止出现price = 0的情况
# 最后计算结果时要把预测到的平滑数据变回去
y_train = np.log1p(train_df.pop('SalePrice')
all_df = pd.concat((train_df, test_df),axis=0)
# 变量转化/特征工程
# 读 data描述,其中有一个MSSubClass的特征,虽然用数字表示,但并没有数学意义上的大小关系比较
# 需要把他变成string
all_df['MSSubClass'] = all_df['MSSubClass'].astype(str)
# 一键one-hot
pd.get_dummies(all_df['MSSubClass'],
prefix='MSSubClass').head()
# 一共形成了12个分类的独热编码
# pandas 可以自动读取所有由分类表达的特征
all_dummy_df = pd.get_dummies(all_df)
all_dummy_df.head()
#先打印出来哪些数据缺失
all_dummy_df.isnull().sum().sort_values(ascending = False).head()
# 这里用平均值处理缺失值
mean_cols = all_dummy_df.mean()
all_dummy_df = all_dummy_df.fillna(mean_cols) # 填补空缺值
numeric_cols = all_df.columns[all_df.dtypes != 'object']
# 计算出每个numeric 的平均值和标准差,从而计算方程
numeric_col_means = all_dummy_df.loc[:,numeric_cols].mean()
numeric_col_std = all_dummy_df.loc[:,numeric_cols].std()
all_dummy_df.loc[:,numeric_cols] = (all_dummy_df.loc[:,numeric_cols] - numeric_col_means)/ numeric_col_std
dummy_train_df = all_dummy_df.loc[train_df.index]
dummy_test_df = all_dummy_df.loc[test_df.index]
from sklearn.linear_model import Ridge
from sklearn.model_selection import cross_val_score
# 这一步不是很必要,只是把DF转化成了Numpy Array,这跟sklearn更加配
X_train = dummy_train_df.values
X_test = dummy_test_df.values
# 用交叉验证测试模型选用哪一套
alphas = np.logspace(-3,2,50)
test_scores = []
for alpha in alphas:
clf = Ridge(alpha)
test_score = np.sqrt(-cross_val_score(clf,X_train,y_train,cv=10,scoring='neg_mean_squared_error'))
test_scores.append(np.mean(test_score))
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(alphas, test_scores)
plt.title("Alpha vs CV Error")
# 可见,大概alpha=10-20时,score接近0.135
from sklearn.ensemble import RandomForestRegressor
max_features = [.1, .3, .5, .7, .9, .99] #从10%--99%
test_scores = []
for max_feat in max_features:
clf = RandomForestRegressor(n_estimators=200, max_features=max_feat)
test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=5, scoring='neg_mean_squared_error'))
test_scores.append(np.mean(test_score))
plt.plot(max_features, test_scores)
plt.title("Max Features vs CV Error")
# 大约再max features = 0.5时达到了最优值 大约为0.137-0.138
ridge = Ridge(alpha=15)
rf = RandomForestRegressor(n_estimators=500,max_features=0.5)
ridge.fit(X_train, y_train)
rf.fit(X_train,y_train)
# 因为最前面给label做了个log(1+x),于是这里需要把predict的值给exp回去,并且减掉那个“1”
# 所以就是我们的expm1()函数
y_ridge = np.expm1(ridge.predict(X_test))
y_rf = np.expm1(rf.predict(X_test))
y_final = (y_ridge + y_rf)/2
# 平均化预测结果
submission_df = pd.DataFrame(data = {'Id': test_df.index, 'SalePrice':y_final})
# 模型进阶
# bagging把很多的小分类器放在一起,每个train随机的一部分数据,然后把他们的最终结果综合起来(多数投票制)
from sklearn.ensemble import BaggingRegressor
from sklearn.model_selection import cross_val_score
# 在刚才的实验中,ridge(alpha=15)是最好的结果
from sklearn.linear_model import Ridge
ridge = Ridge(15)
Jupyter Notebook
房价预测案例(七月kaggle)
(自动保存)
Current Kernel Logo
Python 3
File
Edit
View
Insert
Cell
Kernel
Widgets
Help
import numpy as np
import