作者|Mauro Di Pietro
編譯|VK
來源|Towards Data Science
摘要
在本文中,我將使用NLP和Python解釋如何為機器學習模型分析文本資料和提取特征,

自然語言處理(NLP)是人工智能的一個研究領域,它研究計算機與人類語言之間的相互作用,特別是如何對計算機進行編程以處理和分析大量自然語言資料,
NLP常用于文本資料的分類,文本分類是根據文本資料的內容對其進行分類的問題,文本分類最重要的部分是特征工程:從原始文本資料為機器學習模型創建特征的程序,
在本文中,我將解釋不同的方法來分析文本并提取可用于構建分類模型的特征,我將介紹一些有用的Python代碼,
這些代碼可以很容易地應用于其他類似的情況(只需復制、粘貼、運行),并且我加上了注釋,以便你可以理解示例(鏈接到下面的完整代碼),
https://github.com/mdipietro09/DataScience_ArtificialIntelligence_Utils/blob/master/deep_learning_natural_language_processing/text_classification_example.ipynb
我將使用“新聞類別資料集”(以下鏈接),其中向你提供從赫芬頓郵報獲得的2012年至2018年的新聞標題,并要求你使用正確的類別對其進行分類,
https://www.kaggle.com/rmisra/news-category-dataset
特別是,我將通過:
-
環境設定:匯入包并讀取資料,
-
語言檢測:了解哪些自然語言資料在其中,
-
文本預處理:文本清理和轉換,
-
長度分析:用不同的指標來衡量,
-
情緒分析:判斷一篇文章是正面的還是負面的,
-
命名物體識別:帶有預定義類別(如人名、組織、位置)的標識文本,
-
詞頻:找出最重要的n個字母,
-
詞向量:把一個字轉換成向量,
-
主題模型:從語料庫中提取主題,
環境設定
首先,我需要匯入以下庫,
## 資料
import pandas as pd
import collections
import json
## 繪圖
import matplotlib.pyplot as plt
import seaborn as sns
import wordcloud
## 文本處理
import re
import nltk
## 語言檢測
import langdetect
## 情感分析
from textblob import TextBlob
## 命名物體識別
import spacy
## 詞頻
from sklearn import feature_extraction, manifold
## word embedding
import gensim.downloader as gensim_api
## 主題模型
import gensim
資料集包含在一個json檔案中,因此我將首先使用json包將其讀入字典串列,然后將其轉換為pandas資料幀,
lst_dics = []
with open('data.json', mode='r', errors='ignore') as json_file:
for dic in json_file:
lst_dics.append( json.loads(dic) )
## 列印第一個
lst_dics[0]

原始資料集包含30多個類別,但在本教程中,我將使用3個類別的子集:娛樂、政治和技術(Entertainment, Politics, Tech),
## 創建dtf
dtf = pd.DataFrame(lst_dics)
## 篩選類別
dtf = dtf[ dtf["category"].isin(['ENTERTAINMENT','POLITICS','TECH']) ][["category","headline"]]
## 重命名列
dtf = dtf.rename(columns={"category":"y", "headline":"text"})
## 列印5個隨機行
dtf.sample(5)

為了理解資料集的組成,我將通過用條形圖顯示標簽頻率來研究單變數分布(僅一個變數的概率分布),
x = "y"
fig, ax = plt.subplots()
fig.suptitle(x, fontsize=12)
dtf[x].reset_index().groupby(x).count().sort_values(by=
"index").plot(kind="barh", legend=False,
ax=ax).grid(axis='x')
plt.show()

資料集是不平衡的:與其他資料集相比,科技新聞的比例確實很小,這可能是建模程序中的一個問題,對資料集重新采樣可能很有用,
現在已經設定好了,我將從清理資料開始,然后從原始文本中提取不同的細節,并將它們作為資料幀的新列添加,這些新資訊可以作為分類模型的潛在特征,

語言檢測
首先,我想確保我使用的是同一種語言,并且使用langdetect包,這非常簡單,為了舉例說明,我將在資料集的第一個新聞標題上使用它:
txt = dtf["text"].iloc[0]
print(txt, " --> ", langdetect.detect(txt))

我們為整個資料集添加一個包含語言資訊的列:
dtf['lang'] = dtf["text"].apply(lambda x: langdetect.detect(x) if
x.strip() != "" else "")
dtf.head()

資料幀現在有一個新列,使用之前的相同代碼,我可以看到有多少種不同的語言:

即使有不同的語言,英語也是主要的語言,所以我要用英語過濾新聞,
dtf = dtf[dtf["lang"]=="en"]
文本預處理
資料預處理是準備原始資料以使其適合機器學習模型的階段,對于NLP,這包括文本清理、洗掉停用詞、詞干還原,
文本清理步驟因資料型別和所需任務而異,通常,在文本被標識化之前,字串被轉換為小寫,標點符號被洗掉,標識化(Tokenization)是將字串拆分為字串串列(或“標識”)的程序,
再以第一條新聞標題為例:
print("--- original ---")
print(txt)
print("--- cleaning ---")
txt = re.sub(r'[^\w\s]', '', str(txt).lower().strip())
print(txt)
print("--- tokenization ---")
txt = txt.split()
print(txt)

我們要保留串列中的所有標識嗎?我們沒有,事實上,我們想洗掉所有不提供額外資訊的單詞,
在這個例子中,最重要的詞是“song”,因為它可以將任何分類模型指向正確的方向,相比之下,像“and”、“for”、“the”這樣的詞并不有用,因為它們可能出現在資料集中幾乎所有的觀察中,
這些是停用詞的例子,停用詞通常指的是語言中最常見的單詞,但是我們沒有一個通用的停用詞串列,
我們可以使用NLTK(自然語言工具包)為英語詞匯表創建一個通用停用詞串列,它是一套用于符號和統計自然語言處理的庫和程式,
lst_stopwords = nltk.corpus.stopwords.words("english")
lst_stopwords

讓我們從第一個新聞標題中洗掉這些停用詞:
print("--- remove stopwords ---")
txt = [word for word in txt if word not in lst_stopwords]
print(txt)
我們需要非常小心的停用詞,因為如果你洗掉了錯誤的標識,你可能會失去重要的資訊,例如,洗掉了“Will”一詞,我們丟失了此人是Will Smith的資訊,
考慮到這一點,在洗掉停用詞之前對原始文本進行一些手動修改是很有用的(例如,將“Will Smith”替換為“Will_Smith”),
既然我們有了所有有用的標識,就可以應用word轉換了,詞干化(Stemming)和引理化(Lemmatization)都產生了單詞的詞根形式,
他們的區別在于詞干可能不是一個實際的單詞,而引理是一個實際的語言單詞(詞干通常更快),這些演算法都是由NLTK提供的,
繼續示例:
print("--- stemming ---")
ps = nltk.stem.porter.PorterStemmer()
print([ps.stem(word) for word in txt])
print("--- lemmatisation ---")
lem = nltk.stem.wordnet.WordNetLemmatizer()
print([lem.lemmatize(word) for word in txt])

如你所見,有些單詞已經改變了:“joins”變成了它的根形式“join”,就像“cups”,另一方面,“official”只隨著詞干的變化而變化,詞干“offici”不是一個詞,而是通過去掉后綴“-al”而產生的,
我將把所有這些預處理步驟放在一個函式中,并將其應用于整個資料集,
'''
預處理.
:parameter
:param text: string - 包含文本的列的名稱
:param lst_stopwords: list - 要洗掉的停用詞串列
:param flg_stemm: bool - 是否應用詞干
:param flg_lemm: bool - 是否應用引理化
:return
cleaned text
'''
def utils_preprocess_text(text, flg_stemm=False, flg_lemm=True, lst_stopwords=None):
## 清洗(轉換為小寫并洗掉標點和字符,然后洗掉)
text = re.sub(r'[^\w\s]', '', str(text).lower().strip())
## 標識化(從字串轉換為串列)
lst_text = text.split()
## 洗掉停用詞
if lst_stopwords is not None:
lst_text = [word for word in lst_text if word not in
lst_stopwords]
## 詞干化
if flg_stemm == True:
ps = nltk.stem.porter.PorterStemmer()
lst_text = [ps.stem(word) for word in lst_text]
## 引理化
if flg_lemm == True:
lem = nltk.stem.wordnet.WordNetLemmatizer()
lst_text = [lem.lemmatize(word) for word in lst_text]
## 從串列回傳到字串
text = " ".join(lst_text)
return text
請注意,你不應該同時應用詞干和引理化,在這里我將使用后者,
dtf["text_clean"] = dtf["text"].apply(lambda x: utils_preprocess_text(x, flg_stemm=False, flg_lemm=True, lst_stopwords))
和以前一樣,我創建了一個新的列:
dtf.head()

print(dtf["text"].iloc[0], " --> ", dtf["text_clean"].iloc[0])

長度分析
查看文本的長度很重要,因為這是一個簡單的計算,可以提供很多資訊,
例如,也許我們足夠幸運地發現,一個類別系統地比另一個類別長,而長度只是構建模型所需的唯一特征,不幸的是,由于新聞標題的長度相似,情況并非如此,但值得一試,
文本資料有幾種長度度量,我將舉幾個例子:
- 字數:統計文本中的標識數(用空格分隔)
- 字符數:將每個標識的字符數相加
- 句子計數:計算句子的數量(用句點分隔)
- 平均字長:字長之和除以字數(字數/字數)
- 平均句子長度:句子長度之和除以句子數(字數/句子數)
dtf['word_count'] = dtf["text"].apply(lambda x: len(str(x).split(" ")))
dtf['char_count'] = dtf["text"].apply(lambda x: sum(len(word) for word in str(x).split(" ")))
dtf['sentence_count'] = dtf["text"].apply(lambda x: len(str(x).split(".")))
dtf['avg_word_length'] = dtf['char_count'] / dtf['word_count']
dtf['avg_sentence_lenght'] = dtf['word_count'] / dtf['sentence_count']
dtf.head()

讓我們看看例子:

這些新變數相對于目標的分布情況如何?為了回答這個問題,我將研究二元分布(兩個變數如何一起影響),
首先,我將整個觀察結果分成3個樣本(政治、娛樂、科技),然后比較樣本的直方圖和密度,如果分布不同,那么變數是可預測的,因為這三組有不同的模式,
例如,讓我們看看字符數是否與目標變數相關:
x, y = "char_count", "y"
fig, ax = plt.subplots(nrows=1, ncols=2)
fig.suptitle(x, fontsize=12)
for i in dtf[y].unique():
sns.distplot(dtf[dtf[y]==i][x], hist=True, kde=False,
bins=10, hist_kws={"alpha":0.8},
axlabel="histogram", ax=ax[0])
sns.distplot(dtf[dtf[y]==i][x], hist=False, kde=True,
kde_kws={"shade":True}, axlabel="density",
ax=ax[1])
ax[0].grid(True)
ax[0].legend(dtf[y].unique())
ax[1].grid(True)
plt.show()
這三個類別具有相似的長度分布,在這里,密度圖非常有用,因為樣本有不同的大小,
情感分析
情感分析是通過數字或類來表達文本資料的主觀情感,由于自然語言的模糊性,計算情感是自然語言處理中最困難的任務之一,
例如,短語“This is so bad that it’s good”有不止一種解釋,一個模型可以給“好”這個詞分配一個積極的信號,給“壞”這個詞分配一個消極的信號,從而產生一種中性的情緒,這是因為背景關系未知,
最好的方法是訓練你自己的情緒模型,使之適合你的資料,當沒有足夠的時間或資料時,可以使用預訓練好的模型,比如Textblob和Vader,
- Textblob建立在NLTK的基礎上,是最流行的一種,它可以給單詞賦予極性,并作為一個平均值來估計整個文本的情緒,
- 另一方面,Vader(Valence-aware dictionary and mootion reasoner)是一個基于規則的模型,尤其適用于社交媒體資料,
我將使用Textblob添加一個情感特征:
dtf["sentiment"] = dtf[column].apply(lambda x:
TextBlob(x).sentiment.polarity)
dtf.head()

print(dtf["text"].iloc[0], " --> ", dtf["sentiment"].iloc[0])

分類和情緒之間有規律嗎?

大多數的頭條新聞都是中性的,除了政治新聞偏向于負面,科技新聞偏向于正面,
命名物體識別
命名物體識別(Named entity recognition,NER)是用預定義的類別(如人名、組織、位置、時間運算式、數量等)提取非結構化文本中的命名物體的程序,
訓練一個NER模型是非常耗時的,因為它需要一個非常豐富的資料集,幸運的是有人已經為我們做了這項作業,最好的開源NER工具之一是SpaCy,它提供了不同的NLP模型,這些模型能夠識別多種型別的物體,

我將在我們通常的標題(未經預處理的原始文本)中使用SpaCy模型en_core_web_lg(網路資料上訓練的英語的大型模型),給出一個例子:
## 呼叫
ner = spacy.load("en_core_web_lg")
## 打標簽
txt = dtf["text"].iloc[0]
doc = ner(txt)
## 展示結果
spacy.displacy.render(doc, style="ent")

這很酷,但是我們怎么能把它變成有用的特征呢?這就是我要做的:
-
對資料集中的每個文本觀察運行NER模型,就像我在前面的示例中所做的那樣,
-
對于每個新聞標題,我將把所有被認可的物體以及同一物體出現在文本中的次數放入一個新的列(稱為“tags”),
在這個例子中:
{ (‘Will Smith’, ‘PERSON’):1,
(‘Diplo’, ‘PERSON’):1,
(‘Nicky Jam’, ‘PERSON’):1,
(“The 2018 World Cup’s”, ‘EVENT’):1 } -
然后,我將為每個標識類別(Person、Org、Event,…)創建一個新列,并計算每個標識類別找到的物體數,在上面的例子中,特征將是
tags_PERSON = 3
tags_EVENT = 1
## 標識文本并將標識匯出到串列中
dtf["tags"] = dtf["text"].apply(lambda x: [(tag.text, tag.label_)
for tag in ner(x).ents] )
## utils函式計算串列元素
def utils_lst_count(lst):
dic_counter = collections.Counter()
for x in lst:
dic_counter[x] += 1
dic_counter = collections.OrderedDict(
sorted(dic_counter.items(),
key=lambda x: x[1], reverse=True))
lst_count = [ {key:value} for key,value in dic_counter.items() ]
return lst_count
## 計數
dtf["tags"] = dtf["tags"].apply(lambda x: utils_lst_count(x))
## utils函式為每個標識類別創建新列
def utils_ner_features(lst_dics_tuples, tag):
if len(lst_dics_tuples) > 0:
tag_type = []
for dic_tuples in lst_dics_tuples:
for tuple in dic_tuples:
type, n = tuple[1], dic_tuples[tuple]
tag_type = tag_type + [type]*n
dic_counter = collections.Counter()
for x in tag_type:
dic_counter[x] += 1
return dic_counter[tag]
else:
return 0
## 提取特征
tags_set = []
for lst in dtf["tags"].tolist():
for dic in lst:
for k in dic.keys():
tags_set.append(k[1])
tags_set = list(set(tags_set))
for feature in tags_set:
dtf["tags_"+feature] = dtf["tags"].apply(lambda x:
utils_ner_features(x, feature))
## 結果
dtf.head()

現在我們可以在標識型別分布上有一個視圖,以組織標簽(公司和組織)為例:

為了更深入地分析,我們需要使用在前面的代碼中創建的列“tags”,讓我們為標題類別之一繪制最常用的標識:
y = "ENTERTAINMENT"
tags_list = dtf[dtf["y"]==y]["tags"].sum()
map_lst = list(map(lambda x: list(x.keys())[0], tags_list))
dtf_tags = pd.DataFrame(map_lst, columns=['tag','type'])
dtf_tags["count"] = 1
dtf_tags = dtf_tags.groupby(['type',
'tag']).count().reset_index().sort_values("count",
ascending=False)
fig, ax = plt.subplots()
fig.suptitle("Top frequent tags", fontsize=12)
sns.barplot(x="count", y="tag", hue="type",
data=https://www.cnblogs.com/panchuangai/p/dtf_tags.iloc[:top,:], dodge=False, ax=ax)
ax.grid(axis="x")
plt.show()

接著介紹NER的另一個有用的應用程式:你還記得我們從“Will Smith”的名稱中洗掉了“Will”這個單詞的停用詞嗎?解決這個問題的一個有趣的方法是將“Will Smith”替換為“Will_Smith”,這樣它就不會受到停用詞洗掉的影響,
遍歷資料集中的所有文本來更改名稱是不可能的,所以讓我們使用SpaCy,如我們所知,SpaCy可以識別一個人名,因此我們可以使用它來檢測姓名,然后修改字串,
## 預測
txt = dtf["text"].iloc[0]
entities = ner(txt).ents
## 打標簽
tagged_txt = txt
for tag in entities:
tagged_txt = re.sub(tag.text, "_".join(tag.text.split()),
tagged_txt)
## 結果
print(tagged_txt)

詞頻
到目前為止,我們已經看到了如何通過分析和處理整個文本來進行特征工程,
現在,我們將通過計算n-grams頻率來研究單個單詞的重要性,n-gram是給定文本樣本中n個項的連續序列,當n-gram的大小為1時,稱為unigram(大小為2是一個bigram),
例如,短語“I like this article”可以分解為:
- 4個unigram: “I”, “like”, “this”, “article”
- 3個bigrams:“I like”, “like this”, “this article”
我將以政治新聞為例說明如何計算unigram和bigrams頻率,
y = "POLITICS"
corpus = dtf[dtf["y"]==y]["text_clean"]
lst_tokens = nltk.tokenize.word_tokenize(corpus.str.cat(sep=" "))
fig, ax = plt.subplots(nrows=1, ncols=2)
fig.suptitle("Most frequent words", fontsize=15)
## unigrams
dic_words_freq = nltk.FreqDist(lst_tokens)
dtf_uni = pd.DataFrame(dic_words_freq.most_common(),
columns=["Word","Freq"])
dtf_uni.set_index("Word").iloc[:top,:].sort_values(by="Freq").plot(
kind="barh", title="Unigrams", ax=ax[0],
legend=False).grid(axis='x')
ax[0].set(ylabel=None)
## bigrams
dic_words_freq = nltk.FreqDist(nltk.ngrams(lst_tokens, 2))
dtf_bi = pd.DataFrame(dic_words_freq.most_common(),
columns=["Word","Freq"])
dtf_bi["Word"] = dtf_bi["Word"].apply(lambda x: " ".join(
string for string in x) )
dtf_bi.set_index("Word").iloc[:top,:].sort_values(by="Freq").plot(
kind="barh", title="Bigrams", ax=ax[1],
legend=False).grid(axis='x')
ax[1].set(ylabel=None)
plt.show()

如果有n個字母只出現在一個類別中(即政治新聞中的“Republican”),那么這些就可能成為新的特征,一種更為費力的方法是對整個語料庫進行向量化,并使用所有的單詞作為特征(單詞包方法),
現在我將向你展示如何在資料幀中添加單詞頻率作為特征,我們只需要Scikit learn中的CountVectorizer,它是Python中最流行的機器學習庫之一,
CountVectorizer將文本檔案集合轉換為計數矩陣,我將用3個n-grams來舉例:“box office”(經常出現在娛樂圈)、“republican”(經常出現在政界)、“apple”(經常出現在科技界),
lst_words = ["box office", "republican", "apple"]
## 計數
lst_grams = [len(word.split(" ")) for word in lst_words]
vectorizer = feature_extraction.text.CountVectorizer(
vocabulary=lst_words,
ngram_range=(min(lst_grams),max(lst_grams)))
dtf_X = pd.DataFrame(vectorizer.fit_transform(dtf["text_clean"]).todense(), columns=lst_words)
## 將新特征添加為列
dtf = pd.concat([dtf, dtf_X.set_index(dtf.index)], axis=1)
dtf.head()

可視化相同資訊的一個很好的方法是使用word cloud,其中每個標識的頻率用字體大小和顏色顯示,
wc = wordcloud.WordCloud(background_color='black', max_words=100,
max_font_size=35)
wc = wc.generate(str(corpus))
fig = plt.figure(num=1)
plt.axis('off')
plt.imshow(wc, cmap=None)
plt.show()

詞向量
最近,NLP領域開發了新的語言模型,這些模型依賴于神經網路結構,而不是更傳統的n-gram模型,這些新技術是一套語言建模和特征學習技術,將單詞轉換為實數向量,因此稱為詞嵌入,
詞嵌入模型通過構建所選單詞前后出現的標識的概率分布,將特定單詞映射到向量,這些模型很快變得流行,因為一旦你有了實數而不是字串,你就可以執行計算了,例如,要查找相同背景關系的單詞,可以簡單地計算向量距離,
有幾個Python庫可以使用這種模型,SpaCy是其中之一,但由于我們已經使用過它,我將談論另一個著名的包:Gensim,
它是使用現代統計機器學習的用于無監督主題模型和自然語言處理的開源庫,使用Gensim,我將加載一個預訓練的GloVe模型,
GloVe是一種無監督學習演算法,用于獲取300個單詞的向量表示,
nlp = gensim_api.load("glove-wiki-gigaword-300")
我們可以使用此物件將單詞映射到向量:
word = "love"
nlp[word]

nlp[word].shape
現在讓我們來看看什么是最接近的詞向量,換句話說,就是大多數出現在相似背景關系中的詞,
為了在二維空間中繪制向量圖,我需要將維數從300降到2,我將使用Scikit learn中的t-分布隨機鄰居嵌入來實作這一點,
t-SNE是一種可視化高維資料的工具,它將資料點之間的相似性轉換為聯合概率,
## 找到最近的向量
labels, X, x, y = [], [], [], []
for t in nlp.most_similar(word, topn=20):
X.append(nlp[t[0]])
labels.append(t[0])
## 降維
pca = manifold.TSNE(perplexity=40, n_components=2, init='pca')
new_values = pca.fit_transform(X)
for value in new_values:
x.append(value[0])
y.append(value[1])
## 繪圖
fig = plt.figure()
for i in range(len(x)):
plt.scatter(x[i], y[i], c="black")
plt.annotate(labels[i], xy=(x[i],y[i]), xytext=(5,2),
textcoords='offset points', ha='right', va='bottom')
## 添加中心
plt.scatter(x=0, y=0, c="red")
plt.annotate(word, xy=(0,0), xytext=(5,2), textcoords='offset
points', ha='right', va='bottom')

主題模型
Genism包專門用于主題模型,主題模型是一種用于發現檔案集合中出現的抽象“主題”的統計模型,
我將展示如何使用LDA(潛Dirichlet分布)提取主題:它是一個生成統計模型,它允許由未觀察到的組解釋觀察結果集,解釋為什么資料的某些部分是相似的,
基本上,檔案被表示為潛在主題上的隨機混合,每個主題的特征是在單詞上的分布,
讓我們看看我們可以從科技新聞中提取哪些主題,我需要指定模型必須簇的主題數,我將嘗試使用3:
y = "TECH"
corpus = dtf[dtf["y"]==y]["text_clean"]
## 預處理語料庫
lst_corpus = []
for string in corpus:
lst_words = string.split()
lst_grams = [" ".join(lst_words[i:i + 2]) for i in range(0,
len(lst_words), 2)]
lst_corpus.append(lst_grams)
## 將單詞映射到id
id2word = gensim.corpora.Dictionary(lst_corpus)
## 創建詞典 word:freq
dic_corpus = [id2word.doc2bow(word) for word in lst_corpus]
## 訓練LDA
lda_model = gensim.models.ldamodel.LdaModel(corpus=dic_corpus, id2word=id2word, num_topics=3, random_state=123, update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True)
## 輸出
lst_dics = []
for i in range(0,3):
lst_tuples = lda_model.get_topic_terms(i)
for tupla in lst_tuples:
lst_dics.append({"topic":i, "id":tupla[0],
"word":id2word[tupla[0]],
"weight":tupla[1]})
dtf_topics = pd.DataFrame(lst_dics,
columns=['topic','id','word','weight'])
## plot
fig, ax = plt.subplots()
sns.barplot(y="word", x="weight", hue="topic", data=https://www.cnblogs.com/panchuangai/p/dtf_topics, dodge=False, ax=ax).set_title('Main Topics')
ax.set(ylabel="", xlabel="Word Importance")
plt.show()

試圖僅用3個主題捕捉6年的內容可能有點困難,但正如我們所看到的,關于蘋果公司的一切都以同一個主題結束,
結論
本文是演示如何使用NLP分析文本資料并為機器學習模型提取特征的教程,
我演示了如何檢測資料所使用的語言,以及如何預處理和清除文本,然后我解釋了長度的不同度量,用Textblob進行了情緒分析,并使用SpaCy進行命名物體識別,最后,我解釋了Scikit學習的傳統詞頻方法與Gensim的現代語言模型之間的區別,
現在,你已經了解了開始處理文本資料的所有NLP基礎知識,
原文鏈接:https://towardsdatascience.com/text-analysis-feature-engineering-with-nlp-502d6ea9225d
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/6804.html
標籤:其他
