Python語言結(jié)合機器學習算法進行微博預測

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

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

其中a為發(fā)送原始微博的用戶屉更,b徙融,b1,b2都是用戶a的粉絲瑰谜,所以a所發(fā)的微博會被他的所有粉絲看到欺冀,假如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ù)军援,并且每個數(shù)據(jù)都具有相應(yīng)的標簽仅淑,然后往此數(shù)據(jù)中輸入新的無任何標簽的數(shù)據(jù)值,然后比較新輸入數(shù)據(jù)的特征與已有的特征作對比胸哥,找出數(shù)據(jù)特征最為相近的數(shù)據(jù)值涯竟,將其貼上最多的數(shù)據(jù)值所具有的標簽。

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

決策樹算法是屬于機器學習監(jiān)督學習分類算法中的空厌,一般在理解隨機森林之前要對決策樹有所理解庐船,其中決策樹就是一個比較簡單的是否問題,對所有的問題都只會有是和否兩種結(jié)果供選擇嘲更,不同的選擇會導致不同的樹的走向筐钟,直到最終走向葉子結(jié)點,決策樹就是在這種不斷分類中而形成的一種樹形的分類算法赋朦。

決策樹算法原理.png

從上圖就可以看出篓冲,其實決策樹就是If()語句的層層嵌套李破,會一直根據(jù)判斷是否來樹狀延伸下去。

2.4 隨機森林算法

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

隨機森林算法原理.png
2.5 決策樹算法改進原理

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

決策樹算法改進原理.png
2.6 隨機森林算法改進原理

首先隨機森林是一種隨機構(gòu)建特征值的機器學習算法川抡,其包含眾多決策樹算法模型,且每一個決策樹之間都沒有任何聯(lián)系须尚,基于這種情況崖堤,可以采用對特征值進行劃分的方法,將不同的特征值應(yīng)用到不同的隨機森林模型中去進行訓練耐床,對同一條微博的不同預測所產(chǎn)生的值去構(gòu)建集合密幔,就可以得到每條微博預測值集合,在所統(tǒng)計的集合中選擇出最佳的單條微博預測值撩轰,最終將最佳預測結(jié)果進行整合胯甩,構(gòu)成最佳預測集合】吧總的來說偎箫,改進后的隨進森林是通過構(gòu)建多隨機森林對數(shù)據(jù)集進行多次預測,每次取出最佳預測值皆串,然后組成預測集合淹办,再從集合中取出誤差最小的,最后再將所有誤差最小的預測結(jié)果進行整合恶复,構(gòu)成最佳預測集合怜森。

改進后的隨機森林算法原理圖.png

在微博傳播廣度下使用機器學習算法進行預測的完整代碼如下(其中包括KNN算法齐遵、決策樹算法改進前后、隨機森林算法改進前后):

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

# 導入所需要的模塊
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_col = ["emotional_level", "follow_num", "at_flag", "topic_flag", "url_flag", "content_length",
         "time_step", "fans_num", "width1", "width2", "width3", "width4"]
# 定義自變量和目標變量
x_train = data[x_col][:14717]
y_train = data['repost_num'][:14717]
# 定義需要預測的自變量和目標變量
predict_value = data[x_col][14717:]
true_value = data['repost_num'][14717:]


# KNN算法
def knn_algorithm(x_train, y_train):
    # 預測出來的數(shù)據(jù)
    pre_data = (KNeighborsClassifier().fit(x_train, y_train)).predict(predict_value)
    # 平均絕對百分比誤差
    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):
    # 預測出來的數(shù)據(jù)
    pre_data = (tree.DecisionTreeClassifier().fit(x_train, y_train)).predict(predict_value)
    # 平均絕對百分比誤差
    avg_error = calculate_avg_error(pre_data, true_value)
    accuracy = (100 - avg_error * 100) / 100
    return avg_error, accuracy


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


# 改進的決策樹算法
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來查找最佳參數(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'])
    # 訓練數(shù)據(jù)集  使用預測值訓練真實值
    best_decision_tree_classifier.fit(x_train, y_train)
    # 預測數(shù)據(jù)集
    best_pre_value = best_decision_tree_classifier.predict(predict_value)
    # 計算真實值與預測值之間的平均百分比
    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


# 改進的隨機森林算法
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)
            # 用一個三元組梗摇,分別記錄當前的 min_samples_leaf,n_estimators想许, 和平均誤差
            results.append((leaf_size, n_estimators_size, predict, average_err))
    # 打印精度最大的那一個三元組
    min_pre = min(results, key=lambda x: x[3])
    accuracy_rate = (100 - min_pre[3]*100)/100
    return min_pre[3], accuracy_rate


# 計算平均絕對百分比誤差
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算法預測出的結(jié)果
    res_knn = knn_algorithm(x_train, y_train)
    error_list.append(res_knn[0])
    accuracy_list.append(res_knn[1])

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

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

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

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

    # 打印所使用的算法的預測平均絕對百分比誤差
    print(error_list)
    # 打印所使用的算法的預測準確率
    print(accuracy_list)

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

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

# 導入所需要的模塊
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)系散點圖------  #
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()

# ------計算在某個時間段內(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)的時刻
    max_sub_time = line.index(max(line)) + int(1)
    MAX_TIME_DICT.append(max_sub_time)
    # 在差值里面統(tǒng)計時刻和最大差值
time_count = []
for i in range(1, 12):
    # 輸出出現(xiàn)最大差值的時刻的數(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ù)的散點圖------  #
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()

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漱凝,一起剝皮案震驚了整個濱河市疮蹦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茸炒,老刑警劉巖愕乎,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異壁公,居然都是意外死亡感论,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門紊册,熙熙樓的掌柜王于貴愁眉苦臉地迎上來比肄,“玉大人,你說我怎么就攤上這事囊陡》技ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵撞反,是天一觀的道長妥色。 經(jīng)常有香客問我,道長痢畜,這世上最難降的妖魔是什么垛膝? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮丁稀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倚聚。我一直安慰自己线衫,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布惑折。 她就那樣靜靜地躺著授账,像睡著了一般枯跑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上白热,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天敛助,我揣著相機與錄音,去河邊找鬼屋确。 笑死纳击,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的攻臀。 我是一名探鬼主播焕数,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刨啸!你這毒婦竟也來了堡赔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤设联,失蹤者是張志新(化名)和其女友劉穎善已,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體离例,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡雕拼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了粘招。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啥寇。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖洒扎,靈堂內(nèi)的尸體忽然破棺而出辑甜,到底是詐尸還是另有隱情,我是刑警寧澤袍冷,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布磷醋,位于F島的核電站,受9級特大地震影響胡诗,放射性物質(zhì)發(fā)生泄漏邓线。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一煌恢、第九天 我趴在偏房一處隱蔽的房頂上張望骇陈。 院中可真熱鬧,春花似錦瑰抵、人聲如沸你雌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婿崭。三九已至拨拓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間氓栈,已是汗流浹背渣磷。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留授瘦,地道東北人醋界。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像奥务,于是被迫代替她去往敵國和親物独。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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