Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7 如何在Python Scikit learn中存储与预矢量化X匹配的预测类?_Python 2.7_Machine Learning_Scikit Learn_Classification_Prediction - Fatal编程技术网

Python 2.7 如何在Python Scikit learn中存储与预矢量化X匹配的预测类?

Python 2.7 如何在Python Scikit learn中存储与预矢量化X匹配的预测类?,python-2.7,machine-learning,scikit-learn,classification,prediction,Python 2.7,Machine Learning,Scikit Learn,Classification,Prediction,我想用名字来预测性别。不仅仅是名字,还有名字特征,比如把“姓氏”提取为从名字派生的特征。我的代码的流程是这样的,将数据放入df>指定lr分类器和dv dictVectorizer>使用函数创建特征>执行dictVectorization>训练。我想做以下工作,但找不到如何做的任何资源 1) 我想将预测的类(0和1)添加回原始数据集或可以看到名称和预测的性别类的数据集。目前我的y_测试预测只对应于X_测试,X_测试是一个稀疏矩阵 2) 我如何保留经过训练的分类器,并使用它来预测具有一组名称的不同数

我想用名字来预测性别。不仅仅是名字,还有名字特征,比如把“姓氏”提取为从名字派生的特征。我的代码的流程是这样的,将数据放入df>指定lr分类器和dv dictVectorizer>使用函数创建特征>执行dictVectorization>训练。我想做以下工作,但找不到如何做的任何资源

1) 我想将预测的类(0和1)添加回原始数据集或可以看到名称和预测的性别类的数据集。目前我的y_测试预测只对应于X_测试,X_测试是一个稀疏矩阵

2) 我如何保留经过训练的分类器,并使用它来预测具有一组名称的不同数据集的性别?我怎么能插入一个名字“Rick Grime”让分类器告诉我它预测的性别

我用nltk做过类似的事情,但在Scikit learn中找不到任何这样做的示例或参考

代码:

    import pandas as pd
    from pandas import DataFrame, Series
    import numpy as np
    import re
    import random
    import time
    from random import randint
    import csv
    import sys
    from sklearn.metrics import classification_report
    from sklearn.linear_model import LogisticRegression
    from sklearn.svm import LinearSVC
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.naive_bayes import MultinomialNB
    from sklearn.feature_extraction import DictVectorizer
    from sklearn.metrics import confusion_matrix as sk_confusion_matrix
    from sklearn.metrics import roc_curve, auc
    import matplotlib.pyplot as plt
    from sklearn.metrics import precision_recall_curve
    from sklearn import cross_validation 

    data = pd.read_csv("file.csv", header=0, encoding="utf-8")
    df = DataFrame(data)
    dv = DictVectorizer()
    lr = LogisticRegression()

    X = df.raw_name.values
    X2 = df.name.values
    y = df.gender.values

    def feature_full_name(nameString):
        try:
            full_name = nameString
            if len(full_name) > 1: # not accept name with only 1 character
                return full_name
            else: return '?'
        except: return '?'

    def feature_full_last_name(nameString):
        try:
            last_name = nameString.rsplit(None, 1)[-1]
            if len(last_name) > 1: # not accept name with only 1 character
                return last_name
            else: return '?'
        except: return '?'

    def feature_name_entity(nameString2):
        space = 0
        try:
            for i in nameString2:
                if i == ' ':
                    space += 1
            return space+1
        except: return 0

    my_dict = [{'last-name': feature_full_last_name(i)} for i in X]
    my_dict2 = [{'name-entity': feature_name_entity(feature_full_name(i))} for i in X2]


    all_dict = []
    for i in range(0, len(my_dict)):
        temp_dict = dict(
            my_dict[i].items() + my_dict2[i].items()
            )
        all_dict.append(temp_dict)

    newX = dv.fit_transform(all_dict)

    X_train, X_test, y_train, y_test = cross_validation.train_test_split(newX, y, test_size=0.3)

    lr.fit(X_train, y_train)

    y_test_predictions = lr.predict(X_test)

我会使用scikit learn的一些内置工具来分割数据帧,对名称进行矢量化,并预测结果。然后,您可以将预测结果添加回测试数据帧。例如,使用一小组名称作为示例:

data = {'Bruce Lee': 'Male',
        'Bruce Banner': 'Male',
        'Bruce Springsteen': 'Male',
        'Bruce Willis': 'Male',
        'Sarah McLaughlin': 'Female',
        'Sarah Silverman': 'Female',
        'Sarah Palin': 'Female',
        'Sarah Hyland': 'Female'}

import pandas as pd
df = pd.DataFrame.from_dict(data, orient='index').reset_index()
df.columns = ['name', 'gender']
print(df)
                name  gender
0    Sarah Silverman  Female
1        Sarah Palin  Female
2  Bruce Springsteen    Male
3       Bruce Banner    Male
4          Bruce Lee    Male
5       Sarah Hyland  Female
6   Sarah McLaughlin  Female
7       Bruce Willis    Male
现在我们可以使用scikit learn的
CountVectorizer
来计算名称中的单词;这将产生与上面所做的基本相同的输出,只是它不会根据名称的长度等进行过滤。为了便于使用,我们将使用交叉验证的逻辑回归将其放入管道中:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegressionCV
from sklearn.pipeline import make_pipeline

clf = make_pipeline(CountVectorizer(), LogisticRegressionCV(cv=2))
现在,我们可以将数据拆分为一个训练集/测试集,拟合管道,然后分配结果:

from sklearn.cross_validation import train_test_split

df_train, df_test = train_test_split(df, train_size=0.5, random_state=0)

clf.fit(df_train['name'], df_train['gender'])

df_test = df_test.copy() # so we can modify it
df_test['predicted'] = clf.predict(df_test['name'])

print(df_test)
                name  gender predicted
6   Sarah McLaughlin  Female    Female
2  Bruce Springsteen    Male      Male
1        Sarah Palin  Female    Female
7       Bruce Willis    Male      Male
类似地,我们可以将一个名称列表传递给管道并得到一个预测:

>>> clf.predict(['Bruce Campbell', 'Sarah Roemer'])
array(['Male', 'Female'], dtype=object)
如果您想在文本矢量化中实现更复杂的逻辑,您可以为输入数据创建一个自定义转换器:“scikit learn custom transformer”的web搜索应该会为您提供一组不错的示例


编辑:下面是一个使用自定义转换器从输入名称生成DICT的示例:

from sklearn.base import TransformerMixin

class ExtractNames(TransformerMixin):
    def transform(self, X, *args):
        return [{'first': name.split()[0],
                 'last': name.split()[-1]}
                for name in X]

    def fit(self, *args):
        return self

trans = ExtractNames()

>>> trans.fit_transform(df['name'])
[{'first': 'Bruce', 'last': 'Springsteen'},
 {'first': 'Bruce', 'last': 'Banner'},
 {'first': 'Sarah', 'last': 'Hyland'},
 {'first': 'Sarah', 'last': 'Silverman'},
 {'first': 'Sarah', 'last': 'Palin'},
 {'first': 'Bruce', 'last': 'Lee'},
 {'first': 'Bruce', 'last': 'Willis'},
 {'first': 'Sarah', 'last': 'McLaughlin'}]
现在,您可以使用
DictVectorizer
将其放入管道中,以生成稀疏特征:

from sklearn.feature_extraction import DictVectorizer
from sklearn.pipeline import make_pipeline

pipe = make_pipeline(ExtractNames(), DictVectorizer())

>>> pipe.fit_transform(df['name'])
<8x10 sparse matrix of type '<class 'numpy.float64'>'
    with 16 stored elements in Compressed Sparse Row format>

从这里,如果您愿意,您可以修改
ExtractNames
转换器来进行更复杂的特征提取(使用上面的一些代码),最终实现过程的管道实现,但只需在字符串输入列表上调用
predict()
。希望有帮助

我会使用scikit learn的一些内置工具来分割数据帧、矢量化名称和预测结果。然后,您可以将预测结果添加回测试数据帧。例如,使用一小组名称作为示例:

data = {'Bruce Lee': 'Male',
        'Bruce Banner': 'Male',
        'Bruce Springsteen': 'Male',
        'Bruce Willis': 'Male',
        'Sarah McLaughlin': 'Female',
        'Sarah Silverman': 'Female',
        'Sarah Palin': 'Female',
        'Sarah Hyland': 'Female'}

import pandas as pd
df = pd.DataFrame.from_dict(data, orient='index').reset_index()
df.columns = ['name', 'gender']
print(df)
                name  gender
0    Sarah Silverman  Female
1        Sarah Palin  Female
2  Bruce Springsteen    Male
3       Bruce Banner    Male
4          Bruce Lee    Male
5       Sarah Hyland  Female
6   Sarah McLaughlin  Female
7       Bruce Willis    Male
现在我们可以使用scikit learn的
CountVectorizer
来计算名称中的单词;这将产生与上面所做的基本相同的输出,只是它不会根据名称的长度等进行过滤。为了便于使用,我们将使用交叉验证的逻辑回归将其放入管道中:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegressionCV
from sklearn.pipeline import make_pipeline

clf = make_pipeline(CountVectorizer(), LogisticRegressionCV(cv=2))
现在,我们可以将数据拆分为一个训练集/测试集,拟合管道,然后分配结果:

from sklearn.cross_validation import train_test_split

df_train, df_test = train_test_split(df, train_size=0.5, random_state=0)

clf.fit(df_train['name'], df_train['gender'])

df_test = df_test.copy() # so we can modify it
df_test['predicted'] = clf.predict(df_test['name'])

print(df_test)
                name  gender predicted
6   Sarah McLaughlin  Female    Female
2  Bruce Springsteen    Male      Male
1        Sarah Palin  Female    Female
7       Bruce Willis    Male      Male
类似地,我们可以将一个名称列表传递给管道并得到一个预测:

>>> clf.predict(['Bruce Campbell', 'Sarah Roemer'])
array(['Male', 'Female'], dtype=object)
如果您想在文本矢量化中实现更复杂的逻辑,您可以为输入数据创建一个自定义转换器:“scikit learn custom transformer”的web搜索应该会为您提供一组不错的示例


编辑:下面是一个使用自定义转换器从输入名称生成DICT的示例:

from sklearn.base import TransformerMixin

class ExtractNames(TransformerMixin):
    def transform(self, X, *args):
        return [{'first': name.split()[0],
                 'last': name.split()[-1]}
                for name in X]

    def fit(self, *args):
        return self

trans = ExtractNames()

>>> trans.fit_transform(df['name'])
[{'first': 'Bruce', 'last': 'Springsteen'},
 {'first': 'Bruce', 'last': 'Banner'},
 {'first': 'Sarah', 'last': 'Hyland'},
 {'first': 'Sarah', 'last': 'Silverman'},
 {'first': 'Sarah', 'last': 'Palin'},
 {'first': 'Bruce', 'last': 'Lee'},
 {'first': 'Bruce', 'last': 'Willis'},
 {'first': 'Sarah', 'last': 'McLaughlin'}]
现在,您可以使用
DictVectorizer
将其放入管道中,以生成稀疏特征:

from sklearn.feature_extraction import DictVectorizer
from sklearn.pipeline import make_pipeline

pipe = make_pipeline(ExtractNames(), DictVectorizer())

>>> pipe.fit_transform(df['name'])
<8x10 sparse matrix of type '<class 'numpy.float64'>'
    with 16 stored elements in Compressed Sparse Row format>

从这里,如果您愿意,您可以修改
ExtractNames
转换器来进行更复杂的特征提取(使用上面的一些代码),最终实现过程的管道实现,但只需在字符串输入列表上调用
predict()
。希望有帮助

有没有一种方法可以将管道与DictVectorizer一起用于上面的示例?我有更多需要使用DictVectorizer的功能。是的,您可以将
DictVectorizer
放入管道中,就像我在上面使用
CountVectorizer
一样。您只需将dict列表传递到
clf.fit()
。更好的做法是编写一个自定义转换器来接收字符串列表并创建dict,然后将其传递给
DictVectorizer
。管道可以有任意多个步骤。对不起,请您在代码中显示“只需将dict列表传递给clf.fit()”,我在scikit学习方面不是很先进。或者让我知道一个我可以从中学习的参考将非常感谢。在上面,我定义了一个管道,第一步是使用
CountVectorizer
,并将字符串列表传递给它。第一步,您可以使用
DictVectorizer
定义一个管道,并向其传递一个dicts列表。我添加了一个编辑,并提供了一个示例,希望对您有所帮助。是否有一种方法可以将管道与DictVectorizer一起使用,以代替上面的示例?我有更多需要使用DictVectorizer的功能。是的,您可以将
DictVectorizer
放入管道中,就像我在上面使用
CountVectorizer
一样。您只需将dict列表传递到
clf.fit()
。更好的做法是编写一个自定义转换器来接收字符串列表并创建dict,然后将其传递给
DictVectorizer
。管道可以有任意多个步骤。对不起,请您在代码中显示“只需将dict列表传递给clf.fit()”,我在scikit学习方面不是很先进。或者让我知道我可以从中学习的参考资料将非常感谢。在上面,我定义了一个管道,第一个管道是
CountVectorizer