我正在尝试在逻辑回归中使用一些排名数据。我希望使用机器学习来创建一个简单的分类器,以判断一个网页是“好”还是“不好”。这只是一个学习练习,所以我不期望有很好的结果;只是希望学习“过程”和编码技术。
我已经将数据放入了一个.csv文件中,如下所示:
URL WebsiteText AlexaRank GooglePageRank
在我的测试CSV文件中,我们有:
URL WebsiteText AlexaRank GooglePageRank Label
Label是一个二元分类,表示“好”为1,“不好”为0。
我目前仅使用网站文本运行我的LR;我对其进行了TF-IDF处理。
我有两个问题需要帮助:
-
如何对AlexaRank的排名数据进行归一化?我有一组10,000个网页,我有它们的Alexa排名;然而它们的排名并不是
1-10,000
。它们是在整个互联网上的排名,所以虽然http://www.google.com
可能排名#1
,http://www.notasite.com
可能排名#83904803289480
。如何在Scikit learn中对其进行归一化,以便从我的数据中获得最佳结果? -
我以这种方式运行我的逻辑回归;我几乎可以肯定我做错了。我试图对网站文本进行TF-IDF处理,然后添加另外两个相关列并拟合逻辑回归。如果有人能快速验证我是否正确地使用了我想在LR中使用的三个列,我将不胜感激。
loadData = lambda f: np.genfromtxt(open(f,'r'), delimiter=' ') print "loading data.." traindata = list(np.array(p.read_table('train.tsv'))[:,2])#Reading WebsiteText column for TF-IDF. testdata = list(np.array(p.read_table('test.tsv'))[:,2]) y = np.array(p.read_table('train.tsv'))[:,-1] #reading label tfv = TfidfVectorizer(min_df=3, max_features=None, strip_accents='unicode', analyzer='word', token_pattern=r'\w{1,}', ngram_range=(1, 2), use_idf=1, smooth_idf=1,sublinear_tf=1) rd = lm.LogisticRegression(penalty='l2', dual=True, tol=0.0001, C=1, fit_intercept=True, intercept_scaling=1.0, class_weight=None, random_state=None) X_all = traindata + testdata lentrain = len(traindata) print "fitting pipeline" tfv.fit(X_all) print "transforming data" X_all = tfv.transform(X_all) X = X_all[:lentrain] X_test = X_all[lentrain:] print "20 Fold CV Score: ", np.mean(cross_validation.cross_val_score(rd, X, y, cv=20, scoring='roc_auc')) #Add Two Integer Columns AlexaAndGoogleTrainData = list(np.array(p.read_table('train.tsv'))[2:,3])#Not sure if I am doing this correctly. Expecting it to contain AlexaRank and GooglePageRank columns. AlexaAndGoogleTestData = list(np.array(p.read_table('test.tsv'))[2:,3]) AllAlexaAndGoogleInfo = AlexaAndGoogleTestData + AlexaAndGoogleTrainData #Add two columns to X. X = np.append(X, AllAlexaAndGoogleInfo, 1) #Think I have done this incorrectly. print "training on full data" rd.fit(X,y) pred = rd.predict_proba(X_test)[:,1] testfile = p.read_csv('test.tsv', sep="\t", na_values=['?'], index_col=1) pred_df = p.DataFrame(pred, index=testfile.index, columns=['label']) pred_df.to_csv('benchmark.csv') print "submission file created.."
回答:
我想sklearn.preprocessing.StandardScaler
是你首先想要尝试的东西。StandardScaler将所有特征转换为均值为0、标准差为1的特征。
- 这肯定能解决你的第一个问题。
AlexaRank
将被保证分布在0周围并有界。(是的,即使是像83904803289480
这样巨大的AlexaRank
值也会被转换为小的浮点数)。当然,结果不会是1
到10000
之间的整数,但它们会保持与原始排名相同的顺序。在这种情况下,保持排名有界和归一化将有助于解决你的第二个问题,如下所示。 - 为了理解为什么归一化在LR中会有所帮助,让我们重新审视LR的logit公式。
在你的情况下,X1, X2, X3是三个TF-IDF特征,X4, X5是与Alexa/Google排名相关的特征。现在,线性形式的方程表明系数代表变量一个单位变化时y的logit的变化。想想当你的X4保持在一个巨大的排名值上时会发生什么,比如83904803289480
。在这种情况下,Alexa排名变量会主导你的LR拟合,而TF-IDF值的微小变化几乎不会对LR拟合产生影响。现在有人可能会认为系数应该能够调整到小/大值以适应这些特征之间的差异。在这种情况下不是这样——不仅变量的幅度重要,它们的范围也很重要。Alexa排名肯定有很大的范围,在这种情况下应该会主导你的LR拟合。因此,我认为使用StandardScaler对所有变量进行归一化以调整它们的范围将改善拟合效果。