用機器學習判定紅樓夢後40回是否曹雪芹所寫

思路來源於此,註明出處:

https://mp.weixin.qq.com/s/5qqkHFVPhKlWcewCzSX5HQ

 

文章裏面說的已經很清楚了,就是我們對紅樓夢這本書每一章分詞,統計出現次數(對一些虛詞進行過濾,過濾算法和上篇的 數據分析:當迴音哥唱music時,他在唱些什麼~~~一樣)

首先展示一下我們從網上找到的紅樓夢素材:

由於有頁碼的標註,還有一些‘------’和分節閱讀字段的干擾,我們在做分詞的時候要對這些東西處理,話不多說,先上代碼:

# coding=UTF-8

import re
import jieba.posseg as psg
from collections import Counter
import xlwt

def check_is_title(line):
   if(re.match('第[\u4e00-\u9fa5\u767e\u5343\u96f6]{1,10}回', line) != None):
       return True
   return False

def check_is_sundry(line):
    if (line.find('page') != -1 or line.find('------------') != -1 or line.find('分節閱讀') != -1):
        return True
    return False

def check_word_characteristic(word_flag):
    if(word_flag.find('r') != -1 or word_flag.find('p') != -1 or word_flag.find('c') != -1 or word_flag.find('u') != -1):
        return False
    return True

def init_excel():
    for index, row in enumerate(frequently_used_words):
        sheet.write(index + 1, 0, row)
    for index in range(120):
        sheet.write(0, index + 1, index + 1)
    for i, row in enumerate(frequently_used_words):
        for j in range(120):
            sheet.write(i + 1, j + 1, 0)

def save_date(date, index):
    for item in date:
        sheet.write(frequently_used_words.index(item[0]) + 1, index + 1, item[1])

frequently_used_words = ['道', '說', '是', '也', '又', '人', '來', '去', '不', '便', '有', '笑', '都', '就', '叫', '呢', '見', '一', '聽', '要', '兒', '好', '還', '只', '個', '一個', '上', '到', '才', '問', '倒', '們', '罷', '看', '襲', '忙', '事', '說道', '姑娘', '知道', '吃', '再', '如今', '拿', '起來', '大', '些', '出來', '太太', '將', '衆人', '一面', '奶奶', '沒', '做', '沒有', '想', '裏', '只見', '請', '話', '聽見', '走', '兩個', '不知', '家', '就是', '進來', '二', '平兒', '時', '坐', '東西', '告訴', '回', '回來', '已', '丫頭', '老爺', '下', '卻', '中', '只得', '大家', '子', '帶', '打', '不敢', '送', '先', '命', '小', '多', '可', '出去', '瞧', '不好', '姐姐', '死', '出', '起', '心裏', '過來', '鴛鴦', '二爺', '哭', '屋裏', '一時', '不能', '找', '竟', '今日', '答應', '湘雲', '幾個', '銀子', '住', '更', '正', '說話', '心', '還有', '晴雯', '無', '錢', '三', '病', '快', '知', '怕', '外頭', '字', '茶', '一回', '頭', '自然', '打發', '睡', '後', '問道', '看見', '人家', '麼', '妹妹', '早', '內', '鬧', '媳婦', '不用', '今兒', '忽', '氣', '站', '拉', '方', '會子', '罷了', '皆', '作', '別', '不得', '讓', '聽說', '原來', '到底', '一聲', '裏頭', '家裏', '老', '一句', '回去', '連忙', '使', '喝', '衆', '完', '前', '日', '進去', '很', '婆子', '已經', '放', '一件', '過去', '兩', '麝月', '香菱', '起身', '寫', '方纔', '身上', '太', '哥哥', '心中', '跑', '如', '小廝', '越發', '進', '四', '勸', '喜歡', '罵', '今', '瞧瞧', '手', '誰知', '果然', '玉', '官', '原', '夫人', '一日', '難道', '跟前', '豈', '不必', '酒', '弄', '遂', '丫鬟', '會', '明兒', '象', '吩咐', '時候', '主意', '急', '仍', '不肯', '不成', '月', '接', '母親', '玩', '亦', '難', '詩', '臉', '未', '好些', '一處', '上來', '待', '忘', '明日', '提', '姐兒', '開', '衣裳', '散', '看着', '偏', '放心', '跟着', '敢', '嗎', '不見', '花', '想着', '不覺', '素日', '應', '畢', '疼', '茗', '多少', '娘', '坐下', '紅', '依', '想起', '門', '書', '外', '香', '正說', '點頭', '真']

with open('file/紅樓夢.txt','r') as f:
    is_one_chapter = False
    one_chapter = []
    # all_txt = []
    index = 0

    # 實例化一個Workbook()對象(即excel文件)
    wbk = xlwt.Workbook()
    # 新建一個名爲Sheet1的excel sheet。此處的cell_overwrite_ok =True是爲了能對同一個單元格重複操作。
    sheet = wbk.add_sheet('Sheet1', cell_overwrite_ok=True)

    init_excel()

    for line in f.readlines():
        line = line.strip()
        line = re.sub(r"[0-9\s+\.\!\/_,$%^*()?:;;:-【】+\"\']+|[+——!,;:。?、~@#¥%……&*()]+", "", line)
        if check_is_title(line):
            is_one_chapter = False
            if(is_one_chapter == False and one_chapter.__len__() != 0):
                c = Counter(one_chapter)
                print(c)
                # print(index)
                save_date(list(c.most_common()), index)
                index = index + 1
                one_chapter = []
            print(line)
            is_one_chapter = True
        elif check_is_sundry(line):
            continue
        else:
            if line is not '':
                for word, flag in psg.cut(line.strip()):
                    if (check_word_characteristic(flag) and word in frequently_used_words):
                        # all_txt.append(temp)
                        one_chapter.append(word)
    #最後一回的數據保存
    c = Counter(one_chapter)
    print(c)
    # print(index)
    save_date(list(c.most_common()), index)

    # c = Counter(all_txt)
    # print(c)
    # frequently_used_words = []
    # for index, item in enumerate(list(c.most_common(280))):
    #     frequently_used_words.append(item[0])
    # print(frequently_used_words)

    wbk.save('紅樓夢.xls')

代碼的大致思路是,我們先把全文遍歷一遍,抽出最常出現的280個詞。然後記錄這些單詞,然後我們分章遍歷,記錄這些單詞在每章的出現次數,生成excel表格,爲後邊的數據分析充當原始數據。

然後是數據的分析,這裏我們基本上用的是鏈接文章裏的思想,用的sklean裏的svm,來進行預測,直接上代碼:

from sklearn import svm
import numpy
import random

import xlrd

workbook = xlrd.open_workbook('紅樓夢.xls')
sheet = workbook.sheet_by_index(0)

indexs_in_front_80 = random.sample(range(1,80),15);
indexs_in_end_40 = random.sample(range(81,120),15);

date_x = []
date_y = []
total = []

for index in indexs_in_front_80:
    date_x.append(sheet.col_values(index, 1, -1))
    date_y.append(0)
for index in indexs_in_end_40:
    date_x.append(sheet.col_values(index, 1, -1))
    date_y.append(1)

for index in range(120):
    total.append(sheet.col_values(index + 1, 1, -1))

date_numpy_x = numpy.array(date_x)
date_numpy_y = numpy.array(date_y)
# print(date_x)

clf = svm.LinearSVC()
clf.fit(date_numpy_x,date_numpy_y)

print(clf.predict(total))

error = 0

for index, result in enumerate(clf.predict(total)):
    if index < 80 and result == 1:
        error = error + 1
    if index >= 80 and result == 0:
        error = error + 1
print('錯誤率爲{}'.format(float(error / 100)))

這裏大致流程是把上邊生成的excel文件讀取,從前80章和後40章各取15章,做訓練,然後對全部120章做預測,讓機器去判斷他屬於前80章還是後40章。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章