連語表現の一覧

I went to school yesterday.

I went
  went to
       to school
          school yesterday

ファイルを窓を開いて選択し、2語表現(2-gram)の一覧を出力する

my2gram <- function(){
  
  ngramV <- c()                                           # ベクトルとしてまとめる
  
    lines.tmp <- scan(choose.files(), what="char", sep="\n")
    data.tmp <- grep("\\*(JPN|NS)...:\t", lines.tmp, value=T)
    body.tmp <- gsub("\\*(JPN|NS)...:\t", "", data.tmp)
    body.tmp <- body.tmp[body.tmp != ""] #空行を削除。
    body.tmp.lower <- tolower(body.tmp) # 小文字に
    token.tmp <- unlist(strsplit(body.tmp.lower, "\\W+")) # 単語に
    token.tmp = token.tmp[token.tmp !=""] # あるのだけに

    for (i in 1:(length(token.tmp)-1)) {                  # 単語数マイナス1
    #cat(token.tmp[i], token.tmp[i+1], "\n")               # i語目とi+1語目を出力
      tmp <- paste(token.tmp[i], token.tmp[i+1], collapse=" ") # pasteで二つの要素をつなげる
      ngramV <- c(ngramV, tmp)               # i語目とi+1語目を出力
    }
    ngramV
}
my2gram()

連語表現を並べ替えて頻度一覧表を作る

bigram.tmp <- my2gram()                                  # bigramの出力結果を保存

bigram.tmp                        # 中を見てみる

bigram.tmp.sorted <- sort(bigram.tmp)          # 並べ替える

head(bigram.tmp.sorted)                 # 並べ替えた結果の先頭部分を見てみる

table(bigram.tmp.sorted)                 # 頻度一覧表にする

sort(table(bigram.tmp.sorted), decreasing = T)           # 多いもの順に並べ替える

head(sort(table(bigram.tmp.sorted), decreasing = T))     # 多いもの順に並べ替えたものの先頭部分を見る

フォルダー内のすべてのファイルを対象に、2語表現(2-gram)の一覧を出力する

my2gramFiles <- function(){
  
  files <- list.files()
  
  ngramFilesV <- c()
  
  for(j in files){
  
    ngramV <- c()                                           # ベクトルとしてまとめる
  
    #lines.tmp <- scan(choose.files(), what="char", sep="\n")                # ファイルを選ぶのではなく
    lines.tmp <- scan(j, what="char", sep="\n")                # list.filesからのファイルを一つずつ 
    data.tmp <- grep("\\*(JPN|NS)...:\t", lines.tmp, value=T)
    body.tmp <- gsub("\\*(JPN|NS)...:\t", "", data.tmp)
    body.tmp <- body.tmp[body.tmp != ""] #空行を削除。
    body.tmp.lower <- tolower(body.tmp) # 小文字に
    token.tmp <- unlist(strsplit(body.tmp.lower, "\\W+")) # 単語に
    token.tmp = token.tmp[token.tmp !=""] # あるのだけに

    for (i in 1:(length(token.tmp)-1)) {                  # 単語数マイナス1
        #cat(token.tmp[i], token.tmp[i+1], "\n")               # i語目とi+1語目を出力
      tmp <- paste(token.tmp[i], token.tmp[i+1], collapse=" ") # pasteで二つの要素をつなげる
      ngramV <- c(ngramV, tmp)               # i語目とi+1語目を出力
    }
    ngramFilesV <- c(ngramFilesV, ngramV)      # ファイルごとのデータを累積する
  }
ngramFilesV  
}
  • 実行:母語話者データの場合

setwd("NICER1_3/NICER_NS")      # どちらか選ぶ
#setwd("NICER1_3/NICER_NNS")

bigramFiles <- my2gramFiles()

#head(bigramFiles)
head(sort(table(sort(bigramFiles)), decreasing = T))
## 
##    of the    in the     it is    to the     to be the world 
##       388       370       188       161       155       130

学習者データの場合

#setwd("NICER1_3/NICER_NS")      # どちらか選ぶ
setwd("NICER1_3/NICER_NNS")

bigramFiles <- my2gramFiles()

#head(bigramFiles)
head(sort(table(sort(bigramFiles)), decreasing = T))
## 
##       it is     i think      in the       don t high school       a lot 
##         533         467         353         329         288         280

ファイルを選んで、2連語で、上位10位まで

my2gramTop10 <- function(){
  
  ngramV <- c()                                           # ベクトルとしてまとめる
  
    lines.tmp <- scan(choose.files(), what="char", sep="\n")
    data.tmp <- grep("\\*(JPN|NS)...:\t", lines.tmp, value=T)
    body.tmp <- gsub("\\*(JPN|NS)...:\t", "", data.tmp)
    body.tmp <- body.tmp[body.tmp != ""] #空行を削除。
    body.tmp.lower <- tolower(body.tmp) # 小文字に
    token.tmp <- unlist(strsplit(body.tmp.lower, "\\W+")) # 単語に
    token.tmp = token.tmp[token.tmp !=""] # あるのだけに

    for (i in 1:(length(token.tmp)-1)) {                  # 単語数マイナス1
    #cat(token.tmp[i], token.tmp[i+1], "\n")               # i語目とi+1語目を出力
      tmp <- paste(token.tmp[i], token.tmp[i+1], collapse=" ") # pasteで二つの要素をつなげる
      ngramV <- c(ngramV, tmp)               # i語目とi+1語目を出力
    }
    ngramV

bigram.tmp <- ngramV                  # 中を見てみる

bigram.tmp.sorted <- sort(bigram.tmp)          # 並べ替える

sort(table(bigram.tmp.sorted), decreasing = T)           # 多いもの順に並べ替える

head(sort(table(bigram.tmp.sorted), decreasing = T), 10)     # 多いもの順に並べ替えたものの先頭部分を見る

}

実行

my2gramTop10()

ファイルを選んで、2連語で、上位何位まで表示するか指定できるようにする

my2gramTopN <- function(a){                                 # function(a)で、a に「引数」をとる
  
  ngramV <- c()                                          
  
    lines.tmp <- scan(choose.files(), what="char", sep="\n")
    data.tmp <- grep("\\*(JPN|NS)...:\t", lines.tmp, value=T)
    body.tmp <- gsub("\\*(JPN|NS)...:\t", "", data.tmp)
    body.tmp <- body.tmp[body.tmp != ""] #空行を削除。
    body.tmp.lower <- tolower(body.tmp) # 小文字に
    token.tmp <- unlist(strsplit(body.tmp.lower, "\\W+"))
    token.tmp = token.tmp[token.tmp !=""] # あるのだけに

    for (i in 1:(length(token.tmp)-1)) {                  
    #cat(token.tmp[i], token.tmp[i+1], "\n")               
      tmp <- paste(token.tmp[i], token.tmp[i+1], collapse=" ") 
      ngramV <- c(ngramV, tmp)               
    }
    ngramV

bigram.tmp <- ngramV                 

bigram.tmp.sorted <- sort(bigram.tmp)         

#sort(table(bigram.tmp.sorted), decreasing = T)          

head(sort(table(bigram.tmp.sorted), decreasing = T), a)     # 順位を a で設定する

}

実行

my2gramTopN(20)

ディレクトリー内のすべてのファイルを対象に、3連語で、指定した順位まで

my3gramFilesN <- function(a){
  
  files <- list.files()
  
  ngramFilesV <- c()
  
  for(j in files){
  
    ngramV <- c()                                          
  
    #lines.tmp <- scan(choose.files(), what="char", sep="\n")               
    lines.tmp <- scan(j, what="char", sep="\n")                 
    data.tmp <- grep("\\*(JPN|NS)...:\t", lines.tmp, value=T)
    body.tmp <- gsub("\\*(JPN|NS)...:\t", "", data.tmp)
    body.tmp <- body.tmp[body.tmp != ""]
    body.tmp.lower <- tolower(body.tmp) 
    token.tmp <- unlist(strsplit(body.tmp.lower, "\\W+")) 
    token.tmp = token.tmp[token.tmp !=""] 

    for (i in 1:(length(token.tmp)-2)) {                  # 単語数マイナス2

      tmp <- paste(token.tmp[i], token.tmp[i+1], token.tmp[i+2], collapse=" ") # pasteで3つの要素をつなげる
      ngramV <- c(ngramV, tmp)               # i語目とi+1語目とi+2語目を出力
    }
    ngramFilesV <- c(ngramFilesV, ngramV)      # ファイルごとのデータを累積する
  }
ngramFilesV

ngramFilesV.sorted <- sort(ngramFilesV) 

head(sort(table(ngramFilesV.sorted), decreasing = T), a)     # 順位を a で設定する


}

実行

#setwd("NICER1_3/NICER_NS")      # どちらか選ぶ
setwd("NICER1_3/NICER_NNS")

my3gramFilesN(10)
## ngramFilesV.sorted
##           a lot of       i think that junior high school         when i was 
##                262                149                121                109 
##          i want to          and so on       in the world            i don t 
##                107                 99                 94                 84 
##         one of the            i was a 
##                 76                 71

出現頻度の検定:カイ自乗検定

例: 副詞の生起位置

a. However, such men don't make good husbands.
b. Such men, however, don't make good husbands.
c. Such men don't, however, make good husbands.
d. Such men don't make good husbands, however.
             (Halliday, 1985: 82)
  • 文頭・文中・文末のどこにでも置くことができる。 *実際は、どうなのか、コーパスで観察する。

LOB コーパス中のhowever の生起位置を調べたところ、次のような結果になった。

文頭 109 文中 347 文末 8

  • はて、本当にどこに置いてもよいのか、それとも、「偏り」があるのか。
  • 頻度の差が、偶然による誤差のうちなのか、誤差とは言えないのか、カイ自乗検定で調べる。

頻度に差があるか: chisq:test()

however.data <- c(109, 347, 8)

chisq.test(however.data)
## 
##  Chi-squared test for given probabilities
## 
## data:  however.data
## X-squared = 391.74, df = 2, p-value < 2.2e-16
  • 2.2e-16 意味は、2.2×10-16 (つまりほとんどゼロ)
  • このバラつきは、偶然の誤差とは言えない。

文末は、少ないのでほとんど使わないとして、文頭と文中の使い分けに何か原則があるのだろうか?

Sugiura, M. (1991:平成 3年 3月 1日). The Distribution Environment of the Connective “However” and the Principle of Its Position —Based on the LOB Corpus—. 『中部大学女子短期大学紀要・言語文化研究』, 2, 47-63. https://ci.nii.ac.jp/lognavi?name=nels&lang=ja&type=pdf&id=ART0000872455&naid=110000483331

二次元の頻度差を考える。

イギリス英語とアメリカ英語で、 therefore の生起位置に違いがあるか。

位置 英 米 文頭 15 38 文中 96 53

行列データを作る:matrix()

  • c( , , , )の中のデータは、まず列(row)順に並べていく
  • nrow は行数、ncol は列数
therefore.data <- matrix(c(15,96,38,53), nrow=2, ncol=2)

chisq.test(therefore.data)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  therefore.data
## X-squared = 19.179, df = 1, p-value = 1.19e-05
  • イギリス英語とアメリカ英語で、therefore の生起位置に有意な偏りがある

可視化: mozaicplot()

mosaicplot(however.data)

mosaicplot(therefore.data)

どこに差があるか:残差分析

群馬大学の青木先生のサイト

   http://aoki2.si.gunma-u.ac.jp/R/     * 度数に関する検定 * カイ二乗分布を使用する独立性の検定と残差分析

source("http://aoki2.si.gunma-u.ac.jp/R/src/my-chisq-test.R", encoding="euc-jp")
  • my-chisq-test.Rというファイル名だが、関数名はmy.chisq.test()
my.chisq.test(therefore.data)
## 
##  カイ二乗分布を用いる独立性の検定(残差分析)
## 
## data:  therefore.data
## X-squared = 20.612, df = 1, p-value = 5.623e-06
result.ct <- my.chisq.test(therefore.data)

summary(result.ct)
## 調整された残差
##         [,1]    [,2]
## [1,] -4.5401  4.5401
## [2,]  4.5401 -4.5401
## 
## P 値
##            [,1]       [,2]
## [1,] 5.6231e-06 5.6231e-06
## [2,] 5.6231e-06 5.6231e-06
  • (結果の解釈例)
  • カイ二乗検定の結果より、イギリス英語とアメリカ英語で、therefore の生起位置に有意な偏りがある。残差分析の結果より、イギリス英語では、アメリカ英語に比べて、therefore を文中で用いる頻度が有意に高く、文頭で用いる頻度が有意に低いことが分かる。

対数尤度比検定:G^2

  • #カイ二乗検定よりも統計理論的には、対数尤度比検定を利用する方が望ましい。 *(カイ二乗検定は対数尤度の近似、対数尤度比検定は対数尤度を直接扱う)
source("http://aoki2.si.gunma-u.ac.jp/R/src/G2.R", encoding="euc-jp")

G2(therefore.data)
## 
##  対数尤度比に基づく独立性の検定(G-squared test)
## 
## data:  therefore.data
## G-squared = 20.925, df = 1, p-value = 4.776e-06

サンプルサイズに関係ない効果量

2×2の場合

  • オッヅ比:Fisherの直接確率検定(正確確率検定): fisher.test()
  • 解釈の仕方:「1」が基準=確率に差はない。1より大きければ、分子の方の確率が高い。
fisher.test(therefore.data)
## 
##  Fisher's Exact Test for Count Data
## 
## data:  therefore.data
## p-value = 9.958e-06
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
##  0.1021974 0.4526589
## sample estimates:
## odds ratio 
##  0.2196899

2x2以上の場合

  • クラメールのV(Cramer’s V)
  • 解釈の仕方:0から1の間
install.packages("lsr", dependencies = T, repos="http://cran.rstudio.com/")
##  パッケージを 'C:/Users/sgrm/R/win-library/4.1' 中にインストールします 
##  ('lib' が指定されていないため)
## package 'lsr' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\Public\Documents\Wondershare\CreatorTemp\Rtmp427Scj\downloaded_packages
library(lsr)

cramersV(therefore.data)
## [1] 0.3081308

調べたい表現の頻度


コーパス分析専用パッケージの利用

quanteda: Quantitative Analysis of Textual Data

http://sugiura-ken.org/wiki/wiki.cgi/exp?page=quanteda