from sklearn.feature_extraction.text import TfidfVectorizertfidf = TfidfVectorizer(sublinear_tf= True, min_df = 5, norm= 'l2', ngram_range= (1,2), stop_words ='english')feature1 = tfidf.fit_transform(df.Rejoined_Stem)array_of_feature = feature1.toarray()
我使用上面的代码来获取文本文档的特征。
from sklearn.naive_bayes import MultinomialNB # Multinomial Naive Bayes on Lemmatized TextX_train, X_test, y_train, y_test = train_test_split(df['Rejoined_Lemmatize'], df['Product'], random_state = 0)X_train_counts = tfidf.fit_transform(X_train)clf = MultinomialNB().fit(X_train_counts, y_train)y_pred = clf.predict(tfidf.transform(X_test))
然后我使用这段代码来训练我的模型。能有人解释一下在训练模型时具体是如何使用上述特征的吗?因为那个feature1变量在训练时并没有被使用到?
回答:
不,你没有使用feature1
,因为你进行了另一个转换X_train_count
。
让我们按逻辑流程浏览你的代码,并只使用在特征提取和模型训练中使用的变量。
# 导入所使用的库from sklearn.model_selection import train_test_splitfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.naive_bayes import MultinomialNB# 使用随机状态0和默认的测试大小0.25分割数据,你没有指定测试大小X_train, X_test, y_train, y_test = train_test_split(df[['Rejoined_Lemmatize']], df['Product'], random_state = 0)# 你初始化了转换器以`fit_transform` X_train,并`transform` X_testtfidf = TfidfVectorizer(sublinear_tf= True, min_df = 5, norm= 'l2', ngram_range= (1,2), stop_words ='english')X_train_counts = tfidf.fit_transform(X_train)X_test_counts = tfidf.transform(X_test)# 你初始化了模型并使用X_train_counts和y_train进行拟合clf = MultinomialNB()cls.fit(X_train_counts, y_train)# 你使用转换后的特征进行预测y_pred = clf.predict(X_test_counts)
有一个更好的方法来使用Scikit-learn API,这可以消除混淆,并帮助你避免混淆。这种方法使用Pipelines
# 导入所使用的库:见Pipelinefrom sklearn.pipeline import Pipelinefrom sklearn.model_selection import train_test_splitfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.naive_bayes import MultinomialNB# 使用随机状态0和默认的测试大小0.25分割数据,你没有指定测试大小X_train, X_test, y_train, y_test = train_test_split(df[['Rejoined_Lemmatize']], df['Product'], random_state = 0)# 获取参数tfidf_params = dict(sublinear_tf= True, min_df = 5, norm= 'l2', ngram_range= (1,2), stop_words ='english')# 创建一个Pipeline,它将进行特征转换然后传递给模型clf = Pipeline(steps=[('features', TfidfVectorizer(**tfidf_params)),('model', MultinomialNB())])# 使用clf作为模型,拟合X_train和y_traincls.fit(X_train, y_train)# 预测y_pred = clf.predict(X_test)
在.fit
中,pipeline所做的就是对数据进行fit_transform,然后传递给模型。在.predict
中,它会在传递给模型之前进行转换。
这种方法最好的地方是你可以轻松地切换模型或转换器。这里有一个模型基线比较的例子:
# 收集存储结果的容器from collections import defaultdictimport pandas as pdfrom sklearn.pipeline import Pipelinefrom sklearn.model_selection import train_test_splitfrom sklearn.feature_extraction.text import TfidfVectorizer# 要测试的模型from sklearn.linear_model import PassiveAggressiveClassifier from sklearn.linear_model import RidgeClassifierCVfrom sklearn.linear_model import SGDClassifierfrom sklearn.linear_model import LogisticRegressionCV # 初始化我们的存储容器bench_mark = defaultdict(list)# 使用随机状态0和默认的测试大小0.25分割数据,你没有指定测试大小X_train, X_test, y_train, y_test = train_test_split(df[['Rejoined_Lemmatize']], df['Product'], random_state = 0)# 获取转换器参数tfidf_params = dict(sublinear_tf= True, min_df = 5, norm= 'l2', ngram_range= (1,2), stop_words ='english')# 我们想要完成的模型列表models = [PassiveAggressiveClassifier(C=1e-1,max_iter=1e3, tol=1e3), RidgeClassifierCV(scoring='roc_auc', cv=10),LogisticRegressionCV(cv=5,solver='saga',scoring='accuracy', random_state=1, n_jobs=-1),SGDClassifier(loss='log', random_state=1, max_iter=101), ]# 训练、测试并存储每个模型for model in models: # 我们的pipeline被更改为接受模型 clf = Pipeline(steps=[ ('features', TfidfVectorizer(**tfidf_params)), ('model', model) #仅模型,不需要model(),因为我们在models列表中已经这样做了 ]) clf.fit(X_train,y_train) score = clf.score(X_test,y_test) model_name = clf.named_steps['model'].__class__.__name__ # 一个获取名称的技巧 model_params = clf.named_steps['model']. get_params() print(f'{model_name} 得分: {score:.3f}\n') bench_mark['model_name'].append(model_name) bench_mark['score'].append(score) bench_mark['model'].append(clf) bench_mark['used_params'].append(model_params)# 最后,将bench_mark放入DataFrame中models_df = pd.DataFrame(bench_mark)# 现在你已经在DataFrame中有了训练好的模型、它们的得分和参数。# 你可以访问和使用任何模型。logistic_reg = models_df[models_df['model_name']=='LogisticRegressionCV']['model'].iloc[0]y_preds = logistic_reg.predict(X_test)
希望这对你有帮助