机器学习从入门到创业手记-应用与实践
结束了sklearn的培训的同时也迎来了阶段考核,经过这段时间的学习除了发我对机器学习有所入门,另外也发现了高维已经天天和刘思聪出双入对了,但两个人均矢口否认两人的关系,由于刘思聪坐我旁边,我也时常听他在上班时间和他那个正牌女友煲电话,我还让路思帮我旁敲侧击的问了高维,高维也说只是在北京人生地不熟,刘思聪尽一下地主之谊而已,让我别想太多了,但每个周末去约她,她都说忙。路思劝我:你别那么傻了,人家图你什么啊,要什么没什么。我说:我将来会也会去创业的,也能挣钱买房的。路思:人家没空等你这样的空头支票的,咱们还是应付好阶段考核吧,不然就得提前出局了。。
考核由李里出题,考核前大家先坐在一起开了个沟通会,李里:现在公司已经到了B轮融资的时刻,曙光就在眼前,希望大家珍惜眼前的机会,努力成为公司的骨干,到时期权股份少不了的。
我:能讲讲公司现在到底都做什么产品么?咱们有自己的技术么?
李里:恩,技术很重要,但现在大环境做产品的思路重点都在模仿,低价,营销上了,技术可以不断迭代,重要的如注册数,日活量等才是公司活下去的指标。
我:如果我想靠机器学习创业,您认为做哪个方面比较好?
李里:这个我没法回答你,我也没有经验,但做产品一定要找到用户的痛点,这个痛点不是你坐在那里想出来的,而是你在生活工作中自然而然形成而被发掘出来的,好了,创业这个论题太大了,你有空可以参加David王或者产品经理的会议,去了解一下如何发掘客户痛点,现在先考试。
考试题目:根据数据集中的内容建立算法模型,完成对目标结果的预测。数据集见图3.4.4.1,这里需要根据西瓜的各个属性判断出该西瓜是否为好瓜。
图3.4.4.1
我拿到题后先分析了一下各个属性,编号字段是用来索引数据的,对最终目标没有影响需要去掉,密度和含糖率都是浮点类型的数据,取值范围都在0到1之间,所以也需要标准化和归一化操作,好瓜字段是需要确定的目标值,而剩下的色泽,根蒂等字段都是分类型数据,需要进行先编码成色泽{乌黑,浅白,青绿…}这样的分类字段再用One-Hot编码,而目标字段只有是和否两个值,所以可以用二值编码处理。所以先要完成数据读取和预处理部分的代码。
数据读取与预处理部分的代码:
import pandas as pd #将数据库中的数据导入 CSVPATH = './data/xigua.csv' df_data = pd.read_csv(CSVPATH,encoding='utf-8') #获取每个字段的名称 CSV_COLUMNS = [] for name in df_data.columns: CSV_COLUMNS.append(name)
from sklearn import preprocessing #对分类型字段进行One-Hot编码 enc = preprocessing.LabelEncoder() for i in range(1,7): df_data[CSV_COLUMNS[i]] = enc.fit_transform(df_data[CSV_COLUMNS[i]])
#对结果字段进行二值编码 enc = preprocessing.LabelBinarizer() df_data[CSV_COLUMNS[9]] = enc.fit_transform(df_data[CSV_COLUMNS[9]]) #打印数据 print (df_data) |
进过数据预处理后,数据集变为图3.4.4.2,这里距离可以用来训练还需要将index字段去除,将result字段提取出来作为训练目标。
图3.4.4.2
去除index字段与分离result到目标字段,使用随机森林结合网格搜索超参数的方案进行训练与验证。
#去除index与result字段,构建训练数据 data =df_data.drop([CSV_COLUMNS[0],CSV_COLUMNS[9]],axis=1) result = df_data[CSV_COLUMNS[9]]
from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test = train_test_split(data,result,random_state=33,test_size=0.25)
from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import GridSearchCV
#使用随机森林方式进行bagging预测 parameters = {'n_estimators':[1,100], 'max_depth':[1, 10]}
clf = GridSearchCV(RandomForestClassifier(min_samples_split=2,random_state=0), parameters) clf.fit(X_train, y_train) y_pred = clf.predict(X_test)
print ("best_estimator_ : ",clf.best_estimator_) print ("best_score_ : ",clf.best_score_) print ("best_params_ : ",clf.best_params_)
print("RandomForestClassifier score : ",clf.score(X_test,y_test))
#使用梯度提升完成boost算法 from sklearn.ensemble import GradientBoostingClassifier parameters = {'n_estimators':[1,100], 'max_depth':[1, 10]}
clf = GridSearchCV(GradientBoostingClassifier(min_samples_split=2,random_state=0), parameters) clf.fit(X_train, y_train) y_pred = clf.predict(X_test)
print ("best_estimator_ : ",clf.best_estimator_) print ("best_score_ : ",clf.best_score_) print ("best_params_ : ",clf.best_params_)
print("GradientBoostingClassifier score : ",clf.score(X_test,y_test)) |
|
提交代码系统返回运行结果如图3.4.4.3。
图3.4.4.3
李里:你们的算法预测准确率看着还不错,但在实际应用中很多数据集都具有极不平衡的数据分布,比如在线监测信用卡交易诈骗时,可能每一万笔业务才有一笔是欺诈交易,而我们的防风险算法准确率就算是99.99%时,可能还是监测不到任何欺诈业务,由于这些稀有的负样本很少出现,所以检测难度很大,通常采用ROC曲线来检验我们的模型是否涵盖这些了稀有负样本,讲ROC曲线之前,先讲下真正率和假正率,真正率是指被模型正确预测的正样本的比例,假正率指的是被模型预测为正样本而实际是负样本的比例,而ROC曲线的Y轴表示的是真正率,X轴表示的假正率,所以曲线是沿着Y轴上升的同时而X轴越趋近于原点是模型的理想状态。
ROC示例文件[1]:
import numpy as np from scipy import interp import matplotlib.pyplot as plt from itertools import cycle from sklearn import svm, datasets from sklearn.metrics import roc_curve, auc from sklearn.model_selection import StratifiedKFold # Data IO and generation # Import some data to play with iris = datasets.load_iris() X = iris.data y = iris.target X, y = X[y != 2], y[y != 2] n_samples, n_features = X.shape # Add noisy features random_state = np.random.RandomState(0) X = np.c_[X, random_state.randn(n_samples, 200 * n_features)] # Classification and ROC analysis # Run classifier with cross-validation and plot ROC curves cv = StratifiedKFold(n_splits=6) classifier = svm.SVC(kernel='linear', probability=True, random_state=random_state) tprs = [] aucs = [] mean_fpr = np.linspace(0, 1, 100) i = 0 for train, test in cv.split(X, y): probas_ = classifier.fit(X[train], y[train]).predict_proba(X[test]) # Compute ROC curve and area the curve fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1]) tprs.append(interp(mean_fpr, fpr, tpr)) tprs[-1][0] = 0.0 roc_auc = auc(fpr, tpr) aucs.append(roc_auc) plt.plot(fpr, tpr, lw=1, alpha=0.3, label='ROC fold %d (AUC = %0.2f)' % (i, roc_auc)) i += 1 plt.plot([0, 1], [0, 1], linestyle='--', lw=2, color='r', label='Luck', alpha=.8) mean_tpr = np.mean(tprs, axis=0) mean_tpr[-1] = 1.0 mean_auc = auc(mean_fpr, mean_tpr) std_auc = np.std(aucs) plt.plot(mean_fpr, mean_tpr, color='b', label=r'Mean ROC (AUC = %0.2f $\pm$ %0.2f)' % (mean_auc, std_auc), lw=2, alpha=.8) std_tpr = np.std(tprs, axis=0) tprs_upper = np.minimum(mean_tpr + std_tpr, 1) tprs_lower = np.maximum(mean_tpr - std_tpr, 0) plt.fill_between(mean_fpr, tprs_lower, tprs_upper, color='grey', alpha=.2, label=r'$\pm$ 1 std. dev.') plt.xlim([-0.05, 1.05]) plt.ylim([-0.05, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver operating characteristic example') plt.legend(loc="lower right") plt.show()
|
图3.4.4.4:ROC示例文件运行结果
李里:到这里sklearn的培训都以结束,你们还有什么问题么?
安逸:在现实中人多的进行决策真的会更好么?我听过一个说法,一个人买车,如果问第十个人,那他可能反而不知道该买哪个好了,按我们学的群体决策不应该更好么?
高维:你这个问题涉及到群体决策方面的理论,群体决策有两个缺陷分别是群体极化指的是群体讨论后观点会朝着更极端的观点转移,比如,开始只有部分成员赞成某个观点,讨论后就会变得强烈赞同这个观点,若是反对某个观点,讨论后会更加反对这个观点,这有点像我们的投票集成算法,另一个缺陷是讨论会渐渐从做出最佳决策转移到维持小群体一致的小团体意识,当产生小团体意识时结论已经不重要了,维护自己团体的观点才重要。当然群体决策也有好处,比如当你受知识所限时无法获得最佳决策时,可以让很多类似你的人都去做决策,按少数服从多数的原则得出最后的决策,这样的结果虽然不见得是最好的,但也不见得太差。
李里:恩,多个弱学习算法集成到一起变成一个强集成算法。安逸你再举个例子说明下梯度提升算法。
安逸:这个关于缩小残差的算法,我觉得和猜数字的游戏很类似,游戏的规则是5次以内猜出一个100以内的任意数,我先说出一个区间如是不是大于50,对方说是,这样我的残差就是50,然后我在50的残差上又猜是不是小于75,若不是,则残差变为76~100,这样每次我都只在残差上做猜测,与真实值的误差越来越小。
李里:我可以给你鼓掌的,解释的不错,你对下一步培训有什么要求,我可以满足你一下。
安逸:我能和高维分一组学习么?
李里:OK。
[1] http://sklearn.apachecn.org/cn/0.19.0/auto_examples/model_selection/plot_roc_crossval.html#sphx-glr-auto-examples-model-selection-plot-roc-crossval-py