1. 程式人生 > >python 卡方檢驗原理及應用

python 卡方檢驗原理及應用

卡方檢驗,或稱x2檢驗。

無關性假設:
假設我們有一堆新聞或者評論,需要判斷內容中包含某個詞(比如6得很)是否與該條新聞的情感歸屬(比如正向)是否有關,我們只需要簡單統計就可以獲得這樣的一個四格表:

組別  屬於正向    不屬於正向   合計
不包含6得很  19  24  43
包含6得很   34  10  44
合計  53  34  87  

通過這個四格表我們得到的第一個資訊是:內容是否包含某個詞比如6得很確實對新聞是否屬於正向有統計上的差別,包含6得很的新聞屬於正向的比例更高,但我們還無法排除這個差別是否由於抽樣誤差導致。那麼首先假設內容是否包含6得很與新聞是否屬於正向是獨立無關的,隨機抽取一條新聞標題,屬於正向類別的概率是:(19 + 34) / (19 + 34 + 24 +10) = 60.9%

理論值四格表:
第二步,根據無關性假設生成新的理論值四格表:

組別  屬於正向    不屬於正向   合計
不包含6得很  43 * 0.609 = 26.2   43 * 0.391 = 16.8   43
包含6得很   44 * 0.609 = 26.8   44 * 0.391 = 17.2   44

顯然,如果兩個變數是獨立無關的,那麼四格表中的理論值與實際值的差異會非常小。

x2值的計算
這裡寫圖片描述

其中A為實際值,也就是第一個四格表裡的4個數據,T為理論值,也就是理論值四格表裡的4個數據。

x2用於衡量實際值與理論值的差異程度(也就是卡方檢驗的核心思想),包含了以下兩個資訊:

實際值與理論值偏差的絕對大小(由於平方的存在,差異是被放大的)
差異程度與理論值的相對大小

對上述場景可計算x2值為10.01。

卡方分佈的臨界值
既然已經得到了x2值,我們又怎麼知道x2值是否合理?也就是說,怎麼知道無關性假設是否可靠?答案是,通過查詢卡方分佈的臨界值表。
這裡需要用到一個自由度的概念,自由度等於V = (行數 - 1) * (列數 - 1),對四格表,自由度V = 1。
對V = 1,卡方分佈的臨界概率是:

這裡寫圖片描述

顯然10.01 > 7.88,也就是內容是否包含6得很與新聞是否屬於正向無關的可能性小於0.5%,反過來,就是兩者相關的概率大於99.5%。

應用場景
卡方檢驗的一個典型應用場景是衡量特定條件下的分佈是否與理論分佈一致,比如:特定使用者某項指標的分佈與大盤的分佈是否差異很大,這時通過臨界概率可以合理又科學的篩選異常使用者。

另外,x2值描述了自變數與因變數之間的相關程度:x2值越大,相關程度也越大,所以很自然的可以利用x2值來做降維,保留相關程度大的變數。再回到剛才新聞情感分類的場景,如果我們希望獲取和正向類別相關性最強的100個詞,以後就按照內容是否包含這100個詞來確定新聞是否歸屬於正向,怎麼做?很簡單,對正向類所包含的每個詞按上述步驟計算x2值,然後按x2值排序,取x2值最大的100個詞。

#! /usr/bin/env python2.7
#coding=utf-8

"""
Use positive and negative review set as corpus to train a sentiment classifier.
This module use labeled positive and negative reviews as training set, then use nltk scikit-learn api to do classification task.
Aim to train a classifier automatically identifiy review's positive or negative sentiment, and use the probability as review helpfulness feature.

"""

from Preprocessing_module import textprocessing as tp
import pickle
import itertools
from random import shuffle

import nltk
from nltk.collocations import BigramCollocationFinder
from nltk.metrics import BigramAssocMeasures
from nltk.probability import FreqDist, ConditionalFreqDist

import sklearn
from sklearn.svm import SVC, LinearSVC, NuSVC
from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB
from sklearn.linear_model import LogisticRegression
from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.metrics import accuracy_score


# 1. Load positive and negative review data
pos_review = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\pos.xlsx", 1, 1)
neg = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\neg.xlsx", 1, 1)
zhong = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\zhong.xlsx",1,1)
pos = pos_review
neg = neg
zhong = zhong

"""
# Cut positive review to make it the same number of nagtive review (optional)

shuffle(pos_review)
size = int(len(pos_review)/2 - 18)

pos = pos_review[:size]
neg = neg

"""


# 2. Feature extraction function
# 2.1 Use all words as features
def bag_of_words(words):
    return dict([(word, True) for word in words])


# 2.2 Use bigrams as features (use chi square chose top 200 bigrams)
def bigrams(words, score_fn=BigramAssocMeasures.chi_sq, n=200):
    bigram_finder = BigramCollocationFinder.from_words(words)
    bigrams = bigram_finder.nbest(score_fn, n)
    return bag_of_words(bigrams)


# 2.3 Use words and bigrams as features (use chi square chose top 200 bigrams)
def bigram_words(words, score_fn=BigramAssocMeasures.chi_sq, n=200):
    bigram_finder = BigramCollocationFinder.from_words(words)
    bigrams = bigram_finder.nbest(score_fn, n)
    return bag_of_words(words + bigrams)


# 2.4 Use chi_sq to find most informative features of the review
# 2.4.1 First we should compute words or bigrams information score
def create_word_scores():
    posdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\pos.xlsx", 1, 1)
    negdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\neg.xlsx", 1, 1)
    zhongdata = negdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\zhong.xlsx", 1, 1)

    posWords = list(itertools.chain(*posdata))
    negWords = list(itertools.chain(*negdata))
    zhongWords = list(itertools.chain(*zhongdata))

    word_fd = FreqDist()
    cond_word_fd = ConditionalFreqDist()
    for word in posWords:
        word_fd.inc(word)
        cond_word_fd['pos'].inc(word)
    for word in negWords:
        word_fd.inc(word)
        cond_word_fd['neg'].inc(word)
    for word in zhongWords:
        word_fd.inc(word)
        cond_word_fd['zhong'].inc(word)
    pos_word_count = cond_word_fd['pos'].N()
    neg_word_count = cond_word_fd['neg'].N()
    zhong_word_count = cond_word_fd['zhong'].N()
    #print zhong_word_count
    total_word_count = pos_word_count + neg_word_count + zhong_word_count

    word_scores = {}
    for word, freq in word_fd.iteritems():
        pos_score = BigramAssocMeasures.chi_sq(cond_word_fd['pos'][word], (freq, pos_word_count), total_word_count)
        neg_score = BigramAssocMeasures.chi_sq(cond_word_fd['neg'][word], (freq, neg_word_count), total_word_count)
        zhong_score = BigramAssocMeasures.chi_sq(cond_word_fd['zhong'][word], (freq, zhong_word_count), total_word_count)
        word_scores[word] = pos_score + neg_score +zhong_score

    return word_scores

def create_bigram_scores():
    posdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\pos.xlsx", 1, 1)
    negdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\neg.xlsx", 1, 1)
    zhongdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\zhong.xlsx", 1, 1)

    posWords = list(itertools.chain(*posdata))
    negWords = list(itertools.chain(*negdata))
    zhongWords = list(itertools.chain(*zhongdata))

    bigram_finder = BigramCollocationFinder.from_words(posWords)
    bigram_finder = BigramCollocationFinder.from_words(negWords)
    bigram_finder = BigramCollocationFinder.from_words(zhongWords)
    posBigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, 8000)
    negBigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, 8000)
    zhongBigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, 8000)
    pos = posBigrams
    neg = negBigrams
    zhong = zhongBigrams
    word_fd = FreqDist()
    cond_word_fd = ConditionalFreqDist()
    for word in pos:
        word_fd.inc(word)
        cond_word_fd['pos'].inc(word)
    for word in neg:
        word_fd.inc(word)
        cond_word_fd['neg'].inc(word)
    for word in neg:
        word_fd.inc(word)
        cond_word_fd['zhong'].inc(word)
    pos_word_count = cond_word_fd['pos'].N()
    neg_word_count = cond_word_fd['neg'].N()
    zhong_word_count = cond_word_fd['zhong'].N()
    total_word_count = pos_word_count + neg_word_count + zhong_word_count

    word_scores = {}
    for word, freq in word_fd.iteritems():
        pos_score = BigramAssocMeasures.chi_sq(cond_word_fd['pos'][word], (freq, pos_word_count), total_word_count)
        neg_score = BigramAssocMeasures.chi_sq(cond_word_fd['neg'][word], (freq, neg_word_count), total_word_count)
        zhong_score = BigramAssocMeasures.chi_sq(cond_word_fd['zhong'][word], (freq, neg_word_count), total_word_count)
        word_scores[word] = pos_score + neg_score + zhong_score

    return word_scores

# Combine words and bigrams and compute words and bigrams information scores
def create_word_bigram_scores():
    posdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\pos.xlsx", 1, 1)
    negdata = tp.seg_fil_senti_excel(r"D:\tomcat\review_protection\Feature_extraction_module\Sentiment_features\Machine learning features\seniment review set\neg.xlsx", 1, 1)

    posWords = list(itertools.chain(*posdata))
    negWords = list(itertools.chain(*negdata))

    bigram_finder = BigramCollocationFinder.from_words(posWords)
    bigram_finder = BigramCollocationFinder.from_words(negWords)
    posBigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, 5000)
    negBigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, 5000)

    pos = posWords + posBigrams
    neg = negWords + negBigrams

    word_fd = FreqDist()
    cond_word_fd = ConditionalFreqDist()
    for word in pos:
        word_fd.inc(word)
        cond_word_fd['pos'].inc(word)
    for word in neg:
        word_fd.inc(word)
        cond_word_fd['neg'].inc(word)

    pos_word_count = cond_word_fd['pos'].N()
    neg_word_count = cond_word_fd['neg'].N()
    total_word_count = pos_word_count + neg_word_count

    word_scores = {}
    for word, freq in word_fd.iteritems():
        pos_score = BigramAssocMeasures.chi_sq(cond_word_fd['pos'][word], (freq, pos_word_count), total_word_count)
        neg_score = BigramAssocMeasures.chi_sq(cond_word_fd['neg'][word], (freq, neg_word_count), total_word_count)
        word_scores[word] = pos_score + neg_score

    return word_scores

# Choose word_scores extaction methods
word_scores = create_word_scores()
#word_scores = create_bigram_scores()
# word_scores = create_word_bigram_scores()


# 2.4.2 Second we should extact the most informative words or bigrams based on the information score
def find_best_words(word_scores, number):
    best_vals = sorted(word_scores.iteritems(), key=lambda (w, s): s, reverse=True)[:number]
    best_words = set([w for w, s in best_vals])
    return best_words

# 2.4.3 Third we could use the most informative words and bigrams as machine learning features
# Use chi_sq to find most informative words of the review
def best_word_features(words):
    return dict([(word, True) for word in words if word in best_words])

# Use chi_sq to find most informative bigrams of the review
def best_word_features_bi(words):
    return dict([(word, True) for word in nltk.bigrams(words) if word in best_words])

# Use chi_sq to find most informative words and bigrams of the review
def best_word_features_com(words):
    d1 = dict([(word, True) for word in words if word in best_words])
    d2 = dict([(word, True) for word in nltk.bigrams(words) if word in best_words])
    d3 = dict(d1, **d2)
    return d3



# 3. Transform review to features by setting labels to words in review
def pos_features(feature_extraction_method):
    posFeatures = []
    #print "pos"
    for i in pos:
        #for key in feature_extraction_method(i):
            #print key
        posWords = [feature_extraction_method(i),'pos']
        posFeatures.append(posWords)
    return posFeatures

def neg_features(feature_extraction_method):
    negFeatures = []
    #print "neg"
    for j in neg:
        #for key in feature_extraction_method(j):
          # print key
        negWords = [feature_extraction_method(j),'neg']
        negFeatures.append(negWords)
    return negFeatures

def zhong_Features(feature_extraction_method):
    zhongFeatures = []
    print "zhong"
    for j in zhong:
        for key in feature_extraction_method(j):
            print key
        zhongWords = [feature_extraction_method(j),'zhong']
        zhongFeatures.append(zhongWords)
    return zhongFeatures
best_words = find_best_words(word_scores, 1000) # Set dimension and initiallize most informative words

posFeatures = pos_features(best_word_features_com)
negFeatures = neg_features(best_word_features_com)
zhongFeatures = zhong_Features(best_word_features_com)
# posFeatures = pos_features(bigram_words)
# negFeatures = neg_features(bigram_words)

#posFeatures = pos_features(best_word_features)
#print type(posFeatures)

#negFeatures = neg_features(best_word_features)
#zhongFeatures = zhong_Features(best_word_features)
# posFeatures = pos_features(best_word_features_com)
# negFeatures = neg_features(best_word_features_com)

結果如下:

中性情感詞:
普及
成為
家庭
資訊
成
事件
謀求
事情
產生
輿論
引發
發生
當而
方
場
人們
相信
世界
翻轉
反
公眾
羅爾
網路時代
規則
對稱
應該
面對
更要
對立
不要
媒體
微信
一輪
網路
號
換位
陣營
網友
都
技能
不明智
新聞
很
激烈
不
蘊藏
聰明反被聰明誤
相關
社交
大
刷屏
二小
學會
感到
越來越
人
清晰
中關村
破壞
微博
影響
彙集
屢有
不同
真實性
正向情感詞:

榮譽證書
去年
第二
名叫
年前
寫
會
節省
患
同意
收下
申請
爬
李慶國
當下
無疑
搶救
8
買藥
但確
湊
健康
難以
醫藥費
好心人
家裡
感謝
19
仍然
年
一年
廣懷
呼吸困難
公里
二
江蘇
學校
母親
長大
小時
狀態
看起來
常態
成功
暈倒
爬樓梯
3
出發
一拖再拖
無法
患有
想法
期限
趕到
減輕
出去
出現
火車
最早
父母



負向情感詞:
改革
往往
率
取消
月
說法
中止執行
會
搞
存在
事情
案件
工作
執行
資料
司法
視訊
後續
迴應
刑事拘留
指標
不合理
法
不
應該
法院
會議
日
這次
澎湃
之前
數
不算
考核
卻
告別
堅決
其實
屢屢
提出
必要
任務
手段
結案率
進行
執法
法官
撤案
審理
新
罰款
法律
不停
年
年底
專案
不是
杜絕
承德縣

相關推薦

python 檢驗原理應用

卡方檢驗,或稱x2檢驗。 無關性假設: 假設我們有一堆新聞或者評論,需要判斷內容中包含某個詞(比如6得很)是否與該條新聞的情感歸屬(比如正向)是否有關,我們只需要簡單統計就可以獲得這樣的一個四格表: 組別 屬於正向 不屬於正向 合計 不包含

機器學習中的數學(8)——檢驗原理應用

卡方檢驗原理及應用 什麼是卡方檢驗 卡方檢驗是一種用途很廣的計數資料的假設檢驗方法。它屬於非引數檢驗的範疇,主要是比較兩個及兩個以上樣本率( 構成比)以及兩個分類變數的關聯性分析。其根本思想就是在於比較理論頻數和實際頻數的吻合程度或擬合優度問題。 無關

檢驗思想及其應用

卡方檢驗是以χ2分佈為基礎的一種常用假設檢驗方法,它的無效假設H0是:觀察頻數與期望頻數沒有差別。   該檢驗的基本思想是:首先假設H0成立,基於此前提計算出χ2值,它表示觀察值與理論值之間的偏離

python Ridge 回歸(嶺回歸)的原理應用

原理 blog 得到 one 技術 設置 fun src print 嶺回歸的原理: 首先要了解最小二乘法的回歸原理 設有多重線性回歸模型 y=Xβ+ε ,參數β的最小二乘估計為 當自變量間存在多重共線性,|X‘X|≈0時,設想|X‘X|給加上一個正常數矩陣(k>

selenium + python自動化測試unittest框架學習(一)selenium原理應用

自動化 網上 下載安裝 src .cn 基礎 client cnblogs pytho unittest框架的學習得益於蟲師的《selenium+python自動化實踐》這一書,該書講得很詳細,大家可以去看下,我也只學到一點點用於工作中,閑暇時記錄下自己所學才能更加印象深刻

爾曼濾波原理應用(一)

出於科研需要,打算開始學習卡爾曼濾波(Kalmam Filter)。很早之前就聽說過卡爾曼濾波,但一直沒能深入學習,這次終於有機會了,哈哈。 1.卡爾曼濾波的發展過程 卡爾曼濾波的本質屬於"估計"範疇.先介紹下估計,所謂“估計”問題,就是對收到隨機干擾和隨機測量誤差作用的物理系統,按照某種效

Python資料預處理之---統計學的t檢驗檢驗以及均值,中位數等

Python資料預處理過程:利用統計學對資料進行檢驗,對連續屬性檢驗正態分佈,針對正態分佈屬性繼續使用t檢驗檢驗方差齊次性,針對非正態分佈使用Mann-Whitney檢驗。針對分類變數進行卡方檢驗(涉及三種卡方的檢驗:Pearson卡方,校準卡方,精準卡方)等。

Python統計分析-檢驗

卡方檢驗是一種用途很廣的計數資料的假設檢驗方法。它屬於非引數檢驗的範疇,主要是比較兩個及兩個以上樣本率( 構成比)以及兩個分類變數的關聯性分析。其根本思想就是在於比較理論頻數和實際頻數的吻合程度或擬合優度問題。 卡方檢驗的基本思想: 卡方檢驗是以χ2\chi^2

特徵選擇——檢驗(使用Python sklearn進行實現)

在看這篇文章之前,如果對卡方檢驗不熟悉,可以先參考:卡方檢驗 Python有包可以直接實現特徵選擇,也就是看自變數對因變數的相關性。今天我們先開看一下如何用卡方檢驗實現特徵選擇。 1. 首先import包和實驗資料: from sklearn.feature_selecti

Python邏輯回歸原理實際案例應用

repo 項目 isf 最優解 oss 重命名 梯度下降法 根據 最小 前言 上面我們介紹了線性回歸, 嶺回歸, Lasso回歸, 今天我們來看看另外一種模型—"邏輯回歸". 雖然它有"回歸"一詞, 但解決的卻是分類問題 目錄 1. 邏輯回歸 2. 優缺點及優化問題 3.

分佈與檢驗------以及python的實現

經典的卡方檢驗是檢驗定性自變數對定性因變數的相關性。假設自變數有N種取值,因變數有M種取值,考慮自變數等於i且因變數等於j的樣本頻數的觀察值與期望的差距,構建統計量:   這個統計量的含義簡而言之就是自變數對因變數的相關性。用feature_selection庫的SelectKBest類

檢驗和互信息

其中 學習 learn 介紹 ear div 合計 應該 python實現 在機器學習中,特征選擇主要有兩個目的: 1. 減少特征數量,提高訓練速度 2. 減少噪聲特征從而提高模型在測試集上的準確率。一些噪聲特征會導致模型出現錯誤的泛化,容易產生overfittin

數據庫原理應用——關系數據庫

block 關系數據庫 ces and 卡爾 svg 數據庫原理 -m 元組 關系數據結構 實體,實體間的聯系都是關系表示,用戶角度的邏輯結構就是二維表 關系:笛卡爾積的子集 關系操作集合 傳統集合操作:並、交、差、笛卡爾積 專門的關系運算:

數據庫原理應用(SQL Server 2016數據處理)【上海精品視頻課程】

應用 原理 sql 信息無處不在,數據處理無處不用。物質、信息、能源已經成為人類生存和發展的重要保障。數據庫的應用廣度深度及建設規模已經成為衡量一個國家信息化程度的一項重要標誌。數據庫技術是計算機學科的一個重要分支,反映了數據管理的最新技術。數據庫技術與計算機網絡、人工智能一起被稱為計算機三大

VUE -- JSONP的誕生、原理應用實例

some body 發送 我們 att box 想要 random ati 問題: 頁面中有一個按鈕,點擊之後會更新網頁中的一個盒子的內容。 Ajax可以很容易的滿足這種無須刷新整個頁面就可以實現數據變換的需求。 但是,Ajax有一個缺點,就是他不允許跨域請求資源。

MyBatis的原理應用

sql 關系 str dma 事務管理器 space ransac 文件的 讀取 MyBatis是一個基於Java的持久層ORM關系映射框架,是一種支持定制化 SQL、存儲過程以及高級映射的優秀的持久層框架。它避免了幾乎所有的 JDBC 代碼和手工設置參數以及抽取結果集。

SpringAOP原理應用

call span 簡述 ... 開始 spring源碼 gpo 業務 eat SpringAOP原理及應用 一、背景 什麽是AOP,英文直譯是Aspect-OrientedProgramming,面向方面編程。從名字也可以看出,如果把我們代碼的執行過程

數據庫原理應用-數據庫管理系統 DBMS

元組 並且 大小 持久 currency 小型 解決方法 結果 表達式 2018-02-20 14:35:34 數據庫管理系統(英語:database management system,縮寫:DBMS) 是一種針對對象數據庫,為管理數據庫而設計的大型電腦軟件管理系統。具有

Docker五種存儲驅動原理應用場景和性能測試對比

Docker 存儲驅動 Docker最開始采用AUFS作為文件系統,也得益於AUFS分層的概念,實現了多個Container可以共享同一個image。但由於AUFS未並入Linux內核,且只支持Ubuntu,考慮到兼容性問題,在Docker 0.7版本中引入了存儲驅動, 目前,Docker支持AUFS

數學知識點查漏補缺(分布與檢驗

檢驗 element 影響 body protect 兩個 ram -m style 一、卡方分布 若k個獨立的隨機變量Z1,Z2,?,Zk,且符合標準正態分布N(0,1),則這k個隨機變量的平方和,為服從自由度為k的卡方分布。 卡方分布之所以經常被利用到,是因為對符合正態