1

町の名前を含む 2 つのベクトルがあり、どちらも異なる形式であり、水域 (水) の名前をそれぞれの国勢調査データ (町) に一致させる必要があります。基本的に、water の各行について、町で最もよく一致するものを知る必要があります。それらのほとんどには、city などの類似した単語が含まれているからです。私が目にするもう 1 つの問題は、あるデータ セットでは単語が大文字であり、別のデータ セットでは大文字ではないということです。これが私のサンプルデータです:

towns= c("Acalanes Ridge CDP, Contra Costa County", "Bellflower city, Los Angeles County", "Arvin city, Kern County", "Alturas city, Modoc County")

water=c("Alturas City of","Casitas Municipal Water District","California Water Service Company Bellflower City", "Contra Costa City of Public Works")
4

2 に答える 2

2

tmおよびパッケージを使用するとslam、これはテキスト処理技術を組み込んだ単純ではないアプローチになります。

## load the requisite libraries
library(tm)
library(slam)

まず、組み合わせた町と水のベクトルからコーパスを作成します。最終的には、テキストに基づいて、すべての町とすべての水域の間の距離を計算します。

corpus <- Corpus(VectorSource((c(towns, water))))

ここでは、句読点を削除して「ドキュメント」をステミングすることで、標準的な前処理を行います。ステミングは、単語の共通の基本部分を見つけます。たとえば、都市と都市の語幹は同じです: citi

corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, stemDocument)

標準的な Term Document Matrix には、どの単語がどのドキュメントに含まれているかを示すバイナリ インジケーターがあります。単語がコーパス全体でどのくらいの頻度であるかについての追加情報もエンコードしたいと考えています。たとえば、"the" は非常に一般的であるため、ドキュメントにどのくらいの頻度で表示されるかは気にしません。

tdm <- weightTfIdf(TermDocumentMatrix(corpus))

最後に、すべてのドキュメント間のコサイン距離を計算します。このtmパッケージは、通常非常にメモリ効率の良い疎行列を作成します。このslamパッケージには、疎行列用の行列数学関数が含まれています。

cosine_dist <- function(tdm) {
  crossprod_simple_triplet_matrix(tdm)/(sqrt(col_sums(tdm^2) %*% t(col_sums(tdm^2))))
}

d <- cosine_dist(tdm)
> d
    Docs
Docs          1           2           3           4          5         6           7           8
   1 1.00000000 0.034622992 0.038063800 0.044272011 0.00000000 0.0000000 0.000000000 0.260626250
   2 0.03462299 1.000000000 0.055616255 0.064687275 0.01751883 0.0000000 0.146145917 0.006994714
   3 0.03806380 0.055616255 1.000000000 0.071115850 0.01925984 0.0000000 0.006633427 0.007689843
   4 0.04427201 0.064687275 0.071115850 1.000000000 0.54258275 0.0000000 0.007715340 0.008944058
   5 0.00000000 0.017518827 0.019259836 0.542582752 1.00000000 0.0000000 0.014219656 0.016484228
   6 0.00000000 0.000000000 0.000000000 0.000000000 0.00000000 1.0000000 0.121137618 0.000000000
   7 0.00000000 0.146145917 0.006633427 0.007715340 0.01421966 0.1211376 1.000000000 0.005677459
   8 0.26062625 0.006994714 0.007689843 0.008944058 0.01648423 0.0000000 0.005677459 1.000000000

これで、同じマトリックス内のすべての町と水域の間の類似度スコアのマトリックスが得られました。ただし、この行列の半分の距離だけを気にします。したがって、以下の apply 関数のインデックス表記は次のようになります。

best.match <- apply(d[5:8,1:4], 1, function(row) if(all(row == 0)) NA else which.max(row))

出力は次のとおりです。

> cbind(water, towns[best.match])
     water                                                                                       
[1,] "Alturas City of"                                  "Alturas city, Modoc County"             
[2,] "Casitas Municipal Water District"                 NA                                       
[3,] "California Water Service Company Bellflower City" "Bellflower city, Los Angeles County"    
[4,] "Contra Costa City of Public Works"                "Acalanes Ridge CDP, Contra Costa County"

NA 値に注意してください。NA は、水域とすべての町の間で一致する単語が 1 つもない場合に返されます。

于 2016-04-28T18:10:00.207 に答える
0

base だけを使用してそれを行う別の方法Rwater文字列をusingから分割してリストを作成し、これらの文字列のどれがusingstrsplitで見つかったかを確認します。これで、4 つの論理行列のリストができました。を適用すると、各行の「TRUE」の合計が得られます。「TRUE」値が最も多い行を識別するために使用します。最後に、これらの値をインデックス作成に使用します。 townsgreplrowSumswhich.maxtowns

lst <- lapply(strsplit(water, ' '), function(i)
                       sapply(tolower(i), function(j)
                                 grepl(j, tolower(towns))))

ind <- unlist(as.numeric(lapply(lst, function(i)
                   which.max(rowSums(i)[!is.na(match(TRUE, i))]))))

cbind(water, towns[ind])
#            water                                                                                       
#[1,] "Alturas City of"                                  "Alturas city, Modoc County"             
#[2,] "Casitas Municipal Water District"                 NA                                       
#[3,] "California Water Service Company Bellflower City" "Bellflower city, Los Angeles County"    
#[4,] "Contra Costa City of Public Works"                "Acalanes Ridge CDP, Contra Costa County"

補足: 以前は、マトリックスに実際に「TRUE」値がある場合に[!is.na(match(TRUE, i))]のみ計算していました。rowSumsそうでなければ、すべてrowSums'FALSE' の 4 x 4 論理0, 0, 0, 0行列which.max(c(0, 0, 0, 0))1

于 2016-04-28T20:27:32.657 に答える