Python 在Logistic回归中使用排序数据

Python 在Logistic回归中使用排序数据,python,algorithm,machine-learning,artificial-intelligence,scikit-learn,Python,Algorithm,Machine Learning,Artificial Intelligence,Scikit Learn,在我努力学习这些概念的时候,我会把最大的悬赏放在这上面!我试图在逻辑回归中使用一些排名数据。我想用机器学习来做一个简单的分类器,判断一个网页是否“好”。这只是一个学习练习,所以我不期望有好的结果;只是希望学习“过程”和编码技术 我已将我的数据放在.csv中,如下所示: URL WebsiteText AlexaRank GooglePageRank 在我的测试CSV中,我们有: URL WebsiteText AlexaRank GooglePageRank Label 标签是一种二进制分类

在我努力学习这些概念的时候,我会把最大的悬赏放在这上面!我试图在逻辑回归中使用一些排名数据。我想用机器学习来做一个简单的分类器,判断一个网页是否“好”。这只是一个学习练习,所以我不期望有好的结果;只是希望学习“过程”和编码技术

我已将我的数据放在.csv中,如下所示:

URL WebsiteText AlexaRank GooglePageRank
在我的测试CSV中,我们有:

URL WebsiteText AlexaRank GooglePageRank Label
标签是一种二进制分类,用1表示“好”,用0表示“坏”

我目前只使用网站文本运行我的LR;我在上面运行TF-IDF

我有两个问题需要帮助。我将对这个问题给予最大的奖励,并将其授予最佳答案,因为这是我希望得到一些好的帮助的事情,所以我和其他人可能会学习

  • 如何规范AlexaRank的排名数据?我有一套 10000个网页,我拥有所有网页的Alexa排名; 但是,他们没有排名
    1-10000
    。他们被排在最前面 整个互联网,所以当
    http://www.google.com
    可能被列为
    #1
    http://www.notasite.com
    可能被排名为
    83904803289480
    。我该怎么办 在Scikit学习中对此进行规范化,以获得最佳效果 我的数据的结果
  • 我以这种方式运行逻辑回归;我几乎可以肯定我做得不对。我试图在网站文本上做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将所有特征转换为Mean-0-Std-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 Rank绝对有很大的射程,在这种情况下,它绝对会主宰你的LR贴合度。因此,我想使用StandardScaler规范化所有变量以调整其范围将改善拟合
下面是如何缩放
X
矩阵

sc = proprocessing.StandardScaler().fit(X)
X = sc.transform(X)
不要忘记使用相同的定标器来转换
X\u测试

X_test = sc.transform(X_test)
现在您可以使用装配程序等

rd.fit(X, y)
re.predict_proba(X_test)
有关sklearn预处理的更多信息,请查看以下内容:

编辑:使用pandas可以轻松完成解析和列合并部分,即不需要将矩阵转换为列表,然后追加它们。此外,数据帧可以通过其列名直接索引

AlexaAndGoogleTrainData = p.read_table('train.tsv', header=0)[["AlexaRank", "GooglePageRank"]]
AlexaAndGoogleTestData = p.read_table('test.tsv', header=0)[["AlexaRank", "GooglePageRank"]]
AllAlexaAndGoogleInfo = AlexaAndGoogleTestData.append(AlexaAndGoogleTrainData)
请注意,我们正在将
header=0
参数传递给read_表,以维护tsv文件中的原始头名称。还要注意如何使用整个列集进行索引。最后,您可以使用
numpy.hstack
使用
X
堆叠这个新矩阵

X = np.hstack((X, AllAlexaAndGoogleInfo))

hstack
水平组合的两个多维数组状结构,前提是它们的长度相同。

关于数字列的规格化,scikit
标准缩放器
或对数变换(或两者)应该可以很好地工作

为了建立一个工作管道,我发现使用Pandas包和
sklearn.pipeline
实用程序可以极大地提高我的理智。下面是一个简单的脚本,它可以完成您需要的任务

首先是一些我似乎一直需要的Utlity课程。在
sklearn.pipeline
sklearn.utilities
中有这样的东西会很好

from sklearn import base
class Columns(base.TransformerMixin, base.BaseEstimator):
    def __init__(self, columns):
        super(Columns, self).__init__()
        self.columns_ = columns
    def fit(self, *args, **kwargs):
        return self
    def transform(self, X, *args, **kwargs):
        return X[self.columns_]

class Text(base.TransformerMixin, base.BaseEstimator):
    def fit(self, *args, **kwargs):
        return self
    def transform(self, X, *args, **kwargs):
        return (X.apply("\t".join, axis=1, raw=False))
现在安装管道。 我使用了逻辑回归的
sgdclassizer
实现,因为它往往更适合于高维数据,如文本分类。我通常发现铰链损失通常比逻辑回归的结果更好

from sklearn import linear_model as lin
from sklearn import  metrics
from sklearn.feature_extraction import text as txt
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn import preprocessing as prep
import numpy as np
from pandas.io import parsers
import pandas as pd

pipe = Pipeline([
    ('feat', FeatureUnion([
        ('txt', Pipeline([
            ('txtcols', Columns(["WebsiteText"])),
            ('totxt', Text()),
            ('vect', txt.TfidfVectorizer()),
            ])),
        ('num', Pipeline([
            ('numcols', Columns(["AlexaRank", "GooglePageRank"])),
            ('scale', prep.StandardScaler()),
            ])),
        ])),
    ('clf', lin.SGDClassifier(loss="log")),
    ])
下一列车模型:

train=parsers.read_csv("train.csv")
pipe.fit(train, train.Label)
最后根据测试数据进行评估:

test=parsers.read_csv("test.csv")
tstlbl=np.array(test.Label)

print pipe.score(test, tstlbl)

pred = pipe.predict(test)
print metrics.confusion_matrix(tstlbl, pred)
print metrics.classification_report(tstlbl, pred)
print metrics.f1_score(tstlbl, pred)

prob = pipe.decision_function(test)
print metrics.roc_auc_score(tstlbl, prob)
print metrics.average_precision_score(tstlbl, prob)
使用这样的默认设置,您可能不会得到很好的结果,
但它应该给你一个工作基准。如果您愿意,我可以建议一些通常适用于我的参数设置。

非常感谢您的回答;真正的信息和教育。我真的很感激!还有一个简单的问题-如何将TF-IDF numpy数组与包含排名值的numpy数组组合起来。我曾试图在我的代码中这样做,但我相信我做得完全错误