gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 08:52:25 24 4
gpt4 key购买 nike

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

1) 我想将预测类别(0 和 1)添加回原始数据集或我可以看到姓名和预测性别类别的数据集中。目前我的 y_test_predictions 仅对应于 X_test,它是一个稀疏矩阵。

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 自定义转换器”应该会为您提供一组不错的示例供您使用。

<小时/>

编辑:这是使用自定义转换器从输入名称生成字典的示例:

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>

最后,您可以创建一个将这些与交叉验证的逻辑回归相结合的管道,并按上述步骤进行:

clf = make_pipeline(ExtractNames(), DictVectorizer(), LogisticRegressionCV())
clf.fit(df_train['name'], df_train['gender'])
df_test['predicted'] = clf.predict(df_test['name'])

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

关于python-2.7 - 如何在 Python Scikit-learn 中存储与预向量化 X 匹配的预测类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33381000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com