(更新:Posted最终结果作为单独答案)
我开始尝试了解如何使用scikit模型进行培训。我已经尝试过众所周知的数据集,如iris,MNIST等 - 它们都是结构良好的数据,随时可以使用。这是我第一次尝试用自己的原始数据构建模型,结果不太理想。
过去3年,我选择使用的数据是NHSTA's crash data。
以下是数据的快照,让您无需下载数据即可了解这些字段。
我的第一个实验很简单 - 尝试构建一个给出“许可证状态代码”和“年龄”的模型,尝试并预测性别(M或F)。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
import tensorflow.contrib.learn as skflow
from tensorflow.contrib.learn.python.learn.estimators import run_config
from sklearn.svm import SVC
import pickle, seaborn
def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
n_jobs=1, train_sizes=np.linspace(.1, 1.0, 5)):
#http://scikit-learn.org/stable/auto_examples/model_selection/plot_learning_curve.html
plt.figure()
plt.title(title)
if ylim is not None:
plt.ylim(*ylim)
plt.xlabel("Training examples")
plt.ylabel("Score")
train_sizes, train_scores, test_scores = learning_curve(
estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
plt.grid()
plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
train_scores_mean + train_scores_std, alpha=0.1,
color="r")
plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
test_scores_mean + test_scores_std, alpha=0.1, color="g")
plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
label="Training score")
plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
label="Cross-validation score")
plt.legend(loc="best")
plt.show()
#MAIN
crashes = pd.read_csv("crashes.csv", nrows=100000)
# drop useless cols
crashes.drop(["Year","Case Individual ID", "Case Vehicle ID", "Transported
By", "Injury Location", "Role Type"],axis=1, inplace=True)
crashes = crashes [pd.notnull(crashes['Age'])]
crashes = crashes[crashes.Age >= 10 ] # There are ages < 10 - likely junk data. I don't think they drive
# lets drop rows that are empty
crashes = crashes [pd.notnull(crashes['License State Code'])]
crashes = crashes [pd.notnull(crashes['Injury Severity'])]
crashes = crashes [pd.notnull(crashes['Safety Equipment'])]
crashes = crashes [pd.notnull(crashes['Sex'])]
# converts text fields to numerical values
le = LabelEncoder()
crashes = crashes[crashes.columns[:]].apply(le.fit_transform)
crashes = crashes._get_numeric_data()
# lets plot a heat map to show correlation
corr = crashes.corr()
ax = seaborn.heatmap (corr, xticklabels=corr.columns.values,
yticklabels=corr.columns.values, annot=True)
plt.setp( ax.xaxis.get_majorticklabels(), rotation=45 )
plt.setp( ax.yaxis.get_majorticklabels(), rotation=-45 )
plt.show()
crashes_train, crashes_test = train_test_split(crashes, test_size = 0.2)
Y_train = crashes_train['Sex']
X_train = crashes_train[[ 'Age', 'License State Code']]
Y_test = crashes_test['Sex']
X_test = crashes_test[[ 'Age', 'License State Code']]
names_train = crashes_train.columns.values
print "train size ",len (X_train)
print "test size",len (X_test)
#
# cls = RandomForestClassifier(verbose = True)
#
cls = MLPClassifier(hidden_layer_sizes=(10,10,10), max_iter=500, alpha=1e-4,
solver='sgd', verbose=10, tol=1e-4, random_state=1,
learning_rate_init=0.01)
#cls = tf.contrib.learn.DNNClassifier(feature_columns=feats,
# hidden_units=[50, 50, 50],
# n_classes=3)
#
#
#cls = SVC(verbose = True)
print "Fitting..."
cls.fit(X_train, Y_train)
plot_learning_curve(cls,"Crash Learning", X_train, Y_train)
print("Training set score: %f" % cls.score(X_train, Y_train))
print("Test set score: %f" % cls.score(X_test, Y_test))
我尝试了多种模式(从RandomForest到SVC再到MLP等) - 他们都得到了大约0.56的训练分数和0.6x的损失
看起来在RandomForest中得分减少,但总体而言它与MLP类似。我做错了什么,如何改进这种方法?感谢
编辑:基于下面的两个答案,我做了所有列之间相关性的热图(在删除了明显无用之后) - 这很糟糕,但这是正确的方法吗?我也可以做一个PCA,但是如果基本的场间相关性很差,它是否表明数据集在挖掘预测时基本没用了?
答案 0 :(得分:2)
我的第一个实验很简单 - 尝试建立一个给定的模型 &#34;许可证状态代码&#34;和&#34;年龄&#34;,尝试并预测性别(M或F)。
嗯,事情并非那么简单。您不能简单地获取任何数据并尝试预测某些内容。数据至少需要相互关联。
要做的一些好事:
feature_importances_
的属性。此属性告诉您哪些功能在数据集中最重要(相应于当然的模型)
功能重要性(功能越高,功能越重要)。分类算法简单地将输入数据映射到类别。但是,如果输入和输出之间没有任何关系,则此任务不可行。特征选择是机器学习中非常重要的一个领域。来自wikipedia:
在机器学习和统计中,特征选择(也称为变量选择,属性选择或变量子集选择)是选择用于模型构建的相关特征(变量,预测变量)子集的过程。
答案 1 :(得分:1)
问题不在于模型,而在于数据。 &#39;年龄&#39;和#34;许可证状态代码&#39;不是确定“性别”的最佳参数。 。
尝试使用相同的模型来预测伤害严重程度&#39;与安全设备&#39;你应该得到更好的结果。
答案 2 :(得分:0)
我想感谢@gnobre和@Giantrun指出我正确的方向。我不想放弃我的最终目标,试图看看我是否能够预测一种模式来预测性别&#39; (性别)来自任何其他专栏,并且能够更好地关联我的交叉验证和测试/训练图表。
首先,我在所有列之间运行了一个简单的关联,结果看起来非常糟糕。我不确定我是否正在使用正确的数据集。
然后,我决定使用RFE对最重要的功能进行排名,假设&#39;性别&#39;是期望的预测。这给了我一组功能 - 我把所有的True值(1级)作为我的功能集。这给了我以下培训(和测试)图:
总体训练分数仍然很低(0.58),但是训练和交叉验证之间的相关性很好,这意味着我选择了正确的功能,但我的目标是预测&#39;性& #39;从这个数据开始,可能不是一个好的。我可能一直在玩MLP层等,但我怀疑我能够从0.5x到0.9x
我的下一个兴趣是预测“伤害严重程度”,所以我改变了Y目标并再次运行RFE,这给了我另一套可供选择的功能。具体来说,这些是Injury Severity
['Victim Status', 'Ejection', 'Injury Descriptor', 'Sex']
使用结果字段作为特征使我获得了更高的训练和验证分数(0.98)和图表:
我得出的一个结论是直接相关图比做RFE或PCA(正确吗?)更有用
一个悬而未决的问题:在这个特定的例子中,当我设法获得高分测试和训练分数时,我还能面对哪些其他问题?