Python語(yǔ)言結(jié)合機(jī)器學(xué)習(xí)算法進(jìn)行微博預(yù)測(cè)

本文是基于Python語(yǔ)言結(jié)合基礎(chǔ)的機(jī)器學(xué)習(xí)算法來(lái)對(duì)微博傳播廣度下的微博轉(zhuǎn)發(fā)次數(shù)來(lái)進(jìn)行預(yù)測(cè)的,并分析了微博在轉(zhuǎn)發(fā)過(guò)程中有可能出現(xiàn)峰值的時(shí)刻。

1、環(huán)境準(zhǔn)備
  1. 使用語(yǔ)言:python
  2. 軟件IDE:PyCharm
  3. 數(shù)據(jù)來(lái)源:DataCastle(數(shù)據(jù)城堡)原始發(fā)布數(shù)據(jù)
2、理論知識(shí)儲(chǔ)備以及機(jī)器學(xué)習(xí)算法原理圖解
2.1 微博轉(zhuǎn)發(fā)廣度

其中a為發(fā)送原始微博的用戶,b,b1,b2都是用戶a的粉絲,所以a所發(fā)的微博會(huì)被他的所有粉絲看到,假如b轉(zhuǎn)發(fā)了a所發(fā)的微博,則b的所有粉絲即c,c1,c2都可以看到b所轉(zhuǎn)發(fā)的a的那條微博,微博的轉(zhuǎn)發(fā)廣度就是在被轉(zhuǎn)發(fā)人所發(fā)布的這條微博被轉(zhuǎn)發(fā)者所轉(zhuǎn)發(fā)之后所覆蓋的所有用戶。

微博轉(zhuǎn)發(fā)廣度示意圖.png

故這條微博的轉(zhuǎn)發(fā)廣度就為6。如果c還繼續(xù)轉(zhuǎn)發(fā)b所轉(zhuǎn)發(fā)的a發(fā)布的微博,同理,這里不再做演示。

2.2 KNN算法

現(xiàn)已經(jīng)存在一部分樣本數(shù)據(jù),并且每個(gè)數(shù)據(jù)都具有相應(yīng)的標(biāo)簽,然后往此數(shù)據(jù)中輸入新的無(wú)任何標(biāo)簽的數(shù)據(jù)值,然后比較新輸入數(shù)據(jù)的特征與已有的特征作對(duì)比,找出數(shù)據(jù)特征最為相近的數(shù)據(jù)值,將其貼上最多的數(shù)據(jù)值所具有的標(biāo)簽。

KNN原理圖解.jpg
2.3 決策樹算法

決策樹算法是屬于機(jī)器學(xué)習(xí)監(jiān)督學(xué)習(xí)分類算法中的,一般在理解隨機(jī)森林之前要對(duì)決策樹有所理解,其中決策樹就是一個(gè)比較簡(jiǎn)單的是否問(wèn)題,對(duì)所有的問(wèn)題都只會(huì)有是和否兩種結(jié)果供選擇,不同的選擇會(huì)導(dǎo)致不同的樹的走向,直到最終走向葉子結(jié)點(diǎn),決策樹就是在這種不斷分類中而形成的一種樹形的分類算法。

決策樹算法原理.png

從上圖就可以看出,其實(shí)決策樹就是If()語(yǔ)句的層層嵌套,會(huì)一直根據(jù)判斷是否來(lái)樹狀延伸下去。

2.4 隨機(jī)森林算法

隨機(jī)森林首先是一種有放回的分類算法,是基于決策樹的一種算法,其中隨機(jī)森林是通過(guò)決策樹隨機(jī)構(gòu)建的,并且每一棵決策樹之間都是沒(méi)有任何關(guān)聯(lián)的,并且對(duì)數(shù)據(jù)也是進(jìn)行隨機(jī)采樣的,對(duì)特征的選取也是完全隨機(jī)的,然后對(duì)數(shù)據(jù)分別進(jìn)行訓(xùn)練,訓(xùn)練完成之后以一種投票的方式來(lái)決定最終的結(jié)果,隨機(jī)森林這種通過(guò)隨機(jī)和森林的方式可以保證模型的方差降低而不需要進(jìn)行剪枝,也可以取得比較好的泛化能力和抗擬合能力。

隨機(jī)森林算法原理.png
2.5 決策樹算法改進(jìn)原理

本次對(duì)決策樹算法的改進(jìn)是通過(guò)使用sklearn.grid_search庫(kù)下的GridSearchCV方法,通過(guò)對(duì)原始數(shù)據(jù)集進(jìn)行訓(xùn)練,再通過(guò)構(gòu)建決策樹中的參數(shù)列表來(lái)使用網(wǎng)格搜索和交叉驗(yàn)證的暴力搜索方式來(lái)對(duì)決策樹中的各個(gè)參數(shù)的取值進(jìn)行驗(yàn)證,每次獲取某個(gè)參數(shù)的最佳值應(yīng)用到下一次搜索中去,使用迭代的思想對(duì)參數(shù)值進(jìn)行窮盡搜索,根據(jù)得分情況來(lái)對(duì)參數(shù)的取值進(jìn)行統(tǒng)計(jì),最終取出最佳分?jǐn)?shù)值以及對(duì)應(yīng)的最佳參數(shù)列表,直接將最佳參數(shù)的取值應(yīng)用到?jīng)Q策樹算法模型構(gòu)建中去,來(lái)分析算法改進(jìn)前后的性能差異。

決策樹算法改進(jìn)原理.png
2.6 隨機(jī)森林算法改進(jìn)原理

首先隨機(jī)森林是一種隨機(jī)構(gòu)建特征值的機(jī)器學(xué)習(xí)算法,其包含眾多決策樹算法模型,且每一個(gè)決策樹之間都沒(méi)有任何聯(lián)系,基于這種情況,可以采用對(duì)特征值進(jìn)行劃分的方法,將不同的特征值應(yīng)用到不同的隨機(jī)森林模型中去進(jìn)行訓(xùn)練,對(duì)同一條微博的不同預(yù)測(cè)所產(chǎn)生的值去構(gòu)建集合,就可以得到每條微博預(yù)測(cè)值集合,在所統(tǒng)計(jì)的集合中選擇出最佳的單條微博預(yù)測(cè)值,最終將最佳預(yù)測(cè)結(jié)果進(jìn)行整合,構(gòu)成最佳預(yù)測(cè)集合。總的來(lái)說(shuō),改進(jìn)后的隨進(jìn)森林是通過(guò)構(gòu)建多隨機(jī)森林對(duì)數(shù)據(jù)集進(jìn)行多次預(yù)測(cè),每次取出最佳預(yù)測(cè)值,然后組成預(yù)測(cè)集合,再?gòu)募现腥〕稣`差最小的,最后再將所有誤差最小的預(yù)測(cè)結(jié)果進(jìn)行整合,構(gòu)成最佳預(yù)測(cè)集合。

改進(jìn)后的隨機(jī)森林算法原理圖.png

在微博傳播廣度下使用機(jī)器學(xué)習(xí)算法進(jìn)行預(yù)測(cè)的完整代碼如下(其中包括KNN算法、決策樹算法改進(jìn)前后、隨機(jī)森林算法改進(jìn)前后):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Moxiaofei
# @File    : handle.py
# @Software: PyCharm
# 微博傳播廣度下預(yù)測(cè)

# 導(dǎo)入所需要的模塊
import pandas
from sklearn.neighbors import KNeighborsClassifier
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV


# 讀取數(shù)據(jù)
data = pandas.read_csv('handle.csv', sep=' ')
# 定義用于訓(xùn)練時(shí)的特征
x_col = ["emotional_level", "follow_num", "at_flag", "topic_flag", "url_flag", "content_length",
         "time_step", "fans_num", "width1", "width2", "width3", "width4"]
# 定義自變量和目標(biāo)變量
x_train = data[x_col][:14717]
y_train = data['repost_num'][:14717]
# 定義需要預(yù)測(cè)的自變量和目標(biāo)變量
predict_value = data[x_col][14717:]
true_value = data['repost_num'][14717:]


# KNN算法
def knn_algorithm(x_train, y_train):
    # 預(yù)測(cè)出來(lái)的數(shù)據(jù)
    pre_data = (KNeighborsClassifier().fit(x_train, y_train)).predict(predict_value)
    # 平均絕對(duì)百分比誤差
    avg_error = calculate_avg_error(pre_data, true_value)
    accuracy = (100 - avg_error*100)/100
    return avg_error, accuracy


# 決策樹算法
def decisionTree_algorithm(x_train, y_train):
    # 預(yù)測(cè)出來(lái)的數(shù)據(jù)
    pre_data = (tree.DecisionTreeClassifier().fit(x_train, y_train)).predict(predict_value)
    # 平均絕對(duì)百分比誤差
    avg_error = calculate_avg_error(pre_data, true_value)
    accuracy = (100 - avg_error * 100) / 100
    return avg_error, accuracy


# 隨機(jī)森林算法
def randomForest_algorithm(x_train, y_train):
    # 預(yù)測(cè)出來(lái)的數(shù)據(jù)
    pre_data = (RandomForestClassifier().fit(x_train, y_train)).predict(predict_value)
    # 平均絕對(duì)百分比誤差
    avg_error = calculate_avg_error(pre_data, true_value)
    accuracy = (100 - avg_error * 100) / 100
    return avg_error, accuracy


# 改進(jìn)的決策樹算法
def imporve_decisionTree(x_train, y_train):
    decision_tree_classifier = tree.DecisionTreeClassifier(max_features='sqrt')
    # 要選擇的參數(shù)列表
    parameter_grid = {'max_depth': list(range(1, 10)),
                      'min_samples_split': list(range(2, 10)),
                      'min_samples_leaf': list(range(1, 10))}
    # 使用GridSearchCV來(lái)查找最佳參數(shù)
    gridsearch = GridSearchCV(decision_tree_classifier, param_grid=parameter_grid, cv=5)
    gridsearch.fit(x_train, y_train)
    # 取出得分最高的參數(shù)值,并構(gòu)建最佳的決策樹
    best_param = gridsearch.best_params_
    print(best_param)
    best_decision_tree_classifier = tree.DecisionTreeClassifier(max_depth=best_param['max_depth'],
                                                                min_samples_split=best_param['min_samples_split'],
                                                                min_samples_leaf=best_param['min_samples_leaf'])
    # 訓(xùn)練數(shù)據(jù)集  使用預(yù)測(cè)值訓(xùn)練真實(shí)值
    best_decision_tree_classifier.fit(x_train, y_train)
    # 預(yù)測(cè)數(shù)據(jù)集
    best_pre_value = best_decision_tree_classifier.predict(predict_value)
    # 計(jì)算真實(shí)值與預(yù)測(cè)值之間的平均百分比
    best_avg_error = calculate_avg_error(best_pre_value, true_value)
    best_accuracy = (100-100*best_avg_error)/100
    return best_avg_error, best_accuracy


# 改進(jìn)的隨機(jī)森林算法
def improve_randomForest(x_train, y_train):
    # n_estimators的取值范圍
    n_estimators_options = list(range(10, 100, 10))
    sample_leaf_options = list(range(1, 10, 1))
    results = []
    for leaf_size in sample_leaf_options:
        for n_estimators_size in n_estimators_options:
            alg = RandomForestClassifier(min_samples_leaf=leaf_size, n_estimators=n_estimators_size, random_state=50)
            alg.fit(x_train, y_train)
            predict = alg.predict(predict_value)
            average_err = calculate_avg_error(predict, true_value)
            # 用一個(gè)三元組,分別記錄當(dāng)前的 min_samples_leaf,n_estimators, 和平均誤差
            results.append((leaf_size, n_estimators_size, predict, average_err))
    # 打印精度最大的那一個(gè)三元組
    min_pre = min(results, key=lambda x: x[3])
    accuracy_rate = (100 - min_pre[3]*100)/100
    return min_pre[3], accuracy_rate


# 計(jì)算平均絕對(duì)百分比誤差
def calculate_avg_error(pre_value, true_value):
    return float(format(((abs(pre_value - true_value) / true_value).sum()) / len(pre_value), '.2f'))


if __name__ == '__main__':
    error_list = []
    accuracy_list = []

    # KNN算法預(yù)測(cè)出的結(jié)果
    res_knn = knn_algorithm(x_train, y_train)
    error_list.append(res_knn[0])
    accuracy_list.append(res_knn[1])

    # 決策樹算法預(yù)測(cè)出的結(jié)果
    res_decisoinTree = decisionTree_algorithm(x_train, y_train)
    error_list.append(res_decisoinTree[0])
    accuracy_list.append(res_decisoinTree[1])

    # 隨機(jī)森林算法預(yù)測(cè)出的結(jié)果
    res_randomForest = randomForest_algorithm(x_train, y_train)
    error_list.append(res_randomForest[0])
    accuracy_list.append(res_randomForest[1])

    # 改進(jìn)之后的決策樹算法預(yù)測(cè)出的結(jié)果
    res_improve_decisionTree = imporve_decisionTree(x_train, y_train)
    error_list.append(res_improve_decisionTree[0])
    accuracy_list.append(res_improve_decisionTree[1])

    # 改進(jìn)之后的隨機(jī)森林算法預(yù)測(cè)出的結(jié)果
    res_improve_randomForest = improve_randomForest(x_train, y_train)
    error_list.append(res_improve_randomForest[0])
    accuracy_list.append(res_improve_randomForest[1])

    # 打印所使用的算法的預(yù)測(cè)平均絕對(duì)百分比誤差
    print(error_list)
    # 打印所使用的算法的預(yù)測(cè)準(zhǔn)確率
    print(accuracy_list)

在微博傳播廣度下各數(shù)據(jù)特征之間的關(guān)系以及峰值出現(xiàn)的時(shí)刻圖:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : Moxiaofei
# @File    : draw.py
# @Software: PyCharm
# 繪圖

# 導(dǎo)入所需要的模塊
from matplotlib import pyplot as plt
import pandas as pd

# *******************************
# 微博傳播廣度下的圖形繪制
# *******************************
# 讀取數(shù)據(jù)
data = pd.read_csv('handle.csv', sep=' ')

# ------用戶粉絲數(shù)與轉(zhuǎn)發(fā)數(shù)的關(guān)系散點(diǎn)圖------  #
plt.figure(figsize=(7, 5))
fans_num = data['fans_num']
repost_num = data['repost_num']
plt.scatter(fans_num, repost_num)
plt.title('The relationship between fans_num and repost_num')
plt.xlabel('the number of the fans')
plt.ylabel('the number of the repost')
# 保存圖片到本路徑下
# plt.savefig('repost_fans.png', dpi=400, bbox_inches='tight')
# plt.show()

# ------計(jì)算在某個(gè)時(shí)間段內(nèi)轉(zhuǎn)發(fā)次數(shù)最多的,繪制成圖顯示峰值------  #
res = []
# i的取值為[1,11]
for i in range(1, 12):
    res.append(data['width'+str(i+1)] - data['width'+str(i)])
time_repost_num = []
MAX_TIME_DICT = []
for j in range(0, 14767):
    # [32, 85, 1, 267, 95, 74, 18, 8, 103, 33, 17]  所有的差值
    line = [x[j] for x in res]
    # print(line)
    # 最大值所出現(xiàn)的時(shí)刻
    max_sub_time = line.index(max(line)) + int(1)
    MAX_TIME_DICT.append(max_sub_time)
    # 在差值里面統(tǒng)計(jì)時(shí)刻和最大差值
time_count = []
for i in range(1, 12):
    # 輸出出現(xiàn)最大差值的時(shí)刻的數(shù)量
    time_count.append(MAX_TIME_DICT.count(i))
plt.figure(figsize=(7, 5))
time = range(1, 12)
plt.plot(time, time_count)
plt.title('The relationship between time and D-value')
plt.xlabel('the number of the time')
plt.ylabel('the number of the D-value')
# plt.savefig('top.png', dpi=400, bbox_inches='tight')
# plt.show()


#  ------峰值 微博3小時(shí)傳播次數(shù)和總傳播次數(shù)的散點(diǎn)圖------  #
plt.figure(figsize=(7, 5))
x1 = data['width12']
y1 = data['repost_num']
plt.scatter(x1, y1)
plt.title('The relationship between spread_num and repost_num')
plt.xlabel('the number of the spread_num')
plt.ylabel('the number of the repost_num')
# plt.savefig('3_all.png', dpi=400, bbox_inches='tight')
# plt.show()

這里只是簡(jiǎn)述了所使用算法的原理,并對(duì)微博傳播廣度下的轉(zhuǎn)發(fā)數(shù)進(jìn)行預(yù)測(cè)的代碼的展示;此外,還對(duì)微博深度下的特征進(jìn)行了預(yù)測(cè)研究,預(yù)測(cè)了其可能出現(xiàn)峰值的時(shí)刻。需要完整代碼可移步至此

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,412評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,514評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,373評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,975評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,743評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,199評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,414評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,951評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,780評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,218評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,649評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,889評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,673評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,967評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容