自然语言处理及案例

'''
    自然语言处理(NLP)
            词袋模型:一句话的语义很大程度取决于某个单词出现的次数,所以可以把句子中所有可能出现的单词作为特征名,
                    每一个句子为一个样本,单词在句子中出现的次数为特征值构建数学模型,称为词袋模型。
                    例如:
                        1 The brown dog is running
                        2 The black dog is in the black room
                        3 Running in the room is forbidden
                        the    brown    dog    is    running    black    in    room    forbidden
                        1    1        1    1        1    0        0        0    0
                        2    0        1    1        0    2        1        1    0
                        1    0        0    1        1    0        1        1    1
            词袋模型化相关API:
                import sklearn.feature_extraction.text as ft
                # 构建词袋模型对象
                cv = ft.CountVectorizer()
                # 训练模型,把句子中所有可能出现的单词作为特征名,每一个句子为一个样本,单词在句子中出现的次数为特征值。
                bow = cv.fit_transform(sentences).toarray()
                print(bow)
                # 获取所有特征名
                words = cv.get_feature_names()

            词频(TF):单词在句子中出现的次数除以句子的总词数称为词频。即一个单词在一个句子中出现的频率。
                        词频相比单词的出现次数可以更加客观的评估单词对一句话的语义的贡献度。词频越高,
                        对语义的贡献度越大。对词袋矩阵归一化即可得到词频。
            文档频率(DF):含有某个单词的文档样本数/总文档样本数。文档频率越高,对语义的贡献度越低。
            逆文档频率(IDF):总样本数/含有某个单词的样本数。逆文档频率越高,对语义的贡献度越高。
            词频-逆文档频率(TF-IDF):词频矩阵中的每一个元素乘以相应单词的逆文档频率,其值越大说明该词对样本语义的贡献越大,
                                    根据每个词的贡献力度,构建学习模型。
            获取词频逆文档频率(TF-IDF)矩阵相关API:
                            # 获取词袋模型
                            cv = ft.CountVectorizer()
                            bow = cv.fit_transform(sentences).toarray()
                            # 获取TF-IDF模型训练器
                            tt = ft.TfidfTransformer()
                            tfidf = tt.fit_transform(bow).toarray()

'''
import nltk.tokenize as tk
import sklearn.feature_extraction.text as ft
import numpy as np

doc = "The brown dog is running." 
      "The black dog is in the black room." 
      "Running in the room is forbidden."

sents = tk.sent_tokenize(doc)
print(sents)

# 构建词袋模型
cv = ft.CountVectorizer()
bow = cv.fit_transform(sents)  # 稀疏矩阵
bow = bow.toarray()  # 正常矩阵
print(bow)
# 打印特征名称
print(cv.get_feature_names())

# 获取TFIDF矩阵
tt = ft.TfidfTransformer()
tfidf = tt.fit_transform(bow)
print(np.round(tfidf.toarray(), 2))
'''
    文本分类(主体识别):使用给定的文本数据集进行主题识别训练,自定义测试集测试模型准确性。
'''
import sklearn.datasets as sd
import sklearn.feature_extraction.text as ft
import sklearn.naive_bayes as nb
import numpy as np

train = sd.load_files('./ml_data/20news', encoding='latin1', shuffle=True, random_state=7)
# 获取训练样本
train_data = train.data
# 获取样本输出
train_y = train.target
# 获取类别标签名
categories = train.target_names
print(np.array(train_data).shape)
print(np.array(train_y).shape)
print(categories)

# 构建TFIDF矩阵
cv = ft.CountVectorizer()
bow = cv.fit_transform(train_data).toarray()
tt = ft.TfidfTransformer()
tfidf = tt.fit_transform(bow)

# 模型训练,使用MultinomialNB是因为tfidf矩阵中样本的分布更匹配多项式分布
model = nb.MultinomialNB()
model.fit(tfidf, train_y)
# 测试
test_data = [
    'The curveballs of right handed pithers tend to curve to the left.',
    'Caesar cipher is an ancient form of encryption.',
    'This two-wheeler is really good on slipper'
]
test_bow = cv.transform(test_data)
test_tfidf = tt.transform(test_bow)
pred_test_y = model.predict(test_tfidf)
for sent, index in zip(test_data, pred_test_y):
    print(sent, '---->', categories[index])