From 0926b8cc13b33ac79e3fdf1f644ecb3119699142 Mon Sep 17 00:00:00 2001 From: hnu202410040315 <3522968684@qq.com> Date: Wed, 14 May 2025 15:46:25 +0800 Subject: [PATCH] Delete '01 (1).html' --- 01 (1).html | 14377 -------------------------------------------------- 1 file changed, 14377 deletions(-) delete mode 100644 01 (1).html diff --git a/01 (1).html b/01 (1).html deleted file mode 100644 index 30aae29..0000000 --- a/01 (1).html +++ /dev/null @@ -1,14377 +0,0 @@ - - -
- -完成科比投篮预测案例,即数据的特征处理与训练预测代码。在学习该实训之前,你需要学习pandas、numpy 以及 keras 等 python 库的使用方法。
- -数据来源:
-数据来源于 kaggle,该数据集收集了科比近20年职业生涯中所尝试的每个投篮命中的位置和情况,其中包含了 30697 次投篮出手的数据,包含了 25 个特征属性,由于是篮球领域的数据,这里做一个简短的说明。
-数据官方说明和介绍及下载:https://www.kaggle.com/c/kobe-bryant-shot-selection/data
-在 kaggle 上该数据集的准确率最高也只有 60% 多。
-数据特征属性有:
-标签:
-这其中包含了一些不是那么重要的属性和无关的属性,这些将在数据预处理中进行剔除
- -#### 载入数据
-import numpy as np
-import pandas as pd
-import matplotlib.pyplot as plt
-# /data/shixunfiles/21979737119eb4fafd62cae509c0c571_1602468291676.csv
-# 读入数据
-data = pd.read_csv("/data/shixunfiles/21979737119eb4fafd62cae509c0c571_1602468291676.csv")
-#显示大小
-print("数据集大小:",data.shape)
-# 数据集详细信息
-print(data.info())
-数据分析是为了查看数据集中正负样本的比例或者各个类别的分布情况,以便训练时调整样本比例,防止训练出现过拟合或者欠拟合的现象。
- -# 投中与未中的数量
-yes=0
-no=0
-for i in data[pd.notnull(data['shot_made_flag'])]['shot_made_flag']:
- if i==1.0:
- yes+=1
- else:
- no+=1
-
-plt.bar([0,1], [yes,no])
-plt.xticks([0,1])
-plt.show()
-
-print('命中次数:',yes)
-print('未命中次数:',no)
-#保留标签缺失值的数据
-data_no = data[pd.isnull(data['shot_made_flag'])]
-print(data_no.shape)
-#保留标签不为缺失值的数据
-data = data[pd.notnull(data['shot_made_flag'])]
-print(data.shape)
-#分配画布大小
-plt.figure(figsize = (10,10))
-
-plt.subplot(1,2,1)
-#alpha为不透明度,loc_x,loc_y为科比投篮的位置
-plt.scatter(data.loc_x,data.loc_y,color ='g',alpha = 0.05)
-plt.title('loc_x and loc_y')
-
-plt.subplot(1,2,2)
-#lat为纬度,lon为经度
-plt.scatter(data.lon,data.lat,color ='b',alpha = 0.05)
-plt.title('lat and lon')
-
-plt.show()
-分钟与秒特征重复 -原始特征中既有分钟又有秒,所以可以把这两组特征进行合并
- -data['remain_time'] = data['minutes_remaining']*60 + data['seconds_remaining']
-data['remain_time'][:5]
-'shot_zone_basic','shot_zone_range','shot_zone_area'这三个特征为投篮位置的不同表示,比较一下
-画图分析,其形状与坐标位置差不多,所以选用更加准确的坐标来表示投篮位置
- -import matplotlib.cm as cm
-plt.figure(figsize=(20,10))
-
-# data.groupyby(feature),是将数据根据feature里的类进行分类
-def scatterbygroupby(feature):
- alpha = 0.1
- gb = data.groupby(feature)
- cl = cm.rainbow(np.linspace(0,1,len(gb)))
- for g,c in zip(gb,cl):
- plt.scatter(g[1].loc_x,g[1].loc_y,color = c,alpha = alpha)
-# 画图对比三种投篮位置
-plt.subplot(1,3,1)
-scatterbygroupby('shot_zone_basic')
-plt.title('shot_zone_basic')
-
-plt.subplot(1,3,2)
-scatterbygroupby('shot_zone_range')
-plt.title('shot_zone_range')
-
-plt.subplot(1,3,3)
-scatterbygroupby('shot_zone_area')
-plt.title('shot_zone_area')
-plt.show()
-包括比赛 id,球队 id,team_name(科比只效力过洛杉矶湖人,所以可以删除),其他的投篮位置的表示,分钟数,比赛时间等
-剩余有用的特征:
-# 去掉如比赛id,投篮id等无关特征
-drops = ['combined_shot_type','shot_id', 'team_id', 'team_name', 'shot_zone_area', 'shot_zone_range', 'shot_zone_basic', \
- 'matchup', 'lon', 'lat', 'seconds_remaining', 'minutes_remaining', \
- 'shot_distance', 'game_event_id', 'game_id', 'game_date','season']
-for drop in drops:
- data = data.drop(drop, 1)
-data.head()
-a = ['action_type', 'shot_type', 'opponent']
-for i in a:
- #使用one-hot编码,将a中的特征里的属性值都当作新的特征附在数据的列上,特征名为前缀prefix加上该属性名
- data = pd.concat([data, pd.get_dummies(data[i], prefix=i)], 1)
- data = data.drop(i, 1) #0-行,1-列
-data.head()
-data.to_csv("./data_processed.csv", encoding="utf-8-sig", mode="w", header=True, index=False)
-data = pd.read_csv("data_processed.csv")
-data_label = data['shot_made_flag']
-#读入数据
-data = pd.read_csv("data_processed.csv")
-#显示大小
-print("数据集大小:",data.shape)
-# 数据集详细信息
-print(data.info())
-分离特征和标签是为了之后训练模型时,让数据处理更加方便。
- -data_feature = data.drop('shot_made_flag',1)
-data_label = data['shot_made_flag']
-data_label.shape
-data_label = np.array(data_label)
-data_label.shape
-由于各个特征之间存在很大的量纲上的差异,所以先进行标准化,我们使用sklearn的工具包实现数据的标准化。
-fit_transform(X,y=None,**fit_params): 通过fit_params调整数据X,y得到一个调整后的X
- -#### 对data_feature进行数据标准化
-#### 上述cell的答案
-from sklearn.preprocessing import StandardScaler
-scaler = StandardScaler()
-data_feature = scaler.fit_transform(data_feature)
-data_feature = pd.DataFrame(data_feature)
-data_feature.head()
-data_feature.to_csv("./data_feature_standard.csv", encoding="utf-8-sig", mode="w", header=True, index=False)
-data_feature = pd.read_csv("data_feature_standard.csv")
-#### 载入数据和标签
-knn_data = data_feature
-knn_label = data_label
-为了对模型进行训练和测试,我们需要将原始数据分为训练集和测试集,这里我们采用sklearn的库函数实现数据集的拆分,该函数如下所示:
- -X_train,X_test, y_train, y_test =sklearn.model_selection.train_test_split(train_data,train_target,test_size=0.4,random_state=0,stratify=y_train)
-其中各个参数如下所示:
-train_data:所要划分的样本特征集
-train_target:所要划分的样本结果
-test_size:样本占比,如果是整数的话就是样本的数量
-random_state:是随机数的种子。随机数种子其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
-stratify是为了保持split前类的分布。比如有100个数据,80个属于A类,20个属于B类。如果train_test_split(... test_size=0.25, stratify = y_all), 那么split之后数据如下: training: 75个数据,其中60个属于A类,15个属于B类。 testing: 25个数据,其中20个属于A类,5个属于B类。 用了stratify参数,training集和testing集的类的比例是 A:B= 4:1,等同于split前的比例(80:20)。通常在这种类分布不平衡的情况下会用到stratify。将stratify=X就是按照X中的比例分配。 将stratify=y就是按照y中的比例分配。
-from sklearn.model_selection import train_test_split
-X_train, X_test, y_train, y_test = train_test_split(knn_data,knn_label, random_state=2020, test_size=0.25)
-我们采用sklearn库的KNeighborsClassifier实现KNN模型,模型调用方法如下:
- -from sklearn.neighbors import KNeighborsClassifier
-KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30,p=2, metric=’minkowski’, metric_params=None, n_jobs=1)
-参数说明如下:
-该模型的参数如下:
-from sklearn.neighbors import KNeighborsClassifier
-knn = KNeighborsClassifier(n_neighbors=3)
-knn.fit(X_train, y_train)
-score = knn.score(X_train, y_train)
-print('训练数据集的准确率:{:.3}%'.format(score*100))
-score = knn.score(X_test, y_test)
-print('测试数据集的准确率:{:.3}%'.format(score*100))
-我们通过尝试使用KNN算法不同的K值进行模型训练,并利用sklearn库的cross_val_score函数观察不同K值的训练结果,该函数调用方法如下
- -sklearn.cross_validation.cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)
-返回交叉验证每次运行的评分数组。 -参数如下:
-# 运行时间较长,请耐心等待
-# 交叉验证
-from sklearn.model_selection import cross_val_score
-from time import time
-import datetime
-k_range = range(1,21,2)
-cv_scores = []
-time0 = time()
-# 遍历1到21的分类数,得到每个分类数下的分数
-for n in k_range:
- print(n)
- knn = KNeighborsClassifier(n_neighbors=n)
- scores = cross_val_score(knn,X_train,y_train,cv=10,scoring='accuracy')
- cv_scores.append(scores.mean())
-print('计算所用时长:%s' % (datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f")))
-print('最高准确率:',max(cv_scores),',对应的k值为:',k_range[cv_scores.index(max(cv_scores))])
-plt.plot(k_range,cv_scores)
-plt.xlabel('K')
-plt.ylabel('Accuracy')
-plt.show()
-由上图观察可知在17到21区间模型的准确度较高,我们继续选定参数范围为[17,23]进行训练调试。
- -# 进一步
-k_range = range(17,23,2)
-cv_scores = []
-time0 = time()
-for n in k_range:
- print(n)
- knn = KNeighborsClassifier(n_neighbors=n)
- scores = cross_val_score(knn,X_train,y_train,cv=10,scoring='accuracy')
- cv_scores.append(scores.mean())
-print('计算所用时长:%s' % (datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f")))
-print('最高准确率:',max(cv_scores),',对应的k值为:',k_range[cv_scores.index(max(cv_scores))])
-plt.plot(k_range,cv_scores)
-plt.xlabel('K')
-plt.ylabel('Accuracy')
-plt.show()
-可知模型最好的参数K值为19。
- -ROC的全名叫做Receiver Operating Characteristic,其主要分析工具是一个画在二维平面上的曲线——ROC 曲线。平面的横坐标是false positive rate(FPR),纵坐标是true positive rate(TPR)。对某个分类器而言,我们可以根据其在测试样本上的表现得到一个TPR和FPR点对。这样,此分类器就可以映射成ROC平面上的一个点。调整这个分类器分类时候使用的阈值,我们就可以得到一个经过(0, 0),(1, 1)的曲线,这就是此分类器的ROC曲线。一般情况下,这个曲线都应该处于(0, 0)和(1, 1)连线的上方。因为(0, 0)和(1, 1)连线形成的ROC曲线实际上代表的是一个随机分类器。如果很不幸,你得到一个位于此直线下方的分类器的话,一个直观的补救办法就是把所有的预测结果反向,即:分类器输出结果为正类,则最终分类的结果为负类,反之,则为正类。
-真正(True Positive , TP)被模型预测为正的正样本; -假负(False Negative , FN)被模型预测为负的正样本; -假正(False Positive , FP)被模型预测为正的负样本; -真负(True Negative , TN)被模型预测为负的负样本。
-真正例率(Ture positive rare),TPR=TP/(TP+FN)ROC曲线的纵轴; -假正例率(False positive rare),FPR=FP/(TN+FP) ROC曲线的横轴
-AUC的值就是处于ROC 曲线下方的那部分面积的大小。通常,AUC的值介于0.5到1.0之间,较大的AUC代表了较好的性能。AUC(Area Under roc Curve)是一种用来度量分类模型好坏的一个标准。
-目的: -评估分类器准确性
-函数:
- -sklearn.metrics.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)
-输入:
-输出: -一个矩阵,shape=[y中的类型数,y中的类型数]
-矩阵中每个值表征分类的准确性:
-第0行第0列的数表示y_true中值为0,y_pred中值也为0的个数
-第0行第1列的数表示y_true中值为0,y_pred中值为1的个数
- -# 测试集评估
-knn = KNeighborsClassifier(n_neighbors=19)
-knn.fit(X_train, y_train)
-score = knn.score(X_train, y_train)
-print('训练数据集的准确率:{:.3}%'.format(score*100))
-score = knn.score(X_test, y_test)
-print('测试数据集的准确率:{:.3}%'.format(score*100))
-# ROC
-from sklearn.metrics import roc_curve, auc, roc_auc_score
-from sklearn.preprocessing import label_binarize
-# y_test_hot = label_binarize(y_test, classes=(0, 1))
-knn_y_score = knn.predict_proba(X_test)
-knn_fpr, knn_tpr, _ = roc_curve(y_test,knn_y_score[:,1], pos_label=1)
-plt.plot(knn_fpr, knn_tpr,
- label='micro-average ROC curve',
- color='g', linewidth=4)
-plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
-plt.title('knn roc')
-plt.show()
-# AUC
-knn_auc = auc(knn_fpr, knn_tpr)
-knn_auc
-由于传统的机器学习方法精确度有限,我们尝试使用神经网络进行训练,看看神经网络的模型训练结果。
- -cnn_data = np.asarray(data_feature)
-cnn_label = np.asarray(data_label)
-cnn_data.shape
-x_train = cnn_data[:20000]
-y_train = cnn_label[:20000]
-x_test = cnn_data[20000:]
-y_test = cnn_label[20000:]
-from keras import models
-from keras import layers
-model = models.Sequential()
-## 输入层,激活函数为relu
-model.add(layers.Dense(16,activation='relu',input_shape=(95,)))
-## 中间层,激活函数为relu
-model.add(layers.Dense(16,activation='relu'))
-## 输出层,维数为1
-model.add(layers.Dense(1,activation='sigmoid'))
-model.summary()
-model.compile(optimizer = 'rmsprop',
- loss='binary_crossentropy',
- metrics=['accuracy'])
-x_val = x_train[:7000]
-partial_x_train = x_train[7000:]
-
-y_val = y_train[:7000]
-partial_y_train = y_train[7000:]
-history = model.fit(partial_x_train,
- partial_y_train,
- epochs=20,
- batch_size=512,
- validation_data=(x_val,y_val))
-history_dict = history.history
-history_dict.keys()
-results = model.evaluate(x_test,y_test)
-results
-我们查看历史不同的迭代次数下训练以及验证集的损失函数,以及不同迭代次数下,训练集与测试集的准确率,来查看迭代次数对模型的影响。
- -## 损失值
-loss_values = history_dict['loss']
-val_loss_values = history_dict['val_loss']
-## 迭代次数
-epochs = range(1,len(loss_values)+1)
-plt.plot(epochs,loss_values,'bo',label='Training loss')
-plt.plot(epochs,val_loss_values,'b',label='Validation loss')
-plt.title('Trian and Validation loss')
-plt.xlabel('Epochs')
-plt.ylabel('Loss')
-plt.legend()
-plt.show()
-
-acc = history_dict['acc']
-val_acc = history_dict['val_acc']
-plt.plot(epochs,acc,'bo',label='Training acc')
-plt.plot(epochs,val_acc,'b',label='Validation acc')
-plt.title('Trian and Validation acc')
-plt.xlabel('Epochs')
-plt.ylabel('acc')
-plt.legend()
-plt.show()
-我们通过遍历输入层以及中间层不同层数,尝试不同迭代次数,将最优解参数放入best_param数组中。
- -# nums1 = [16,32,64]
-# nums2 = [16,32,64]
-# epochs = [7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
-# 由于上述3行代码运行时间过长,为了减少运行时间,我们将最优参数标出如下3行,
-# 若同学学有余力可取消注释进行完整训练。
-nums1 = [32]
-nums2 = [32]
-epochs = [10]
-
-best_result = 0
-best_param = []
-## 设置中间层不同的节点数,不同的迭代次数取最好的训练结果参数
-for num1 in nums1:
- for num2 in nums2:
- for epoch in epochs:
- model = models.Sequential()
- model.add(layers.Dense(num1,activation='relu',input_shape=(95,)))
- model.add(layers.Dense(num2,activation='relu'))
- model.add(layers.Dense(1,activation='sigmoid'))
-
- model.compile(optimizer = 'rmsprop',
- loss='binary_crossentropy',
- metrics=['accuracy'])
-
- history = model.fit(x_train,y_train,epochs=epoch,batch_size=512)
-
- results = model.evaluate(x_test,y_test)
- if best_result<results[1]:
- best_result = results[1]
- best_param = []
- best_param.append(num1)
- best_param.append(num2)
- best_param.append(epoch)
-print('最高的准确率:',best_result)
-print('最好的参数:',best_param)
-model = models.Sequential()
-model.add(layers.Dense(16,activation='relu',input_shape=(95,)))
-model.add(layers.Dense(32,activation='relu'))
-model.add(layers.Dense(1,activation='sigmoid'))
-model.compile(optimizer = 'rmsprop',
- loss='binary_crossentropy',
- metrics=['accuracy'])
-history = model.fit(x_train,y_train,epochs=14,batch_size=512)
-results = model.evaluate(x_test,y_test)
-results
-
-model.save('cnn_model.h5')
-# 载入
-from keras.models import load_model
-model = load_model('cnn_model.h5')
-模型评估的方法如上。
- -# 绘制混淆矩阵
-from sklearn.metrics import confusion_matrix
-y_pred = model.predict(x_test)
-y_pred = y_pred.reshape(-1)
-for i,pred in enumerate(y_pred):
- if pred>0.5:
- y_pred[i]=1.0
- else:
- y_pred[i]=0.0
-print(y_pred.shape)
-print(y_test.shape)
-
-# ROC
-from sklearn.metrics import confusion_matrix
-from sklearn.metrics import roc_curve, auc, roc_auc_score
-model_y_score = model.predict_proba(x_test)
-model_y_score = model_y_score.reshape(-1)
-model_fpr, model_tpr, _ = roc_curve(y_test,model_y_score, pos_label=1)
-plt.plot(model_fpr, model_tpr,
- label='micro-average ROC curve',
- color='g', linewidth=4)
-plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
-plt.title('model roc')
-plt.show()
-
-# AUC
-model_auc = auc(model_fpr, model_tpr)
-model_auc
-根据上述学习内容,完成以下练习:
-数据集路径如下:
-训练数据:/data/shixunfiles/2309cc5f04782ed9bb6016d9f4e381cf_1607607386535.csv
-测试数据:/data/shixunfiles/7533b82eae4b582610cbd68aa636b017_1607607386511.csv
- -练习内容如下
- -import pandas as pd
-train_data = pd.read_csv('/data/shixunfiles/2309cc5f04782ed9bb6016d9f4e381cf_1607607386535.csv')
-test_data = pd.read_csv('/data/shixunfiles/7533b82eae4b582610cbd68aa636b017_1607607386511.csv')
-combined_data = pd.concat([train_data, test_data], axis=0, sort=False)
-print("数据集形状:", combined_data.shape)
-print("数据信息:")
-print(combined_data.info())
-print(combined_data.head(10))
-import matplotlib.pyplot as plt
-import matplotlib
-matplotlib.rcParams['font.sans-serif'] = ['SimHei']
-matplotlib.rcParams['axes.unicode_minus'] = False
-male_survival_rate = combined_data[combined_data['Sex'] =='male']['Survived'].mean()
-female_survival_rate = combined_data[combined_data['Sex'] == 'female']['Survived'].mean()
-labels = ['男性', '女性']
-survival_rates = [male_survival_rate, female_survival_rate]
-plt.bar(labels, survival_rates)
-plt.xlabel('性别')
-plt.ylabel('生存比例')
-plt.title('男性与女性乘客生存比例')
-plt.show()
-pclass_1_survival_rate = combined_data[combined_data['Pclass'] == 1]['Survived'].mean()
-pclass_2_survival_rate = combined_data[combined_data['Pclass'] == 2]['Survived'].mean()
-pclass_3_survival_rate = combined_data[combined_data['Pclass'] == 3]['Survived'].mean()
-labels = ['一等舱', '二等舱', '三等舱']
-survival_rates = [pclass_1_survival_rate, pclass_2_survival_rate, pclass_3_survival_rate]
-plt.bar(labels, survival_rates)
-plt.xlabel('客舱等级')
-plt.ylabel('生存比例')
-plt.title('不同客舱乘客生存比例')
-plt.show()
-
-